Zmiana komunikatu git commit po wypchnięciu (biorąc pod uwagę, że nikt nie wyciągnął ze zdalnego)

981

Zrobiłem git commit i późniejszy push. Chciałbym zmienić komunikat zatwierdzenia. Jeśli dobrze rozumiem, nie jest to zalecane, ponieważ ktoś mógł wyciągnąć ze zdalnego repozytorium, zanim dokonam takich zmian. Co jeśli wiem, że nikt nie pociągnął?

Czy jest na to sposób?

K_U
źródło
Czego próbowałeś? Zakładając, że wiesz już, jak zmienić komunikat zatwierdzenia, a następnie spróbuj go nacisnąć, Git powie ci, co musisz zrobić, aby tak się stało.
Andrew Marshall,
1
Zobacz odpowiedź na pytanie „Jak edytować niepoprawną wiadomość zatwierdzenia w git (wypchnąłem)?” stackoverflow.com/a/457396/444639
Mike Rylander
4
Deklaracja - Google Pytanie git commit Ranga nr 1!
Manish Shrivastava
Jeśli zmienisz zatwierdzenie HEAD i wypychasz zwykle (bez --force), to, co zaskakujące, nie zawiedzie. Komunikat zatwierdzenia HEAD jest aktualizowany o zmieniony identyfikator zatwierdzenia. Oznacza to, że inne identyfikatory zatwierdzenia oprócz HEAD pozostają nienaruszone. Zauważyłem to zachowanie w wersji git 2.8.1.
tęczówka

Odpowiedzi:

1370

Zmieniająca się historia

Jeśli jest to ostatni zatwierdzenie, możesz po prostu to zrobić:

git commit --amend

Spowoduje to wyświetlenie edytora z ostatnią wiadomością zatwierdzenia i umożliwi edycję wiadomości. (Możesz użyć, -mjeśli chcesz usunąć starą wiadomość i użyć nowej).

Popychanie

A potem, kiedy naciskasz, zrób to:

git push --force-with-lease <repository> <branch>

Lub możesz użyć „+”:

git push <repository> +<branch>

Lub możesz użyć --force:

git push --force <repository> <branch>

Zachowaj ostrożność podczas korzystania z tych poleceń.

  • Jeśli ktoś wprowadził zmiany do tej samej gałęzi, prawdopodobnie chcesz uniknąć ich zniszczenia. Ta --force-with-leaseopcja jest najbezpieczniejsza, ponieważ zostanie przerwana, jeśli wystąpią jakiekolwiek zmiany na wcześniejszych etapach (

  • Jeśli nie określisz gałęzi wyraźnie, Git użyje domyślnych ustawień wypychania. Jeśli domyślnym ustawieniem wypychania jest „dopasowanie”, możesz zniszczyć zmiany w kilku oddziałach jednocześnie.

Ciągnięcie / pobieranie później

Każdy, kto już ściągnął, otrzyma teraz komunikat o błędzie i będzie musiał zaktualizować (zakładając, że sami nie wprowadzają żadnych zmian), wykonując coś takiego:

git fetch origin
git reset --hard origin/master # Loses local commits

Zachowaj ostrożność podczas używania reset --hard. Jeśli masz zmiany w oddziale, zmiany te zostaną zniszczone.

Uwaga na temat modyfikacji historii

Zniszczone dane to tak naprawdę stary komunikat zatwierdzenia, ale --forcenie wie o tym i chętnie usunie także inne dane. Pomyśl więc o tym: --force„Chcę zniszczyć dane i wiem na pewno, które dane są niszczone”. Ale kiedy zatwierdzone są zniszczone dane, często można odzyskać stare zatwierdzenia z dziennika ponownego logowania - dane są faktycznie osierocone zamiast niszczone (chociaż osierocone zatwierdzenia są okresowo usuwane).

Jeśli nie uważasz, że niszczysz dane, trzymaj się z dala od --force... złych rzeczy może się zdarzyć .

Dlatego --force-with-leasejest nieco bezpieczniejszy.

Dietrich Epp
źródło
13
Bądź ostrożny z tą „poprawką”, ponieważ jeśli mają jakieś lokalne, nieprzypisane zobowiązania, zostaną „utracone” ( utracone prawdziwie osierocone , ale ich odzyskanie nie jest oczywiste).
Andrew Marshall
1
prawdopodobnie chcesz podać nazwę gałęzi, kiedy naciskasz - force, w przeciwnym razie możesz pushować więcej niż się spodziewałeś.
user693960,
1
@ user693960: Git będzie wypychał tylko to, co skonfigurowałeś do wypychania.
Dietrich Epp,
10
Po prostu git push --forcebez opcji <repository> i <branch> działa również, jeśli masz skonfigurowane upstream.
ahnbizcad
2
Czy możesz podać przykład <repository>? Czy to originjest org/repo? A może po prostu repo?
MikeSchinkel,
439

Tylko powiedz :

git commit --amend -m "New commit message"

i wtedy

git push --force
Manish Shrivastava
źródło
8
W moim przypadku git push origin <BRANCH-NAME>nie działało, musiałem użyć, git push --forcejak wyjaśniono w zaakceptowanej odpowiedzi.
Gabriel
1
to nie działa dla mnie. musisz nas git push --force, bo inaczej push nie przejdzie.
ahnbizcad
4
@ahnbizcad, powinno działać. Upewnij się tylko, że nazwa oddziału jest poprawna.
William
3
Kibicuję prostocie twojego wyjaśnienia! Używam go bardziej niż często
Vasikos
3
Z powodzeniem zastosowałem te polecenie dopiero po tymczasowym „niezabezpieczeniu” mojej gałęzi, co miało miejsce w moim projekcie hostowanym przez GitLab. Jeśli masz ten problem, przed zastosowaniem tych poleceń zapoznaj się z tym stackoverflow.com/a/32267118/1423345, aby „nie chronić” gałęzi, i możesz „zabezpieczyć” ją ponownie po zakończeniu zmiany komunikatu zatwierdzenia :)
John
261

