I recently switched to using Hugo to generate this site and needed a strategy to publish it. Previously I was using Octopress which has scripts for managing the gh-pages branch automatically. The documentation on gohugo.io shows a workflow that uses
git subtree, a tool I knew about but had never actually used before. I found the tutorial on the gohugo.io page to be confusing. Here, I describe the approach I used instead.
My goal is to have a clean
gh-pages branch that contains the minimum content it needs to have a meaningful history, and a
master branch that makes sense.
The first thing to do is generate the site in
public/ by running
hugo while on
master and in the root directory of the repository:
$ git checkout master $ hugo
At this point, create an orphaned
$ git checkout --orphan gh-pages
gh-pages branch won’t show up in
git branch yet. Don’t worry about that.
If you check
git status you’ll see a bunch of staged files–the contents that were in
master. Unstage these with
$ git reset .
Now everything that was staged will be untracked. Clean up those untracked files with
git clean, excluding public:
$ git clean --force -d --exclude public
Now you should see
public/ as the only untracked directory.
Of course, GitHub Pages wants the content that’s currently in
public/ as the root of the
gh-pages branch. Let’s make that happen. Copy the contents of
public/ to the current directory with the tool of your choice, like
$ mv public/* .
At this point you can safely get rid of
public/, so run
git clean again, this time only including
$ git clean --force -d public # or just rm -r public
Now you’re in a position to add everything that was in
public/, and is now in the current directory, to make the initial commit. I used “Generate site” as the message:
$ git add . $ git commit -m "Generate site"
Note: Only after making the above commit will the
gh-pages branch appear in
Now push the
gh-pages branch to origin:
$ git push -u origin gh-pages:gh-pages
At this point your GitHub Pages site will be generated by GitHub, and will be live shortly.
The following steps are what we’ll do to make re-generating and updating the site an easy affair. First, check out
$ git checkout master
Now that the branch is on the remote, we’ll add it as a subtree under
master. Be sure to replace the
<placeholder> with your own repo:
$ git subtree add --prefix public <repo_url> gh-pages
ls public you’ll see the content generated by hugo, and if you
git log -2 you’ll see the commit you made on
gh-pages in addition to the commit that added the subtree to
master and you’re all set:
$ git push origin master:master
Now each time you update something in
- commit the changes to
- re-generate the site with
- commit the changes to
- push the changes to the subtree (which will update
- push the changes to
$ git add content $ git commit -m "Added insightful post on the social lives of kittens" $ hugo $ git add public $ git commit -m "Regenerate site" $ git subtree push --prefix public <repo_url> gh-pages $ git push origin master:master
Now when you look at the history of
gh-pages, all you’ll see are the generate/regenerate commits:
$ git fetch gh-pages $ git log gh-pages 102c92b 6 minutes ago Kris Hicks | Regenerate site af759b6 10 minutes ago Kris Hicks | Regenerate site 69045e6 2 hours ago Kris Hicks | Generate site
master you’ll see the changes to the content, in addition to the changes on the subtree:
$ git log master 1df64be 7 minutes ago Kris Hicks | Regenerate site d244956 8 minutes ago Kris Hicks | Update phone-interviews post with HN link 66c4e29 11 minutes ago Kris Hicks | Regenerate site bea8982 11 minutes ago Kris Hicks | Update rerere post 456c79e 14 minutes ago Kris Hicks | Add static/ cfb98dc 18 minutes ago Kris Hicks | Add 'public/' from commit '69045e6db8a929e0476c7553917981e3c9545c4e' 69045e6 2 hours ago Kris Hicks | Generate site daf97fc 3 hours ago Kris Hicks | Add keybase.txt 483bfec 3 hours ago Kris Hicks | Add CNAME
This makes more sense to me than the approach listed on the gohugo.io tutorial, which leaves you with weird merge commits and messy history otherwise.