Git, schreibe frühere Commit-Benutzernamen und E-Mails neu

170

Ich habe eine Reihe von Commits für ein Projekt auf Github festgelegt, jedoch festgestellt, dass ich auf dem Computer, auf dem ich meine Commits mache, und damit den Avatar und die E-Mail-Adresse des Benutzers nicht den richtigen Namen für E-Mail und Committer eingerichtet habe sind nicht da.

Wie kann ich alle früheren Commit-E-Mails und Benutzernamen umschreiben?

JP Silvashy
quelle
9
Mögliches Duplikat von Wie ändere ich den Autor eines Commits in Git?
Givanse
Ich habe dies erlebt, nachdem ich die E-Mail-Adresse in meinem GitHub-Konto geändert habe. Zusätzlich zum Übertragen von Codeänderungen aus dem lokalen Git-Repo über die Git-Befehlszeilenschnittstelle (und nicht über den GitHub-Desktop) habe ich auch Text bearbeitet und Dateien direkt vom Remote-Git-Repo über die GitHub-Weboberfläche verwaltet. Die neue E-Mail-Adresse wurde nur an die aus den letzteren Aktionen resultierenden Commits weitergegeben und nicht an die ersteren.
Robert John

Antworten:

243

Sie können diesen Alias ​​hinzufügen:

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 "

So ändern Sie den Autorennamen:

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

oder die E-Mail nur für die letzten 10 Commits:

git change-commits GIT_AUTHOR_EMAIL "[email protected]" "[email protected]" HEAD~10..HEAD

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 "

Quelle: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig

Brauliobo
quelle
13
Auch git change-commits GIT_COMMITTER_EMAIL "[email protected]" "[email protected]"um die Committer-E-Mail zu ändern.
Laurent
19
behoben für "eval: [[: not found" auf ubuntu und füge eine Bestätigung hinzuchange-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 "
qxo
9
git: 'change-commits' ist kein git-Befehl. Siehe 'git --help'. Bedeutet, dass Sie den Alias ​​nicht zu Ihrer Git-Konfiguration hinzugefügt haben. zB git config -e
Wayne
2
Dadurch wurden nur Duplikate aller Commits mit der E-Mail erstellt, die ich ändern wollte. Scheint die Geschichte nicht neu zu schreiben. Die Lösung von @Olivier Verdier hat bei mir funktioniert.
Jake Wilson
6
Wenn Sie es zweimal hintereinander mit unterschiedlichen Eingaben machen, führt dies zu:Cannot create a new backup. A previous backup already exists in refs/original/
theonlygusti
97

Die Lösung ist bereits da: Ändern Sie den Namen des Autors und des Committers sowie die E-Mail-Adresse mehrerer Commits in Git

Nämlich,

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
Olivier Verdier
quelle
4
Würde dies nicht den Namen des Autors für alle Commits (gesamte Historie) des Zweigs ändern?
hasen
2
Ja, das würde alle Commits für die neuen Autoreninformationen ändern.
Ewall
9
Bitte markieren Sie Fragen als Duplikate, anstatt die Antwort zu kopieren.
Givanse
2
Was ist, wenn ich keinen alten Namen oder keine alte E-Mail-Adresse angegeben habe? Git sagt "leere Identität <> nicht erlaubt"
Griffan
Ich habe diesen Befehl ausgeführt und jetzt wird mein Repo nicht mehr zum Git-Server verschoben oder von diesem abgerufen.
Jesus H
46

Wenn Sie bereits einige Ihrer Commits in das öffentliche Repository verschoben haben, ist dies nicht der Fall möchten tun, da sonst eine alternative Version des Master-Verlaufs erstellt wird, die andere möglicherweise verwendet haben. "Überquere nicht die Bäche ... Es wäre schlimm ..."

