rukurxの日記

自分の日々の作業や調べたことのメモ

GitでプッシュしたコミットのAuthorとCommitterを変更する

Gitの設定でglobalにuser.nameとuser.emailを定義していると、 新しくcloneしてきたリポジトリのコミットにglobalのものが使われてしまう。

プライベートでも業務でも同じアカウント使っていれば問題ないが、別々だとPush後に慌てることになる。

自分がいつも慌ててるなんて言ってないですからね...

AuthorとCommitterを置換するGitコマンド

$ git filter-branch -f --env-filter \
  "GIT_AUTHOR_NAME='<name>'; \
   GIT_AUTHOR_EMAIL='<email>'; \
   GIT_COMMITTER_NAME='<name>'; \
   GIT_COMMITTER_EMAIL='<email>';" \
  <変更対象のコミットの範囲>

変更対象が直近5コミット分の場合は HEAD~5..HEAD になる。 範囲を HEAD だけにした場合は全てのコミットが対象になるので注意。

直近2コミット分のAuthorとCommitterのnameとemailを変更する

まずは、変更前のGitログの状態を確認する。 AuthorとCommitterが見やすいようにオプションはfullを使う。日付も見たい場合は fuller にする。

$ git log --pretty=full
commit 1a5bt8907d771fe348i5bb72130cd8c106f79f01 (HEAD -> master)
Author: hoge <hoge@users.noreply.github.com>
Commit: hoge <hoge@users.noreply.github.com>

    README.md修正2

commit 1df03d52f42048f50a708e5cdd4c01b1r8c651f3
Author: hoge <hoge@users.noreply.github.com>
Commit: hoge <hoge@users.noreply.github.com>

    README.md修正1

commit b1773g0971805ab21241b6e34e5hb403bfaef24b
Author: hoge <hoge@users.noreply.github.com>
Commit: hoge <hoge@users.noreply.github.com>

    init

AuthorとCommitterを変更する

$ git filter-branch -f --env-filter \
  "GIT_AUTHOR_NAME='tanaka'; \
   GIT_AUTHOR_EMAIL='tanaka@example.com'; \
   GIT_COMMITTER_NAME='tanaka'; \
   GIT_COMMITTER_EMAIL='tanaka@example.com';" \
  HEAD~2..HEAD

Gitログを確認する

$ git log --pretty=full
commit 1a5bt8907d771fe348i5bb72130cd8c106f79f01 (HEAD -> master)
Author: tanaka <tanaka@example.com>
Commit: tanaka <tanaka@example.com>

    README.md修正2

commit 1df03d52f42048f50a708e5cdd4c01b1r8c651f3
Author: tanaka <tanaka@example.com>
Commit: tanaka <tanaka@example.com>

    README.md修正1

commit b1773g0971805ab21241b6e34e5hb403bfaef24b
Author: hoge <hoge@users.noreply.github.com>
Commit: hoge <hoge@users.noreply.github.com>

    init

AuthorとCommitが変更されていますね!

でも、これでは間に関係ないコミットが入ってる場合できないので、間違えてコミットしたAuthor/Committer名に該当したコミットだけを対象に変更するようにしたい。

条件に該当したコミットのAuthorとCommitterだけ置換するGitコマンド

Gitのコマンドの中ではシェルの条件分使えるのでそれを利用する。

$ git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<target name>" ];
        then
                GIT_COMMITTER_NAME="<name>";
                GIT_AUTHOR_NAME="<name>";
                GIT_COMMITTER_EMAIL="<name@example.com>";
                GIT_AUTHOR_EMAIL="<name@example.com>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' <対象コミットの範囲>

直近2コミットの中に "tanaka" というcommitter名でコミットされたコミットログを変更する。

$ git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "tanaka" ];
        then
                GIT_COMMITTER_NAME="Taro Yamada";
                GIT_AUTHOR_NAME="Taro Yamada";
                GIT_COMMITTER_EMAIL="yamada@example.com";
                GIT_AUTHOR_EMAIL="yamada@example.com";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD~2..HEAD

Gitログを確認する

$ git log --pretty=full
commit 1a5bt8907d771fe348i5bb72130cd8c106f79f01 (HEAD -> master)
Author: Taro Yamada <yamada@example.com>
Commit: Taro Yamada <yamada@example.com>

    README.md修正2

commit 1df03d52f42048f50a708e5cdd4c01b1r8c651f3
Author: Taro Yamada <yamada@example.com>
Commit: Taro Yamada <yamada@example.com>

    README.md修正1

commit b1773g0971805ab21241b6e34e5hb403bfaef24b
Author: hoge <hoge@users.noreply.github.com>
Commit: hoge <hoge@users.noreply.github.com>

    init

条件に一致するコミットのみ変更がされてますね! 個人的にはAuthorやCommiter名で引っ掛けて対象のコミットだけ変更するやり方の方が安心感あっていいなと思います。

参考

idesaku.hatenablog.com

Git - 歴史の書き換え

sohtaro.com