Aby edytować zatwierdzenie inne niż najnowszy:

Krok 1 : git rebase -i HEAD~nzrobić interaktywny rebase dla ostatnich nzatwierdzonych zmian. (tzn. jeśli chcesz zmienić komunikat zatwierdzenia, 3 zatwierdza z powrotem, zrób git rebase -i HEAD~3)

git wyświetli edytor do obsługi tych zatwierdzeń, zwróć uwagę na to polecenie:

#  r, reword = use commit, but edit the commit message

właśnie tego potrzebujemy!

Krok 2 : Zmień pickna rdla zatwierdzeń, które chcesz zaktualizować wiadomość. Nie przejmuj się tutaj zmianą komunikatu zatwierdzenia, zostanie on zignorowany. Zrobisz to w następnym kroku. Zapisz i zamknij edytor.

Pamiętaj, że jeśli edytujesz „plan” bazy bazowej, ale nie rozpoczyna się proces umożliwiający zmianę nazwy plików, uruchom:

git rebase --continue

Jeśli chcesz zmienić edytor tekstu używany w sesji interaktywnej (np. Z domyślnej vi na nano), uruchom:

GIT_EDITOR=nano git rebase -i HEAD~n

Krok 3 : Git wyświetli inny edytor dla każdej wprowadzonej rwcześniej wersji. Zaktualizuj msg zatwierdzenia, jak chcesz, a następnie zapisz i zamknij edytor.

Krok 4 : Po zaktualizowaniu wszystkich zatwierdzeń wiadomości. możesz zrobić, git push -faby zaktualizować pilota.

Jinsong Li
źródło
21
Należy zaakceptować odpowiedź, ponieważ daje ona możliwość zmiany innych zatwierdzeń niż ostatnie zatwierdzenie, w przeciwieństwie do zaakceptowanej odpowiedzi. Uratowałeś mi dzień. Dziękuję Ci!
xZero
1
Wybierz n = 3 dla ostatnich 3 zatwierdzeń:git rebase -i HEAD~3
HeikoS
Jeśli edytujesz „plan” bazy bazowej, ale nie rozpoczyna się proces pozwalający na zmianę nazwy plików, uruchom git rebase --continue. A jeśli chcesz zmienić edytor tekstu używany w sesji interaktywnej (np. Z domyślnej vina nano), uruchom GIT_EDITOR=nano git rebase -i HEAD~n.
Jamie Birch,
Zredagowałem to, aby dodać trochę więcej informacji. Proszę spojrzeć. To była odpowiedź na to, co chciałem zrobić, ale przewinąłem ją, ponieważ nie miała nagłówka.
Kip
Dokonałem sugerowanej edycji, aby umieścić użyteczny komentarz z @JamieBirch w odpowiedzi, być może chciałbym przejrzeć.
Notts90 obsługuje Monikę
44

Użyj tych dwóch kroków w konsoli:

