Using Git Worktree to Deploy GitHub Pages
GitHub Pages is a website hosted directly from your GitHub repository. Generally, it is used together with static site generators. Static site generators (e.g. Jekyll, Hugo, and Gitbook) make the process of making a site easily and the generated HTML pages can be hosted on GitHub Pages.
When you use static site generators, there would be sources and generated files. For hosting on GitHub Pages, it needs generated files but not sources. GitHub Pages supports to select a source branch: master or gh-pages. So, general configuration is to have sources in master branch and put generated files in gh-pages branch.
In this configuration, there is a cumbersome deploy work. Static site generators usually generate files in the subdirectory such as _site. Since there are two branches, master and gh-pages, you need to move them from master branch to the root directory of gh-pages branch. It is required whenever you want to deploy.
Since Git 2.5, Git supports to manage multiple working trees attached to the same repository. With that, you can mount a git branch as a subdirectory. This makes a deploy process easier and it doesn’t require git checkout. Let’s see how to do it step by step.
Setup
First of all, you need to have a gh-pages branch which is going to be mounted. If you don’t have, you can create a branch with git branch.
$ git branch gh-pagesThis makes a branch based on the master HEAD. It would be okay but the files and the git history of master branch are not meaningful on gh-pages branch. Using an orphan branch, you can initialize gh-pages in a clean way.
$ git checkout --orphan gh-pages
$ git reset --hard
$ git commit --allow-empty -m "Init"
$ git checkout masterThen, you can mount the branch as a subdirectory using git worktree. Make sure that you don’t have an existing target subdirectory.
$ rm -rf _site
$ git worktree add _site gh-pages
Preparing _site (identifier _site)
HEAD is now at b475e3e Initializing gh-pages branchIf you didn’t ignore
_sitein git, ignore it so that you don’t add generated files accidentally.
$ echo "_site" >> .gitignoreWhen everything is set correctly, git branch shows a different branch for a root directory and a subdirectory.
$ git branch
gh-pages
* master
$ cd _site
$ git branch
* gh-pages
masterDeploy
When you build a static site, generated files are in _site directory. Since _site is now gh-pages branch, you can deploy by just creating a commit and pushing it.
$ cd _site
$ git add --all
$ git commit -m "Deploy updates"
$ git push origin gh-pagesClean Up
To unmount the subdirectory, you can run a below command. When you run, it will remove the worktree information and the mounted subdirectory.
$ git worktree remove _siteIf you delete the
_sitedirectory withoutgit worktree remove,git worktreedoesn’t know it and keep showing it in thegit worktree list. It will be eventually removed (gc.worktreePruneExpire). If you clean up immediately, rungit worktree prune.
Automate with Script
You now understand how to do it step by step. Now, it’s time to automate with a shell script. Using below script, you just need to run it when you want to deploy.