Jak zmodyfikować istniejące, nieprzesłane komunikaty zatwierdzania?


7664

Napisałem niewłaściwą wiadomość w komunikacie zatwierdzenia.

Jak mogę zmienić wiadomość? Zatwierdzenie nie zostało jeszcze wypchnięte.


868
Dla tych, którzy są nieco nowi na git: ważne jest, aby Laurie nie była jeszcze naciskać. Podobnie jak zmiana, to zmienia historię. Jeśli ktoś sklonował / wyciągnął z twojego repozytorium między historią oryginalną a przepisaną, to nie będzie mógł pobrać po przepisaniu (dla tej gałęzi).
Pat Notz,

Odpowiedzi:


16123

Zmiana najnowszego komunikatu zatwierdzenia

git commit --amend

otworzy edytor, umożliwiając zmianę komunikatu zatwierdzenia ostatniego zatwierdzenia. Dodatkowo możesz ustawić komunikat zatwierdzenia bezpośrednio w wierszu poleceń za pomocą:

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

… Może to jednak sprawić, że wprowadzanie wielu wierszy lub małych poprawek stanie się trudniejsze.

Upewnij się, że nie ma żadnych zmian w pracy kopiowania wystawił przed wykonaniem tego czy będą one uzyskać popełnił zbyt. ( Nieustalone zmiany nie zostaną zatwierdzone ).

Zmiana wiadomości zatwierdzenia, którą już wypchnąłeś do swojego zdalnego oddziału

Jeśli już wypchnąłeś swoje zatwierdzenie do zdalnego oddziału, to po lokalnej zmianie zatwierdzenia (jak opisano powyżej) - będziesz musiał również wymusić wypchnięcie zatwierdzenia za pomocą:

git push <remote> <branch> --force
# Or
git push <remote> <branch> -f

Ostrzeżenie: wymuszone zastąpienie zdalnej gałęzi stanem twojego lokalnego . Jeśli istnieją commity na pilocie zdalnego oddziału, który nie ma w swoim lokalnym oddziale, to będzie tracić te rewizje.

Ostrzeżenie: zachowaj ostrożność przy wprowadzaniu zmian, które już udostępniasz innym osobom. Zmiana zatwierdza zasadniczo przepisuje je na różne identyfikatory SHA , co stanowi problem, jeśli inne osoby mają kopie starego zatwierdzenia, które przepisałeś. Każdy, kto ma kopię starego zatwierdzenia, będzie musiał zsynchronizować swoją pracę z nowo przepisanym zatwierdzeniem, co czasem może być trudne, więc upewnij się, że koordynujesz z innymi podczas próby przepisania wspólnej historii zatwierdzeń lub po prostu unikniesz przepisywania wspólnych zatwierdzeń całkowicie.


Wykonaj interaktywny rebase

Inną opcją jest użycie interaktywnego rebase. Umożliwia to edycję dowolnej wiadomości, którą chcesz zaktualizować, nawet jeśli nie jest to najnowsza wiadomość.

Aby wykonać squash Git, wykonaj następujące kroki:

// n is the number of commits up to the last commit you want to be able to edit
git rebase -i HEAD~n

Gdy zmiażdżysz swoje zobowiązania - wybierz e/rdo edycji wiadomość:

Wpisz opis zdjęcia tutaj

Ważna uwaga na temat interaktywnej bazy danych

Podczas używania git rebase -i HEAD~nmoże być więcej niż n zatwierdzeń. Git „zbierze” wszystkie zatwierdzenia z ostatnich n zatwierdzeń, a jeśli gdzieś pomiędzy tym zakresem nastąpiło scalenie, zobaczysz również wszystkie zatwierdzenia, więc wynikiem będzie n +.

Dobra wskazówka:

Jeśli musisz to zrobić dla więcej niż jednego oddziału, a podczas modyfikowania treści możesz napotkać konflikty, skonfiguruj git rererei pozwól Gitowi automatycznie rozwiązać te konflikty.


Dokumentacja


257
Jednak git commit --amendnie jest tak potężny jak git rebase -i.
Jeffrey Jose

76
@jeffjose, zdecydowanie nie musi tak być. Ponadto git commit --amendmożna naprawić (a?) Master commit.
strager

116
Jeśli już naciskałeś, po prostu ponownie naciśnij przycisk siłą:git push -f origin branchname
przytula

177
@hughes nie git push -fjest trochę niebezpieczny, jeśli inne osoby korzystają z tego samego repozytorium?
Armand,

91
Jeśli nie chcesz przepisać całej wiadomości zatwierdzenia, przejdź do git commit --amend -c HEAD. Spowoduje to otwarcie edytora wstępnie wypełnionego starym komunikatem zatwierdzenia, aby można go było zmienić.
Sam

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

7
Zrobiłem git commit --amend -m „Nowa wiadomość”, ale przekazanie do Github wygenerowało „Scal zdalne zmiany przed ponownym wysłaniem”. Po ściągnięciu, zatwierdzeniu --amend i ponownym naciśnięciu nowa wiadomość nie pojawia się. Zamiast tego mam „Merge branch 'master” z github.com:[myrepo] ”
Dave Everitt

8
@DaveEveritt najprawdopodobniej popchnąłeś swoje zatwierdzenie przed próbą naprawy.
Thorbjørn Ravn Andersen

12
@ Kyralessa nieprawda. W bash możesz łatwo komponować wiadomości zatwierdzania wieloliniowego, po prostu nie zamykając cytatu, dopóki nie skończysz (uderzając return na końcu każdej linii w cudzysłowie).
płyty grzewcze