git commit --amend -m "new commit message"

i wtedy

git push -f

Gotowy :)

Abdul Rizwan
źródło
Dzięki, czy to tylko kroki do zmiany ostatniego komentarza, czy można go również zastosować do starszych komentarzy?
Jay
@ Przepraszam za spóźnioną odpowiedź, te kroki dotyczą tylko zmiany ostatniej wiadomości zatwierdzenia.
Abdul Rizwan
19

Należy zauważyć, że jeśli użyjesz wielu push --forcereferencji, zostaną one WSZYSTKIE zmodyfikowane. Pamiętaj, aby zwrócić uwagę na to, gdzie repozytorium git jest skonfigurowane do wypychania. Na szczęście istnieje sposób, aby nieco zabezpieczyć ten proces, określając jeden oddział do aktualizacji. Czytaj ze stron man git:

Zauważ, że --force stosuje się do wszystkich wypychanych referencji, dlatego też używa go z ustawieniem push.default na dopasowanie lub z wieloma miejscami docelowymi wypychania skonfigurowanymi ze zdalnym. *. Push może zastąpić referencje inne niż bieżąca gałąź (w tym referencje lokalne, które są ściśle za ich odległym odpowiednikiem). Aby wymusić push tylko do jednej gałęzi, użyj + przed refspec, aby push (np. Git push origin + master, aby wymusić push do gałęzi master).

Steve Benner
źródło
3
Bardzo ważna uwaga.
peterh - Przywróć Monikę
żadna z odpowiedzi wymuszonych nie działa dla mnie, ponieważ nie mam uprawnień ForcePush na serwerze. Zamiast tego chcę wykonać zatwierdzenie, które zmienia poprzednią wiadomość zatwierdzenia. Mógłbym napisać „zmieniono komunikat zatwierdzenia” w sekcji komentarza tego zatwierdzenia.
nurettin
11

Jeżeli chcesz zmodyfikować starszy popełnienia, nie ostatni, będzie trzeba użyć rebasepolecenia jak wyjaśniono tu, strona pomocy Github na zmieniający przesłanie starsze lub wielokrotność popełnić wiadomości sekcję

Carlos
źródło
11

Polecenie 1 .

git commit --amend -m "New and correct message"

Następnie,

Polecenie 2 .

git push origin --force
Teo Choong Ping
źródło
8
git commit --amend

następnie edytuj i zmień wiadomość w bieżącym oknie. Po tym zrób

git push --force-with-lease
Beu
źródło
2

Inną opcją jest utworzenie dodatkowego „zatwierdzenia erraty” (i wypychania), który odwołuje się do obiektu zatwierdzenia zawierającego błąd - nowe zatwierdzenie erraty również zapewnia korektę. Zatwierdzenie erraty jest zatwierdzeniem bez istotnych zmian kodu, ale ważnym komunikatem zatwierdzenia - na przykład dodaj jeden znak spacji do pliku readme i zatwierdź tę zmianę za pomocą ważnego komunikatu zatwierdzenia lub użyj opcji git--allow-empty . Jest to z pewnością łatwiejsze i bezpieczniejsze niż ponowne bazowanie, nie modyfikuje prawdziwej historii i utrzymuje drzewo gałęzi w czystości (używającamendjest również dobrym wyborem, jeśli poprawiasz ostatnie zatwierdzenie, ale zatwierdzenie errata może być dobrym wyborem dla starszych zatwierdzeń). Tego rodzaju rzeczy zdarzają się tak rzadko, że wystarczy udokumentować błąd. W przyszłości, jeśli będziesz musiał przeszukiwać dziennik git w poszukiwaniu słowa kluczowego funkcji, oryginalne (błędne) zatwierdzenie może się nie pojawić, ponieważ w tym oryginalnym zatwierdzeniu użyto niewłaściwego słowa kluczowego (oryginalnej literówki) - pojawi się jednak słowo kluczowe w erracie commit, która następnie wskaże ci oryginalne zatwierdzenie, które zawierało literówkę. Oto przykład:

$ git log
zatwierdzić 0c28141c68adae276840f17ccd4766542c33cf1d
Autor: pierwszy ostatni 
Data: śr. 8 sierpnia 15:55:52 2018 -0600

    Errata commit:
    Ta zmiana nie ma istotnej zmiany kodu.
    To zatwierdzenie służy jedynie do udokumentowania korekty poprzedniego komunikatu zatwierdzenia.
    Dotyczy to zatwierdzenia obiektu e083a7abd8deb5776cb304fa13731a4182a24be1
    Oryginalny niepoprawny komunikat zatwierdzenia:
        Zmieniono kolor tła na czerwony
    Korekta (* podświetlona zmiana *):
        Zmieniono kolor tła na * niebieski *

