Git, przepisz poprzednie nazwy użytkowników i e-maile

170

Zaangażowałem się w projekt na Githubie, ale zdałem sobie sprawę, że nie ustawiłem odpowiedniego adresu e-mail i imienia i nazwiska osoby odpowiedzialnej na komputerze, którego obecnie używam do tworzenia zatwierdzeń, a tym samym awatara użytkownika i adresu e-mail nie ma.

Jak mogę przepisać wszystkie poprzednie adresy e-mail i nazwy użytkowników?

JP Silvashy
źródło
9
możliwy duplikat Jak zmienić autora zatwierdzenia w git?
givanse
Doświadczyłem tego po zmianie adresu e-mail na moim koncie GitHub. Oprócz wypychania zmian w kodzie z lokalnego repozytorium git za pomocą interfejsu wiersza poleceń git (a nie pulpitu GitHub), edytowałem również tekst i pliki zarządzane bezpośrednio ze zdalnego repozytorium git za pomocą interfejsu internetowego GitHub. Nowy adres e-mail rozprzestrzeniał się tylko do zatwierdzeń wynikających z tych ostatnich, a nie do pierwszych.
Robert John

Odpowiedzi:

243

Możesz dodać ten alias:

git config 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\" \$@; }; f "

Aby zmienić nazwisko autora:

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

lub e-mail dotyczący tylko ostatnich 10 zatwierdzeń:

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

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\" \$@; }; f "

Źródło: https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig

brauliobo
źródło
13
Również git change-commits GIT_COMMITTER_EMAIL "[email protected]" "[email protected]"do zmiany adresu e-mail osoby zatwierdzającej.
laurent
19
naprawiono dla "eval: [[: not found" na ubuntu i dodaj potwierdzeniechange-commits = "!f() { VAR1=$1; VAR='$'$1; OLD=$2; NEW=$3; echo \"Are you sure for replace $VAR $OLD => $NEW ?(Y/N)\";read OK;if [ \"$OK\" = 'Y' ] ; then shift 3; git filter-branch --env-filter \"if [ \\\"${VAR}\\\" = '$OLD' ]; then export $VAR1='$NEW';echo 'to $NEW'; fi\" $@; fi;}; f "
qxo
9
git: 'change-commits' nie jest poleceniem git. Zobacz „git --help”. Oznacza, że ​​nie dodałeś aliasu do konfiguracji git. np. git config -e
Wayne
2
To właśnie spowodowało duplikaty wszystkich zatwierdzeń w e-mailu, który chciałem zmienić. Wydaje się, że nie zmienia historii. Rozwiązanie @Olivier Verdier zadziałało dla mnie.
Jake Wilson
6
Zrobienie tego dwa razy z rzędu z różnymi wejściami prowadzi do:Cannot create a new backup. A previous backup already exists in refs/original/
theonlygusti
97

Rozwiązanie już tam jest: Zmień autora i autora oraz adres e-mail wielu zatwierdzeń w Git

Mianowicie,

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD
Olivier Verdier
źródło
4
czy nie zmieniłoby to nazwiska autora dla wszystkich zatwierdzeń (całej historii) gałęzi?
hasen
2
Tak, to zmieniłoby wszystkie zatwierdzenia nowych informacji o autorze.
ewall
9
Oznacz pytania jako duplikaty zamiast kopiować i wklejać odpowiedź.
givanse
2
co jeśli nie podam starej nazwy lub starego adresu e-mail? git mówi „pusty ident <> niedozwolony”
Griffan,
Uruchomiłem to polecenie i teraz moje repozytorium nie chce wypychać ani pobierać z serwera git.
Jezus H
46

Jeśli już umieściłeś część swoich zatwierdzeń w repozytorium publicznym, nie chcesz tego robić, bo inaczej stworzyłoby to alternatywną wersję historii mastera, z której mogliby korzystać inni. „Nie przekraczaj strumieni… Byłoby źle…”

To powiedziawszy, jeśli są to tylko zatwierdzenia, które wykonałeś w swoim lokalnym repozytorium, to wszelkimi sposobami napraw to przed wysłaniem na serwer. Możesz użyć git filter-branchpolecenia z --commit-filteropcją, więc edytuje tylko zatwierdzenia, które pasują do twoich nieprawidłowych informacji, na przykład:

