Git: ошибка «Невозможно сжать без предыдущей фиксации» при перебазировании

102

У меня в тексте дел git rebase -i HEAD~2:

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

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

Теперь, когда я пытаюсь раздавить первый ( 56bcce7) и выбрать второй, добавив «s» перед первым, я получаю следующую ошибку:

Cannot 'squash' without a previous commit

Может кто-нибудь объяснить мне, что это значит и как мне это сделать?

Я хочу сжать первую фиксацию ( 56bcce7) и «выбрать и переписать» вторую e43cebaфиксацию ( )

Рассвет33
источник
1
Измените HEAD ~ 2 на HEAD ~ 3, если вы действительно хотите раздавить.
ElpieKay
1
И, возможно, используйте --root, если HEAD ~ 2 - ваш первый коммит: stackoverflow.com/a/598788/2444812
Sybille Peters

Ответы:

89

Интерактивное перебазирование представляет коммиты в порядке, обратном тому, к которому вы привыкли при использовании git log. git rebase -iвоспроизводит выбранные коммиты в точном (сверху вниз) порядке, в котором они перечислены в сохраненном файле инструкций по перебазированию. При сжатии фиксация, выбранная для сжатия, объединяется с фиксацией, которая предшествует ему в (отредактированном) списке, то есть фиксацией из предыдущей строки. В вашем случае - предыдущей фиксации для 56bcce7. Вы должны сделать одно из следующих

  • git rebase -i HEAD~3(если вы хотите , чтобы раздавить 56bcce7в 684f917)
  • Если вы хотите объединить 56bcce7с e43cebaи e43cebaне зависит от 56bcce7, просто измените их порядок:

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

    ОБНОВЛЕНИЕ : ответ Гаса ниже предлагает лучший способ сделать то же самое, не меняя порядок двух коммитов:

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

    Это сведет / объединит два коммита в один. Когда интерактивная перебазировка запрашивает измененное сообщение фиксации для 56bcce7, предоставьте сообщение фиксации, которое описывает объединение 56bcce7и e43ceba.

Леон
источник
1
Я хочу , чтобы раздавить 56bcce7 в e43ceba. Итак, как мне выполнить Шаг 1 здесь?
Dawny33
86

У меня была аналогичная проблема, которую я решил следующим образом:

Это группа коммитов, которую я хотел раздавить:

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

Как видите, я не хотел. 4, но у 1, 2 и 3 не было предыдущего коммита, в который можно было бы сквошить . Следовательно, невозможно "сжать" без предыдущей ошибки фиксации .

Мое решение заключалось в использовании rопции для# r, reword = use commit, but edit the commit message

Итак, мой список коммитов выглядел так:

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

После сохранения интерактивная оболочка попросила меня переформулировать выбранный коммит.

После этого мой журнал фиксации привел к единственной фиксации, которая привела к более чистой истории фиксации.

Гас
источник
2
как и я, если вы получили ошибку, потому что вы не выбрали какое-либо обязательство для переформулирования или выбора и получения упомянутой ошибки (по вопросу), вам нужно будет git rebase --edit-todoисправить и исправить, ссылаясь на этот ответ, а затем сделатьgit rebase --continue
old-monk
Ответ был кратким и точным, действительно помог, спасибо
gonzofish
20

У меня была эта проблема, и причина, по которой это произошло в моем случае, заключалась в том, что вы не можете раздавить старые коммиты на новый коммит. Вот пример, скажем, у вас есть 3 коммита:

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

Теперь, если вы скажете git rebase -i HEAD~3и сделаете что-то вроде

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

Это приведет к ошибке:

ошибка: невозможно «сжать» без предыдущей фиксации. Вы можете исправить это с помощью «git rebase --edit-todo», а затем запустить «git rebase --continue». Или вы можете прервать перебазирование с помощью git rebase --abort.

Решение :

При сжатии коммитов вы должны свешивать недавние коммиты на старые, а не наоборот, поэтому в примере это будет примерно так:

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

Это будет работать нормально, если вам нужны все сообщения о фиксации, я бы предложил исправить вместо сквоша .

DvixExtract
источник
5
Спасибо - я не часто коммитирую, и совет выбрать самый старый коммит - это то, что помогло мне справиться с бесполезной ошибкой git.
0x574F4F54
4

Сквош с обратной логикой . Вы сможете выбрать желаемое сообщение фиксации на более позднем этапе.

  • pickпервая фиксация, для которой вы не хотите получать сообщение фиксации.
  • squashили fixupкоммит (и), который вы хотите объединить, до тех пор, пока не появится тот, который имеет сообщение о коммите, которое вы действительно хотели.
pick 56bcce7 Closes #2774
squash e43ceba Lint.py: Replace deprecated link
  • подтвердить изменение ( :x)
  • удалить сообщение фиксации (s) , что вы не хотите , и оставить только сообщение от фиксации , что вы хотите (в данном случае: Lint.py: Replace deprecated link).
  • подтвердите выбор ( :x)

Надеюсь, кому-то станет понятнее ✌🏽

Kamafeather
источник
2

Лучше всего будет просто сказать в интерактивном редакторе, содержащем коммиты, git всегда сквош снизу вверх, и нужно оставить запись «выбрать» вверху, чтобы получать сквош снизу.

ekyu88
источник
2

Я просто попробовал такой подход.

git log -n3

Это покажет последние 3 коммита, которые дадут мне представление о том, какой коммит последний, а какой был ранее. Теперь заявил ребазинг,

git rebase -i ГОЛОВКА ~ 3

Выберите самый последний коммит, поверх которого нам нужно раздавить два других. Идентификатор фиксации, выбранный в качестве базовой фиксации, будет выглядеть так:

выберите commit_id

Для двух других идентификаторов фиксации измените их на,

сквош commit_id

или просто,

s commit_id

Том Тейлор
источник
0

Я также уже встречался с этой проблемой только сейчас, это просто небрежно. Вы можете решить проблему следующим образом: когда вы пытаетесь раздавить первую (56bcce7) и выбрать вторую, вы должны добавить "s" перед второй строкой, но не первый. вы также можете сослаться на следующий веб-сайт: http://backlogtool.com/git-guide/en/stepup/stepup7_5.html

user8073722
источник
1
Здравствуй ! Было бы лучше, если бы вы ознакомились с тем, как создать минимальный, полный и проверяемый пример для будущих усилий при переполнении стека. -Спасибо
Момин