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.