Git: Почему ребаза приводит к конфликтам, в то время как слияния нет?

Я, вероятно, не понимаю что-то правильно, но может ли кто-нибудь объяснить мне, почему git rebase приводит к конфликтам, а git merge (та же ветка) - нет?

Насколько мне известно, git rebase помещает коммиты из другой ветки до коммитов, которые я сделал в моей текущей ветке, тогда как git merge принимает те же самые коммиты и применяет их к моей ветке как патчу, не так ли? Является ли diff тогда не тем же, хотя, возможно, наоборот? Не знаю, почему исправление моей ветки с другими коммитами не является проблемой, а исправление другой ветки с моими коммитами.

Ответ 1

Я вижу, что иногда мой вопрос по-прежнему набирает обороты. Позвольте мне объяснить для тех, кто не понимает выбранный в настоящее время ответ, потому что я уверен, что не понял, когда впервые прочитал его.

Допустим, у вас есть master веток с коммитами A, B и C

Затем из коммита C вы создаете новую ветку mybranch. Вы фиксируете, и вы получаете коммиты D и E

Тем временем кто-то еще передает F и G на мастера.

Затем master выглядит так: ABCFG, а mybranch выглядит так: ABCDE.

Теперь у вас есть две стратегии слияния:

сливаться

Находясь на mybranch, вы mybranch git merge master. Он берет все коммиты от master, которых у вас нет на mybranch - F и G Сначала он объединяет F поверх вашего E (последний коммит mybranch), а затем объединяет G поверх F

Конечный результат: ABCDEFG. Несмотря на то, что эти буквы были в одном и том же порядке, коммиты не были выполнены в хронологическом порядке, потому что на самом деле F и G были (или могли быть) сделаны до D и E В этом случае вы также увидите коммит слияния.

Rebase

На mybranch вы mybranch git rebase master. Он берет все коммиты от master, которых у вас нет на mybranch - F и G Затем он берет ваш первый коммит - D - и сливает его поверх G (последний коммит в master). Затем он берет E и помещает его поверх E

Конечный результат: ABCFGDE. Похоже, что ни одна ветвь не была отделена от мастера, и если мастер - это одна непрерывная работа, потому что вы как бы сказали: "Я хочу, чтобы моя ветвь выглядела так, как будто она была просто отделена от мастера, а затем моя работа была помещена поверх нее". ".

Почему перебазирование может привести к конфликту, а слияние - нет.

Не вдаваясь в подробности, давайте просто скажем, что слияние master F поверх mybranch E может не привести к конфликту, но слияние mybranch D поверх master F может. Это действительно зависит от того, какой код был изменен и является ли это изменение совместимым с предыдущим коммитом. Конфликты слияния могут возникнуть в обоих случаях.

Ответ 2

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

См. Также git rerere который позволяет автоматически решать конфликты, которые вы уже решили.