it-swarm.com.de

Wie ändere ich den Namen und die E-Mail-Adresse von Autor und Committer mehrerer Commits in Git?

Ich habe ein einfaches Skript auf dem Schulcomputer geschrieben und die Änderungen an Git festgeschrieben (in einem Repo, das sich auf meinem pendrive befand und von meinem Computer zu Hause geklont wurde). Nach mehreren Commits wurde mir klar, dass ich als Root-Benutzer ein Commit ausführte.

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

2219
Flávio Amieiro

Wenn Sie den Autor (oder Committer) ändern, müssen Sie die gesamte Historie neu schreiben. Wenn du damit einverstanden bist und denkst, dass es sich lohnt, solltest du git filter-branch . Die Manpage enthält einige Beispiele, um Ihnen den Einstieg zu erleichtern. Beachten Sie auch, dass Sie Umgebungsvariablen verwenden können, um den Namen des Autors, Committers, Datums usw. zu ändern - siehe Abschnitt "Umgebungsvariablen" auf der Git-Manpage .

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

#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="[email protected]"
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
1041
Pat Notz

Verwenden von Interactive Rebase

Du könntest es tun

git rebase -i -p <some HEAD before all of your bad commits>

Markieren Sie dann alle Ihre fehlerhaften Commits in der Rebase-Datei als "Bearbeiten". Wenn Sie auch Ihr erstes Commit ändern möchten, müssen Sie es manuell als erste Zeile in die Rebase-Datei einfügen (folgen Sie dem Format der anderen Zeilen). Wenn git Sie dann auffordert, jedes Commit zu ändern, tun Sie Folgendes

 git commit --amend --author "New Author Name <[email protected]>" 

bearbeiten oder schließen Sie einfach den sich öffnenden Editor

git rebase --continue

die Basis fortsetzen.

Sie können das Öffnen des Editors hier insgesamt überspringen, indem Sie --no-edit anhängen, sodass der Befehl wie folgt lautet:

git commit --amend --author "New Author Name <[email protected]>" --no-edit && \
git rebase --continue

Single Commit

Wie einige Kommentatoren festgestellt haben, ist der Befehl rebase nicht erforderlich, wenn Sie nur das letzte Commit ändern möchten. Mach einfach

 git commit --amend --author "New Author Name <[email protected]>"

Dadurch wird der Autor in den angegebenen Namen geändert, aber der Committer wird in git config user.name und git config user.email auf Ihren konfigurierten Benutzer eingestellt. Wenn Sie den Committer auf einen von Ihnen festgelegten Wert festlegen möchten, werden sowohl der Autor als auch der Committer festgelegt:

 git -c user.name="New Author Name" -c [email protected] commit --amend --reset-author

Hinweis zu Merge-Commits

Es gab einen kleinen Fehler in meiner ursprünglichen Antwort. Wenn es Zusammenführungs-Commits zwischen dem aktuellen HEAD und Ihrem <some HEAD before all your bad commits> gibt, werden diese durch git rebase reduziert (und im Übrigen, wenn Sie GitHub-Pull-Anforderungen verwenden, wird es einen geben tonnenweise Merge-Commits in Ihrem Verlauf). Dies kann sehr oft zu einem sehr unterschiedlichen Verlauf führen (da doppelte Änderungen möglicherweise "auslagern") und im schlimmsten Fall dazu führen, dass git rebase Sie auffordert, schwierige Zusammenführungskonflikte zu lösen (die wahrscheinlich bereits in behoben wurden) die Zusammenführung wird festgeschrieben). Die Lösung besteht darin, das -p -Flag für git rebase zu verwenden, wodurch die Zusammenführungsstruktur Ihres Verlaufs beibehalten wird. Die Manpage für git rebase warnt davor, dass die Verwendung von -p und -i zu Problemen führen kann. Im Abschnitt BUGS heißt es jedoch: "Commits bearbeiten und Commit-Nachrichten neu formulieren sollte funktionieren. "

