Published: October 27, 2019

Source Control with Hugo

A quick guide about source controlling a statically generated Hugo website

When building a Hugo base website, I think of the code as three parts:

  1. The foundational Hugo code. E.g. The content for blog posts, the archetypes, configuration files, etc.
  2. The theme (and customizations)
  3. The final product (website files)

In order to organize these, and deploy to production easily, I use git submodules.


This project includes all of the foundational Hugo code, excludes the generated website files, and excludes the theme.

├── archetypes
├── configs
├── config.yaml
├── content
├── data
├── layouts
├── Makefile
├── production (git submodule)
├── resources
├── static
└── themes (git submodule in subdirectory)


This is the generated directory I get when running:

hugo --config config.yaml,configs/production.yaml -d production

This directory is also source controlled separately, that way I also have a source controlled copy of what is running in production.

├── about
├── blog
├── categories
├── contact
├── css
├── error
├── .git
├── .gitlab-ci.yml
├── images
├── index.html
├── index.xml
├── sitemap.xml
├── tags
└── taxonomy

I maintain a mirror of production and source via a .gitlab-ci.yml file which automatically builds and deploys the site when pushed to Gitlab.


Since I built a custom theme for Hugo, I also maintain that separately.

The themes directory allows you to store multiple themes, so I control my custom theme in a separate repo for ease of porting and sharing.