32
Nie rozumiem, jak odpowiedź, która wygląda bardzo podobnie jak główna idea odpowiedzi, która została napisana dwa lata temu, a także zaakceptowana odpowiedź zdobywa tyle głosów. Dziwne. (nic złego z odpowiedzią)
szczęśliwy koder

7
@AmalMurali, cóż. Nie chodziło mi o popularność pytania ani użyteczność odpowiedzi. Ale ta konkretna odpowiedź nie jest najstarszą odpowiedzią, ani nie zapewnia dalszego wglądu w zaakceptowaną odpowiedź. Wygląda na kopię części zaakceptowanej odpowiedzi. To był mój cel. TWOJE ZDROWIE!
szczęśliwy programista

2376

Jeśli zatwierdzenie, które chcesz naprawić, nie jest najnowsze:

  1. git rebase --interactive $parent_of_flawed_commit

    Jeśli chcesz naprawić kilka wadliwych zatwierdzeń, przekaż element nadrzędny najstarszego z nich.

  2. Pojawi się edytor z listą wszystkich zatwierdzeń od tego, który podałeś.

    1. Zmień pickna reword(lub na starsze wersje Git, na edit) przed wszelkimi zatwierdzeniami, które chcesz naprawić.
    2. Po zapisaniu Git odtworzy wymienione zatwierdzenia.

  3. Za każdym zatwierdzeniem, które chcesz przeredagować , Git przeniesie Cię z powrotem do edytora. Dla każdego zatwierdzenia, które chcesz edytować , Git umieszcza cię w powłoce. Jeśli jesteś w powłoce:

    1. Zmień zatwierdzenie w dowolny sposób.
    2. git commit --amend
    3. git rebase --continue

Większość tej sekwencji zostanie wyjaśniona na podstawie danych wyjściowych różnych poleceń. To jest bardzo łatwe; nie musisz go zapamiętywać - pamiętaj tylko, że git rebase --interactivepozwala to korygować zatwierdzenia bez względu na to, jak dawno temu były.


Pamiętaj, że nie będziesz chciał zmieniać zatwierdzeń, które już wypchnąłeś. A może robisz to, ale w takim przypadku będziesz musiał bardzo uważnie komunikować się ze wszystkimi, którzy mogli wywiązać się z twoich zobowiązań i wykonali nad nimi pracę. Jak mogę odzyskać / ponownie zsynchronizować po tym, jak ktoś przekaże bazę lub reset do opublikowanej gałęzi?


39
Czy można zmienić komunikat pierwszego zatwierdzenia (który nie ma rodzica)?
13ren

27
Wspomniano o tym w jednej z pozostałych odpowiedzi, ale opiszę to tutaj. Od wersji 1.6.6 git możesz używać rewordzamiast pickedytować komunikat w dzienniku.
MitMaro

89
Nawiasem mówiąc, $parent_of_flawed_commitjest równoważne z $flawed_commit^.
Peeja

67
Nigdy NIGDY nie rób tego (lub generalnie dokonuj zmiany bazy), jeśli już zepchnąłeś się na górę!
Daniel Rinser

20
Użyj -p( --preserve-merges), jeśli po wadliwym zatwierdzeniu nastąpiło scalenie.
ahven

778

Aby zmienić poprzednie zatwierdzenie, wprowadź odpowiednie zmiany i wprowadź zmiany, a następnie uruchom

git commit --amend

Spowoduje to otwarcie pliku w edytorze tekstu reprezentującym nową wiadomość zatwierdzenia. Zaczyna się od tekstu ze starej wiadomości zatwierdzenia. Zmień komunikat zatwierdzenia, jak chcesz, a następnie zapisz plik i zamknij edytor, aby zakończyć.

Aby zmienić poprzednie zatwierdzenie i zachować ten sam komunikat dziennika, uruchom

git commit --amend -C HEAD

Aby naprawić poprzednie zatwierdzenie, usuwając je całkowicie, uruchom

git reset --hard HEAD^

Jeśli chcesz edytować więcej niż jedną wiadomość zatwierdzenia, uruchom

git rebase -i HEAD~commit_count

(Zastąp licznik zatwierdzeń liczbą zatwierdzeń, które chcesz edytować.) To polecenie uruchamia edytor. Oznacz pierwszy zatwierdzenie (ten, który chcesz zmienić) jako „edytuj” zamiast „wybierz”, a następnie zapisz i zamknij edytor. Wprowadź zmiany, które chcesz zatwierdzić, a następnie uruchom

git commit --amend
git rebase --continue

Uwaga: Możesz także „Dokonać żądanej zmiany” z edytora otwartego przez git commit --amend


18
git rebase -i HEAD~commit_countpozwoli również na zmianę komunikatów zatwierdzenia dowolnej wybranej liczby zatwierdzeń. Po prostu zaznacz wybrane zatwierdzenia jako „przeredaguj” zamiast „wybierz”.
Joe

2
Co jeśli nie chcesz bazować? Chcesz tylko zmienić starszą wiadomość?
SuperUberDuper 21.04.16

3
git reset --hardniszczy niezatwierdzone zmiany. Proszę wymienić --hardz --soft.
węgorz ghEEz

1
Uzgodnione, git reset --hardjest całkowicie uzasadnionym poleceniem, ale jest mylące, biorąc pod uwagę pytanie. Używasz --hard, jeśli dokonałeś zmian, które chcesz wyrzucić, a nie, jeśli popełniłeś literówkę w komunikacie zatwierdzenia!
Soren Bjornstad,