Ich habe -p zum obigen Befehl hinzugefügt. Für den Fall, dass Sie nur das letzte Commit ändern, ist dies kein Problem.

1518
asmeurer

Sie können 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 "[email protected]";
        else
                git commit-tree "[email protected]";
        fi' HEAD

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

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 "[email protected]";
        else
                git commit-tree "[email protected]";
        fi" HEAD
579
Rognon

Ein Liner, aber seien Sie vorsichtig, wenn Sie ein Repository für mehrere Benutzer haben - dies ändert sich alle verpflichtet sich, denselben (neuen) Autor und Committer zu haben.

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='[email protected]'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='[email protected]';" HEAD

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

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='[email protected]'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='[email protected]'
  " HEAD
520

Dies passiert, wenn Sie kein $ HOME/.gitconfig initialisiert haben. Sie können dies beheben als:

git config --global user.name "you name"
git config --global user.email [email protected]
git commit --amend --reset-author

getestet mit git version 1.7.5.4

214
lrkwz

Für ein einzelnes Commit:

git commit --amend --author="Author Name <[email protected]>"

(Auszug aus der Antwort von asmeurer)

181
blueyed

In dem Fall, in dem nur die ersten Commits schlechte Autoren haben, können Sie dies alles in git rebase -i ausführen, indem Sie den Befehl exec und das Commit --amend wie folgt ausführen:

git rebase -i HEAD~6 # as required

daraufhin wird die bearbeitbare Liste der Commits angezeigt:

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

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

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

speichern und Editor beenden (ausführen).

Diese Lösung ist möglicherweise länger zu tippen als einige andere, lässt sich jedoch sehr gut steuern - ich weiß genau, welche Commits sie trifft.

Vielen Dank an @asmeurer für die Inspiration.

170
Alex Brown

Github hat ein Schöne Lösung , welches das folgende Shell-Skript ist:

#!/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" = "[email protected]" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]
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"
'
109
Olivier Verdier

Wie docgnome bereits erwähnt hat, ist das Umschreiben von Historien gefährlich und kann die Repositories anderer Leute beschädigen.

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

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

Um die Arbeit zu beschleunigen, können Sie eine Reihe von Revisionen angeben, die Sie neu schreiben möchten:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = [email protected] ];
    then [email protected];
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD
80
svick

Wenn Sie ein nicht zusammengeführtes Commit von einem anderen Autor übernehmen, gibt es eine einfache Möglichkeit, damit umzugehen.

git commit --amend --reset-author

47
Ryanmt

Sie können dies als Alias ​​ verwenden, um Folgendes zu tun:

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

oder für die letzten 10 Commits:

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

Hinzufügen zu ~/.gitconfig:

[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\" [email protected]; }; f "

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

Hoffe es ist nützlich.

41
brauliobo

Dies ist eine ausgearbeitete Version von @ Brians Version:

Um den Autor und Committer zu ändern, können Sie dies tun (mit Zeilenumbrüchen in der Zeichenfolge, die in Bash möglich ist):

_git filter-branch --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all
_

Möglicherweise tritt einer der folgenden Fehler auf:

  1. Das temporäre Verzeichnis existiert bereits
  2. Referenzen, die mit refs/original beginnen, sind bereits vorhanden
    (Dies bedeutet, dass zuvor eine andere Filter-Verzweigung im Repository ausgeführt wurde und die ursprüngliche Verzweigungsreferenz unter refs/original gesichert wird. )

Wenn Sie die Ausführung trotz dieser Fehler erzwingen möchten, fügen Sie das Flag --force hinzu:

_git filter-branch --force --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all
_

Eine kleine Erklärung der _-- --all_ -Option könnte erforderlich sein: Sie bewirkt, dass der Filterzweig bei allen Revisionen von allen Refs (die alle enthalten) funktioniert Geäst). Dies bedeutet beispielsweise, dass Tags ebenfalls neu geschrieben werden und in den neu geschriebenen Zweigen sichtbar sind.

