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
done
Windowsの場合
ファイル先頭が#!/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