Automatically update timestamp in Hugo posts

Feels kinda weird and pretty obsolete to think or write about anything non-Corona these days, but actually it’s probably good to take a mental break from it every so often. I’ve been wanting to document this tiny little hack for a while now, so here goes:

I’m using Hugo to create this blog. Hugo is a so-called static website generator and amazing. It is very flexible and could do much more than just a simple blog. However, as it is not a blogging tool per se, it does not do all the things that specialized solutions like WordPress do. For example, when I publish a new post, it does not automatically set the publishing date to the current timestamp. Instead, the date of a post is set when a new draft is created. It is very rare for me to finish a post on the same day as I start it1, so I always have to fix that before actually publishing, otherwise the posts would be listed with the wrong date.2

Luckily, I’m not alone in having this problem. Roman Peshkov posted a solution in form of a neat little Python script that does all the magic. However, as he notes in the post, it is not happening automagically — running the script is easier than doing it manually, but I still have to run the script myself. Like a Neanderthal!

Even more luckily, I’m using Git to store and publish the blog. That means I can use a git hook to automate this task.

I copied Roman’s Python script into the root directory of my blog and also added this super simple Shell script called hook.sh:

#!/bin/sh

git diff --cached --name-only --diff-filter=A | grep \\.md | xargs -n 1 ./set-publishing-date.py
git diff --cached --name-only --diff-filter=A | grep \\.md | xargs -n 1 git add

Then use a relative symlink to set hook.sh as a pre-commit git hook:

ln -s ../../hook.sh .git/hooks/pre-commit

This means that the script will run after I execute git commit. A bit confusing, yeah. What does the hook-script do? It takes all newly added (--diff-filter=A) Markdown files (grep \\.md) I’m currently trying to commit. Why only those files? Only new ones, because I often fix typos or broken links in older posts, and their date should not be changed. And of course template or code changes should not be automatically modified, only content.

So then the hook-script throws the files into the Python script using xargs, which causes the publishing date to be updated. Because that is a new change to the file(s), they need to be git added again afterwards, otherwise the change would not be recorded within the same commit for which the hook just ran.

It’s not a perfect solution, but I’ve been using it for a few months now and am very happy with not having to manually adjust timestamps anymore.


  1. I finished this post almost within an hour, though. ↩︎

  2. Also, though it is not displayed, the exact time is also stored – so even when finishing on the same day, the publishing timestamp would be off by a few hours. Not acceptable! ↩︎