:books: Today I Learned

How to update a static build in a Git branch

programming Git git

Static site generators like Jekyll or Hugo ingest Markdown and other such files and data to produce a static site that you can then host wherever you want. One free deployment option is GitHub Pages. You just commit the static files to a branch, push to GitHub, and GitHub Pages serves them for you either under *.github.io or under a custom domain if you have one.

This procedure explains a convoluted way of updating your branch when you have a new version of your static site to deploy. Because why do things the easy way when you can do them the hard way?

  1. Initialize an empty repository somewhere:

    cd /path/to/example
    git init
    
  2. Add the GitHub Pages repository as a remote and fetch, but do not checkout, the deployed branch:

    git remote add origin git@github.com:you/example.git
    git fetch origin gh-pages
    

    This avoids a checkout of all files for nothing, which is a somewhat expensive Git operation depending on the number of files in the repository.

  3. Build your static site into the repository (this example assumes a Jekyll site):

    cd /path/to/site
    bundle exec jekyll build --destination /path/to/example
    
  4. Go back to the repository and create a local branch that points to the latest commit, but without switching to the branch to avoid a checkout:

    git branch --track gh-pages origin/gh-pages
    
  5. This is where the Git magic happens. Change the HEAD to point to the new local branch, but do it with the symbolic-ref Git plumbing command:

    git symbolic-ref HEAD refs/heads/gh-pages
    

    This switches to the gh-pages branch which becomes the current branch, but without touching either the working tree or the index of the repository. This means that the index remains in the same state as the latest commit on origin/gh-pages, and the working tree contains your fresh static build with your latest changes.

  6. Stage all additions, modifications and deletions:

    git add .
    

    Any file which was present in the previous version but is no longer present in the newest build of your static site will be automatically marked as deleted by Git.

  7. Commit all changes:

    git commit -m "Deploy on $(date)"
    
  8. Push the new build:

    git push origin gh-pages
    

You can say you used a Git plumbing command at your next meeting.