Simple deployment to GH Pages

The tutorial section on GitHub deployment describes a rather complex approach using Git subtrees. There are two much simpler approaches which I thought are worth sharing.

This is based on the assumption that you are using a project page (no user or organization page, see here for the difference) and that your remote is called “upstream”.

Publish from /docs folder on master branch

As described in the GitHub Pages docs, you can deploy from a folder called docs on your master branch. This requires to change the Hugo publish directory in the site config:

publishDir: "docs"

After running hugo, push your master branch to the upstream repo and choose the docs folder as the website source ("Settings " -> “GitHub Pages” -> “Source” -> “master branch /docs folder”). If that option isn’t enabled, you like haven’t pushed your docs folder yet.

This is the simplest approach but requires the usage of a non-standard publish directory (GitHub Pages cannot be configured to use another directory than docs currenty). Also the presence of generated files on the master branch may not be to eveyone’s taste.

Deployment to gh-pages branch

The easiest way to sync the state of the public directory with your “gh-pages” branch is to create a clone of your repo under public, commit the changes and push them to the “gh-pages” branch in your local repo:

# remove previous publication
rm -rf public
mkdir public

# clone gh-pages branch from the local repo into a repo located within "public"
git clone .git --branch gh-pages public
# generate
# commit the changes in the clone and push them back to the local gh-pages branch    
cd public && git add --all && git commit -m "Publishing to gh-pages" && git push origin gh-pages

# publish
git push upstream gh-pages

That’s my preferred approach as it keeps sources and generated HTML in two different branches, uses the default public folder and also keeps the histories of source branch and “gh-pages” branch fully separated from each other (unlike the subtree approach). Don’t forget to add public to your .gitignore file.

I’m using a script which does this plus a few sanity checks (work area is clean etc.) which you can find in my repo.

Note that if you are on Git 2.5 or later, the new worktree feature can be used alternatively, avoiding the cloning of the repo:

git worktree add -B gh-pages public upstream/gh-pages

This checks out the “gh-pages” branch into public, but it’s linked to the local repo. I.e. if you commit the changes in public that affects the local “gh-pages” branch directly, no further push is needed.


@gunnarmorling This is good stuff and much simple than the gut modules. I think that tutorial was written before a lot of GitHub pages recent improvements (they now make it so that you can basically make any repo a GH Pages site with the click of a button). I think your pointers would be a good addition to the docs.

Thanks! I’ll see whether I can file a pull request for the doc page on GH deployment.

Please file a PR. And just replace the page that is there already. I wrote the part about sub trees, and I guess most of it is out of date by now. And it is good to not give the users too many options. Confuses them.


Delete public folder > create a new empty public folder > clone gh-pages /.git into the public folder > push the public folder to the gh-pages. This method is so simple.
Do you have any ideas about How to make it quickly I mean (1-click publish to gh-pages)?