3052 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).

2220voto

asmeurer Punkte 79555

HINWEIS: Diese Antwort ändert SHA1s, seien Sie also vorsichtig, wenn Sie sie auf einem Zweig verwenden, der bereits gepusht wurde. Wenn Sie nur die Schreibweise eines Namens korrigieren oder eine alte E-Mail aktualisieren möchten, können Sie dies mit Git tun, ohne die Geschichte neu zu schreiben. .mailmap . Siehe meine andere Antwort .

Rebase verwenden

Wenn Sie es noch nicht getan haben, sollten Sie zunächst Ihren Namen in git-config ändern:

git config --global user.name "New Author Name"
git config --global user.email "<email@address.com>"

Dies ist optional, aber es wird auch dafür sorgen, dass der Name des Committers zurückgesetzt wird, sofern Sie dies benötigen.

Um Metadaten für eine Reihe von Commits mit einem Rebase neu zu schreiben, führen Sie Folgendes aus

git rebase -r <some commit before all of your bad commits> \
    --exec 'git commit --amend --no-edit --reset-author'

--exec wird die git commit Schritt nach jeder Übertragung neu geschrieben wird (als ob Sie git commit && git rebase --continue wiederholt).

Wenn Sie auch Ihren ersten Commit (auch 'Root'-Commit genannt) ändern wollen, müssen Sie Folgendes hinzufügen --root zum Aufruf von rebase.

Dadurch werden sowohl der Committer als auch der Autor in Ihre user.name / user.email Konfiguration. Wenn Sie diese Konfiguration nicht ändern wollen, können Sie --author "New Author Name <email@address.com>" anstelle von --reset-author . Beachten Sie, dass dies zu einer no den Committer aktualisieren - nur den Autor.

Einzelverpflichtung

Wenn Sie nur den letzten Commit ändern wollen, ist ein rebase nicht notwendig. Ändern Sie einfach den Commit:

 git commit --amend --no-edit --reset-author

Für ältere Git-Kunden (vor Juli 2020)

-r,--rebase-merges gibt es für Sie vielleicht nicht. Als Ersatz können Sie Folgendes verwenden -p . Beachten Sie, dass -p hat ernsthafte Probleme und ist jetzt veraltet.

2 Stimmen

Das würde bedeuten für immer wenn Sie auch nur ein paar hundert Übertragungen zu durchforsten hätten.

33 Stimmen

Ideal für gelegentliche Übertragungen - nützlich, wenn man beim Paaren vergisst, den Autor zu ändern

37 Stimmen

+1 für die Erwähnung des Anwendungsfalls für die typische Ein-Fehler-Korrektur: git commit --amend --author=username

1564voto

Pat Notz Punkte 196406

Diese Antwort verwendet git-filter-branch , für die die Dokumente jetzt diese Warnung aussprechen:

git filter-branch hat eine Fülle von Fallstricken, die zu nicht offensichtlichen Verfälschungen des beabsichtigten Umschreibens der Historie führen können (und Ihnen wenig Zeit lassen, solche Probleme zu untersuchen, da es eine so miserable Leistung hat). Diese Sicherheits- und Leistungsprobleme können nicht rückwärtskompatibel behoben werden, so dass seine Verwendung nicht empfohlen wird. Bitte verwenden Sie ein alternatives Werkzeug zum Filtern der Historie wie z.B. git filter-repo . Wenn Sie dennoch git filter-branch verwenden müssen, lesen Sie bitte sorgfältig SICHERHEIT (und PERFORMANCE ), um sich über die Landminen der Filterbranche zu informieren und dann so viele der dort aufgeführten Gefahren zu vermeiden, wie es vernünftigerweise möglich ist.

Das Ändern des Autors (oder Committers) würde bedeuten, dass die gesamte Historie neu geschrieben werden müsste. Wenn Sie damit einverstanden sind und denken, dass es das wert ist, dann sollten Sie sich folgendes ansehen git filter-branch . Die Handbuchseite enthält mehrere Beispiele, die Ihnen den Einstieg erleichtern. Beachten Sie auch, dass Sie Umgebungsvariablen verwenden können, um den Namen des Autors, Committers, Datums usw. zu ändern. -- siehe den Abschnitt "Umgebungsvariablen" in der Git-Handbuch-Seite .

