Gitで複数のコミットの作者・コミット者名・メールを変更するには?

私は学校のコンピュータで簡単なスクリプトを書き、その変更をGitにコミットしていました(自宅のコンピュータからクローンしたペンドライブにあるレポに入れていました)。何度かコミットしているうちに、自分がルート・ユーザーとしてコミットしていることに気づきました。

このコミットの作者を私の名前に変更する方法はありませんか?

ソリューション

作者 (あるいはコミッター) を変更するには、すべての履歴を書き直さなければなりません。 もしそれでいいなら、そしてそれに価値があると思うなら、git filter-branchをチェックしてみましょう。 manページにはいくつかの例が掲載されているので、まずはそれを見てみましょう。 また、環境変数を使って作者やコミット者の名前、日付などを変更できることにも注意しましょう。-- git man ページ]2 の "Environment Variables" の項をご覧ください。

具体的には、次のコマンドですべてのブランチとタグについて**間違った作者名とメールを修正することができます(ソースはこちら)。GitHub helpを参照してください。)

#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
解説 (18)

することもできます。

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "" ];
        then
                GIT_COMMITTER_NAME="";
                GIT_AUTHOR_NAME="";
                GIT_COMMITTER_EMAIL="";
                GIT_AUTHOR_EMAIL="";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

なお、このコマンドをWindowsのコマンドプロンプトで使用する場合は、'の代わりに"を使用する必要があります。

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "" ];
        then
                GIT_COMMITTER_NAME="";
                GIT_AUTHOR_NAME="";
                GIT_COMMITTER_EMAIL="";
                GIT_AUTHOR_EMAIL="";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD
解説 (13)

ワンライナーですが、マルチユーザーのリポジトリを使用している場合は注意が必要です。

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD

文字列に改行を入れた場合(bashでは可能です)。

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='new@email'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='new@email'
  " HEAD
解説 (9)