Dodaj zmianę do poprzedniego zatwierdzenia za pomocą Magit

43

Mam 2 zatwierdzenia, A, a następnie B, gotowe do wypchnięcia. Zdaję sobie sprawę, że zapomniałem dodać coś w A.

Jak mogę dodać tę zmianę do A za pomocą Magit? Nie wiem nawet, na którą część dokumentacji Git powinienem spojrzeć.

Mathieu Marques
źródło

Odpowiedzi:

68

Udawajmy przez chwilę, że chcesz dodać coś do HEADzatwierdzenia, tj. „Drugi zatwierdzenie B” w twoim przykładzie.

Wyskakujące okienko zatwierdzenia czawiera wiążące „ aPopraw”. Naciśnięcie tego klawisza spowoduje „zmianę” wprowadzonych zmian do HEADzatwierdzenia. Ponieważ zatwierdzeń nie można modyfikować w Git, zastąpi to stare zatwierdzenie nowym zatwierdzeniem. Pojawi się bufor ze starym komunikatem zatwierdzenia, abyś mógł go zmodyfikować, na wypadek gdyby dodana zmiana wymagała również dostosowania komunikatu. Jak zawsze naciśnij C-c C-cpo zakończeniu edycji wiadomości. Jest to równoważne z uruchomieniem git commit --amendw wierszu polecenia.

  • a Popraw - dodaj zmiany etapowe HEADi edytuj komunikat zatwierdzenia

Ponieważ często zdarza się, że wystarczy tylko zmienić zmianę lub komunikat, Magit oferuje dwa dodatkowe warianty:

  • e Rozszerz - dodaj zmiany etapowe HEADbez edytowania komunikatu zatwierdzenia
  • w Reword - zmień wiadomość HEADbez dodawania do niej etapowych zmian

Jeśli chcesz edytować zatwierdzenie, które nie jest HEAD, to powyższe nie będzie działać. Te polecenia zawsze „modyfikują” (tj. Zastępują) HEADzatwierdzenie. Git nie udostępnia ani jednego polecenia do modyfikowania zatwierdzenia, HEADale jest to nieco bardziej zaangażowane.

Magit jest zapewnienie takiego polecenia, ale dlatego, że istnieją sytuacje, w których korzystne jest, aby zrobić to w kilku krokach, będziemy dyskutować, że w pierwszej kolejności.

Modyfikowanie zatwierdzenia inne niż HEADmoże być podzielone na trzy kroki:

  1. Tymczasowo ustaw, aby inny commit ( A) był HEAD.
  2. Zmodyfikuj HEAD(jak opisano powyżej), co powoduje zatwierdzenie A'.
  3. Powiedz Gitowi, aby ponownie zastosował zatwierdzenia, które nastąpiły A, ale na dodatek A'.

Można to zrobić za pomocą interaktywnego bazy danych. Wpisz, raby wyświetlić wyskakujące okienko. Następnie wpisz, maby wywołać wariant bazy „edytuj zatwierdzenie”. Pojawi się bufor z ostatnimi zatwierdzeniami. Przejdź do zatwierdzenia, które chcesz zmodyfikować, i wpisz, C-c C-caby je wybrać. Następnie Git przewija historię do tego zatwierdzenia i wyświetla informacje o bieżącym bazowaniu w buforze stanu.

Zmodyfikuj HEADjak opisano powyżej. Następnie powiedz Gitowi, że skończyłeś, pisząc r r. Jeśli A'i Bkonflikt, rebase zatrzyma się na Bi musisz rozwiązać konflikt. Po zakończeniu naciśnij przycisk, r raby kontynuować.

Jeśli wiesz, że wprowadzone zmiany Aspowodują konflikty B, postępuj zgodnie z powyższym opisem, w przeciwnym razie zastosuj następujące podejście.


Git umożliwia tworzenie „zatwierdzeń napraw” za pomocą git commit --fixup A. Spowoduje to utworzenie nowego zatwierdzenia, które rejestruje zmiany, które „powinny były zostać wprowadzone w innym zatwierdzeniu”. To zatwierdzenie staje się nowe HEAD. Istnieje również --squashwariant. Informacje o różnicach znajdują się na git-commitstronie man.

Aby faktycznie połączyć Azatwierdzenie i nowe zatwierdzenie, A'a następnie ponownie Bzastosować, musisz użyć bazy. Magit zapewnia wygodne do tego polecenie r f.

