Отмена ошибок git rebase - PullRequest
       82

Отмена ошибок git rebase

0 голосов
/ 27 февраля 2019

У меня никогда не было особых проблем с rebase, в основном потому, что я стараюсь быть более осторожным при определении количества кода и области видимости.Но, работая над объединением некоторых изменений прежних проектов с моими коллегами, у нас возникла серьезная проблема с использованием подхода rebase-first (из-за большого количества изменений в коммитах).Так что это заставило меня задуматься о том, как решить некоторые из этих проблем, которые кажутся очень распространенными в этой ситуации.

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

1) Как я могу повторить ребаз для этого единственно ошибочно объединенного файла?

2) Как я могу повторить ребаз для всех файлов в этом коммите?применение, если я сделал больше одной ошибки слияния / удаления или добавления файлов?

3) Как я могу вернуться к уже примененным коммитам в этом ребазе, если я понимаю, что сделал ошибку, объединяя один или два файла, которые уже былиприменил некоторые коммиты назад?

PS .: Мне известны git reflog и указатель ORIG_HEAD.Я хочу, чтобы он работал, сохраняя состояние операции git rebase.Я не знаю, есть ли более простой способ обойти это.

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Это (а) сложная проблема в целом, и (б) решение с личными предпочтениями, что делает действительно трудным найти хорошее общее решение.

Способ думать о ее решениипомнить, что копии rebase фиксирует.Нам нужен способ установить какое-то удобное для пользователя отображение между несколькими копиями коммитов.

То есть предположим, что у нас есть:

       O1--O2--O3   <-- branch@{1} (as originally developed with original commits)
      /
...--M1--M2--M3--M4   <-- mainline
               \   \
                \   S1--S2   <-- HEAD (in middle of second rebase)
                 \
                  R1--R2--R3   <-- branch (after first rebase)

Отображение здесь состоит в том, что O1, R1 иS1 все как-то «эквивалентны», даже если их идентификаторы патчей не совпадают и / или есть ошибка в R1 и / или S1.Аналогично, O2, R2 и S2 являются «эквивалентными», а O3 и R3 являются «эквивалентными» (S3 отсутствует).

Git не предлагает механизм возврата к S1.Вы можете возиться с S2 сколько хотите, используя git commit --amend, чтобы создать S2a, чьим родителем является S1, но ваша единственная встроенная опция - продолжать или полностью прекратить работу.Если вы продолжите, имя branch будет удалено с R3 и вставлено на S3, а branch@{1} станет branch@{2}, с branch@{1} и ORIG_HEAD, помня R3.

Git также делаетне предлагать надежный механизм для пометки каких-либо коммитов O / R / S как «эквивалентных».Самое близкое, что вы получите - git patch-id.И, конечно же, если вы использовали операции сквоша или фиксации в автоматическом перебазировании, то, что вы действительно хотите, чтобы что-то более изумительное, например, «R2 эквивалентен волу, сжатому с Oy» или что-то еще.

Вы можете используйте reflogs или задайте имя ветки или тега, чтобы иметь возможность восстановить хэш-идентификатор коммита S2, из которого вы можете найти S1.Это позволяет вам создать собственную команду, похожую на rebase, которая работает, выбирая вишню S1 и останавливаясь для изменения, затем выбирая вишню S2 и переходя к вишне R3.Но вы будете знать, как сделать это в целом только с помощью карты эквивалентности.

Как действовать дальше, зависит от вас: вы будете создавать свои собственные инструменты.Вы можете использовать git rev-list, чтобы получить хэш-идентификаторы выбранных коммитов.Просто убедитесь, что если в последовательности коммитов есть операции ветвления и слияния, которые нужно выбрать из вишни, вы использовали --topo-order для получения последовательного порядка.

0 голосов
/ 28 февраля 2019

Ладно ... просто думаю ..... Я думаю, вы могли бы --abort выполнить операцию перебазирования, вернуться к перебазированной ревизии, которую вы хотели бы исправить, а затем снова запустить перебазирование но указав новый сегмент ревизий для применения.Давайте предположим, что у вас есть ветвь A, которая была запущена из master ..... она имеет 20 ревизий.Итак ... вы уже опровергаете A ~ 10 ..... и вы только что заметили, что это на самом деле не правильно ... A ~ 15 был неправильно перебазирован.Итак ... это то, что я бы сделал

git rebase --abort # stop rebase
git reflog # find the rebased revision of A~15 on top of master
git checkout rebased-revision-for-A~15
# correct the revision
git add .
git commit --amend --no-edit # correct the rebased revision
# continue with the process
git rebase --onto HEAD A~15 A

Таким образом, вы можете продолжать, как вы делали ... только с объездом.

...