Adding last modified timestamps with Git
A common ask of Jekyll, Gatsby, and other static site generator users is, “how do I automatically set the date in YAML front matter?” Today I learned you can do just that with a Git pre-commit hook.
If your project has been setup with git init
you should have a Git hooks directory with several sample files to inspect.
├── .git
│ └── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── ...
You can either create a new file named pre-commit
inside of the hooks
directory (or rename the .sample
file). Then add the following shell script:
#!/bin/sh
# Contents of .git/hooks/pre-commit
# Replace `last_modified_at` timestamp with current time
git diff --cached --name-status | egrep -i "^(A|M).*\.(md)$" | while read a b; do
cat $b | sed "/---.*/,/---.*/s/^last_modified_at:.*$/last_modified_at: $(date -u "+%Y-%m-%dT%H:%M:%S")/" > tmp
mv tmp $b
git add $b
done
Now when you commit a modified file with Git, the value of last_modified_at
will be replaced with the current time i.e., YYYY-MM-DDThh:mm:ss
. If you’re using a different front matter variable for modified timestamps, adjust the script above accordingly.
Before commit | After commit |
---|---|
last_modified_at: | last_modified_at: 2021-08-04T20:34:59 |
I’ve always followed the convention of using date
for published timestamp and last_modified_at
for the modified timestamp. Mostly because core Jekyll plugins like jekyll-sitemap and jekyll-feed support that front matter value.
---
title: "My awesome Markdown post"
date: 2020-01-01
last_modified_at: 2021-08-04T20:34:59
---
I’d be interested if the script could be improved on to append the date if last_modified_at
hasn’t already been added, and replace the value if it has. Let me know below if you have any improves there.
I’m also not sure if this pre-commit hook is automatically installed when the Git repository is cloned. Do I need to install it on both my iMac running macOS and laptop running Windows 10? Or does it come along for the ride when push/pulling from remote?
Tags: Static sitesTILTutorials
5 comments
Brilliant, thanks. I’ve checked, and based on git-scm:
Something weird happened after I implemented the hook. Code-wise was perfect,
last_modified_at
worked like a charm. However, after I’ve added the same hook to my colleague’spre-commit
hook, she committed a big chunk of images, which turned all of them into 0-bytes files.After a test, the same happened to me, so I removed the hook and the issue went away. Did this happened to you?
@Simone - I’ve only used this method to do some light testing and didn’t see any issues.
I did come across more robust versions of precommit hooks that appeared to check against file type, which would probably get around your issue of messing with binary files like images. For example this blog post has a version that looks for modified
.html
files. I’m sure it could be adapted for.md
.All that said, not sure if I completely trust either scripts 💯 and still add last modified dates in a somewhat manual way using the Insert Date String VS Code plugin to drop in a new timestamp after I touch a file.
Thanks for your help. Just checked that VS extension… it might be time to leave Atom for good. After I left Sublime Text for good a few years ago. And that was after I ditched Textmate 😬
I made a script that would update all “*.md” files to add in last_modified_at tag to every single one of them. It worked for all my existing .md files. If there’s any exceptions please let me know.
https://pastebin.com/jz3zYL6p