【Git】過去のコミットのメールアドレスを全て変える

先日、開発に使う用のメールアドレスを新しく作ったのだが、今コミットしている自分の個人用レポジトリを git log で見ると、プライベート用のメールアドレスも混じってしまっていた。なんとなく気持ち悪いというだけなのだが、統一する方法はないかと調べてみたところ filter-branch というコマンドが使えそうだった。

filter-branchとは

filter-branch は、大量のコミットを機械的に書き換えるためのコマンドである。もちろん非常に危険なコマンドで、ドキュメントの最初にWARNINGが書かれているだけでなく、実行すると最初の数秒間は処理が開始されずWARNINGメッセージが表示されるほどである。
非常に容量が大きいファイルを誤ってコミットしてしまったり、かなり前のコミットを変えたいがそれ以降の多くのコミットに影響してしまうという時に使われることが多い。

git-scm.com

メールアドレスを変える

今回はコミットの中身は変えず、author/commiter情報を書き換えたいだけなので、 --env-filter オプションを使う。注意点として、今回のレポジトリは自分一人しかコミットしていないが、もし他人のコミットも混じっている場合、 --commit-filter オプションの中でif文などを書き、コミットを絞り込む必要がある。

git filter-branch -f --env-filter \
'GIT_AUTHOR_EMAIL="udomomo@example.com"; \
GIT_COMMITTER_EMAIL="udomomo@example.com"; \
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"' HEAD

--env-filter オプションの中で、author/commiterそれぞれの新しいメールアドレスを指定している。末尾の HEAD は、対象となるコミットの範囲を指定するもの。今回の場合、initial commitからの全てのコミットが対象となる。
また、最後の行の export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" は、コミットの日付を変えないためのもの。Gitにはタイムスタンプが2つあり、 git log で表示される日付は GIT_AUTHOR_DATE だが、GitHub等で参照される日付は GIT_COMMITER_DATE の方。
そのため、GIT_COMMITER_DATEGIT_AUTHOR_DATE に合わせないと、コミットの日付が今日になり、草が変わってしまう。なお、 git log --verboseGIT_COMMITER_DATE も表示させることができる。

git-scm.com