Git pre-commitフックでFrontmatterの「更新日時」を自動更新する
今までブログ記事コンテンツの「更新日時」はgitの履歴情報を元にしていました。
たとえば、Hugoの場合はenableGitInfo = trueとすると、Gitの履歴情報からMarkdownの最終更新日時を自動で取得してlastmodとして割り当てられていました。
しかし、GitHub ActionsでHugoのビルドを行う際に、全履歴を取得するのをやめたことで、Markdownのlastmodの項目を見るように変更しています。
今後はlastmodをメンテナンスする必要があるため、いちいち「更新日時」を手動更新するのではなく、gitのpre-commitフックを利用して更新日時を自動更新する方法を調べました。
Git hooksとは
git hooksとは特定のアクションが発生した時に、カスタムスクリプトを実行する方法を指します。
git hooksは、クライアントサイドとサーバーサイドの2つに分類できます。
クライアントサイドのコミット時フック(コミットプロセスに関する)には主な4つがあります。
pre-commit- コミットメッセージが入力される前に実行
prepare-commit-msg- コミットメッセージエディターが起動する直前、デフォルトメッセージが生成された直後に実行
commit-msg- コミットメッセージを保存した一時ファイルへのパスをパラメータに取る
post-commit- コミットプロセスが全て完了した後に実行
今回はpre-commitフックを利用して、対象のMarkdownファイルをCommitした際に、更新日時を自動的に更新させます。
pre-commit shell script
次のShell Scriptを.git/hooks/pre-commitとして作成して、chmod +xなどで実行権限を付与します。
あとは、git commitコマンドを実行した際には、自動的にlastmodが更新されるようになります。
#!/bin/sh
# Read YAML front matter in all the modified files for committing,
# and replace "lastmod:" line to "lastmod: current date and time"
git diff --cached --name-status | grep "^M" | while read a b; do
cat $b | sed "/---.*/,/---.*/s/^lastmod:.*$/lastmod: $(TZ=Asia/Tokyo date "+%Y-%m-%dT%T")+09:00/" > tmp
mv tmp $b
git add $b
doneWindowsの場合
ファイル先頭が#!/bin/shだとerror: cannot spawn .git/hooks/pre-commit: No such file or directoryというエラーが発生しました。
#!/bin/bashに変更することで動作することを確認しました。
#!/bin/bash
git diff --cached --name-status | grep "^M" | while read a b; do
cat $b | sed "/---.*/,/---.*/s/^lastmod:.*$/lastmod: $(TZ=Asia/Tokyo date "+%Y-%m-%dT%T")+09:00/" > tmp
mv tmp $b
git add $b
done参考
まとめ
面倒でついつい更新をサボってしまうような処理は自動化するのがよいですね。 今回このスクリプトを用意したことで、今後は意識せずとも更新日時が更新されるようになります。
参考
Related contents

TECH
2018.07.11

TECH
2021.01.24

TECH
2021.01.09

TECH
2023.07.24

TECH
2023.02.03

TECH
2022.09.03

TECH
2022.08.29

TECH
2022.08.14