zatwierdzić 032d0ff0601bff79bdef3c6f0a02ebfa061c4ad4
Autor: pierwszy ostatni 
Data: śr. 8 sierpnia 15:43:16 2018 -0600

    Niektóre komunikaty tymczasowego zatwierdzenia

zatwierdzić e083a7abd8deb5776cb304fa13731a4182a24be1
Autor: pierwszy ostatni 
Data: śr. 8 sierpnia 13:31:32 2018 -0600

    Zmieniono kolor tła na czerwony
rob_7cc
źródło
rob, to wygląda obiecująco. czy możesz pokazać komendy potrzebne do wykonania „errata commit”. tylko ten post pojawia się w google na tych warunkach.
Jim,
1
„Zatwierdzenie erraty” to po prostu normalne zatwierdzenie z komunikatem, który odwołuje się do poprzedniego błędnego zatwierdzenia, dokumentując i zapewniając korektę dla poprzedniego błędu. git commit -m “fixed feature A”(Załóżmy, że git podaje identyfikator zatwierdzenia e3ab7312 ... ... (później zdasz sobie sprawę, że twoja wiadomość była niepoprawna, więc teraz dokonaj nieistotnej zmiany w pliku, np. Dodając spację do pliku readme lub użyj —allow-emptyopcji git). .. git commit -m “Errata commit for previous commit e3ab7312... original message should have been ‘fixed feature *B*’'' '
rob_7cc
1
... jeśli później będziesz musiał przeszukać dziennik git w poszukiwaniu odniesień do „funkcji B”, zatwierdzenie erraty pojawi się, ale komunikat zatwierdzenia erraty zawiera odniesienie do oryginalnego identyfikatora zatwierdzenia, który zapewnia pełną identyfikowalność. BTW, termin „zatwierdzenie erraty” nie jest niczym specjalnym (w git nie ma polecenia „errata” ani opcji) ... to tylko moja terminologia dotycząca normalnego zatwierdzenia, która zapewnia korektę poprzedniego zatwierdzenia zawierającego błąd / literówkę.
rob_7cc,
rob, to działało świetnie. Byłem w stanie dodać nowe puste zatwierdzenie z poprawnym opisem, który wskazuje na oryginalny zatwierdzenie, za pomocą SHA. teraz oba są pokazane w moim „łańcuchu git” dla modułów. dzięki!
Jim,
Cieszę się, że ci się udało. Używam tej samej techniki do poprawiania błędów w komunikatach zatwierdzania. Alternatywnie, niedawno odkryłem, git notes że służyłoby to temu samemu celowi, co „errata commit”. Po prostu dodaj notatkę do poprzedniego zatwierdzenia, aby dodać adnotację lub poprawić wszelkie błędy w komunikacie zatwierdzenia: https://git-scm.com/docs/git-notes
rob_7cc
0

To działa dla mnie całkiem dobrze,

git checkout origin / branch name

jeśli jesteś już w oddziale, lepiej zrobić pull lub rebase

git pull

lub

git -c core.quotepath=false fetch origin --progress --prune

Później możesz po prostu użyć

git commit --amend -m "Your message here"

lub jeśli chcesz otworzyć edytor tekstu, użyj

git commit --amend

Wolę używać edytora tekstu, jeśli masz wiele komentarzy. Możesz ustawić preferowany edytor tekstu za pomocą polecenia

git config --global core.editor your_preffered_editor_here

W każdym razie, kiedy skończysz zmieniać komunikat zatwierdzenia, zapisz go i wyjdź

a następnie biegnij

git push --force

I jesteś skończony

Hasasn
źródło
0

dodatkowe informacje dotyczące tego samego problemu, jeśli używasz potoku bitbucket

edytuj swoją wiadomość

git commit --amend

wcisnąć do serwera

git push --force <repository> <branch>

następnie dodaj --force do polecenia push w potoku

git ftp push --force

Spowoduje to usunięcie poprzednich zatwierdzeń i przekazanie bieżącego.

usuń --force po pierwszym wypchnięciu

wypróbowałem to na rurociągu bitbucket i działa dobrze

Abdallah Awwad Alkhwaldah
źródło