Ein häufiger "Fehler" ist, stattdessen HEAD zu verwenden, was bedeutet, dass alle Revisionen nur in dem aktuellen Zweig gefiltert werden. Und dann würden keine Tags (oder andere Verweise) in der neu geschriebenen Verzweigung existieren.

38
stigkj
  1. führe git rebase -i <sha1 or ref of starting point> aus
  2. markieren Sie alle Commits, die Sie ändern möchten, mit edit (oder e)
  3. schleifen Sie die folgenden zwei Befehle, bis Sie alle Commits verarbeitet haben:

    git commit --amend --reuse-message=HEAD --author="New Author <[email protected]>"; git rebase --continue

Dadurch werden alle anderen Festschreibungsinformationen (einschließlich der Daten) beibehalten. Die Option --reuse-message=HEAD verhindert, dass der Nachrichteneditor gestartet wird.

23
sporsh

Ich verwende Folgendes, um den Autor für ein gesamtes Repository neu zu schreiben, einschließlich Tags und aller Zweige:

git filter-branch --tag-name-filter cat --env-filter "
  export GIT_AUTHOR_NAME='New name';
  export GIT_AUTHOR_EMAIL='New email'
" -- --all

Entfernen Sie dann, wie in MAN-Seite von filter-branch beschrieben, alle Originalreferenzen, die mit filter-branch gesichert wurden (dies ist destruktiv, Sicherung zuerst):

git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d
21

Ich habe diese Lösung angepasst, die durch Aufnahme eines einfachen author-conv-file funktioniert (Format ist dasselbe wie für git-cvsimport ). Es funktioniert, indem alle Benutzer, wie im author-conv-file definiert, in allen Zweigen geändert werden.

Wir haben dies in Verbindung mit cvs2git verwendet, um unser Repository von cvs nach git zu migrieren.

d.h. Probe author-conv-file

john=John Doe <[email protected]>
jill=Jill Doe <[email protected]>

Das Drehbuch:

 #!/bin/bash

 export $authors_file=author-conv-file

 git filter-branch -f --env-filter '

 get_name () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=\(.*\) <.*>$/\1/"
 }

 get_email () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=.* <\(.*\)>$/\1/"
 }

 GIT_AUTHOR_NAME=$(get_name $GIT_COMMITTER_NAME) &&
     GIT_AUTHOR_EMAIL=$(get_email $GIT_COMMITTER_NAME) &&
     GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME &&
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL &&
     export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
     export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 ' -- --all
21
Leif Gruenwoldt

Ich fand die vorgestellten Versionen zu aggressiv, besonders wenn Sie Patches von anderen Entwicklern einspielen, wird dies im Wesentlichen deren Code stehlen.

Die folgende Version funktioniert auf allen Zweigen und ändert den Autor und den Comitter separat, um dies zu verhindern.

Ein großes Lob an leif81 für die All-Option.

#!/bin/bash

git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "<old author>" ];
then
    GIT_AUTHOR_NAME="<new author>";
    GIT_AUTHOR_EMAIL="<[email protected]>";
fi
if [ "$GIT_COMMITTER_NAME" = "<old committer>" ];
then
    GIT_COMMITTER_NAME="<new commiter>";
    GIT_COMMITTER_EMAIL="<[email protected]>";