git filter-branch --commit-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong_email@wrong_host.local" ];
      then
              GIT_AUTHOR_NAME="Your Name Here (In Lights)";
              GIT_AUTHOR_EMAIL="correct_email@correct_host.com";
              git commit-tree "$@";
      else
              git commit-tree "$@";
      fi' HEAD
ewall
źródło
5
Działa to doskonale, podczas gdy odpowiedź zaznaczona na zielono nie
jmary
Następnie możesz chcieć wyczyścić kopię zapasową za pomocą git update-ref -d refs/original/refs/heads/master, patrz < stackoverflow.com/a/7654880/333403 >.
cknoll
Do Twojej wiadomości: jeśli masz wiele nieprawidłowych nazw / e-maili, może być konieczne wielokrotne uruchomienie tego. Jeśli tak się stanie, będzie na ciebie jęczeć z tym błędem: A previous backup already exists in refs/original/W takim przypadku uruchom go ponownie z nowym e-mailem i dodaj -fprzed --commit-filter. Używaj według własnego uznania. Zwykle -fjest to niebezpieczne bez wiedzy o tym, co robi.
Chuck
19

Po zastosowaniu odpowiedzi Oliviera Verdiera:

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

... aby wypchnąć zmienioną historię do pierwotnego wykorzystania repozytorium:

git push origin +yourbranch

Powyższe polecenie (uwaga na plus) wymusza przepisanie historii również w oryginalnym repozytorium. Używaj ostrożnie!

sarusso
źródło
U mnie zadziałało, również poprawnie przepisałem historię na pochodzenia.
Xeverous
10
Spowoduje to przepisanie WSZYSTKICH zatwierdzeń - niezależnie od tego, kto jest ich autorem. Używaj ostrożnie.
Bhavin Doshi,
14

https://help.github.com/articles/changing-author-info/

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="[email protected]"
CORRECT_NAME="yourName"
CORRECT_EMAIL="yourEmail"

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

to całkowicie zadziałało dla mnie. Po git push sprawdź aktualizację w portalu internetowym git. Jeśli zatwierdzenie nadal nie było połączone z moim kontem, wyświetlała się domyślna miniatura obok zatwierdzenia i nie została odzwierciedlona na wykresie osi czasu mojego wkładu, przejdź do adresu URL zatwierdzenia i dołącz .patch na końcu adresu URL i sprawdź nazwę i email są poprawne.

Jacccck
źródło
Chociaż może to teoretycznie odpowiedzieć na pytanie, lepiej byłoby zawrzeć tutaj zasadnicze części odpowiedzi i podać link do odniesienia.
jhpratt
1
To jedyny przepis na wszystkie gałęzie.
Bruno Zell
6

Dla tych, którzy chcą tylko łatwej wersji do kopiowania wklejania (oprócz aktualizacji e-maili i nazw):

git config 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\" \$@; }; f "
git change-commits GIT_AUTHOR_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_AUTHOR_EMAIL <[email protected]> <[email protected]> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <[email protected]> <[email protected]> -f
Nick Kuznia
źródło
5
-bash:! f: wydarzenie nie zostało znalezione
Saiyine
Najprawdopodobniej problem z automatyczną ucieczką terminala
Andrei Savin
3

Biorąc pod uwagę, że użycie programu niegit-filter-branch jest pożądane , zrobienie tego samego w git-filter-repo (może być konieczne zainstalowanie go najpierw z pip install git-filter-repo):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"[email protected]", b"[email protected]")'

Jeśli repozytorium jest oryginalne, bez zdalnego, będziesz musiał dodać, --forceaby wymusić przepisanie. (Przed wykonaniem tej czynności możesz utworzyć kopię zapasową repozytorium).

Jeśli nie chcesz zachowywać referencji (będą one wyświetlane w historii gałęzi Git GUI), będziesz musiał dodać --replace-refs delete-no-add.

Aby uzyskać bardziej zaawansowane funkcje, zobacz „Filtrowanie nazw i e-maili” .

PS Skradzione i ulepszone z https://stackoverflow.com/a/59591928/714907 .

Pugsley
źródło