398

Jak już wspomniano, git commit --amendjest to sposób na zastąpienie ostatniego zatwierdzenia. Jedna uwaga: jeśli chcesz również zastąpić pliki , polecenie brzmi:

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

4
A jeśli nie chcesz, aby dodać wszystko, można najpierw zrobić git add file.extto po prostugit commit --amend
MalcolmOcean

358

Możesz również użyć git filter-branchdo tego.

git filter-branch -f --msg-filter "sed 's/errror/error/'" $flawed_commit..HEAD

To nie jest tak proste, jak banalne git commit --amend, ale jest szczególnie przydatne, jeśli masz już kilka scaleń po błędnym komunikacie zatwierdzenia.

Zauważ, że to spróbuje przepisać każde zatwierdzenie pomiędzy HEADi błędne zatwierdzenie, więc powinieneś msg-filterbardzo mądrze wybrać swoje polecenie ;-)


4
Czy istnieje wersja tego, która nie zmienia zatwierdzenia, jeśli wyrażenie regularne niczego nie znajdzie?
sjakubowski

3
AFAIK filter-branch - msg-filter w każdym przypadku wygeneruje nowe zatwierdzenia. Można jednak sprawdzić w filtrze msg, czy sed się powiódł, i użyć tej informacji po zakończeniu operacji filtrowania rozgałęzienia, aby zresetować drzewo do refs / original.
Mark

4
@DavidHogue Jest to prawdą tylko wtedy, gdy używasz metody filter-branch. Identyfikatory zatwierdzeń po zmodyfikowanym zatwierdzeniu nie zmieniają się, jeśli używasz interaktywnej bazy danych.
Mark

6
@ Mark Tak robią, są zobowiązani. Identyfikatory zatwierdzeń zależą od poprzednich zatwierdzeń. Gdyby się nie zmienili, git byłby bezużyteczny.
Miles Rout

2
Potrzebujesz $flawed_commit^..HEADnie $flawed_commit..HEAD. jak podano na stronie podręcznika: « Polecenie spowoduje przepisanie tylko dodatnich referencji wymienionych w wierszu poleceń (np. jeśli przejdziesz a..b, tylko b zostanie przepisane). »
Ángel

319

Wolę w ten sposób:

git commit --amend -c <commit ID>

W przeciwnym razie pojawi się nowe zatwierdzenie z nowym identyfikatorem zatwierdzenia.


7
Dla mnie użycie powyższej komendy powoduje utworzenie nowego zatwierdzenia z nowym identyfikatorem zatwierdzenia i dodatkowym zatwierdzeniem z napisem „scal gałąź” jako domyślną wiadomość zatwierdzenia.
Jan

46
Zmiana zawsze tworzy nowe zatwierdzenie z nowym identyfikatorem zatwierdzenia. Identyfikator zatwierdzenia jest skrótem SHA zawartości zatwierdzenia, w tym komunikatu zatwierdzenia i znaczników czasu autora / zatwierdzenia. Jest to cecha Git, która, wykluczając kolizje skrótów, zapewnia, że ​​dwa zatwierdzenia o tym samym identyfikatorze są dokładnie tym samym zatwierdzeniem, z dokładnie taką samą treścią, historią i tak dalej.
Emil Lundberg,

7
Zgadzam się z Emilem. Dodatkowo, czytanie dokumentacji - wygląda na to, że wszystko, co robi „-c”, mówi gitowi, którego komunikatu zatwierdzenia użyć jako domyślnego / szablonu dla nowego zatwierdzenia. Naprawdę domyślnie już zrobi to „-c <identyfikator zatwierdzenia>” , więc nie trzeba go określać.
Gal

2
-cRobi kilka rzeczy. Domyślnie korzysta ze starej wiadomości, ale kopiuje również informacje o autorze (osoba i czas). -Crobi to samo, ale nie prosi o edycję wiadomości.
Joseph K. Strauss,

1
Podobnie jak @SantanuDey, nie działało to dla mnie. Mamfatal: Option -m cannot be combined with -c/-C/-F/--fixup.
Andrew Grimm

312

Jeśli używasz narzędzia Git GUI, jest przycisk o nazwie Amend ostatnie zatwierdzenie . Kliknij ten przycisk, aby wyświetlić ostatnie pliki zatwierdzeń i wiadomości. Po prostu edytuj tę wiadomość, a możesz zatwierdzić ją za pomocą nowej wiadomości zatwierdzenia.

Lub użyj tego polecenia z konsoli / terminala:

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

4
Ta odpowiedź jest dosłownie identyczna z tą starszą . Czy sprawdziłeś istniejące odpowiedzi przed podaniem innej?
Dan Dascalescu

284

Możesz użyć Git rebasing . Na przykład, jeśli chcesz zmodyfikować z powrotem, aby zatwierdzić bbc643cd, uruchom

$ git rebase bbc643cd^ --interactive

W domyślnym edytorze zmodyfikuj „pick”, aby „edit” w wierszu, którego zatwierdzenie chcesz zmodyfikować. Wprowadź zmiany, a następnie wprowadź je za pomocą

$ git add <filepattern>

Teraz możesz użyć

$ git commit --amend

zmodyfikować zatwierdzenie, a następnie

$ git rebase --continue

aby powrócić do poprzedniego zatwierdzenia głowy.


1
Jeśli chcesz się upewnić, że zmiana z wprowadzonej zmiany git commit --amendwpłynęła, możesz jej użyć git showi wyświetli nową wiadomość.
Steve Tauber,