fi
' -- --all
18
drahnr
  1. Ändern Sie commit author name & email durch Amend und ersetzen Sie dann old-commit with new-one:

    $ git checkout <commit-hash>                            # checkout to the commit need to modify  
    $ git commit --amend --author "name <[email protected]>" # change the author name and email
    
    $ git replace <old-commit-hash> <new-commit-hash>      # replace the old commit by new one
    $ git filter-branch -- --all                           # rewrite all futures commits based on the replacement                   
    
    $ git replace -d <old-commit-hash>     # remove the replacement for cleanliness 
    $ git Push -f Origin HEAD              # force Push 
    
  2. Ein anderer Weg Rebasing:

    $ git rebase -i <good-commit-hash>      # back to last good commit
    
    # Editor would open, replace 'pick' with 'edit' before the commit want to change author
    
    $ git commit --amend --author="author name <[email protected]>"  # change the author name & email
    
    # Save changes and exit the editor
    
    $ git rebase --continue                # finish the rebase
    
17
Sajib Khan

Ich sollte darauf hinweisen, dass, wenn das einzige Problem darin besteht, dass sich der Autor/die E-Mail von Ihrem üblichen unterscheidet, dies kein Problem ist. Die richtige Lösung besteht darin, eine Datei mit dem Namen .mailmap am Ende des Verzeichnisses mit den folgenden Zeilen zu erstellen

Name you want <email you want> Name you don't want <email you don't want>

Und von da an betrachten Befehle wie git shortlog diese beiden Namen als gleich (es sei denn, Sie weisen sie ausdrücklich an, dies nicht zu tun). Weitere Informationen finden Sie unter http://schacon.github.com/git/git-shortlog.html .

Dies hat den Vorteil aller anderen hier beschriebenen Lösungen, dass Sie den Verlauf nicht neu schreiben müssen, was bei einem Upstream zu Problemen führen kann. Dies ist immer ein guter Weg, um versehentlich Daten zu verlieren.

Wenn Sie etwas als Sie selbst festgelegt haben und es wirklich jemand anderes sein sollte und es Ihnen an dieser Stelle nichts ausmacht, die Geschichte neu zu schreiben, ist es wahrscheinlich eine gute Idee, den Festschreibungsautor zu Zuordnungszwecken zu ändern (in diesem Fall leite ich Sie an meine weiter) andere Antwort hier).

16
asmeurer

Angenommen, Sie möchten den Autor für die letzten N Festschreibungen ändern:

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <[email protected]>' --no-edit"

NOTIZEN

  • das --no-edit -Flag stellt sicher, dass das git commit --amend keine zusätzliche Bestätigung verlangt
  • wenn Sie git rebase -i verwenden, können Sie die Commits manuell auswählen, bei denen der Autor geändert werden soll.

die Datei, die Sie bearbeiten, sieht folgendermaßen aus:

pick 897fe9e simplify code a little
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit

Sie können dann noch einige Zeilen ändern, um zu sehen, wo Sie den Autor ändern möchten. Dies gibt Ihnen einen guten Mittelweg zwischen Automatisierung und Steuerung: Sie sehen die Schritte, die ausgeführt werden, und sobald Sie speichern, wird alles auf einmal angewendet.

13
Chris Maes

Wenn Sie der einzige Benutzer dieses Repositorys sind, können Sie rewrite history entweder mit git filter-branch (as svick wrote =) oder git fast-export / git fast-import plus Filterskript (wie in Artikel beschrieben, auf den in docgnome answer verwiesen wird), oder interaktiv rebase . Beides würde jedoch die Revisionen ab dem ersten Commit ändern. Dies bedeutet Ärger für jeden, der seine/ihre Änderungen auf dem vorab umgeschriebenen Zweig basiert.

RECOVERY

Wenn andere Entwickler ihre Arbeit nicht auf der Pre-Rewrite-Version basierten, wäre es die einfachste Lösung, erneut zu klonen (erneut zu klonen).

Alternativ können sie _git rebase --pull_ ausprobieren, was schnell vorwärts gehen würde, wenn keine Änderungen in ihrem Repository vorgenommen würden, oder ihre Verzweigung auf neu geschriebene Commits zurückführen (wir möchten eine Zusammenführung vermeiden, da dies die Voreinstellung behalten würde). comits für immer umschreiben). All dies unter der Annahme, dass sie keine Arbeit geleistet haben; Verwenden Sie _git stash_, um Änderungen ansonsten zu verwahren.

