ある日、git log --oneline を叩いた。
Day 14: チーム定義(24ファイル)
Day 13: 自動化・ツール(34ファイル)
Day 12: コンテンツ・リサーチ(17ファイル)
Day 11: 戦略(12ファイル)
自分の歩みが全部、時系列で残っていた。Day 1 から今日まで、何をやったかが一目でわかる。「あれ、いつやったっけ」がない。日記をつけたことは一度もないのに、git が日記になっていた。
これは手動コミットではない。Mac が勝手にやっている。
なぜ「Day N」をコミットメッセージに入れたか
普通の自動コミットは日時がメッセージに入る。2026-03-19 auto backup みたいなやつ。悪くはない。でも読み返したとき、日付の羅列から「流れ」を感じるのは難しい。
「Day 1」「Day 14」と書いてあると、話が変わる。何日目に何をやったか。どこで加速したか。止まった日はあったか。ログ自体がプロジェクトの年表になる。
しかも計算は自動だ。基準日を一つ決めておけば、あとはスクリプトが date コマンドで勝手に算出する。
auto-backup.sh の中身
やっていることは 3 つ。差分検出、Day N 計算、カテゴリ自動判定。
#!/bin/bash
# プロジェクトの自動バックアップスクリプト
cd "/path/to/project" || exit 1
# 変更がなければ何もしない
if [ -z "$(git status --porcelain)" ]; then
exit 0
fi
# 基準日からの経過日数を計算
FOUNDING_DATE="2026-03-06"
TODAY=$(date '+%Y-%m-%d')
if [[ "$(uname)" == "Darwin" ]]; then
FOUNDING_SEC=$(date -j -f "%Y-%m-%d" "$FOUNDING_DATE" "+%s")
TODAY_SEC=$(date -j -f "%Y-%m-%d" "$TODAY" "+%s")
else
FOUNDING_SEC=$(date -d "$FOUNDING_DATE" "+%s")
TODAY_SEC=$(date -d "$TODAY" "+%s")
fi
DAY_NUM=$(( (TODAY_SEC - FOUNDING_SEC) / 86400 + 1 ))
git add -A
# 変更ファイルのパスからカテゴリを自動判定
CHANGED=$(git diff --cached --name-only)
CATEGORIES=""
echo "$CHANGED" | grep -q "strategy" && CATEGORIES="${CATEGORIES}戦略・"
echo "$CHANGED" | grep -q "automation" && CATEGORIES="${CATEGORIES}自動化・"
echo "$CHANGED" | grep -q "creative" && CATEGORIES="${CATEGORIES}クリエイティブ・"
echo "$CHANGED" | grep -q "research" && CATEGORIES="${CATEGORIES}リサーチ・"
echo "$CHANGED" | grep -q "content" && CATEGORIES="${CATEGORIES}コンテンツ・"
# フォルダ構成に合わせて追加する
CATEGORIES=$(echo "$CATEGORIES" | sed 's/・$//')
if [ -z "$CATEGORIES" ]; then CATEGORIES="更新"; fi
FILE_COUNT=$(echo "$CHANGED" | wc -l | tr -d ' ')
COMMIT_MSG="Day ${DAY_NUM}(${TODAY}): ${CATEGORIES}(${FILE_COUNT}ファイル)"
git commit -m "$COMMIT_MSG"
git push
ポイントを拾っていく
差分がなければ即終了。 git status --porcelain が空なら exit 0。空コミットは作らない。ログが汚れるだけだ。
macOS と Linux で date の書式が違う。 -j -f は macOS の BSD date。Linux の GNU date は -d を使う。ここをサボると CI で事故る。uname で分岐させておく。
Day N の計算は単純な引き算。 UNIX秒に変換して差分を取り、86400(1日の秒数)で割る。+1 しているのは「Day 0」ではなく「Day 1」から始めたいから。
カテゴリ自動判定は grep のパターンマッチ。 フォルダ名に特定の文字列が含まれていれば、対応するカテゴリを連結する。最後に末尾の区切り文字を sed で削る。どのフォルダにもマッチしなければ「更新」をデフォルトにする。
正直、カテゴリ判定は雑だ。複数フォルダにまたがる変更だと「戦略・自動化・リサーチ(42ファイル)」みたいな長いメッセージになる。でもそれはそれで「今日はいろいろやったな」とわかるので、問題にしていない。
launchd で定期実行する
Mac で定期実行するなら launchd 一択。cron は macOS で非推奨だし、スリープ復帰後の挙動が怪しい。launchd ならスリープ中にスケジュールを過ぎても、復帰時に実行してくれる。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.yourname.auto-backup</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/path/to/auto-backup.sh</string>
</array>
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Hour</key><integer>12</integer>
<key>Minute</key><integer>0</integer>
</dict>
<dict>
<key>Hour</key><integer>23</integer>
<key>Minute</key><integer>0</integer>
</dict>
</array>
<key>StandardOutPath</key>
<string>/tmp/auto-backup-stdout.log</string>
<key>StandardErrorPath</key>
<string>/tmp/auto-backup-stderr.log</string>
</dict>
</plist>
12:00 と 23:00 の 1 日 2 回実行。昼に 1 回、寝る前に 1 回。登録は以下。
cp com.yourname.auto-backup.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.yourname.auto-backup.plist
StandardOutPath と StandardErrorPath は必ず入れておく。launchd はデフォルトで stdout/stderr を捨てるので、トラブル時に何も手がかりがなくなる。/tmp/ に吐いておけば十分。
2 週間回した結果
14 日間で 30 回以上のコミットが自動で積まれた。ログの一部がこれ。
Day 14(2026-03-19): チーム定義(24ファイル)
Day 14(2026-03-19): Mailchimp開通(19ファイル)
Day 13(2026-03-18): 自動化・リサーチ(31ファイル)
Day 12(2026-03-17): 戦略・コンテンツ(18ファイル)
Day 11(2026-03-16): 戦略(12ファイル)
同じ Day に複数コミットがある日は「たくさん動いた日」。ファイル数が多い日は「大きな変更があった日」。逆に Day が飛んでいる日は何もしなかった日、ではなく変更がなかった日。空コミットを作らないから、ログに嘘がない。
「Day 12 に大きな設計変更をした」「Day 13 から自動化フェーズに入った」。こういう流れが、意識しなくても記録されている。手動で書いたら三日坊主で終わるタイプの記録が、勝手に溜まっていく。
注意点と Tips
git add -A のリスク。 全ファイルをステージングするので、.env やクレデンシャルが混入する危険がある。.gitignore を事前にしっかり書いておくこと。自動コミットだからこそ、gitignore が最後の砦になる。
push に失敗しても気づかない。 自動実行なので、ネットワーク障害や認証切れで push が失敗しても通知が来ない。stderr ログを定期的に確認するか、失敗時に通知を飛ばす仕組みを入れるといい。自分は stderr ログを別のスクリプトで監視している。
基準日は一度決めたら変えない。 途中で変えると Day N の連番が壊れる。プロジェクト開始日やチーム発足日など、意味のある日を最初に決めること。
cron ではなく launchd を使う理由。 macOS Ventura 以降、cron は非推奨。launchd はスリープ復帰後の遅延実行に対応している。ノート PC を閉じて翌朝開けたときに、昨晩のバックアップが走る。cron にはこの動きがない。
まとめ
シェルスクリプト 30 行と plist 1 枚。やっていることは地味だ。でも 2 週間後に git log を見たとき、「自分は毎日ちゃんと進んでいた」と数字で確認できる。
日記は続かない。でも git は勝手に書いてくれる。