Jak zmienić kilka zatwierdzeń w Git, aby zmienić autora

180

Wykonałem serię zatwierdzeń w Git i zdaję sobie sprawę, że zapomniałem poprawnie ustawić swoją nazwę użytkownika i właściwości adresu e-mail użytkownika (nowy komputer). Nie wysłałem jeszcze tych zatwierdzeń do mojego repozytorium, więc jak mogę je poprawić, zanim to zrobię (tylko 3 najnowsze zatwierdzenia w gałęzi master)?

Patrzyłem na git reseti git commit -C <id> --reset-author, ale nie sądzę, że jestem na dobrej drodze.

pauldoo
źródło
1
Innym powodem, dla którego możesz chcieć zmienić właściwość wiadomości e-mail, jest ten błąd na github: remote: error: GH007: Your push would publish a private email address.... `! [zdalne odrzucenie] master -> master (push odrzucony z powodu ograniczeń prywatności e-mail) `.
Craq
Zobacz także stackoverflow.com/q/750172/1340631 .
scai

Odpowiedzi:

232

Ponowne ustawienie / poprawienie wydaje się nieefektywne, gdy masz moc gałęzi filtru na wyciągnięcie ręki:

git filter-branch --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "incorrect@email" ]; then
     GIT_AUTHOR_EMAIL=correct@email;
     GIT_AUTHOR_NAME="Correct Name";
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
     GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all

(dla jasności podzielone na linie, ale nie jest to konieczne)

Po zakończeniu sprawdź wynik, aby upewnić się, że nie zmieniłeś niczego, czego nie chciałeś!

Cascabel
źródło
Masz ochotę wyjaśnić to trochę więcej? nie jestem pewien, co to jest gałąź filtra
max pleaner
1
@maxpleaner git filter-branch --helpjest całkiem proste :)
alediaferia
3
zobacz także help.github.com/articles/changing-author-info , która również dodaje --tag-name-filter catdo filter-branchw celu migracji tagów do nowej historii. Używa również --branches --tagszamiast --all, co tylko przepisuje historię gałęzi i tagów i pozostawia inne w refsspokoju (choć prawdopodobnie nie robi to dużej różnicy, chyba że np. Używasz git-notes)
Tobias Kienzler
12
aby wykonać to w ciągu zaledwie dwóch ostatnich zatwierdzeń, wymieniłem -- --allzHEAD~1..HEAD
nmz787
1
@ nmz787 Ile dzienników jest wyświetlanych, jeśli to zrobisz git log HEAD~2..HEAD?
Jona
148

Interaktywne podejście rebase jest całkiem przyjemne, gdy jest używane w połączeniu z exec. Możesz uruchomić dowolną komendę powłoki względem określonego zatwierdzenia lub wszystkich zatwierdzeń w rebase.

Najpierw ustaw ustawienia autora git

git config --global user.name "John Doe"
git config --global user.email [email protected]

Następnie, aby zresetować autora dla wszystkich zatwierdzeń po danym SHA

git rebase -i YOUR_SHA -x "git commit --amend --reset-author -CHEAD"

Spowoduje to wyświetlenie edytora, aby potwierdzić zmiany. Wszystko, co musisz tutaj zrobić, to zapisać i wyjść, a przejdzie przez każde zatwierdzenie i uruchomi polecenie określone w opcji -x.

Zgodnie z komentarzem @ Dave poniżej, możesz również zmienić autora, zachowując oryginalne znaczniki czasu za pomocą:

git rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <[email protected]>' -CHEAD"
Alex
źródło
3
Dziękuję za wprowadzenie mnie do opcji -x. To całkiem niesamowite! dla opcji -i użyłem HEAD ~ 4, aby naprawić mój adres e-mail w moich ostatnich 4 zatwierdzeniach. działał jak urok.
Brad Hein,
2
Jest to o wiele prostsze niż filter-branchwtedy, gdy chcesz po prostu naprawić swoje ostatnie zatwierdzenia :). Należy jednak pamiętać, że zmienia to sygnaturę czasową zatwierdzeń.
luator
24
Aby zmienić autora, ale zachować oryginalne znaczniki czasu, użyjgit rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <[email protected]>' -CHEAD"
Dave
2
@Connor git logrównież pokazał mi stare autorstwo, ale status git poprawnie identyfikował nowe zatwierdzenia i po wymuszeniu były one takie, jak zamierzałem.
Dan M.,
6
Aby zmienić bazę wszystkich zatwierdzeń, w tym roota, użyj: git rebase -i --root …zamiast przekazywania SHA.
gfullam
80

Aby zmienić autora tylko dla ostatniego zatwierdzenia:

git commit --amend --author 'Author Name <[email protected]>' --no-edit

Załóżmy, że chcesz zmienić autora tylko dla ostatnich N zatwierdzeń:

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

UWAGI

  • te --no-editodbierają fladze, czy git commit --amendnie poprosić o dodatkowe potwierdzenie
  • kiedy używasz git rebase -i, możesz ręcznie wybrać zmiany, w których chcesz zmienić autora,

edytowany plik będzie wyglądał następująco:

pick 897fe9e simplify code a little
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <[email protected]>' --no-edit
pick dc18f70 bugfix
Chris Maes
źródło
1
dla wszystkich zatwierdzeń od roota. git rebase -i --root UPTO_COMMIT_SHA -x "git commit --amend --author 'NEW_CHANGE' --no-edit"
Ashish Negi
1
Zalecam dodanie --rebase-merges(krótkiej -r) opcji, aby zachować topologię gałęzi w stanie nienaruszonym, jeśli zawiera jakieś scalenia.
donquixote
4

Ta metoda została udokumentowana przez github właśnie w tym celu. Kroki są następujące:

  1. Otwórz terminal i zrób czysty klon repozytorium
git clone --bare https://github.com/user/repo.git
cd repo
  1. Edycja poniższy skrypt (w zastępstwie OLD_EMAIL, CORRECT_EMAILi CORRECT_NAME)
#!/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
  1. Skopiuj / wklej skrypt do swojego terminala i naciśnij klawisz Enter, aby go uruchomić.
  2. Prześlij zmiany za pomocą git push --force --tags origin 'refs/heads/*'i gotowe!
stevec
źródło
Postępowałem zgodnie z tymi samymi instrukcjami na GitHub, do których się odwołałeś, a GitHub wygląda teraz. Jednak jestem nowicjuszem Git i nie jestem pewien, jak zsynchronizować kopię zapasową lokalnego repozytorium. Kiedy pociągam, pojawia się ten sam błąd „odmowy scalania niepowiązanych historii”, o którym mowa w innej odpowiedzi. Myślę, że muszę się oprzeć na nowej historii zatwierdzeń, ale byłbym bardzo wdzięczny za bardziej szczegółowe kroki.
enigment
@enigment Jeśli jesteś zadowolony z repozytorium, które jest na githubie, możesz usunąć (lub przenieść do innej lokalizacji) folder, który masz lokalnie i po prostu sklonować z github
stevec
Dzięki, wiem, ale to nie wygląda na idiomatyczny sposób na GitHub / Git.
enigment
0

Jeśli nie czujesz się bezpiecznie, jeśli chodzi o poniżanie i poprawianie, możesz to zrobić w ten sposób. W tym samym czasie ustawiałbyś również globalną konfigurację, którą prawdopodobnie i tak zamierzałeś zrobić.

git reset HEAD~ (cofnij ostatnie zatwierdzenie)

git config --global user.name "Your Name"

git config --global user.email [email protected]

git commit -m "message"

Edison
źródło