Insbesondere können Sie alle falschen Autorennamen und E-Mail-Adressen korrigieren für alle Zweige und Tags mit diesem Befehl (Quelle: GitHub-Hilfe ):

#!/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

Für die Verwendung des alternativen Verlaufsfilterwerkzeugs git filter-repo können Sie es zunächst installieren und eine git-mailmap gemäß dem Format von gitmailmap .

Proper Name <proper@email.xx> Commit Name <commit@email.xx>

Führen Sie dann filter-repo mit der erstellten Mailmap aus:

git filter-repo --mailmap git-mailmap

49 Stimmen

Nachdem Sie das Skript ausgeführt haben, können Sie den Backup-Zweig entfernen, indem Sie "git update-ref -d refs/original/refs/heads/master" ausführen.

13 Stimmen

@rodowi, es dupliziert alle meine Commits.

12 Stimmen

@RafaelBarros die Autoreninformation (genau wie alles andere in der Historie) ist Teil des Sha-Schlüssels des Commits. Jede Änderung in der Historie ist ein Rewrite, der zu neuen Ids für alle Commits führt. Schreiben Sie also nicht auf einem gemeinsam genutzten Projektarchiv um oder stellen Sie sicher, dass alle Benutzer davon Kenntnis haben ...

762voto

Brian Gianforcaro Punkte 25503

Eine Kleinigkeit, aber seien Sie vorsichtig, wenn Sie ein Mehrbenutzer-Repository haben - dies wird sich ändern tous Commits, die denselben (neuen) Autor und Committer haben.

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

Mit Zeilenumbrüchen in der Zeichenkette (was in der Bash möglich ist):

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

1 Stimmen

Ein kleiner Punkt, der Export ist eigentlich überflüssig, obwohl er nicht schadet. z.B. git-filter-branch --env-filter "GIT_AUTHOR_NAME='Neuer Name';GIT_AUTHOR_EMAIL='Neue E-Mail'" HEAD.

8 Stimmen

Warum werden alle Übertragungen umgeschrieben, wenn Sie angeben HEAD am Ende des Befehls?

5 Stimmen

Dies funktioniert nicht für mein Bitbucket-Repository, irgendeine Idee? Ich mache eine git push --force --tags origin 'refs/heads/*' nach dem empfohlenen Befehl

621voto

Rognon Punkte 6197

Das können Sie auch tun:

git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

Hinweis: Wenn Sie diesen Befehl in der Windows-Eingabeaufforderung verwenden, dann müssen Sie " anstelle von ' :

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD

5 Stimmen

Ist die Verwendung von env-filter nicht die einfachere Lösung? Ich bin mir nicht sicher, warum dies mehr Stimmen erhält.

3 Stimmen

Dann ist der Link defekt. Wie können wir diese Änderungen in ein anderes Repository übertragen?

30 Stimmen

Env-filter wird alle Commits ändern. Diese Lösung erlaubt eine Bedingung.

250voto

lrkwz Punkte 5618

Dies geschieht, wenn Sie keine $HOME/.gitconfig initialisiert. Sie können dies wie folgt beheben:

git config --global user.name "you name"
git config --global user.email you@domain.com
git commit --amend --reset-author

Getestet mit Git Version 1.7.5.4.

Beachten Sie, dass dies nur die letzte Übertragung korrigiert.

11 Stimmen

Das funktioniert wirklich gut bei der letzten Übergabe. Schön und einfach. Tut es nicht haben eine globale Veränderung zu sein, mit --local funktioniert auch

0 Stimmen

Das hier war der große Gewinner für mich! Die git commit --amend --reset-author --no-edit Befehl ist besonders nützlich, wenn Sie Commits mit falschen Autoreninformationen erstellt haben und dann nachträglich den richtigen Autor über git config . Hat mir gerade den Arsch gerettet, als ich meine E-Mail aktualisieren musste.

0 Stimmen

Die Antworten könnten zu viel des Guten sein. Prüfen Sie zunächst, ob dies Ihren Anwendungsfall erfüllt - stackoverflow.com/a/67363253/8293309

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