279
  1. Jeśli chcesz zmodyfikować tylko ostatnią wiadomość zatwierdzenia, wykonaj następujące czynności:

    git commit --amend
    

Spowoduje to umieszczenie cię w edytorze tekstu i zmianę ostatniej wiadomości zatwierdzenia.

  1. Jeśli chcesz zmienić trzy ostatnie popełnić wiadomości, czy którekolwiek z popełnić wiadomości do tego momentu, dostawa HEAD~3do git rebase -ipolecenia:

    git rebase -i HEAD~3
    

6
Ten wcześniej odpowiedź już mówi, że można użyć git commit --amend, a także mówi, że można użyć git rebase -i HEAD~commit_count, wszystko co zrobiłem było podłączyć 3do commit_count.

Również zagłosowano. Ludzie po prostu nie zawracają sobie głowy czytaniem istniejących odpowiedzi .
Dan Dascalescu

261

Jeśli musisz zmienić stary komunikat zatwierdzenia w wielu gałęziach (tj. Zatwierdzenie z błędnym komunikatem jest obecne w wielu gałęziach), możesz użyć:

git filter-branch -f --msg-filter \
'sed "s/<old message>/<new message>/g"' -- --all

Git utworzy tymczasowy katalog do przepisywania i dodatkowo archiwizuje stare odniesienia refs/original/.

  • -fwymusi wykonanie operacji. Jest to konieczne, jeśli katalog tymczasowy jest już obecny lub jeśli istnieją już odwołania w nim przechowywane refs/original. Jeśli tak nie jest, możesz upuścić tę flagę.

  • -- oddziela opcje gałęzi filtrów od opcji wersji.

  • --allupewni się, że wszystkie gałęzie i tagi są przepisane.

Ze względu na kopię zapasową starych odniesień możesz łatwo wrócić do stanu przed wykonaniem polecenia.

Powiedzmy, że chcesz odzyskać swojego mistrza i uzyskać do niego dostęp w oddziale old_master:

git checkout -b old_master refs/original/refs/heads/master

3
Ta odpowiedź nie odnosi się do pytania PO, ponieważ są oni wyłącznie zainteresowani naprawieniem zatwierdzenia, które właśnie zrobili. I regularnie korzysta git commit --amendnaprawić uwag lub dodać pliki zapomniałem git add, ale tylko kiedykolwiek wcześniej mam git pushed. Używam również, git filter-branchgdy chcę całkowicie zepsuć historię wersji, ale OP tego nie chce, więc ta odpowiedź wymaga dużego ostrzeżenia zdrowotnego - nie próbuj tego w domu, podglądacze !!
kbro

226

Posługiwać się

git commit --amend

Aby to szczegółowo zrozumieć, doskonałym postem jest 4. Przepisywanie historii Git . Mówi także o tym, kiedy nie należy używać git commit --amend .


2
Czy istnieje dobry sposób na naprawienie komunikatów zatwierdzenia wypychanych już do publicznego repozytorium? Do tej pory doszedłem do wniosku, że po popchnięciu moje literówki i myślniki z poleceniami muszą żyć wiecznie.
stackunderflow

2
Jednym słowem NOPE! Nie ma dobrego sposobu na wycofanie czegoś, co nacisnąłeś. Wszystkie wycofania są ZŁE w większym lub mniejszym stopniu. Musisz zastosować dyscyplinę pracy w oddziale we własnym prywatnym repozytorium, wykonywania wielu zatwierdzeń podczas dodawania, testowania i poprawiania. Następnie połącz całą gałąź w jeden zatwierdzenie, napisz nowy komunikat zatwierdzenia opisujący ogólną zmianę, PROOFREAD i wciśnij.
kbro

1
Wystarczy wskazać oczywiste, że nie trzeba dokonywać ani jednego zatwierdzenia podczas powrotu z gałęzi funkcji. Wiele osób robi bazowanie na gałęzi docelowej (aby wszystko wyglądało czysto), a następnie łączy się z opcją szybkiego przewijania do przodu. Jednak zgódź się na to, aby zachować ostrożność przed podniesieniem się.
ShawnFumo

1
git commit --amendOdpowiedź została już podana (kilka razy), zanim napisał swoją. Dlaczego opublikowałeś go ponownie? Jeśli chcesz dodać link do „Przepisywanie historii Gitów”, możesz edytować jedną z istniejących odpowiedzi lub zostawić komentarz.
Dan Dascalescu

199

Modyfikować

Masz tutaj kilka opcji. Możesz to zrobić

git commit --amend

pod warunkiem, że jest to twój ostatni zatwierdzenie.

Interaktywna baza danych

W przeciwnym razie, jeśli nie jest to twoje ostatnie zatwierdzenie, możesz zrobić interaktywną bazę,

git rebase -i [branched_from] [hash before commit]

Następnie w interaktywnej bazie dodajesz edycję do tego zatwierdzenia. Kiedy się pojawi, wykonaj a git commit --amendi zmodyfikuj komunikat zatwierdzenia. Jeśli chcesz wycofać zmiany przed tym punktem zatwierdzenia, możesz także użyć git reflogi po prostu usunąć ten zatwierdzenie. Potem po prostu zrób git commitponownie.


191

Jeśli jest to twoje ostatnie zatwierdzenie, po prostu popraw zatwierdzenie:

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

(Używając flagi -o( --only), aby upewnić się, że zmienisz tylko komunikat zatwierdzenia)


