Git: Błąd „Nie można„ zmiażdżyć ”bez poprzedniego zatwierdzenia” podczas rebase

102

W tekście zadań do wykonania mam następujące informacje git rebase -i HEAD~2:

pick 56bcce7 Closes #2774
pick e43ceba Lint.py: Replace deprecated link

# Rebase 684f917..e43ceba onto 684f917 (2 command(s))
#
...

Teraz, gdy próbuję zgnieść pierwszą ( 56bcce7) i wybrać drugą, dodając „s” przed pierwszą, pojawia się następujący błąd:

Cannot 'squash' without a previous commit

Czy ktoś może mi wyjaśnić, co to znaczy i jak mam to zrobić?

Chcę zmiażdżyć pierwsze zatwierdzenie ( 56bcce7) i „wybrać i przeredagować” drugie ( e43ceba) zatwierdzenie

Dawny33
źródło
1
Zmień HEAD ~ 2 na HEAD ~ 3, jeśli naprawdę chcesz zgnieść.
ElpieKay
1
I prawdopodobnie użyj --root, jeśli HEAD ~ 2 jest twoim pierwszym zatwierdzeniem: stackoverflow.com/a/598788/2444812
Sybille Peters

Odpowiedzi:

88

Interaktywna rebase przedstawia zatwierdzenia w odwrotnej kolejności niż ta, do której jesteś przyzwyczajony podczas używania git log. git rebase -iodtwarza wybrane zatwierdzenia w dokładnej (od góry do dołu) kolejności, w jakiej są wymienione w zapisanym pliku instrukcji rebase. Podczas zgniatania zatwierdzenie wybrane do zgniatania jest łączone z zatwierdzeniem, które go poprzedza na (edytowanej) liście, tj. Zatwierdzeniem z poprzedniego wiersza. W twoim przypadku - nie ma wcześniejszego zatwierdzenia dla 56bcce7. Musisz wykonać jedną z następujących czynności

  • git rebase -i HEAD~3(jeśli chcesz, aby zgnieść 56bcce7w 684f917)
  • Jeśli masz zamiar łączyć się 56bcce7z nimi e43cebai e43cebanie są od nich zależne 56bcce7, po prostu zmień ich kolejność:

    r e43ceba Lint.py: Replace deprecated link
    s 56bcce7 Closes #2774
    

    AKTUALIZACJA : Odpowiedź Gusa poniżej sugeruje lepszy sposób zrobienia tego samego, bez zmiany kolejności dwóch zatwierdzeń:

    r 56bcce7 Closes #2774
    s e43ceba Lint.py: Replace deprecated link
    

    Spowoduje to zgniecenie / połączenie dwóch zatwierdzeń w jedno. Gdy interaktywna rebase poprosi o przeformułowany komunikat o zatwierdzeniu dla 56bcce7, podaj komunikat o zatwierdzeniu, który opisuje unię 56bcce7i e43ceba.

Leon
źródło
1
Chcę zgnieść 56bcce7 w e43ceba. Jak więc wykonać tutaj krok 1?
Dawny33
86

Miałem podobny problem, który rozwiązałem w następujący sposób:

Oto grupa commitów, którą chciałem zgnieść:

1 s 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 pick 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Jak widać, nie chciałem. 4, ale 1, 2 i 3 nie miały wcześniejszego zobowiązania do zgniatania . Stąd nie można „zmiażdżyć” bez poprzedniego błędu zatwierdzenia .

Moim rozwiązaniem było skorzystanie z ropcji for# r, reword = use commit, but edit the commit message

Więc moja lista commits wyglądała tak:

1 r 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 s 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

Po zapisaniu interaktywna powłoka poprosiła mnie o przeformułowanie wybranego zatwierdzenia.

Po tym mój dziennik zatwierdzeń spowodował pojedyncze zatwierdzenie, co spowodowało czystszą historię zmian.

Gus
źródło
2
tak jak ja, jeśli masz błąd, ponieważ nie wybrałeś żadnego zatwierdzenia, aby przeformułować lub wybrać i uzyskać wspomniany błąd (na pytanie), będziesz musiał zrobić git rebase --edit-todoi naprawić odsyłanie do tej odpowiedzi, a następnie zrobićgit rebase --continue
stary-mnich
Ta odpowiedź była zwięzła i rzeczowa, naprawdę pomogła, dzięki
gonzofish
20

