脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

Gitの過去のcommitのユーザ名やemail addressを変える方法

過去のコミットのユーザ名やemail addressを変更する方法です。
typoに後から気づいた場合や、アカウントを使い分けていたが統一したくなった場合など。

注意

歴史改変になるのでバックアップ推奨

コマンド

以下のコマンドをコマンドラインで実行する

git filter-branch -f --commit-filter '
if [ "$GIT_AUTHOR_NAME" = "#{置き換え対象ユーザ}" ];
then
GIT_AUTHOR_NAME="#{置き換える文字}";
GIT_AUTHOR_EMAIL="#{置き換えるメールアドレス}";
git commit-tree "$@";
else
git commit-tree "$@";
fi' #{対象のブランチ名}

1. git log確認

今回は以下のように2nd commitを間違ったユーザ(hoge)から正しいユーザ(nouziru)へ変更する

$ git log

commit 503d00b7c70fa087da7fdb5f38ad0a42b1600b14
Author: nouziru <nouziru@email.com>
Date:   Wed Oct 28 15:49:04 2015 +0900

    3rd commit

commit 63ee4eb104423cc396531b30a978f5c20a579ace
Author: hoge <hoge@email.com>  //<===== nouziru <nouziru@email.com>にしたい!!
Date:   Wed Oct 28 15:48:46 2015 +0900

    2nd commit

commit 6469392ccbfa54767579fd8b0099f6ef740b8e88
Author: nouziru <nouziru@email.com>
Date:   Wed Oct 28 15:48:16 2015 +0900

    fist commit
実行
$ git filter-branch -f --commit-filter '
> if [ "$GIT_AUTHOR_NAME" = "hoge" ];
> then
> GIT_AUTHOR_NAME="nouziru";
> GIT_AUTHOR_EMAIL="nouziru@email.com";
> git commit-tree "$@";
> else
> git commit-tree "$@";
> fi' master
  # => Rewrite 503d00b7c70fa087da7fdb5f38ad0a42b1600b14 (3/3)
  # => Ref 'refs/heads/master' was rewritten
確認
$ git log
commit f23730c51cc33ba0a25a10f5e5b1c6cbd8d29fb4
Author: nouziru <nouziru@email.com>
Date:   Wed Oct 28 15:49:04 2015 +0900

    3rd commit

commit 044ea6d1b751846aeb67151ba4729c148b63ecc0
Author: nouziru <nouziru@email.com>  //<====なおってる!!
Date:   Wed Oct 28 15:48:46 2015 +0900

    2nd commit

commit 6469392ccbfa54767579fd8b0099f6ef740b8e88
Author: nouziru <nouziru@email.com>
Date:   Wed Oct 28 15:48:16 2015 +0900

    fist commit

無事Author: hoge からAuthor: nouziru へと変更することが出来ました。
pushしてしまっている場合は-fコマンドで上書き修正できます。

うまくいかない場合

エラー1
You need to run this command from the toplevel of the working tree.
  # =>.gitディレクトリがあるディレクトリで実行しなければいけない
エラー2
fatal: missing object 0000000000000000000000000000000000000000 for refs/remotes/origin/HEAD
 #⇒refsのHEADの参照先が置換しようとしてるディレクトリだと出る

#対象ディレクトリを変更する
tree .git/refs/  
vi .git/refs/remotes/origin/HEAD

# GithubのWeb Consoleの方でも一応変更
 => Setting ⇒ Options ⇒Default Branchを変更

Tips

既に他のブランチにmergeされている場合
  • 修正後のブランチと、修正前のブランチが両方存在する状態になる
  • 必要なけれな修正前のブランチは削除する
    • マージされた(受け取り側)ブランチを削除すれば自動で消える
    • 枝分かれしたブランチはそのまま残るので、必要に応じて削除