Чем отличаются `--abort` и` --quit` как подкоманды секвенсора для `cherry-pick`? - PullRequest
2 голосов
/ 30 марта 2019

Согласно doc , среди трех подкоманд секвенсора для cherry-pick, у нас есть эти две, которые, на мой взгляд, странно похожи:

--quit

Забудьтео текущей операции в процессе.Может использоваться для очистки состояния секвенсора после неудачного выбора или возврата вишни.

--abort

Отмена операции и возврат в состояние предварительной последовательности.


До сих пор я всегда использовал --abort, и он прекрасно работает.Какой будет вариант использования, где --quit отличается / предпочтительнее?

Ответы [ 2 ]

3 голосов
/ 30 марта 2019

Если вы помните, что git rebase - это последовательность git cherry-pick операций, 1 плюс пара полезных уловок в начале и конце, это имеет больше смысла.

Представьте, что у вас есть следующие серии коммитов:

...--o--*--...--o   <-- mainline
         \
          A--B--C   <-- feature

Вы хотите обновить feature до mainline, чтобы вы:

git checkout feature
git rebase mainline

Git начинает с перечисления коммитов, достижимых с feature (C, B, A, *, ...) и коммитов, доступных с mainline (без имени, ..., *, ...). Он вычитает набор mainline из набора feature 2 и использует обратный топологический порядок, так что теперь у него есть хэш-идентификаторы A, B и C, перечисленные в том, что Git вызывает секвенсор . (Секвенсор также записывает операцию, в данном случае rebase / cherry-pick. Секвенсор также используется для нескольких возвратов. Секвенсор может остановиться на полпути, а затем возобновить с помощью --continue. Поэтому ему необходимо знать операцию : продолжаем ли мы вишню, возвращение или ребаз?)

Затем Git отсоединяет HEAD при коммите в конце mainline и запускает операцию, какой бы она ни была, через секвенсор. Поскольку операцией является «rebase», каждый шаг секвенсора представляет собой простой вишневый выбор с одним коммитом:

(with)

...--o--*--...--o   <-- mainline, HEAD
         \
          A--B--C   <-- feature

(execute git cherry-pick A to produce)

                  A'   <-- HEAD
                 /
...--o--*--...--o   <-- mainline
         \
          A--B--C   <-- feature

Может произойти сбой при конфликте слияния. Если это так, секвенсор останавливается, оставляя беспорядок конфликтов слияния в вашем индексе и рабочем дереве. Вы можете исправить их и возобновить работу секвенсора (который обязуется сделать A', если необходимо, если вы сами не сделали A'), или выбрать один из двух видов останова: «прервать» или «выйти» , Если вы возобновите - или если дела пошли хорошо - мы продолжим (пытаться) черри B:

                  A'-B'   <-- HEAD
                 /
...--o--*--...--o   <-- mainline
         \
          A--B--C   <-- feature

Допустим, это также успешно, и мы продолжаем пытаться выбрать вишню C, но эта попытка не удалась . Секвенсор останавливается, оставляя беспорядок в вашем индексе и рабочем дереве, с тем же графиком, который мы видим выше: A' и B' существуют, но C' не существует.

Скажем, мы решили прекратить: завершить пикировку C на данный момент слишком сложно, и нам нужно немного отступить и сделать что-то еще. Теперь у вас есть две опции: прервать или выйти .

Если вы выбираете --abort, Git повторно присоединяет ваш HEAD к feature, давая:

...--o--*--...--o   <-- mainline
         \
          A--B--C   <-- feature (HEAD)

Где A' и B'? Что ж, если вы знаете, что делаете, вы можете выловить их из повторных флагов, или вы уже умело прикрепили название ветви или тега к B' до , выбрав --abort. Но если вы выберете --quit, Git прекратит ребазу , не двигаясь HEAD, так что вы получите:

                  A'-B'   <-- HEAD
                 /
...--o--*--...--o   <-- mainline
         \
          A--B--C   <-- feature

но чистый индекс и рабочее дерево. Таким образом, у вас нет , чтобы быть достаточно умным, чтобы прикрепить имя ветви до --quit.

Это в основном все, что нужно сделать. :-) Но после долгой и разочаровывающей перебазировки с партией конфликтов, где вы хотите сохранить достигнутые результаты и вернуться к работе без перебазирования, прежде чем снова вернуться к перебазировке позже вариант "бросить курить" кажется более удовлетворительным.

(Я думаю, что здесь действительно отсутствует опция сохранения оставшейся части состояния секвенсора и его восстановления позже. Однако, состояние секвенсора является для каждого рабочего дерева, так что если у вас есть текущая задача перебазирования и вам нужно ее прервать с задачей с более высоким приоритетом вы можете просто добавить рабочее дерево для задачи с более высоким приоритетом. Различные ошибки в добавленных рабочих деревьях через Git 2.15 не так уж внушают доверие, но, похоже, они теперь ведут себя хорошо. -деревья также накладывают на другую, более крупную недостающую часть, которая является способностью сохранить конфликтующее слияние в процессе и восстановить его позже.)


1 Обратите внимание, однако, что неинтерактивный git-rebase--am старого стиля все еще использует git format-patch и git am.Этот процесс не работает в некоторых случаях с переименованными файлами и не может скопировать коммит "не вносит изменений", но он работает быстрее .В большинстве случаев как этот, так и стиль выбора «вишня» должны давать одинаковые результаты, несмотря на изменение базового механизма, тем более что вариант «выбор вишни» по умолчанию не копирует коммит «не вносит изменений».

2 Перебазировка также вычитает любые коммиты, которые существуют в наборе mainline и имеют те же git patch-id, что и любые коммиты в наборе feature, и, конечно,по умолчанию вычитает все слияния.

2 голосов
/ 30 марта 2019

--abort вернет вас туда, где вы были до того, как вы начали операцию выбора вишни, тогда как --quit выйдет из операции и сохранит вас в текущей редакции.Я не могу вспомнить случай использования, отличный от того, что вы хотели бы пойти в другом направлении после того, как вы нажали ревизию, которая не могла быть автоматически собрана вишневым сортом, именно поэтому вишневый сбор остановился в первую очередь, верно?

...