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.


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

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ś!


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 johndoe@example.com

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 <new_address@example.com>' -CHEAD"

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 <new_address@example.com>' -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 <author.name@mail.com>' --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 <author.name@mail.com>' --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 <author.name@mail.com>' --no-edit
pick dc18f70 bugfix

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="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
  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!

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 you@example.com

git commit -m "message"

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.