entry emoji

GitでAuthor DateとCommiter Dateを揃える

少し前に知人とGitの話題になり「コミット後のちょっとした修正でgit commit --amendするけど、git logしても日付って変わらないのね」と言われて、AuthorとCommitterの話をしました。

TL;DR

  • GitにはAuthorとCommiterという概念があり、それぞれによる作業日付が記録されています。
  • git log --pretty=fullerを実行すると、Author DateCommitter Dateが確認できます。
  • Author Date--amendで、Committer Daterebaseでオプションを併用すると書き換えられます。
  • ただし日付の書き換えは、リポジトリに関わる他のメンバーに影響がない範囲で行うようにしましょう。

--amendによるコミット記録の書き換えでは日付が変わらない?

コミットに対して追加修正を含める(=コミット自体を修正する)場合にcommit --amendを行いますが、実行前後のログの日付を確認してみます。

$ git log
commit 1b0f146212cecb3a9fa090eb85d71a662315176c (HEAD -> main)
Author: Hoge Fuga <[email protected]m>
Date:   Mon Jun 10 18:50:32 2024 +0900
 
    initial commit
 
$ git commit --amend
 
$ git log
commit bb2e1ea5af18504baac4de3565d0b839651a080f (HEAD -> main)
Author: Hoge Fuga <[email protected]m>
Date:   Mon Jun 10 18:50:32 2024 +0900
 
    initial commit

変わらずどちらもMon Jun 10 18:50:32 2024 +0900となっていますね。

なぜかというと、ここで表示されているのはAuthorによって記録された日時だからです。

AuthorとCommitterとは?

Pro Gitの「2.3 Viewing the Commit History」には、Authorは作業を行った人、Committerはその作業を適用した人と記載がされています。

You may be wondering what the difference is between author and committer. The author is the person who originally wrote the work, whereas the committer is the person who last applied the work. So, if you send in a patch to a project and one of the core members applies the patch, both of you get credit — you as the author, and the core member as the committer.

AuthorとCommitterの詳しい位置づけについては「5.1 Distributed Workflows」に記載されているので割愛しますが、ローカルリポジトリでは通常「作業を行った人=作業を適用した人」になるので、コミット直後はAuthorによる作業日時とCommitterによる作業日時は同じ日時を示します。

サブコマンドのlog--pretty=fullerオプションを付けてコミットログを見てみます。

commit bb2e1ea5af18504baac4de3565d0b839651a080f (HEAD -> main)
Author:     Hoge Fuga <[email protected]m>
AuthorDate: Mon Jun 10 18:50:32 2024 +0900
Commit:     Hoge Fuga <[email protected]m>
CommitDate: Mon Jun 10 18:55:16 2024 +0900
 
    initial commit

Authorの下のDateがAuthor Dateに変化して、その下にCommitとCommit Dateが追加されました。 AuthorDateについてはMon Jun 10 18:50:32 2024 +0900ですが、CommitDateMon Jun 10 18:55:16 2024 +0900と時間がずれています。この時間がcommit --amendをした時間になります。

ざっくりまとめると次のようになります。

  • AuthorDateは基本はコミットが作成された日時が記録される
  • CommitDateAuthorDateと同様になる
  • ただしCommitDateはそのコミットに対してcommit --amendrebaseなどが行われると、Committerによりその作業を適用した日時で上書きされる

それぞれの日付を書き換える

例えばローカルで修正中に頻繁にcommit --amendを繰り返してAuthorDate ≠ CommitDateとなった状態をAuthorDate = CommitDateにしたいという場合も考えられます。 その場合はrebaseのオプションに--committer-date-is-author-dateを付与することで、CommitDateをAuthorDateに揃えることができます。

$ git rebase <branch> --committer-date-is-author-date

今回は初回コミットに対して操作するので--rootオプションでrebaseします。

$ git rebase --root --committer-date-is-author-date
$ git log --pretty=fuller
commit 849cfd5be35d65fc93925eb9b584c6abbfebb0d6 (HEAD -> main)
Author:     Hoge Fuga <[email protected]m>
AuthorDate: Mon Jun 10 18:50:32 2024 +0900
Commit:     Hoge Fuga <[email protected]m>
CommitDate: Mon Jun 10 18:50:32 2024 +0900
 
    initial commit

AuthorDateとCommitDateがMon Jun 10 18:50:32 2024 +0900で揃いました!

上記はCommitDateをAuthorDateに合わせましたが、逆にCommitDateに合わせたい場合は次のようにします。

$ git rebase <branch> --ignore-date

またAuthorDateを書き換えることもできます。commit --amend --date="<日時>"で可能です。

$ git log
commit 1b0f146212cecb3a9fa090eb85d71a662315176c (HEAD -> main)
Author: Hoge Fuga <[email protected]m>
Date:   Mon Jun 10 18:50:32 2024 +0900
 
    initial commit
 
$ git commit --amend --date="Mon Jun 10 18:30:32 2024 +0900"
 
$ git log
commit 1b0f146212cecb3a9fa090eb85d71a662315176c (HEAD -> main)
AuthorDate: Hoge Fuga <[email protected]m>
Date:   Mon Jun 10 18:30:32 2024 +0900
Commit:     Hoge Fuga <[email protected]m>
CommitDate: Mon Jun 10 19:27:15 2024 +0900
 
    initial commit

ただしこの時はもちろんCommitDateが更新されるので、必要に応じて--committer-date-is-author-dateで合わせましょう。

最後に

日付を改ざんすることはそうそうやるオペレーションではないですが、何らかの理由で揃えたい時はありそうです。そんな時に備えて、AuthorとCommiterという概念を覚えておくと便利かなと思います!