間違ったメールアドレス/名前を修正するためにgitの履歴を編集するにはどうすればよいですか[クローズ]


76

私はgitのを使用し始めたとき、私はちょうどでしたgit initし、呼び出しを開始addしてcommit。今、私は注意を払い始めており、私のコミットがcowens@localmachine希望のアドレスではなくとして表示されていることがわかります。設定かのように表示されますGIT_AUTHOR_EMAILGIT_COMMITTER_EMAIL、私がやりたいだろうが、私はまだ間違ったメールアドレス/名前を持つこれらの古いコミットをして。古いコミットを修正するにはどうすればよいですか?


4
将来の読者向け:gitこれに似た目的での使用についての質問は、Stack Overflowでより適切に尋ねられます。
マイケルハンプトン

stackoverflow.comで最も近い質問です。
naught101 14

回答:


82

git filter-branchを1回呼び出すだけで、戻ってすべてのコミットを修正できます。これはリベースと同じ効果がありますが、各コミットを個別に修正するのではなく、1つのコマンドを実行するだけですべての履歴を修正できます。

このコマンドですべての間違った電子メールを修正できます:

git filter-branch --env-filter '
    oldname="(old name)"
    oldemail="(old email)"
    newname="(new name)"
    newemail="(new email)"
    [ "$GIT_AUTHOR_EMAIL"="$oldemail" ] && GIT_AUTHOR_EMAIL="$newemail"
    [ "$GIT_COMMITTER_EMAIL"="$oldemail" ] && GIT_COMMITTER_EMAIL="$newemail"
    [ "$GIT_AUTHOR_NAME"="$oldname" ] && GIT_AUTHOR_NAME="$newname"
    [ "$GIT_COMMITTER_NAME"="$oldname" ] && GIT_COMMITTER_NAME="$newname"
    ' HEAD

詳細はgit docsから入手できます


11
git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL = "foo@example.com"; GIT_AUTHOR_NAME = "Foo"'の方がはるかに簡単です、ありがとう。これを変更できれば、これは受け入れられた回答になります(サーバー障害にバグがあるようです)。
チャス。オーエンズ

7
エクスポート行の等号の両側にスペースがあってはならないことに注意してください。つまり、次のようになります。export GIT_AUTHOR_EMAIL = "(correct email)";
アンディバラム

1
さて、Windowsでこれをどのように行うのでしょうか?
カールステンシュミッツ

2
@Deckard:スクリプトをfixcommits.shなどのテキストファイルに保存し、Git Bashを実行してスクリプトを実行します。私はその後、私は./fixcommits.shでスクリプトを実行した後、Gitのバッシュでそのフォルダに移動し、私のレポのルートにスクリプトファイルを置く
Avalanchis

2
補遺1このコマンド形式は私にとっては機能しませんでしたが、もしそうなら:if [ "$GIT_AUTHOR_EMAIL" = "$oldemail" ]; then GIT_AUTHOR_EMAIL="$newemail"; fi
ジョシュM.

28

Gitのfilter-branchコマンドは強力ですが、たとえば修正する著者が複数いる場合など、些細でないものに使用するのは恐ろしく扱いにくいです。

git-shortlogのマンページで説明されている.mailmap機能を使用する便利な代替手段を次に示します。これにより、gitログのフォーマット機能で使用できる著者マッピングメカニズムが提供されます。これを使用して、コミットの名前付きシーケンスを選択および修正するコマンドを生成できます。

たとえば、ブランチ$ BRANCHのオーサーシップを修正し、コミット$ STARTで開始するとします。

リポジトリの最上位ディレクトリに.mailmapファイルを作成する必要があります。このファイルは、既存の著者名を正しい名前にマッピングします。既存の著者名のリストを取得するには:

git shortlog -se

このような.mailmapファイルで終わる必要があります(たとえば):

You <you@somewhere.org>   cowens@localmachine
You <you@somewhere.org>   root@localmachine

git logのフォーマット機能を使用して、$ BRANCHを$ BRANCH2に書き換えるコマンドを生成できます。

git checkout -b $BRANCH2 $START
git log --reverse --pretty=format:"cherry-pick %H; commit --amend --author='%aN <%aE>' -C %H" $START..$BRANCH | sh - 

最初のコマンドは、コミット$ STARTから新しい空のブランチを作成します。$ STARTから$ BRANCHの終わりまでの各コミットに対して、2番目のコマンドcherryは、現在のブランチ$ BRANCH2の終わりに元のコミットを選択し、それを修正して作成者を正しく設定します。

これも一般的に適用可能です-これを〜/ .gitconfigに入れてください:

[alias]
    # git reauthor $START..$END
    reauthor = !sh -c 'eval `git log --reverse --topo-order --pretty=format:\"git cherry-pick %H &&  git commit --amend -C %H --author=\\\"%aN <%aE>\\\" && \" $0 ` "echo success" '

したがって、著者を修正する必要がある場合は、.mapfileを生成して次の操作を行う必要があります。

git checkout -b $BRANCH2 $START
git reauthor $START..$BRANCH

元のブランチ参照を新しいものに再割り当てし、新しいものを削除できます。

git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2

これはすごい。私がもっと担当者がいたら私はあなたに報いるだろう。ありがとう:)
ピスタッシュ

9

以下からの回答を組み合わせる私が最初にgitにコミットのメタ情報を修正するにはどうすればよいですか?

### Fix the first commit ###    
# create a temporary tag for the root-most commit so we can reference it
git tag root `git rev-list HEAD | tail -1`
# check it out on its own temporary branch
git checkout -b new-root root
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# now you've changed the commit message, so checkout the original branch again
git checkout @{-1}
# and rebase it onto your new root commit
git rebase --onto new-root root
### Fix the rest of the commits ###
git rebase -i root
# edit the file to read "edit <commit number> for each entry
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# move to the next commit
git rebase --continue    
# continue running the last two commands until you see
# Successfully rebased and updated refs/heads/master.
### Clean up ###
# nuke the temporary branch we created
git branch -d new-root
# nuke the temporary tag we created
git tag -d root

正しい軌道に乗れましたが、次のコマンドが必要でした:
Veenstra

5

jedbergの答えに従うには:rebase -i問題のコミットを使用し、編集を選択できます。使用してgit commit --amend --author <AUTHOR DETAILS>からgit rebase continue履歴を修正できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.