Vraag Hoe bewerk ik de geschiedenis van git om een ​​onjuist e-mailadres / -naam te corrigeren [gesloten]


Toen ik Git begon te gebruiken, deed ik gewoon een git init en begon te bellen add en commit. Nu begin ik op te letten en zie ik dat mijn commits verschijnen cowens@localmachine, in plaats van het adres dat ik wil. Het lijkt alsof instelling GIT_AUTHOR_EMAIL en GIT_COMMITTER_EMAIL zal doen wat ik wil, maar ik heb nog steeds die oude commits met het verkeerde e-mailadres / naam. Hoe kan ik de oude commits corrigeren?


72
2018-05-26 20:56


oorsprong


Voor onze toekomstige lezers: vragen over het gebruik git voor soortgelijke doeleinden kan beter worden gevraagd Stapel overloop. - Michael Hampton♦
Hier is de naaste vraag op stackoverflow.com. - naught101


antwoorden:


Je kunt teruggaan en al je commits repareren met een enkele call om filter-branch te activeren. Dit heeft hetzelfde effect als rebase, maar je hoeft maar één commando te doen om je hele geschiedenis te herstellen, in plaats van elke commit afzonderlijk te fixen.

Je kunt alle verkeerde e-mails herstellen met deze opdracht:

git filter-branch --env-filter '
    oldname="(old name)"
    oldemail="(old email)"
    newname="(new name)"
    newemail="(new email)"
    [ "$GIT_AUTHOR_EMAIL"="$oldemail" ] && GIT_AUTHOR_EMAIL="$newemail"
    [ "$GIT_COMMITTER_EMAIL"="$oldemail" ] && GIT_COMMITTER_EMAIL="$newemail"
    [ "$GIT_AUTHOR_NAME"="$oldname" ] && GIT_AUTHOR_NAME="$newname"
    [ "$GIT_COMMITTER_NAME"="$oldname" ] && GIT_COMMITTER_NAME="$newname"
    ' HEAD

Meer informatie is verkrijgbaar bij de git docs


80
2018-05-27 17:51



wel, git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL = "foo@example.com"; GIT_AUTHOR_NAME = "Foo"' is een stuk eenvoudiger, dank je. Dit zou het geaccepteerde antwoord zijn als ik het kon veranderen (het lijkt erop dat er een fout is met Server Fault). - Chas. Owens
Merk op dat de exportregels GEEN spaties moeten hebben aan weerszijden van het gelijkteken. D.w.z. ze zouden er als volgt uit moeten zien: export GIT_AUTHOR_EMAIL = "(correcte e-mail)"; - Andy Balaam
Nu, hoe zou ik dit doen op Windows? - Carsten Schmitz
@Deckard: sla het script op in een tekstbestand zoals fixcommits.sh, voer dan Git Bash uit en voer het script uit. Ik heb het scriptbestand in de root van mijn repo geplaatst en daarna naar die map in Git Bash gelopen, waarna ik het script met ./fixcommits.sh heb uitgevoerd - Avalanchis
Addendum 1 Deze opdrachtindeling werkte niet voor mij, maar als / dan deed het: if [ "$GIT_AUTHOR_EMAIL" = "$oldemail" ]; then GIT_AUTHOR_EMAIL="$newemail"; fi - Josh M.


Het filter-branch-commando van Git is krachtig, maar het is afschuwelijk onhandig om te gebruiken voor alles wat niet triviaal is, zoals bijvoorbeeld als je meer dan één auteur hebt om te corrigeren.

Hier is een alternatief dat ik handig vond, waarbij de .mailmap-functie wordt gebruikt die wordt beschreven in de git-shortlog-manpage. Dit biedt een auteurskaartmechanisme dat we kunnen gebruiken met de opmaakfaciliteit van git log. We kunnen het gebruiken om de commando's te genereren om een ​​benoemde sequentie van commits te selecteren en aan te passen.

Stel dat u het auteurschap op een branch $ BRANCH wilt corrigeren, beginnend bij een commit $ START.

U moet een .mailmap-bestand maken in de bovenste map van uw repository, die de bestaande auteursnamen toewijst aan de juiste. U kunt een lijst met de bestaande auteursnamen krijgen met:

git shortlog -se

Je moet eindigen met een .mailmap-bestand zoals dit (zeg):

You <you@somewhere.org>   cowens@localmachine
You <you@somewhere.org>   root@localmachine

Nu kun je de opmaakfunctie van git log gebruiken om de commando's te genereren om $ BRANCH te herschrijven als $ BRANCH2.

git checkout -b $BRANCH2 $START
git log --reverse --pretty=format:"cherry-pick %H; commit --amend --author='%aN <%aE>' -C %H" $START..$BRANCH | sh - 

Het eerste commando creëert een nieuwe lege tak die ontspruit uit de commit $ START. Voor elke commit tussen $ START en vervolgens het einde van $ BRANCH, selecteert de tweede opdracht cherry de oorspronkelijke commit aan het einde van de huidige branch $ BRANCH2 en wijzigt deze om de auteur correct in te stellen.

Dit is ook algemeen van toepassing - plaats dit in je ~ / .gitconfig:

[alias]
    # git reauthor $START..$END
    reauthor = !sh -c 'eval `git log --reverse --topo-order --pretty=format:\"git cherry-pick %H &&  git commit --amend -C %H --author=\\\"%aN <%aE>\\\" && \" $0 ` "echo success" '

Dus wanneer je auteurs moet corrigeren, moet je nu gewoon een .mapfile genereren en doen:

git checkout -b $BRANCH2 $START
git reauthor $START..$BRANCH

De originele vertakking ref kan opnieuw worden toegewezen aan de nieuwe en de nieuwe wordt verwijderd:

git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2

27
2017-07-29 10:54



Dit is geweldig. Ik zou je belonen als ik meer rep had. Bedankt :) - pistache


Combineer het antwoord van Hoe los ik de metainformatie op de eerste commit in git op?

### Fix the first commit ###    
# create a temporary tag for the root-most commit so we can reference it
git tag root `git rev-list HEAD | tail -1`
# check it out on its own temporary branch
git checkout -b new-root root
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# now you've changed the commit message, so checkout the original branch again
git checkout @{-1}
# and rebase it onto your new root commit
git rebase --onto new-root root
### Fix the rest of the commits ###
git rebase -i root
# edit the file to read "edit <commit number> for each entry
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# move to the next commit
git rebase --continue    
# continue running the last two commands until you see
# Successfully rebased and updated refs/heads/master.
### Clean up ###
# nuke the temporary branch we created
git branch -d new-root
# nuke the temporary tag we created
git tag -d root

8
2018-05-27 16:45



Heb me op de goede weg geholpen, maar had opdracht nodig van: stackoverflow.com/a/28536828/307 in plaats van het --author gebruik - Brett Veenstra


Om jedberg's antwoord te volgen: Je kunt gebruiken rebase -i en kies ervoor om de betreffende commits te bewerken. Als je gebruikt git commit --amend --author <AUTHOR DETAILS> en dan git rebase continue je kunt er doorheen gaan en de geschiedenis herstellen.


4
2018-05-26 22:02