Główna różnica w stosunku do powyższego podejścia polega na tym, że najpierw tworzymy nowy zatwierdzenie, a następnie dokonujemy zmiany podstawy, aby połączyć to z „celem” i zastosować ponownie B. Powyżej zaczęliśmy od bazowania zamiast angażowania się.

W Magit zarówno warianty, jak --fixupi --squashwarianty są dostępne z wyskakującego okienka zatwierdzenia, na fi s. Ale Magit zapewnia również „natychmiastowe” warianty komend naprawczych i squashowych na Fi S. Te warianty tworzą nowe zatwierdzenie, takie jak warianty „nie-natychmiastowe”, ale następnie natychmiast łączą zatwierdzenie naprawy z zatwierdzeniem docelowym za pomocą rebase, bez konieczności wywoływania innego polecenia.

„Natychmiastowa naprawa” ( c F) jest zasadniczo tym samym, co „przedłużyć HEAD” ( c e), z tym wyjątkiem, że działa dla każdego zatwierdzenia, nie tylko HEAD.


Dalsza lektura:

Tarsjusz
źródło
Krystalicznie czyste! Dziękuję, świetny pakiet BTW.
Mathieu Marques
1
Cóż, myślę, że w drugiej połowie mojej odpowiedzi jest kilka papkowatych części. Ale żeby ich uniknąć musiałbym podwoić długość tej i tak już długiej odpowiedzi, więc cieszę się, że to dla ciebie działa ;-)
tarsius
Dzięki za tę odpowiedź, Tarsius, to naprawdę działa dla mnie.
anquegi
Jasność pierwszej części tego wyjaśnienia sprawia, że ​​czytanie drugiej połowy, które jest o wiele trudniejsze do naśladowania, jest dość frustrujące!
Lyn Headley,
git-commitstrona man przekierowuje do git-rebase(1)tych wierszy: Sugerowany komunikat zatwierdzenia dla złożonego zatwierdzenia jest konkatenacją komunikatów zatwierdzenia pierwszego zatwierdzenia i tych z poleceniem „squash”, ale pomija komunikaty zatwierdzania zatwierdzeń przy „poprawce” dowództwo. IOW, użyj fixup, jeśli chcesz tylko naprawić kod w poprzednim zatwierdzeniu, użyj squash, jeśli chcesz również naprawić komunikat zatwierdzenia.
Yasushi Shoji
3

git commit --amend –C HEADto polecenie Git, którego chcesz szukać, i możesz to naprawić w Magit C-c C-a.

Ryan
źródło
Korzystam z Magit najpóźniej, C-c C-apochodzi ze starszej wersji (tak myślę). Ponadto nie widzę śladu „zmiany” w buforze pomocy ( ?).
Mathieu Marques
Zobacz odpowiedź Remi dla odpowiednika magit 2.x.
npostavs
3

Tak więc jeden przepływ pracy to:

  • dokonaj zmiany
  • c (zatwierdzenie) f (naprawa - wybierz zatwierdzenie naprawy)

Następnie

  • r (rebase) -a (autosquash, może być ustawiony domyślnie) i (interaktywny)

Autosquash automatycznie przeniesie wszystkie zatwierdzenia! Fixup we właściwe miejsce i ustawi je tak, aby były zgniecione na bazie.

stsquad
źródło
Jedyne, co zrobiłem, czego nie powiedziałeś, to stanąć między pierwszą kulą a drugą. Uderzenie idaje mi Cannot rebase: Your index contains uncommitted changes. Please commit or stash them.. Tyle że nie mam żadnych niezaangażowanych zmian. : /
Mathieu Marques
Spróbował ponownie po wyciągnięciu, Proceed despite merge in rebase range? [c]ontinue, [s]elect other, [a]bort. Czy to próbuje mi powiedzieć, że moje poprawki mogą narazić na zbliżające się połączenie?
Mathieu Marques
@MathieuMarques: „Tyle że nie mam żadnych niezaangażowanych zmian” - git uważa, że ​​tak. Zauważ, że komunikat sugeruje zmiany etapowe, a nie zmiany etapowe. Re: merge in rebasepatrz BŁĘDY pod git help rebase. Sugeruję wykonanie naprawy przed ściągnięciem w górę.
npostavs
1

Dla poprawienia ostatniego zatwierdzenia jest to „c a”. Poprawka służy do naprawy niektórych starszych zmian.

Rémi
źródło
W takim przypadku popełniłem A, a następnie B. Zaktualizowałem post dla przejrzystości.
Mathieu Marques