Das heißt, wenn es nur die Commits sind, die Sie in Ihrem lokalen Repository vorgenommen haben, beheben Sie dies auf jeden Fall, bevor Sie auf den Server hochschieben. Sie können den git filter-branchBefehl mit der --commit-filterOption verwenden, sodass nur Commits bearbeitet werden, die Ihren falschen Informationen entsprechen, wie folgt:

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
ewall
quelle
5
Dies funktioniert perfekt, während die grün markierte Antwort nicht
12.
Anschließend möchten Sie möglicherweise die Sicherung mit löschengit update-ref -d refs/original/refs/heads/master , siehe < stackoverflow.com/a/7654880/333403 >.
cknoll
Zu Ihrer Information: Wenn Sie mehrere falsche Namen / E-Mails haben, müssen Sie diese möglicherweise mehrmals ausführen. A previous backup already exists in refs/original/In diesem Fall -fstöhnt es Sie mit folgendem Fehler an: Führen Sie es in diesem Fall mit der neuen E-Mail erneut aus und fügen Sie vor dem --commit-Filter ein hinzu. Verwendung nach eigenem Ermessen. Normalerweise -fist es gefährlich, ohne zu wissen, was es tut.
Chuck
19

Nach Anwendung der Antwort von 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

... um den geänderten Verlauf auf das ursprüngliche Repository zu übertragen, verwenden Sie:

git push origin +yourbranch

Der obige Befehl (beachten Sie das Plus) erzwingt das Umschreiben des Verlaufs auch auf dem ursprünglichen Repo. Mit Vorsicht verwenden!

Sarusso
quelle
Hat für mich gearbeitet, auch die Herkunftsgeschichte richtig umgeschrieben.
Xeverous
10
Dadurch werden ALLE Commits neu geschrieben - unabhängig davon, wer sie verfasst hat. Mit Vorsicht verwenden.
Bhavin Doshi
14

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

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="[email protected]"
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

das hat bei mir total geklappt. Stellen Sie nach dem Push von Git sicher, dass das Update im Webportal von Git angezeigt wird. Wenn das Commit immer noch nicht mit meinem Konto verknüpft war, das neben dem Commit angezeigte Standard-Miniaturbild angezeigt wurde und nicht in meinem Beitragszeitplandiagramm angezeigt wurde, rufen Sie die Commit-URL auf und hängen Sie .patch am Ende der URL an, und überprüfen Sie den Namen und E-Mail sind korrekt.

Jacccck
quelle
Während dies theoretisch die Frage beantworten kann, wäre es vorzuziehen , die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen.
Jhpratt
1
Dies ist der einzige, der alle Zweige neu schreibt.
Bruno Zell
6

Für diejenigen, die nur die einfache Version zum Kopieren und Einfügen benötigen (abgesehen vom Aktualisieren von E-Mails und Namen):

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 <[email protected]> <[email protected]> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <[email protected]> <[email protected]> -f
Nick Kuznia
quelle
5
-bash :! f: Ereignis nicht gefunden
Saiyine
Höchstwahrscheinlich ein Problem mit einem Terminal, das automatisch entkommt
Andrei Savin
3

Die Verwendung von git-filter-branchist nicht erwünscht , um dasselbe in git-filter-repo zu tun (möglicherweise müssen Sie es zuerst mit installieren pip install git-filter-repo):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"[email protected]", b"[email protected]")'

Wenn das Repository original ist, ohne Remote, müssen Sie hinzufügen --force, um das Umschreiben zu erzwingen. (Möglicherweise möchten Sie zuvor ein Backup Ihres Repos erstellen.)

Wenn Sie keine Refs beibehalten möchten (diese werden im Zweigverlauf der Git-GUI angezeigt), müssen Sie hinzufügen --replace-refs delete-no-add.

Weitere erweiterte Funktionen finden Sie unter "Filtern von Namen und E-Mails". .

PS Gestohlen und verbessert von https://stackoverflow.com/a/59591928/714907 .

Pugsley
quelle