Зачем git rebase воспроизводить коммит ветки функций по одному? - PullRequest
1 голос
/ 17 апреля 2019

Я новичок в командах git и недавно пришел к команде git rebase.У меня возникло сомнение относительно того, почему команда git rebase воспроизводит коммиты ветви функции один за другим, а не просто воспроизводит последний коммит в ветви функции.

Это был мой сценарий для проекта, в котором я работал:

M1 --- M2 --- M3 --- M4
       |
       M2 --- F1 --- F2 --- F3

Мы были 4 разработчиками, работающими над проектом, и я разветвлял проект от upstream / master в точке M2.

Я начал работать над своей функцией и начал добавлять коммиты.Коммит F1 был с некоторым базовым кодом.Затем фиксация F2 была исправлением некоторых ошибок для фиксации F1, и аналогично фиксация F3 была исправлением ошибки для кода в F2, а F3 была моей последней готовой функцией.

Тем временем другие разработчики завершили свою функцию, и их код был объединен с апстримом / мастером.Теперь я должен поставить свой код поверх их функции, которая называется M4.Теперь нижеследующая часть - мое понимание о git rebase, и я могу ошибаться:

Я проверил ветвь возможностей и выполнил git rebase с upstream / master, что поставило мою ветвь функций поверхM4 и начал воспроизводить мои коммиты (F1, F2 и F3) по одному.Я получил конфликты при повторном воспроизведении F1 и решил их.Поскольку F2 был исправлением ошибки на F1, я снова получил похожие конфликты в том же месте и снова разрешил их.Наконец, я снова получил аналогичные конфликты в том же месте, когда F3 был воспроизведен.Я разрешил конфликты, и все было хорошо.

Но вместо воспроизведения коммитов F1, F2, F3, если бы git попытался поместить только последний коммит моей функциональной ветви поверх M4, мне пришлось бы разрешать конфликты только одним.[Так как мой код в F3 будет иметь код для F1 и F2].Так почему эти дополнительные повторы.

Возможно, мне здесь не хватает некоторых базовых понятий, пожалуйста, поправьте меня, где я ошибаюсь.Спасибо!

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

Вы должны сказать Git раздавить все коммиты, кроме вашего последнего коммита, чтобы добиться того, что вы ожидаете от разрешения конфликтов только один раз.

Для этого инициируйте интерактивную перебазировку поверх M4, пока вашветвь функции извлечена:

git rebase -i M4

Вам будет представлен редактируемый фрагмент, похожий на следующий:

pick 111111 F1
pick 222222 F2
pick 333333 F3

Затем вы отредактируете этот фрагмент, чтобы сказать Git, что нужно раздавить F2 и F3 в F1, в результате чего получается один коммит, который представляет все ваши изменения с тех пор, как вы разветвились:

pick 111111 F1
squash 222222 F2
squash 222222 F3

F1 номинируется как коммит, в который можно раздавить, потому что этокак работает команда (т. е. она объединяет изменения в предыдущий коммит).

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

Имейте в виду, что при сжатии F2 и F3 вы потеряли эти явные наборы изменений.Если вы хотите сохранить их, нет альтернативы разрешению конфликтов на каждом шаге воспроизведения.

0 голосов
/ 17 апреля 2019

Rebase - это применение коммитов поверх другого по одному .

Из документации :

Затем коммиты [...] повторно применяются к текущей ветке, по очереди, по порядку.

Таким образом, rebase эффективно объединяет один коммит за раз поверхпредыдущий.Теперь сравните и сопоставьте с другим видом слияния , который вы можете сделать в Git:

git checkout master
git merge feature

Команда merge выполняет именно то, что вы запрашиваетеfor: применяет кумулятивные изменения, связанные с последним коммитом в ветке feature поверх последнего коммита в master за одну операцию.Это означает, что вам придется разрешать все конфликты только один раз.

Операция слияния обычно приводит к созданию коммита слияния в целевой ветви;Цель коммита слияния - объединить две (или более!) строки истории.Таким образом, хотя обычная фиксация имеет только одного родителя , коммит слияния естественно ссылается на нескольких родителей .

M1 --- M2 --- M3 --- M4 --- MF
       |                    |
       M2 --- F1 --- F2 --- F3

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

Вы можете сделать это, создавтак называемое сквош-слияние :

git checkout master
git merge feature --squash

Разница в том, что объединенные изменения с master и feature записываются в синглеЗафиксируйте поверх master, в результате чего появится история, которая выглядит следующим образом:

M1 --- M2 --- M3 --- M4 --- MF
       |                    
       M2 --- F1 --- F2 --- F3

Где MF содержит объединенные изменения из M4 и F3 со всеми разрешенными конфликтами.

...