Jeśli jest to ukryte zatwierdzenie, skorzystaj z niesamowitej interaktywnej bazy :

git rebase -i @~9   # Show the last 9 commits in a text editor

Znajdź żądane zatwierdzenie, zmień pickna r( reword) oraz zapisz i zamknij plik. Gotowy!



Samouczek miniaturowego Vima (lub, jak wykonać bazowanie za pomocą tylko 8 naciśnięć klawiszy 3jcwrEscZZ):

  • Uruchom, vimtutorjeśli masz czas
  • hjkl odpowiadają klawiszom ruchu
  • Wszystkie polecenia mogą być poprzedzone „zakresem”, np. 3jPrzesuwa się o trzy linie w dół
  • i wejść w tryb wstawiania - wpisany tekst pojawi się w pliku
  • Esclub Ctrlcwyjść z trybu wstawiania i powrócić do trybu „normalnego”
  • u cofnąć
  • Ctrlr zrobić ponownie
  • dd, dw, dlAby usunąć linię, słowo lub list, odpowiednio
  • cc, cw, clAby zmienić linię, słowo lub list, odpowiednio (jak ddi)
  • yy, yw, ylAby skopiować ( „yank”) linię, słowo lub list, odpowiednio
  • plub Pwkleić odpowiednio po bieżącej pozycji lub przed nią
  • :wEnter zapisać (zapisać) plik
  • :q!Enter wyjść bez zapisywania
  • :wqEnterlub ZZzapisać i wyjść

Jeśli często edytujesz tekst, przełącz się na układ klawiatury Dvorak , naucz się pisać na klawiaturze i naucz się Vima. Czy warto? Tak.



ProTip ™: Nie bój się eksperymentować z „niebezpiecznymi” poleceniami, które przepisują historię * - Git domyślnie nie usuwa twoich zobowiązań przez 90 dni; możesz je znaleźć w reflog:

$ git reset @~3   # Go back three commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started

* Uważaj na opcje takie jak --hardi --forcechociaż - mogą odrzucać dane. * Nie zapisuj także historii oddziałów, z którymi współpracujesz.


3
Część vim jest całkowicie nie na temat i zamiast zachęcać użytkowników do spędzania czasu na nauce korzystania z tajemnego edytora, dlaczego nie nauczyć ich czegoś bardziej na temat, na przykład jak skonfigurować domyślny edytor git, aby był przyjazny dla użytkownika, na przykład nano? Mówimy o trywialnych modyfikacjach, które należy wprowadzić w pliku tekstowym, a nie o hardcorowym kodowaniu, które wywołałoby wojnę o „najlepszy” edytor tekstu.
Dan Dascalescu

1
@DanDascalescu: Ponieważ szybciej jest nauczyć się Vima, postępując zgodnie z powyższymi instrukcjami, niż wykonać kilka zmian za pomocą nano. Głównym powodem, dla którego git otwiera edytor tekstu, a nie własny interfejs do zmiany bazy, jest to, że Vim istnieje: jest lekki, instalowany domyślnie w większości systemów i bardzo łatwy do nauczenia się na tyle, aby wykonać z łatwością bazę: np. ddjjpZZPrzesuwa 2 zatwierdzenie w dół. W podstawowej wiedzy Vima nie ma nic tajemniczego; potrzeba 10 minut, aby poczuć się bardziej komfortowo z Vimem niż z nano.
Zaz

185

Jeśli używasz Git GUI, możesz zmienić ostatnie zatwierdzenie, które nie zostało wypchnięte za pomocą:

Commit/Amend Last Commit

168

Używam GUI Git tak często, jak to możliwe, a to daje ci możliwość zmiany ostatniego zatwierdzenia:

Zaznacz to pole

Ponadto, git rebase -i origin/masterjest to ładna mantra, która zawsze przedstawi ci zobowiązania, które wykonałeś na szczycie mistrza, i da ci możliwość zmiany, usunięcia, zmiany kolejności lub zgniecenia. Najpierw nie musisz zdobywać tego skrótu.


4
Jak przejść do tego ekranu, który pokazałeś w swoim przykładzie?
Marwan مروان

2
To dolna prawa część Windows Git Gui. Wystarczy wybrać przełącznik „Zmień ostatnie zatwierdzenie”, a zapełni się najnowszymi informacjami o zatwierdzeniu.
wbdarby

138

Wow, więc jest na to wiele sposobów.

Jeszcze innym sposobem na to jest usunięcie ostatniego zatwierdzenia, ale zachowaj jego zmiany, abyś nie stracił pracy. Następnie możesz wykonać kolejne zatwierdzenie z poprawioną wiadomością. To mogłoby wyglądać mniej więcej tak:

git reset --soft HEAD~1
git commit -m 'New and corrected commit message'

Zawsze tak robię, jeśli zapomnę dodać plik lub dokonać zmiany.

Pamiętaj, aby podać --softzamiast--hard , inaczej stracisz to zatwierdzenie całkowicie.


5
Robi to dokładnie to samo, git commit --amendz wyjątkiem tego, że jest to proces dwuetapowy.
Joseph K. Strauss,

3
@ JosephK.Strauss Wydaje mi się, że poprawianie zatwierdzenia zachowuje również oryginalne informacje o autorze i dacie zatwierdzenia, mając osobne informacje o nowym commiter i dacie. Nie jestem pewien, czy takie podejście to robi.
everton

4
@EvertonAgner Masz rację. --amendzachowa informacje o autorze, ale pytanie dotyczy jedynie zmiany wiadomości.
Joseph K. Strauss,

