Könnte ich meinen Vor- und Nachnamen in allen vorherigen Commits ändern?

122

Ich möchte meinen Vor- und Nachnamen sowie meine E-Mail-Adresse in allen Commits ändern. Ist dies möglich?

Joshua
quelle
2
Ist es ein Reprositorium nur für Sie, für ein paar Leute oder für ein großes Projekt?
thejh
3
Mögliches Duplikat von Wie ändere ich den Autor eines Commits in Git?
Josh Lee

Antworten:

212

Verwenden Sie git-filter-branch.

git filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Josh Lee" ];
  then export GIT_AUTHOR_NAME="Hobo Bob"; export [email protected];
  fi; git commit-tree "$@"'

Dies betrifft nur den Autor, nicht den Committer (der für die meisten Commits mit dem Autor identisch ist). Wenn Sie diese ebenfalls neu schreiben möchten, legen Sie die Variablen GIT_COMMITTER_NAMEund fest GIT_COMMITTER_EMAIL.

Es gilt die Standardwarnung zum Umschreiben des Verlaufs. Machen Sie es nur mit der Geschichte, die noch nicht geteilt wurde.

Juni 2018 Update

Das Handbuch enthält jetzt eine Lösung, die --env-filterin ihren Beispielen Folgendes verwendet : https://git-scm.com/docs/git-filter-branch#_examples :

git filter-branch --env-filter '
    if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
    then
        [email protected]
    fi
    if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
    then
        [email protected]
    fi
' -- --all
Josh Lee
quelle
4
Wenn Sie verwenden msysgit, haben Sie weiterhin Zugriff auf bash. Ansonsten habe ich keine Ahnung.
Josh Lee
@Joshua Wenn Sie etwas verwenden, bei dem Sie keine Bash haben, können Sie wahrscheinlich Windows-Batch-Scripting verwenden, obwohl ich es nicht ausprobiert habe.
MatrixFrog
und was ist mit Tags? Diese Lösung wird den Autor der Tags nicht ändern
Piotrek
@ Joshua überprüfen Sie das Git-Repo auf einer Linux-Box und führen Sie das
Will Sheppard
Gibt es Optionen, die zu einer neuen Verzweigung führen und die Quell-Commits intakt lassen?
Eugen Konkov
56

So schreiben Sie sowohl den Autor als auch den Commiter in allen ausgewählten Commits neu:

git filter-branch --commit-filter \
'if [ "$GIT_AUTHOR_NAME" = "OldAuthor Name" ]; then \
export GIT_AUTHOR_NAME="Author Name";\
export [email protected];\
export GIT_COMMITTER_NAME="Commmiter Name";\
export [email protected];\
fi;\
git commit-tree "$@"'
user11153
quelle
1
Aber wie werden Änderungen auf den Remote-Server angewendet?
Vikyd
5
@ Viky Trygit push --all origin --force
user11153
2
Für mich geht das ! Ich verwende GitLab. Ich muss den Zweig vor dem Push-Befehl aufheben.
Vikyd
37

Wenn es keine anderen Autoren gibt, können Sie Folgendes tun:

git filter-branch --commit-filter 'export GIT_AUTHOR_NAME="authorname"; \
export [email protected]; git commit-tree "$@"'
denis.peplin
quelle
1
Es wird nicht "Committer:" info umgeschrieben.
user11153
1
Es ist nicht beabsichtigt, Committer-Informationen neu zu schreiben. Wenn Sie dies tun möchten, exportieren Sie auch GIT_COMMITTER_NAME und GIT_COMMITTER_EMAIL (siehe akzeptierte Antwort).
Chronospoon
12

Speichern Sie das folgende Skript als zB ~/.bin/git-replace-authorund führen Sie es aus mit zB:

git replace-author "John Ssmith" "John Smith" "[email protected]"

Ohne Argumente werden alle Commits mit Ihrem Namen aktualisiert, um Ihre aktuelle E-Mail-Adresse gemäß der Git-Konfiguration zu verwenden.

DEFAULT_NAME="$(git config user.name)"
DEFAULT_EMAIL="$(git config user.email)"
export OLD_NAME="${1:-$DEFAULT_NAME}"
export NEW_NAME="${2:-$DEFAULT_NAME}"
export NEW_EMAIL="${3:-$DEFAULT_EMAIL}"

echo "Old:" $OLD_NAME "<*>"
echo "New:" "$NEW_NAME <$NEW_EMAIL>"
echo "To undo, use: git reset $(git rev-parse HEAD)"

git filter-branch --env-filter \
'if [ "$GIT_AUTHOR_NAME" = "${OLD_NAME}" ]; then
    export GIT_AUTHOR_NAME="${NEW_NAME}"
    export GIT_AUTHOR_EMAIL="${NEW_EMAIL}"
    export GIT_COMMITTER_NAME="${NEW_NAME}"
    export GIT_COMMITTER_EMAIL="${NEW_EMAIL}"
fi'

Raw (zum Download)

Zaz
quelle
Als kurze Anmerkung: ~/.bin/muss sich innerhalb der Benutzer befinden $PATHund die Datei muss ausführbar sein, also führen Sie Folgendes aus : chmod +x ~/.bin/git-replace-author.
Michael Gecht
Und was macht es mit Argumenten?
Eugen Konkov
2

Nur wenn Sie Ihre Verpflichtungen nicht in die Welt gedrängt haben. Andernfalls hat jeder andere Ihren alten Namen in seinem Repo, was unwahrscheinlich ist, dass Sie den Namen aller ändern können.

EnabrenTane
quelle
Stimmt, aber in einigen Fällen haben Sie keine Wahl. In meinem Fall hatte ich eine falsche E-Mail-Adresse in meiner Git-Konfiguration konfiguriert (wie ich mit "Git-Konfiguration --global -l" sehen konnte). Infolgedessen wurde in meinem eigenen Github-Repo keine Festschreibungsaktivität angezeigt (da die E-Mail-Adresse nicht mit der in Github konfigurierten E-Mail-Adresse übereinstimmte)! Um dies zu lösen, habe ich meine lokalen Commits mithilfe des Rezepts von stackoverflow.com/a/23564785/2474068 korrigiert (hat perfekt funktioniert) und dann die geänderten Commits mit "git push -u -f origin master" (mit der Kraft) an Github gesendet Flag "-f"). Das widerspricht der akzeptierten Praxis, aber ich hatte keine Wahl!
Leo
1
Ja, mein Punkt war, dass Gabeln dieses Repos diese Änderung nicht haben würden, wenn sie nicht Ihren Force Push akzeptieren würden. Es wäre schwierig, jede Gabel zum Aktualisieren zu bringen :)
EnabrenTane
1

Mit Git 2.24 (Q4 2019) ist git filter-branch(und BFG) veraltet .

Das Äquivalent wäre, using newren/git-filter-repound sein Beispielabschnitt :

cd repo
git filter-repo --mailmap my-mailmap

mit my-mailmap:

Correct Name <[email protected]> <[email protected]>

Dies würde den Namen des Autors und die E-Mail-Adresse eines Commits ersetzen, das von jemandem mit ausgeführt wurde <[email protected]>

Siehe git shortlogAbbildung Autor Abschnitt für die genaue Syntax

VonC
quelle