Vraag Hoe de auteur en committer naam en e-mail van meerdere commits in Git te veranderen?


Ik was een eenvoudig script aan het schrijven op de schoolcomputer en de veranderingen aan Git aan het uitvoeren (in een repo die in mijn pendrive zat, die ik thuis van mijn computer heb gekloond). Na verschillende commits besefte ik dat ik dingen als root-gebruiker aan het doen was.

Is er een manier om de auteur van deze commits te veranderen in mijn naam?


1998
2018-04-15 03:09


oorsprong


antwoorden:


Het veranderen van de auteur (of committer) zou het opnieuw schrijven van de geschiedenis vereisen. Als je dat goed vindt en denkt dat het het waard is, moet je het eens proberen git filter-branch. De man-pagina bevat verschillende voorbeelden om u op weg te helpen. Merk ook op dat u omgevingsvariabelen kunt gebruiken om de naam van de auteur, committer, datums, enz. Te wijzigen - zie het gedeelte "Omgevingsvariabelen" van de git man pagina.

In het bijzonder kunt u alle verkeerde auteursnamen en e-mails herstellen voor alle branches en tags met dit commando (bron: GitHub hulp):

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

800
2018-04-15 03:16



Interactieve rebase gebruiken

Je zou kunnen doen

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

Markeer vervolgens al je slechte commits als "edit" in het rebase-bestand. Als u ook uw eerste commit wilt wijzigen, moet u deze handmatig als eerste regel in het rebase-bestand toevoegen (volg het formaat van de andere regels). Dan, als git je vraagt ​​om elke commit aan te passen, doe dat dan

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

bewerk of sluit de editor die wordt geopend en klik vervolgens op

git rebase --continue

om door te gaan met de rebase.

Je zou kunnen overslaan om de editor hier helemaal te openen door het toe te voegen --no-edit zodat het commando zal zijn:

git commit --amend --author "New Author Name <email@address.com>" --no-edit && \
git rebase --continue

Single Commit

Zoals sommige commentatoren hebben opgemerkt, is het niet nodig om de rebase-opdracht te wijzigen als u alleen de meest recente commit wilt wijzigen. Gewoon doen

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

Hierdoor wordt de auteur gewijzigd in de opgegeven naam, maar wordt de committer ingesteld op uw geconfigureerde gebruiker in git config user.name en git config user.email. Als u de committer wilt instellen op iets dat u opgeeft, stelt dit zowel de auteur als de committer in:

 git -c user.name="New Author Name" -c user.email=email@address.com commit --amend --reset-author

Opmerking over samenvoegverbintenissen

Er was een lichte fout in mijn oorspronkelijke antwoord. Als er samenvoegingsbevoegdheden zijn tussen de huidige HEAD en jouw <some HEAD before all your bad commits>, dan git rebase zal ze plat maken (en trouwens, als je GitHub pull-verzoeken gebruikt, zullen er een hoop samenvoegcommissies zijn in je geschiedenis). Dit kan heel vaak tot een heel andere geschiedenis leiden (omdat dubbele wijzigingen mogelijk worden "uitgebouwd") en in het ergste geval kan dit leiden tot git rebase u vragen om moeilijke samenvoegconflicten op te lossen (die waarschijnlijk al in de samenvoegingsopdrachten zijn opgelost). De oplossing is om de -p vlag naar git rebase, die de samenvoegingsstructuur van je geschiedenis zal behouden. De manpage voor git rebase waarschuwt dat gebruik -p en -i kan tot problemen leiden, maar in de BUGS In dit gedeelte staat "Bezig met bewerken van commits en het herformuleren van hun commit-berichten zou goed moeten werken."

Ik heb toegevoegd -p naar het bovenstaande commando. Voor het geval dat u alleen de meest recente commit wijzigt, is dit geen probleem.


1415
2017-08-24 03:08



Je kunt ook doen:

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

Opmerking: als u deze opdracht gebruikt in de Windows-opdrachtprompt, moet u deze gebruiken "in plaats van ':

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

565
2018-05-15 19:15



Eén voering, maar wees voorzichtig als u een repository met meerdere gebruikers hebt - dit zal veranderen alle verbindt zich ertoe dezelfde (nieuwe) auteur en committer te hebben.

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

Met regelafbreking in de reeks (wat mogelijk is bij bash):

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

481
2018-04-15 03:22



Het gebeurt wanneer u geen $ HOME / .gitconfig geïnitialiseerd hebt. U kunt dit oplossen als:

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

getest met git-versie 1.7.5.4


201
2018-02-16 09:46



Voor één commit:

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

(ontleend aan het antwoord van asmeurer)


179
2018-04-26 22:50



In het geval dat alleen de beste paar commits slechte auteurs hebben, kun je dit allemaal van binnen doen git rebase -i de ... gebruiken exec commando en de --amend commit, als volgt:

git rebase -i HEAD~6 # as required

die je de editeerbare lijst met commits presenteert:

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

Dan toevoegen exec ... --author="..." regels na alle regels met slechte auteurs:

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

bewaar en verlaat de editor (om uit te voeren).

Deze oplossing is misschien langer om te typen dan sommige andere, maar het is zeer controleerbaar - ik weet precies wat het begaat.

Bedankt aan @asmeurer voor de inspiratie.


150
2017-12-08 17:05



Github heeft een mooie oplossing, wat het volgende shellscript is:

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

107
2017-10-07 09:54



Zoals docgnome al zei, is het herschrijven van de geschiedenis gevaarlijk en zal het de opslagplaatsen van andere mensen doorbreken.

Maar als je dat echt wilt doen en je bent in een bash-omgeving (geen probleem onder Linux, in Windows kun je git bash gebruiken, dat is voorzien van de installatie van git), gebruik 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'

Om de snelheid te versnellen, kunt u een reeks revisies opgeven die u wilt herschrijven:

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

78
2017-08-04 00:52



Wanneer een niet-gehaalde commit van een andere auteur wordt overgenomen, is er een eenvoudige manier om dit aan te pakken.

git commit --amend --reset-author


45
2018-03-23 22:23



Dit is een meer uitgebreide versie van de @ Brian-versie:

Om de auteur en committer te veranderen, kun je dit doen (met regelafbreking in de string die mogelijk is bij bash):

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

U kunt een van deze fouten krijgen:

  1. De tijdelijke map bestaat al
  2. Refs beginnend met refs / original bestaat al
    (dit betekent dat er al eerder een filter-branch is uitgevoerd op de repository en er wordt een back-up van de toenmalige originele branchreferentie gemaakt refs / original)

Als je ondanks deze fouten de run wilt forceren, voeg je de --force vlag:

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

Een kleine uitleg van de -- --all optie kan nodig zijn: het zorgt ervoor dat de filter-branch werkt op alle revisies ingeschakeld alle refs (die alle takken omvat). Dit betekent bijvoorbeeld dat tags ook herschreven worden en zichtbaar zijn op de herschreven vertakkingen.

Een veel voorkomende "fout" is om te gebruiken HEAD in plaats daarvan, wat betekent filteren van alle revisies op alleen de huidige tak. En dan zouden er geen tags (of andere refs) bestaan ​​in de herschreven vertakking.


36
2017-12-09 10:23