131

Wszystkim, którzy szukają GUI dla Windows / Mac, aby pomóc w edycji starszych wiadomości (tj. Nie tylko najnowszych), polecam Sourcetree . Kroki, które należy wykonać, są poniżej.

Interaktywna baza Sourcetree

W przypadku zatwierdzeń, które nie zostały jeszcze przekazane do pilota:

  1. Upewnij się, że dokonałeś lub przechowałeś wszystkie bieżące zmiany (tzn. Nie ma żadnych plików na karcie „Status pliku”) - inaczej nie zadziała.
  2. W zakładce „Log / History” kliknij prawym przyciskiem myszy wpis z przylegającą linią na wykresie pod zatwierdzeniem (zatwierdzeniami), które chcesz edytować, i wybierz „Rebase child of <zatwierdz ref> interaktywnie ...”
  3. Wybierz cały wiersz dla wiadomości zatwierdzenia, którą chcesz zmienić (kliknij kolumnę „Wiadomość”) .
  4. Kliknij przycisk „Edytuj wiadomość”.
  5. Edytuj wiadomość zgodnie z potrzebami w wyświetlonym oknie dialogowym, a następnie kliknij OK .
  6. Powtórz kroki 3-4, jeśli istnieją inne komunikaty zatwierdzenia do zmiany.
  7. Kliknij OK: Rebasing rozpocznie się. Jeśli wszystko jest w porządku, wyjście zakończy się „Zakończono pomyślnie”. UWAGA: Czasem widziałem ten błąd, Unable to create 'project_path/.git/index.lock': File exists.gdy próbowałem modyfikować wiele komunikatów zatwierdzania jednocześnie. Nie jestem pewien, na czym dokładnie polega problem, ani czy zostanie to naprawione w przyszłej wersji Sourcetree, ale jeśli tak się stanie, zaleca się ponowne ich rozwiązywanie (wolniej, ale wydaje się bardziej niezawodne).

... Lub ... dla zatwierdzeń, które zostały już wypchnięte:

Postępuj zgodnie z krokami w tej odpowiedzi , które są podobne do powyższych, ale wymagają uruchomienia kolejnego polecenia z wiersza poleceń ( git push origin <branch> -f) w celu wymuszenia przesunięcia gałęzi. Polecam przeczytać wszystko i zachować niezbędną ostrożność!


spośród wszystkich odpowiedzi - jest to najbardziej odpowiednie dla wszystkich początkujących gitów ^^^ (użyj darmowego programu SourceTree i zastosuj polecenie „Rebase children of” przy zatwierdzeniu przed tym, który chcesz edytować)
odrzekł

127

Jeśli chcesz po prostu edytować najnowsze zatwierdzenie, użyj:

git commit --amend

lub

git commit --amend -m 'one line message'

Ale jeśli chcesz edytować kilka zatwierdzeń z rzędu, powinieneś zamiast tego użyć zmiany zasad:

git rebase -i <hash of one commit before the wrong commit>

Edycja bazy Git

W pliku, takim jak powyższy, napisz edit/e lub jedną z pozostałych opcji, a następnie naciśnij Zapisz i wyjdź.

Teraz będziesz przy pierwszym błędnym zatwierdzeniu. Wprowadź zmiany w plikach, a zostaną one automatycznie ustawione dla Ciebie. Rodzaj

git commit --amend

Zapisz i zamknij to i wpisz

git rebase --continue

aby przejść do następnej selekcji, aż do zakończenia wszystkich wybranych opcji.

Zauważ, że te rzeczy zmieniają wszystkie twoje skróty SHA po tym konkretnym zatwierdzeniu.


2
git rebase -i <skrót jednego zatwierdzenia przed złym zatwierdzeniem> działa dla mnie. dzięki.
Viraths,

127

Jeśli chcesz zmienić tylko ostatnią wiadomość, powinieneś użyć --onlyflagi lub jej skrótu za -opomocącommit --amend :

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

Zapewnia to, że przypadkowo nie poprawisz zatwierdzenia za pomocą inscenizacji. Oczywiście najlepiej mieć odpowiednią $EDITORkonfigurację. Następnie możesz pominąć tę -mopcję, a Git wstępnie wypełni komunikat zatwierdzenia starym. W ten sposób można go łatwo edytować.


1
„Górna” odpowiedź nie odpowiada na pytanie. To tylko ogólne wprowadzenie do git commit --amend. Pytanie było bardzo szczegółowe, dlatego dłuższe! = Lepsze. Decydujące wzmiankowanie -oflagi prawdopodobnie zostanie zakopane w pozostałej części informacji. Nie lubię też redagować odpowiedzi, która ma już tyle głosów.
David Ongaro,

2
Biorąc to pod uwagę, możesz swobodnie edytować najlepszą odpowiedź, ponieważ istnieje realne niebezpieczeństwo, że ludzie używają jej jako „poprawnej” odpowiedzi. Z łatwością może się zdarzyć, że zmienisz swoje zatwierdzenie za pomocą inscenizacji - przydarzyło mi się to i jest to naprawdę denerwujące, kiedy to naciskasz. Ale nadal ilość nie jest gwarancją poprawności. Ani pod względem liczby odpowiedzi, ani liczby głosów.
David Ongaro,

