Подтвердить что ты не робот

Почему тот же конфликт появляется снова, когда я использую git rebase?

Я прочитал соответствующие вопросы о git merge и git rebase on SO, но я до сих пор не могу полностью понять, что происходит под капотом.

Вот наша ситуация разветвления:

MASTER------------------------
        \        \
         \        \----Feature B---
          \                        \
           \-----Feature A----------\---Feature A+B

У нас есть две ветки функций, которые происходят от мастера в разное время, теперь мы хотим объединить 2 ветки. Мы хотим следовать практике first rebase then merge, но когда мы переустанавливаем функцию A в функцию B, мы получаем конфликты. Это ожидается, потому что обе функции (и мастер) имеют изменения в тех же областях. Но странно, что тот же конфликт продолжает появляться после git rebase --continue. Это сводит нас с ума, поэтому мы заканчиваем отмену rebase и используем git merge. Оказывается, конфликты на самом деле легко разрешаются.

Мой вопрос в два раза:

  • Является ли git rebase подходящим для нашего сайта? Или может быть полезно только для замены нескольких (1 или 2) изменений?
  • Что происходит под капюшоном, которое заставляет тот же конфликт снова и снова появляться снова? Мое понимание - rebase разрешать конфликты по одному, но, сравнивая, какой фиксацией для чего?

Relavant posts на SO:

4b9b3361

Ответ 1

Подходит ли rebase для вашей ситуации?

Исходя из того, что Feature A и Feature B кажутся общими ветвями, я бы сказал, что нет.

Перебазирование - это способ слияния ветвей без коммитов слияния (т.е. Коммитов, имеющих двух или более родителей), делающих его похожим на линейную историю. Лучше всего использовать для объединения локальных веток, то есть веток, которые существуют только в вашем локальном хранилище и не были опубликованы для других людей. Зачем? По крайней мере по двум причинам:

  1. Перебазировка изменяет идентификаторы фиксации (т. SHA-1 хэши их метаданных). Это означает, что после того, как вы отправите переназначенные коммиты в общую ветку, они будут отображаться как абсолютно новые коммиты для всех, кто извлекает их из локального репо, даже если они все еще содержат те же изменения. Теперь, если кто-то тем временем добавил новые коммиты поверх старых, им придется их перемещать. Это создает ненужную путаницу.

  2. Когда вы объединяете публичные ветки, вы часто хотите иметь эти коммиты слияния, чтобы иметь возможность отслеживать, как коммиты перемещались по веткам. Эта информация теряется при перебазировании.

Что происходит под капотом?

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

Обновление: разрешение повторяющихся конфликтов

Как отметил @Jubobs в комментариях, Git действительно имеет автоматическое решение для разрешения конфликтов, которые возникают несколько раз: git rerere или "повторно использовать записанное разрешение".

После включения rerere в файле конфигурации (rerere.enabled true) каждый раз, когда возникает конфликт слияния, Git будет записывать состояние конфликтующих файлов до и после их слияния. В следующий раз, когда возникнет тот же конфликт - конфликт с одинаковыми строками по обе стороны от слияния - Git автоматически применит то же разрешение, которое было записано ранее. Он также сообщит вам об этом в выводе слияния:

КОНФЛИКТ (содержание): конфликт слияния в 'somefile'
Разрешено "somefile" с использованием предыдущего разрешения.

Здесь вы можете найти более подробную информацию о том, как бороться с конфликтами, используя git rerere.

Ответ 2

В моем случае git снова и снова показывал одни и те же файлы как конфликтующие. Я думаю, это потому, что было много изменений в разных коммитах для одного и того же файла. Например, мне пришлось разрешить один файл 7 раз; для этого файла было минимум 7 коммитов в 2 ветках; некоторые из них могут вызвать конфликты.

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

Так что не сдавайся.