Git、以前のコミットのユーザー名とメールを書き換える


170

私はGithubのプロジェクトに多数のコミットをコミットしましたが、コミットを行うために現在使用しているコンピューターに適切なメールとコミッターのフルネームを設定していないため、ユーザーのアバターとメールアドレスが設定されていませんそこにはありません。

過去のコミットメールとユーザー名をすべて書き換えるにはどうすればよいですか?



GitHubアカウントのメールアドレスを変更した後、これを経験しました。gitコマンドライン(GitHubデスクトップではない)インターフェイスを使用してローカルのgit repoからコード変更をプッシュすることに加えて、GitHub Webインターフェイスを使用してリモートgit repoから直接テキストと管理ファイルを編集しました。新しい電子メールアドレスは、前者ではなく、後者のアクションの結果であるコミットにのみ伝播しました。
ロバートジョン

回答:


243

このエイリアスを追加できます:

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "

著者名を変更するには:

git change-commits GIT_AUTHOR_NAME "old name" "new name"

または、最近の10件のコミットのみの電子メール:

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD

エイリアス:

change-commits="!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" \$@; }; f "

ソース:https : //github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig


13
また、git change-commits GIT_COMMITTER_EMAIL "old@example.com" "new@example.com"コミッタのメールアドレスを変更します。
ローレント2017年

19
ubuntuでの「eval:[[:not found」のchange-commits = "!f() { VAR1=$1; VAR='$'$1; OLD=$2; NEW=$3; echo \"Are you sure for replace $VAR $OLD => $NEW ?(Y/N)\";read OK;if [ \"$OK\" = 'Y' ] ; then shift 3; git filter-branch --env-filter \"if [ \\\"${VAR}\\\" = '$OLD' ]; then export $VAR1='$NEW';echo 'to $NEW'; fi\" $@; fi;}; f "
修正

9
git: 'change-commits'はgitコマンドではありません。「git --help」を参照してください。エイリアスをgit設定に追加していないことを意味します。例:git config -e
Wayne

2
これで、変更したいメールですべてのコミットが複製されました。履歴を書き換えていないようです。@Olivier Verdierのソリューションがうまくいきました。
ジェイクウィルソン

6
入力を変えて2回続けて行うと、次のようになりますCannot create a new backup. A previous backup already exists in refs/original/
。– theonlygusti

97

解決策はすでにあります:Gitで複数のコミットの作成者とコミッターの名前と電子メールを変更します

つまり、

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

4
これはブランチのすべてのコミット(履歴全体)の作成者名を変更しませんか?
10

2
ええ、それは新しい作者情報へのすべてのコミットを変更するでしょう。
ewall

9
回答をコピーして貼り付けるのではなく、質問を重複としてマークしてください。
givanse 2014年

2
古い名前または古いメールを指定しなかった場合はどうなりますか?gitは「空のID <>は許可されていません」と言っています
Griffan

私はこのコマンドを実行しましたが、私のリポジトリはgitサーバーにプッシュしたりプルしたりしません。
イエスH

46

コミットの一部をすでにパブリックリポジトリにプッシュしている場合、これを実行する必要はありません。そうしないと、他のユーザーが使用した可能性があるマスターの履歴の代替バージョンになります。「小川を渡らないでください...悪いでしょう...」

つまり、ローカルリポジトリに対して行ったコミットのみの場合は、サーバーにプッシュする前に必ずこれを修正してください。オプションを指定してgit filter-branchコマンドを使用できるため、次の--commit-filterように、誤った情報に一致するコミットのみを編集します。

git filter-branch --commit-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong_email@wrong_host.local" ];
      then
              GIT_AUTHOR_NAME="Your Name Here (In Lights)";
              GIT_AUTHOR_EMAIL="correct_email@correct_host.com";
              git commit-tree "$@";
      else
              git commit-tree "$@";
      fi' HEAD

5
これは完璧に機能しますが、緑色でマークされた回答は機能しませんでした
jmary 2018

その後、でバックアップをクリアしたいgit update-ref -d refs/original/refs/heads/master場合があります。< stackoverflow.com/a/7654880/333403 >を参照してください。
cknoll

参考:複数の正しくない名前/メールがある場合は、これを複数回実行する必要があります。A previous backup already exists in refs/original/その場合、次のエラーでうめきます。その場合は、新しいメールで再実行し、-f-commit-filterの前にaを追加します。独自の裁量で使用してください。通常-f、それが何をしているかを知らずに行うのは危険なことです。
チャック

19

Olivier Verdierの回答を適用した後:

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

...変更された履歴を元のリポジトリにプッシュするには、以下を使用します。

git push origin +yourbranch

上記のコマンド(プラス記号に注意)は、元のリポジトリの履歴も強制的に書き換えます。注意して使用してください!


私のために働いた、また起源の歴史を正しく書き直した。
Xeverous

10
これにより、誰が作成したかに関係なく、すべてのコミットが書き直されます。注意して使用してください。
Bhavin Doshi、2018

14

https://help.github.com/articles/changing-author-info/

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="oldEmail@xxx-MacBook-Pro.local"
CORRECT_NAME="yourName"
CORRECT_EMAIL="yourEmail"

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

これは完全に私のために働いた。git push後、gitのWebポータルで更新を確認してください。コミットがまだアカウントにリンクされておらず、コミットの横にデフォルトのサムネイル画像が表示されていて、それが投稿のタイムラインチャートに反映されていない場合は、コミットURLに移動し、URLの末尾に.patchを追加し、名前を確認しますとメールは正しいです。


これにより理論的には質問に答えることができますが、ここに答えの本質的な部分を含め、参照用のリンクを提供することが望ましいでしょう
jhpratt

1
これは、すべてのブランチを書き換える唯一のものです。
Bruno Zell、

6

簡単なコピーペーストバージョン(電子メールと名前の更新を除く)が必要な場合:

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "
git change-commits GIT_AUTHOR_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_AUTHOR_EMAIL <old@email.com> <new@email.com> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <old@email.com> <new@email.com> -f

5
-bash:!f:イベントが見つかりません
サイイン2018

おそらく、端末が自動的にエスケープする問題
Andrei Savin

3

同じことをgit-filter-repoで行うには、の使用git-filter-branch望ましくありません(最初にをインストールする必要がある場合があります)。pip install git-filter-repo

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'

リポジトリがオリジナルで、リモートがない場合--force、強制的に書き換えるために追加する必要があります。(これを行う前に、リポジトリのバックアップを作成することをお勧めします。)

refを保持したくない場合(それらはGit GUIのブランチ履歴に表示されます)、を追加する必要があります--replace-refs delete-no-add

より高度な機能については、「名前とメールのフィルタリング」を参照してください。

PSはhttps://stackoverflow.com/a/59591928/714907から盗まれて改善されました。

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