3131 Stimmen

Wie ändere ich den Namen des Autors und des Committers sowie die E-Mail von mehreren Commits in Git?

Ich schrieb ein einfaches Skript auf dem Schulcomputer und übertrug die Änderungen an Git (in einem Repo, das sich auf meinem USB-Stick befand und von meinem Computer zu Hause geklont wurde). Nach mehreren Übertragungen stellte ich fest, dass ich als Root-Benutzer etwas übertrug.

Gibt es eine Möglichkeit, den Autor dieser Übertragungen in meinen Namen zu ändern?

17 Stimmen

Frage: Bleiben bei der Verwendung von git filter-branch die SHA1-Werte für frühere Tags, Versionen und Objekte erhalten? Oder werden durch die Änderung des Autorennamens auch die zugehörigen SHA1-Sätze geändert?

0 Stimmen

Oder Sie können versuchen, mit refs/replace/ Mechanismus.

1 Stimmen

Nach der Neufassung, wenn sie ihre Arbeit nicht auf die Geschichte vor der Neufassung gestützt haben, nur git reset --hard origin/master oder einfach git pull origin (der vorspulen sollte). Wenn sie ihre Änderung als Grundlage nehmen, müssen sie eine neue Basis mit git rebase origin/master oder einfach git pull --rebase origin (die Befehle sind nur Beispiele).

211voto

Alex Brown Punkte 40146

Wenn nur die ersten paar Übertragungen schlechte Autoren haben, können Sie dies alles innerhalb von git rebase -i unter Verwendung der exec Befehl und das Befehl --amend wie folgt begehen:

git rebase -i HEAD~6 # as required

die Ihnen die bearbeitbare Liste der Übertragungen präsentiert:

pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2

Dann fügen Sie exec ... --author="..." Zeilen nach allen Zeilen mit schlechten Autoren:

pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD

speichern und Editor beenden (zum Ausführen).

Diese Lösung mag länger dauern als andere, aber sie ist sehr gut kontrollierbar - ich weiß genau, welche Commits sie trifft.

Danke an @asmeurer für die Inspiration.

32 Stimmen

Auf jeden Fall großartig. Kannst du es abkürzen, indem du user.name und user.email in der lokalen Konfiguration des Repos einstellst, und dann ist jede Zeile nur exec git commit --amend --reset-author -C HEAD ?

2 Stimmen

Die kanonische Antwort, filter-branch zu verwenden, hat bei mir nur refs/heads/master gelöscht. Also +1 für Ihre kontrollierbare, editierbare Lösung. Danke!

0 Stimmen

Warum beginnen Sie mit Someone else's commit 代わりに my bad commit 1 ? Ich habe gerade versucht HEAD^^ um die letzten 2 Übertragungen zu ändern, und es funktionierte einwandfrei.

194voto

blueyed Punkte 25926

Für eine einzelne Übertragung:

git commit --amend --author="Author Name <email@address.com>"

(entnommen aus der Antwort von asmeurer)

19 Stimmen

Aber nur, wenn es die letzte Übertragung ist

4 Stimmen

Nach Angaben von git help commit , git commit --amend ändert den Commit an der "Spitze des aktuellen Zweigs" (also HEAD). Normalerweise ist dies der jüngste Commit, aber Sie können es zu einem beliebigen Commit machen, indem Sie zuerst ausprobierend die sich mit git checkout <branch-name> o git checkout <commit-SHA> .

13 Stimmen

Aber wenn Sie das tun, zeigen alle Commits, die diesen Commit bereits als Elternteil haben, auf den falschen Commit. Besser ist es, an diesem Punkt filter-branch zu verwenden.

124voto

Olivier Verdier Punkte 43894

Github hatte ursprünglich eine schöne Lösung ( defekter Link ), die das folgende Shell-Skript enthielt:

#!/bin/sh

git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if [ "$GIT_COMMITTER_EMAIL" = "your@email.to.match" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "your@email.to.match" ]
then
    an="Your New Author Name"
    am="Your New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'

5 Stimmen

Hat perfekt funktioniert. Musste nur git reset --hard HEAD^ ein paar Mal auf die anderen lokalen Repositories, um sie auf eine frühere Version zu bringen, git pull -die geänderte Fassung eingefügt, und hier bin ich ohne Zeilen mit unknown <stupid-windows-user@.StupidWindowsDomain.local> (man muss die Standardeinstellung von Git einfach lieben).

1 Stimmen

Ich kann nicht nachschieben. Muss ich "-f" verwenden?

9 Stimmen

Ich habe git push -f . Außerdem müssen die lokalen Repos danach neu geklont werden.

103voto

Chris Maes Punkte 30364

A Einzelbefehl um den Autor für die letzten N Übertragungen zu ändern:

git rebase -i HEAD~N -x "git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit"

ANMERKUNGEN

  • ersetzen. HEAD~N mit dem Verweis auf die Stelle, bis zu der Sie Ihre Übertragungen umschreiben wollen. Dies kann ein Hash sein, HEAD~4 einen Zweigniederlassungsnamen, ...
  • die --no-edit Flagge stellt sicher, dass die git commit --amend fragt nicht nach einer zusätzlichen Bestätigung
  • wenn Sie git rebase -i können Sie die Commits, in denen der Autor geändert werden soll, manuell auswählen,

sieht die Datei, die Sie bearbeiten, wie folgt aus:

pick 897fe9e simplify code a little
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit

Sie können dann noch einige Zeilen ändern, um zu sehen, wo Sie den Autor ändern wollen. So haben Sie einen guten Mittelweg zwischen Automatisierung und Kontrolle: Sie sehen die Schritte, die ausgeführt werden, und sobald Sie speichern, wird alles auf einmal angewendet.

Beachten Sie, dass Sie, wenn Sie die Autoreninformationen bereits mit git config user.name <your_name> y git config user.email <your_email> können Sie auch diesen Befehl verwenden:

git rebase -i HEAD~N -x "git commit --amend --reset-author --no-edit"

0 Stimmen

Ich habe HEAD~8 verwendet und es werden weit mehr als die letzten 8 Commits angezeigt.

2 Stimmen

@BryanBryce wenn es um Merge Commits geht, wird es kompliziert :)

0 Stimmen

@ChrisMaes Ah, jetzt verstehe ich, was hier los ist. Ich will mich nicht mit denen anlegen, nur mit dem Zweig, in dem ich bin.

89voto

svick Punkte 224493

Wie docgnome erwähnte, ist es gefährlich, die Geschichte umzuschreiben und die Repositories anderer Leute zu zerstören.

Aber wenn Sie das wirklich wollen und sich in einer Bash-Umgebung befinden (unter Linux kein Problem, unter Windows können Sie git bash verwenden, das bei der Installation von git mitgeliefert wird), verwenden Sie git filter-branch :

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL'

Um die Arbeit zu beschleunigen, können Sie einen Bereich von Überarbeitungen angeben, die Sie neu schreiben möchten:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD

2 Stimmen

Beachten Sie, dass dabei alle Tags auf die alten Commits verweisen. --tag-name-filter cat ist die Option "Mach es möglich".

0 Stimmen

@romkyns eine Idee, wie man auch die Tags ändern kann?

0 Stimmen

@NickVolynkin Ja, Sie spezifizieren --tag-name-filter cat . Dies hätte eigentlich die Standardeinstellung sein müssen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X