Wenn andere Entwickler Feature-Zweige verwenden und/oder _git pull --rebase_ nicht funktioniert, z. Da Upstream nicht eingerichtet ist, müssen sie rebase ihre Arbeit zusätzlich zu den Post-Rewrite-Commits ausführen. Beispielsweise muss unmittelbar nach dem Abrufen neuer Änderungen (_git fetch_) für einen Zweig master, der auf/forked from _Origin/master_ basiert, ausgeführt werden

_$ git rebase --onto Origin/master Origin/[email protected]{1} master
_

Hier ist _Origin/[email protected]{1}_ der Zustand vor dem Umschreiben (vor dem Abrufen), siehe gitrevisions .


Eine alternative Lösung wäre die Verwendung des Mechanismus refs/replace/, der in Git seit Version 1.6.5 verfügbar ist. In dieser Lösung ersetzen Sie Commits mit falschen E-Mails. dann würde jeder, der "Ersatz" -Refs abruft (so etwas wie _fetch = +refs/replace/*:refs/replace/*_ refspec an geeigneter Stelle in seinem _.git/config_), transparent Ersatz erhalten, und diejenigen, die dies nicht tun Holen Sie sich diese Refs würde alte Commits sehen.

Das Verfahren sieht ungefähr so ​​aus:

  1. Finden Sie alle Commits mit einer falschen E-Mail, zum Beispiel mit

    _$ git log [email protected] --all
    _
  2. Erstellen Sie für jedes falsche Commit ein Ersatz-Commit und fügen Sie es der Objektdatenbank hinzu

    _$ git cat-file -p <ID of wrong commit> | 
      sed -e 's/[email protected]\.email/[email protected]/g' > tmp.txt
    $ git hash-object -t commit -w tmp.txt
    <ID of corrected commit>
    _
  3. Nachdem Sie das Commit in der Objektdatenbank korrigiert haben, müssen Sie git anweisen, das falsche Commit automatisch und transparent durch das korrigierte zu ersetzen. Verwenden Sie dazu den Befehl git replace :

    _$ git replace <ID of wrong commit> <ID of corrected commit>
    _
  4. Führen Sie abschließend alle Ersetzungen auf, um zu überprüfen, ob dieser Vorgang erfolgreich war

    _$ git replace -l
    _

    und prüfen Sie, ob ein Austausch stattfindet

    _$ git log [email protected] --all
    _

Sie können diesen Vorgang natürlich automatisieren ... naja, alle außer mit _git replace_, das (noch) keinen Batch-Modus hat, also müssten Sie Shell loop dafür verwenden oder "von Hand" ersetzen.

NOT TESTED! YMMV.

Beachten Sie, dass es bei der Verwendung des _refs/replace/_-Mechanismus zu rauen Ecken kommen kann: Er ist neu und noch nicht sehr gut getestet.

9
Jakub Narębski

Wenn es sich bei den Commits, die Sie korrigieren möchten, um die neuesten und nur einige davon handelt, können Sie eine Kombination aus git reset und git stash verwenden, um sie erneut zu bestätigen, nachdem Sie den richtigen Namen und die richtige E-Mail-Adresse konfiguriert haben .

Die Sequenz sieht ungefähr so ​​aus (für 2 falsche Festschreibungen, keine ausstehenden Änderungen):

git config user.name <good name>
git config user.email <good email>
git reset HEAD^
git stash
git reset HEAD^
git commit -a
git stash pop
git commit -a
6
djromero

Am schnellsten und einfachsten geht das mit dem Argument --exec von git rebase:

git rebase -i -p --exec 'git commit --amend --reset-author --no-edit'

Dies erstellt eine Aufgabenliste, die so aussieht:

pick ef11092 Blah blah blah
exec git commit --amend --reset-author --no-edit
pick 52d6391 Blah bloh bloo
exec git commit --amend --reset-author --no-edit
pick 30ebbfe Blah bluh bleh
exec git commit --amend --reset-author --no-edit
...

und das funktioniert alles automatisch, was funktioniert, wenn Sie Hunderte von Commits haben.

6
Lie Ryan

Dein Problem ist wirklich weit verbreitet. Siehe " Verwenden von Mailmap, um die Autorenliste in Git zu reparieren "

Der Einfachheit halber habe ich ein Skript erstellt, um den Vorgang zu vereinfachen: git-changemail

Nachdem Sie dieses Skript in Ihren Pfad eingefügt haben, können Sie Befehle wie die folgenden eingeben:

  • Ändern Sie die Autorenzuordnungen für den aktuellen Zweig

    $ git changemail -a [email protected] -n newname -m [email protected]
    
  • Ändern Sie die Autoren- und Committer-Übereinstimmungen für <branch> und <branch2>. Übergeben Sie -f an filter-branch, um das Neuschreiben von Sicherungen zu ermöglichen

    $ git changemail -b [email protected] -n newname -m [email protected] -- -f &lt;branch> &lt;branch2>
    
  • Zeige bestehende Benutzer im Repo

    $ git changemail --show-both
    

Übrigens, nachdem Sie Ihre Änderungen vorgenommen haben, bereinigen Sie das Backup vom Filterzweig mit: git-backup-clean

5
albfan

Wir haben heute ein Problem festgestellt, bei dem ein UTF8-Zeichen in einem Autornamen Probleme auf dem Build-Server verursachte. Daher mussten wir den Verlauf neu schreiben, um dies zu korrigieren. Folgende Schritte wurden unternommen:

Schritt 1: Ändern Sie Ihren Benutzernamen in git für alle zukünftigen Commits, wie hier beschrieben: https://help.github.com/articles/setting-your-username-in-git/

Schritt 2: Führen Sie das folgende Bash-Skript aus:

#!/bin/sh

REPO_URL=ssh://path/to/your.git
REPO_DIR=rewrite.tmp

# Clone the repository
git clone ${REPO_URL} ${REPO_DIR}

# Change to the cloned repository
cd ${REPO_DIR}

# Checkout all the remote branches as local tracking branches
git branch --list -r Origin/* | cut -c10- | xargs -n1 git checkout

# Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX
git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="New Me"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
fi
' --tag-name-filter cat -- --branches --tags

# Force Push the rewritten branches + tags to the remote
git Push -f

# Remove all knowledge that we did something
rm -rf ${REPO_DIR}

# Tell your colleagues to `git pull --rebase` on all their local remote tracking branches

Kurzübersicht: Checken Sie Ihr Repository in eine temporäre Datei, checken Sie alle Remote-Zweige aus, führen Sie das Skript aus, mit dem der Verlauf neu geschrieben wird, und fordern Sie alle Kollegen auf, einen Rebase-Pull durchzuführen, um die Änderungen zu erhalten.

Wir hatten Probleme damit, dies unter OS X auszuführen, da es die Zeilenenden in Commit-Nachrichten irgendwie durcheinander brachte, sodass wir es anschließend auf einem Linux-Computer erneut ausführen mussten.

5

Beachten Sie, dass git zwei unterschiedliche E-Mail-Adressen speichert, eine für den Committer (die Person, die die Änderung vorgenommen hat) und eine andere eine für den Autor (die Person, die die Änderung geschrieben hat).

Die Committer-Informationen werden an den meisten Stellen nicht angezeigt, können jedoch mit git log -1 --format=%cn,%ce angezeigt werden (oder verwenden Sie show anstelle von log, um ein bestimmtes Commit anzugeben).

Während es so einfach ist, den Autor Ihres letzten Commits zu ändern wie git commit --amend --author "Author Name <[email protected]>", gibt es keinen Einzeiler oder ein Argument, um dasselbe mit den Committer-Informationen zu tun.

Die Lösung besteht darin, Ihre Benutzerinformationen (vorübergehend oder nicht) zu ändern und dann das Commit zu ändern, wodurch der Committer auf Ihre aktuellen Informationen aktualisiert wird:

git config user.email [email protected] 
git commit --amend
5
Sir Athos

Mit der interaktiven Rebase können Sie nach jedem Festschreiben, das Sie ändern möchten, einen Änderungsbefehl einfügen. Zum Beispiel:

pick a07cb86 Project tile template with full details and styling
x git commit --amend --reset-author -Chead
5
j16r

Wenn Sie Eclipse mit EGit verwenden, gibt es eine recht einfache Lösung.
Annahme: Sie haben Commits in einem lokalen Zweig 'local_master_user_x', die aufgrund des ungültigen Benutzers nicht an einen fernen Zweig 'master' übertragen werden können.

  1. Kasse der Remote-Zweigstelle "Master"
  2. Wählen Sie die Projekte/Ordner/Dateien aus, für die 'local_master_user_x' Änderungen enthält
  3. Rechtsklick - Ersetzen durch - Zweig - 'local_master_user_x'
  4. Übernehmen Sie diese Änderungen erneut, diesmal als der richtige Benutzer, und in den lokalen Zweig 'master'.
  5. Push to Remote 'Master'
5
paphko

Wenn Sie der einzige Benutzer dieses Repos sind oder es Ihnen nicht wichtig ist, das Repo für andere Benutzer zu brechen, dann ja. Wenn Sie diese Commits gepusht haben und sie dort existieren, wo irgendwo anders darauf zugegriffen werden kann, dann nein, es sei denn, es ist Ihnen egal, ob Sie die Repos anderer Leute brechen. Das Problem besteht darin, dass Sie durch Ändern dieser Commits neue SHAs generieren, die dazu führen, dass sie als unterschiedliche Commits behandelt werden. Wenn jemand anderes versucht, diese geänderten Commits einzuziehen, ist die Geschichte anders und kaboom.

Diese Seite http://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.html beschreibt, wie es geht. (Ich habe das nicht ausprobiert, also YMMV)

2
baudtack

Ich möchte auch mein Beispiel hinzufügen. Ich möchte eine bash_function mit dem angegebenen Parameter erstellen.

dies funktioniert in Mint-Linux-17.3

# $1 => email to change, $2 => new_name, $3 => new E-Mail

function git_change_user_config_for_commit {

 # defaults
 WRONG_EMAIL=${1:-"[email protected]"}
 NEW_NAME=${2:-"your name"}
 NEW_EMAIL=${3:-"[email protected]"}

 git filter-branch -f --env-filter "
  if [ \$GIT_COMMITTER_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_COMMITTER_NAME='$NEW_NAME'
    export GIT_COMMITTER_EMAIL='$NEW_EMAIL'
  fi
  if [ \$GIT_AUTHOR_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_AUTHOR_NAME='$NEW_NAME'
    export GIT_AUTHOR_EMAIL='$NEW_EMAIL'
  fi
 " --tag-name-filter cat -- --branches --tags;
}
2

Probieren Sie dies aus. Dies geschieht genauso wie oben beschrieben, jedoch interaktiv.

bash <(curl -s  https://raw.githubusercontent.com/majdarbash/git-author-change-script/master/run.sh)

Referenz: https://github.com/majdarbash/git-author-change-script

1
Majd Arbash
git rebase -i YOUR_FIRTS_COMMIT_SHA^

while true; do git commit --amend --author="Name Surname <[email protected]>" --no-edit && git rebase --continue; done

Drücken Sie ^ C #, nachdem der Rebase abgeschlossen ist (die Schleife aktualisiert weiterhin das letzte Commit)

1
Vojtech Vitek