1
Nie posunąłbym się tak daleko, by powiedzieć, że górna odpowiedź jest „niepoprawna” i że „nie odpowiada na pytanie”. To na pewno działa i odpowiada na pytanie, musisz tylko upewnić się, że nie wprowadziłeś zmian etapowych podczas próby zmiany. Ale rozumiem, że masz na myśli ostrzeganie ludzi przed tym. Zmienię to później, jeśli będę miał czas.

1
Szczerze mówiąc : chociaż --onlyopcja z --amendjest dostępna od wersji 1.3.0 git, nie działała poprawnie, dopóki nie została naprawiona w wersji 1.7.11.3 ( ea2d4ed35902ce15959965ab86d80527731a177c ). Więc prawidłowa odpowiedź z powrotem w 2008 roku prawdopodobnie byłby coś takiego: git stash; git commit --amend; git stash pop.
David Ongaro

103

Zaktualizuj swój ostatni zły komunikat zatwierdzenia o nowy komunikat zatwierdzenia w jednym wierszu:

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

Lub spróbuj zresetować Git jak poniżej:

# You can reset your head to n number of commit
# NOT a good idea for changing last commit message,
# but you can get an idea to split commit into multiple commits
git reset --soft HEAD^

# It will reset you last commit. Now, you
# can re-commit it with new commit message.

Używanie resetowania do dzielenia zatwierdzeń na mniejsze zatwierdzenia

git reset może pomóc ci również rozbić jeden zatwierdzenie na wiele zatwierdzeń:

# Reset your head. I am resetting to last commits:
git reset --soft HEAD^
# (You can reset multiple commit by doing HEAD~2(no. of commits)

# Now, reset your head for splitting it to multiple commits
git reset HEAD

# Add and commit your files separately to make multiple commits: e.g
git add app/
git commit -m "add all files in app directory"

git add config/
git commit -m "add all files in config directory"

Tutaj pomyślnie podzieliłeś swój ostatni zatwierdzenie na dwa zatwierdzenia.


3
Jeśli wszystko, co chcesz zrobić, to edytować wiadomość o ostatnim zatwierdzeniu, użycie miękkiego resetu w tym celu jest nadmiernym zabijaniem . Po prostu użyj git commit --amend, dokładnie tak, jak napisano w najczęściej głosowanej odpowiedzi . Dodatkowo git reset --soft HEAD^działa identycznie jak miękki reset w tej wcześniejszej odpowiedzi , ponieważ oba resetują z powrotem do pierwszego zatwierdzenia nadrzędnego.

3
Jedyne, co chcę, to dodać git resetdo rozwiązania, aby dać pomysł na podzielenie jednego komunikatu zatwierdzenia na wiele komunikatów zatwierdzenia. Ponieważ napotkałem ten problem, kiedy zaczynałem używać git. Czasami może to być naprawdę pomocne. :)
przbadu

87

Na to pytanie jest wiele odpowiedzi, ale żadna z nich nie wyjaśnia bardzo szczegółowo, jak zmieniać starsze komunikaty zatwierdzania za pomocą Vima . Utknąłem, próbując to zrobić sam, więc tutaj opiszę szczegółowo, jak to zrobiłem, szczególnie dla osób, które nie mają doświadczenia w Vimie!

Chciałem zmienić pięć ostatnich zatwierdzeń, które już wypchnąłem na serwer. Jest to dość „niebezpieczne”, ponieważ jeśli ktoś już z tego wyciągnął, możesz zepsuć wszystko, zmieniając komunikaty zatwierdzania. Jednak gdy pracujesz nad własną małą gałęzią i jesteś pewien, że nikt jej nie pociągnął, możesz to zmienić w następujący sposób:

Powiedzmy, że chcesz zmienić pięć ostatnich zatwierdzeń, a następnie wpisz to w terminalu:

git rebase -i HEAD~5

* Gdzie 5 to liczba komunikatów zatwierdzenia, które chcesz zmienić (więc jeśli chcesz zmienić od 10 do ostatniego zatwierdzenia, wpisz 10).

To polecenie przeniesie Cię do Vima, gdzie możesz „edytować” swoją historię zatwierdzeń. Na górze zobaczysz pięć ostatnich zmian:

pick <commit hash> commit message

Zamiast tego pickmusisz pisać reword. Możesz to zrobić w Vimie, wpisując i. To powoduje przejście do trybu wstawiania . (Widzisz, że jesteś w trybie wstawiania po słowie WSTAW na dole.) Aby zatwierdzić zmiany, które chcesz zmienić, wpisz rewordzamiastpick .

Następnie musisz zapisać i zamknąć ten ekran. Robisz to, przechodząc najpierw do „trybu poleceń”, naciskając Escprzycisk (możesz sprawdzić, czy jesteś w trybie poleceń, jeśli zniknęło słowo WSTAW na dole). Następnie możesz wpisać polecenie, wpisując :. Poleceniem zapisywania i wychodzenia jest wq. Więc jeśli wpiszesz :wq, jesteś na dobrej drodze.

Następnie Vim przejrzy każdą zatwierdzoną wiadomość, którą chcesz przeredagować, i tutaj możesz faktycznie zmienić komunikaty zatwierdzenia. Zrobisz to, przechodząc do trybu wstawiania, zmieniając komunikat zatwierdzenia, przechodząc do trybu poleceń oraz zapisując i kończąc. Zrób to pięć razy, a skończysz z Vimem!

Następnie, jeśli już wypchnąłeś swoje niepoprawne zatwierdzenia, musisz git push --forceje zastąpić. Pamiętaj, że git push --forcejest to dość niebezpieczna rzecz, więc upewnij się, że nikt nie wyciągnął z serwera, ponieważ popchnąłeś swoje błędne zobowiązania!