Miałem ten problem i powodem, dla którego tak się stało w moim przypadku, było to, że nie możesz zmiażdżyć starszych zatwierdzeń do nowego zatwierdzenia. Oto przykład, z którego wynika, że ​​masz 3 zatwierdzenia:

1 pick 01mn9h78 The lastest commit
2 pick a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

Teraz, jeśli powiesz git rebase -i HEAD~3i zrobisz coś takiego

1 pick 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 s 093479uf An old commit i made a while back

Spowoduje to błąd:

błąd: nie można „zmiażdżyć” bez poprzedniego zatwierdzenia Możesz to naprawić za pomocą polecenia „git rebase --edit-todo”, a następnie uruchomić „git rebase --continue”. Lub możesz przerwać rebase za pomocą polecenia „git rebase --abort”.

Rozwiązanie :

Podczas zgniatania zatwierdzeń powinieneś zgniatać ostatnie zatwierdzenia do starych, a nie odwrotnie, więc w przykładzie będzie to mniej więcej tak:

1 s 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

To zadziała dobrze, o ile chcesz wszystkie swoje komunikaty o zmianach, sugerowałbym naprawę zamiast squasha .

DvixExtract
źródło
5
Dziękuję - nie zgniatam często zatwierdzeń, a rada, aby wybrać najstarszy commit, pomogła mi ominąć nieprzydatny błąd gita.
0x574F4F54
4

Squash z logiką odwrotną . W późniejszym kroku będziesz mógł wybrać żądany komunikat dotyczący zmiany.

  • pickpierwszy zatwierdzenie , dla którego nie chcesz, aby komunikat o zatwierdzeniu.
  • squashlub fixupzmiany, które chcesz scalić, aż do tego, który zawiera komunikat o zmianach, którego faktycznie chciałeś.
pick 56bcce7 Closes #2774
squash e43ceba Lint.py: Replace deprecated link
  • potwierdź zmianę ( :x)
  • usuń wiadomości ze zmian, których nie chcesz i zostaw tylko wiadomość z zatwierdzenia, którego chcesz (w tym przypadku Lint.py: Replace deprecated link:).
  • potwierdź wybór ( :x)

Mam nadzieję, że to dla kogoś jaśniejsze ✌🏽

Kamafeather
źródło
2

Najlepiej będzie po prostu powiedzieć w interaktywnym edytorze zawierającym zatwierdzenia, git zawsze zgniata się od dołu do góry i należy zostawić wpis „wybierz” u góry, aby otrzymać squashy od dołu.

ekyu88
źródło
2

Właśnie wypróbowałem to podejście.

git log -n3

To pokaże ostatnie 3 commity, które dadzą mi wyobrażenie o tym, co jest ostatnim zatwierdzeniem, a które zostało wykonane wcześniej. Teraz stwierdzone zmiany bazy,

git rebase -i HEAD ~ 3

Wybierz ostatnie zatwierdzenie, na szczycie którego musimy zmiażdżyć pozostałe dwa. Identyfikator zatwierdzenia, który jest wybrany jako zatwierdzenie podstawowe, wyglądałby następująco:

wybierz commit_id

W przypadku dwóch pozostałych zatwierdzeń zmień je na,

squash commit_id

lub po prostu,

s commit_id

Tom Taylor
źródło
0

Ja też spotkałem się z tym problemem właśnie teraz, to jest po prostu nieostrożne. Możesz rozwiązać problem jak następny: kiedy spróbujesz zgnieść pierwszy (56bcce7) i wybierzesz drugi, powinieneś dodać „s” przed drugą linią, ale nie pierwszy. możesz również odwołać się do następnej witryny internetowej: http://backlogtool.com/git-guide/en/stepup/stepup7_5.html

user8073722
źródło
1
Cześć ! Byłoby lepiej, gdybyś wyewidencjonował Jak stworzyć minimalny, kompletny i weryfikowalny przykład dla przyszłych wysiłków przy przepełnieniu stosu. -Dziękuję
Momin