Gitの過去のコミットメッセージを日時を維持しつつ修正(初回コミット分も含めて)

Gitの過去のコミットメッセージをgit rebaseで修正したところ、CommitDateの日時がたった今の日時に更新されてしまい、GitHub上での表示やgit logの表示がナンセンスな時系列になってしまいました。ここでは、日時は維持しつつメッセージだけを修正する方法を記載します。
なお、初回コミットだけはやり方が異なりますが、それも含めた方法になります。

初回コミットは修正しない場合

修正したいコミットの範囲を指定します。例えば10個前のコミットまでを修正したい場合はHEAD~10になります。なお、指定した範囲内に初回コミットも含んでいるとエラーになるため、後述の方法で行います。
-iをつけるとインタラクティブモードになり、エディタが開いてどのコミットをどう修正するかを指定できます。

git rebase -i HEAD~

コミットメッセージを修正するには、行頭のpickをrewordに書き換えてエディタを保存終了します。すると、reword指定したコミットのコミットメッセージが自動的に次々とエディタで開かれるので、メッセージを修正してエディタを保存終了するのを繰り返します。

メッセージの修正が終わったところで日時を確認すると、CommitDateが現在時刻に更新されたことが確認できます。AuthorDateは維持されています。

git log --pretty=fuller

CommitDateが現在時刻に変わってしまうのが困る場合(今回の場合)は、CommitDateにAutorDateをコピーすることで過去の日時を復元します。

git rebase HEAD~ --committer-date-is-author-date
git log --pretty=fuller

最後に、問題なければリモートにプッシュします。

git push --force

初回コミットも修正する場合

初回コミットは親がいないため扱いが特別になってしまい、HEAD~25のようなHEADからコミット〇〇個分遡ったところまでリベースする、という引数が効きません。例えば初回コミットがHEAD含め25コミット前だった場合、git rebase -i HEAD~25としたいところですがエラーになります。代わりに--rootを使います。

git rebase -i --root

エディタが開くので行頭のpickをrewordに書き換えてエディタを保存終了することを繰り返します。

メッセージの修正が終わったところで日時を確認すると、CommitDateが現在時刻に更新されたことが確認できます。AuthorDateは維持されています。

git log --pretty=fuller

CommitDateにAuthorDateをコピーすることで過去の日時を復元するためにgit rebase --root --committer-date-is-author-dateを実行したいところですが、--rootは効きません。
そこで、まず初回コミットの日時だけを手動で直して、その後で初回コミットより後の分をまとめて直す方法を取ります。

git rebase -i --root

エディタが開くので、初回コミットの行頭のpickだけをeditに書き換えてエディタを保存終了します。

環境変数GIT_COMMITTER_DATEgit log --pretty=fuller表示されていたAuthorDateの値を代入し、--amendを行い、--continueで確定させます。これで初回コミットのCommitDateの値がAuthorDateと同じになります。

GIT_COMMITTER_DATE='Sun Nov 29 18:11:14 2020 +0900' git commit --amend
git rebase --continue
git log --pretty=fuller

次に、初回コミットより後のコミットのCommitDateもAuthorDateと同じにします。例えば初回コミットがHEAD含め25コミット前だった場合なら、HEAD~24とします。

git rebase HEAD~ --committer-date-is-author-date
git log --pretty=fuller

最後に、問題なければリモートにプッシュします。

git push --force

参考

タグ:

コメントを残す