Teraz zmieniłeś swoje komunikaty zatwierdzania!

(Jak widzisz, nie jestem zbyt doświadczony w Vimie, więc jeśli użyłem niewłaściwego „żargonu”, aby wyjaśnić, co się dzieje, możesz mnie poprawić!)


4
<nitpick>Na przepełnieniu stosu nie ma „wątków”, ponieważ nie jest to forum dyskusyjne, są tylko „pytania”, „odpowiedzi” i „posty”. </nitpick>. Ponadto, nie wszystkie wersje Vima są takie same, nie wszystkie pozwalają usuwać znaki w trybie wstawiania (ma to sens, prawda?). Jeśli chcesz zawsze móc usuwać znaki w Vimie Xi xtak zrobisz (małe xznaki przed kursorem, Xzostaną usunięte za). Jeśli popełnisz błąd, możesz go uwielokrotnie użyć do cofnięcia. Wreszcie rjest skrótem rewordod interaktywnego edytora bazy danych.

1
Aby zmienić słowo w vimie, cwwpisuje się na jego początku (choć pytanie nie dotyczy vima, zgadzam się).
Yaroslav Nikitenko,

Nie musisz używać tej obrzydliwości . Możesz ustawić swój edytor git na coś rozsądnego i przyjaznego dla użytkownika, takiego jak nanommedit Midnight Commander.
Dan Dascalescu

79

Możesz użyć git-rebase-reword

Jest przeznaczony do edycji każdego zatwierdzenia (nie tylko ostatniego) w taki sam sposób jak commit --amend

$ git rebase-reword <commit-or-refname>

Jego nazwa pochodzi od akcji interaktywnej rebase w celu zmiany zatwierdzenia: „reword”. Zobacz ten post i man -section interaktywny tryb-

Przykłady:

$ git rebase-reword b68f560
$ git rebase-reword HEAD^

6
Wymaga to zainstalowania programu zewnętrznego. Moim zdaniem lepiej nauczyć się efektywniej korzystać z wbudowanych narzędzi i aliasów. g c; g rb -i @~9Wpisałbym : (zatwierdzenie i zmiana bazy), przeniesienie nowego zatwierdzenia tam, gdzie chcę, zmień commitna f( fixup) i zapisz. Jeśli chcesz czegoś szybciej, możesz mieć alias git commit --fixup=<commit>; git rebase -i --autosquash <commit>^
Zaz

79

Dodałem aliasy recii recmdo recommit (amend)tego. Teraz mogę to zrobić za pomocą git recmlub git recm -m:

$ vim ~/.gitconfig

[alias]

    ......
    cm = commit
    reci = commit --amend
    recm = commit --amend
    ......

57

Uświadomiłem sobie, że wcisnąłem commit z literówką. Aby cofnąć, wykonałem następujące czynności:

git commit --amend -m "T-1000, advanced prototype"
git push --force

Ostrzeżenie: wymuszenie wprowadzenia zmian spowoduje zastąpienie gałęzi zdalnej gałęzią lokalną. Upewnij się, że nie zastąpisz niczego, co chcesz zachować. Zachowaj także ostrożność, aby wymusić naepchnięcie poprawionego (przepisanego) zatwierdzenia, jeśli ktokolwiek inny udostępnia Ci gałąź, ponieważ będzie musiał przepisać własną historię, jeśli ma starą kopię zatwierdzenia, którą właśnie przepisałeś.


7
Nic nie zostaje „nadpisane” w git. W takim przypadku wskaźnik gałęzi zostanie ustawiony na nowe zatwierdzenie, a stare zatwierdzenie stanie się nieaktualne, jeśli nie pozostaną do niego żadne odniesienia, i może zostać wyczyszczone po kilku tygodniach. (Do tego czasu inni wciąż mogą go znaleźć i odnieść się do niego, np. Zaglądając do dziennika).
David Ongaro,

51

Lubię używać następujących:

  1. git status
  2. git add --all
  3. git commit -am "message goes here about the change"
  4. git pull <origin master>
  5. git push <origin master>

46

Jeśli nie przekazałeś kodu do zdalnej gałęzi ( GitHub / Bitbucket ), możesz zmienić komunikat zatwierdzenia w wierszu poleceń, jak poniżej.

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

Jeśli pracujesz nad konkretnym oddziałem, zrób to:

git commit --amend -m "BRANCH-NAME: new message"

Jeśli już wypchnąłeś kod z niewłaściwą wiadomością, i musisz zachować ostrożność przy zmianie wiadomości. Oznacza to, że po zmianie komunikatu zatwierdzenia i ponownym wypchnięciu go, masz problemy. Aby wygładzić, wykonaj następujące kroki.

Przeczytaj całą moją odpowiedź, zanim to zrobisz.

git commit --amend -m "BRANCH-NAME : your new message"

git push -f origin BRANCH-NAME                # Not a best practice. Read below why?

Ważna uwaga: użycie bezpośredniego wymuszania może spowodować problemy z kodem, które inni programiści pracują nad tym samym oddziałem. Aby uniknąć tych konfliktów, musisz wyciągnąć kod z gałęzi, zanim wymusisz wypchnięcie :

 git commit --amend -m "BRANCH-NAME : your new message"
 git pull origin BRANCH-NAME
 git push -f origin BRANCH-NAME

Jest to najlepsza praktyka przy zmianie komunikatu zatwierdzenia, jeśli został już wypchnięty.

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.