LEON SCHERER

BLOG

The problem

Maybe you’ve found yourself in the same position as me:
I use a website generator that takes all the files I wrote and puts a resulting static, ready to be served website into a separate directory. GitHub Pages can only deploy sites located either in the /docs folder or in the root of the gh-pages branch. You could configure the generator to bake into a folder called /docs but the website doesn’t always have to be a documentation, which breeds confusion. It is much cleaner to (git-)ignore the generated files on the main/development branch of the repository and rather deploy them to the root of a completely independent branch (i.e. gh-pages).

The environment

Let’s look at an example project demanding a solution for this problem. Suppose we have a git repository with two branches: main, which is used for the development of the site, and gh-pages, where the prebuilt, static website from /dist is supposed to live. /dist is the directory we want to push to the gh-pages branch.

main
  |-- ...
  |-- dist -----------> gh-pages
						  |-- index.html
						  |-- styles.css
						  |-- scripts.js
						  |-- ...

Using git to make it happen

git worktree lets us define a sub-directory inside a git repo which contains a different branch than the root directory. This way we can checkout and push to multiple different branches at once. We will use the command as follows:

git worktree add dist gh-pages --no-checkout

# Or, more generally:
git worktree add <directory-name> <branch-name>

This will create a file called .git (may be hidden in your file system) inside /dist, which lets the local repository know that the directory is a separate worktree tracking a separate branch. In my case, I don’t want to checkout the branch into the folder (--no-checkout) because it will be deleted by the generator anyway.

With the worktree set up, you can simply change directory (cd dist), make changes, commit them, and push them as you usually would.

Troubleshooting

There is still one piece of the puzzle missing. When building into the /dist folder, most generators delete the whole directory, including our much needed .git file. To save it from deletion, we should copy it before running the generate command, and bring it back to where it belongs after. Now the procedure looks as follows:

# remove worktree for it to be added again
git worktree remove dist

# add worktree again, creating the .git file
git worktree add dist gh-pages --no-checkout

# save .git file from being deleted by the generator
cp dist/.git ~.git.tmp

# generate website here (could be any generator; I'm using NuxtJS).
nuxt generate

# restore .git worktree marker file
mv ~.git.tmp dist/.git

# change directory and do what you like
cd dist

Also, make sure to add the dist folder to the main branch’s .gitignore file.