Я столкнулся с ситуацией, связанной с git и Bitbucket, которую я не понимаю.
Я создал ветку branchB
, которая возникла из master
. Я сделал несколько коммитов и создал запрос на включение в master
. Пока этот пулреквест рассматривался, я начал работать над другой функцией, которая была расширением функции из branchB
. Поэтому я создал еще одну ветку (branchC
), которая возникла из branchB
. Когда моя расширенная функция была готова, я создал запрос на включение в branchB
. См. Изображение I. В то время у меня не было конфликтов слияния.
Я хотел, чтобы рецензенты могли просматривать оба пулл-реквеста по отдельности и иметь отдельные пулл-реквесты с небольшими изменениями.
Мой план был следующим:
PR1
) с мастером, используя опцию --squash
PR2
) на master (см. Изображение 2)PR2
) с мастеромОднако, когда я объединяю пул реквест 1 (PR1
) с мастером, используя опцию --squash
, Bitbucket автоматически изменил целевую ветвь запроса на вытягивание 2 (PR2
) на master
, и у меня возникли некоторые конфликты в запросе на вытягивание 2 (PR2
).
Итак, я разрешил конфликты:
git checkout master
git pull
git checkout branchC
git rebase master
git mergetool
Я решил все конфликты здесь.
git rebase --continue
На самом деле, описанная проблема случилась со мной дважды, так как у меня тоже было branchD
, происходящее от branchC
. Когда я объединил branchB
в master
, мне пришлось разрешить некоторые конфликты на шаге 6. Однако, когда я объединил branchC
в master
, мне не пришлось разрешать какие-либо конфликты вручную на шаге 6 (хотя Bitbucket показал мне конфликты слияния, поэтому мне пришлось перебазировать branchC
).
Му вопросы следующие:
PR2
, когда я объединил PR1
с мастером, используя опцию --squash
? Я ожидаю, что он поймет, что разница между картинками I
и II
есть только в идентификаторах коммитов — код не изменился. Git/Butbucket должен определить, какие изменения я хочу внести.branchD
в master
(после слияния branch C
в master
)? Поскольку Bitbucket не смог объединить мой запрос на извлечение, я ожидаю, что мне придется разрешать некоторые конфликты вручную. Может ли это быть связано с версией git на моем рабочем столе и на Bitbucket?Дополнительная информация:
2.17.1.windows.2
v5.12.2
2.14.5
Я был бы признателен за любое объяснение этого явления.
Редактировать:
1. Я объединил все свои пулреквесты с помощью опции --squash
.
2. Я обновил картинку, чтобы показать, что branchB
и branchC
не начинаются с коммитов B1
и C1
соответственно.
@Code-Apprentice, ты прав. Я не хотел предложить, чтобы branchB
и branchC
начинались с коммитов B1
и C1
. У меня были линии, соединяющие коммиты A2
- B1
и B2
- C1
на моей картинке, чтобы показать, что все ветки содержат коммиты из master
. Обновил картинку-надеюсь теперь понятно.
Если я правильно Вас понимаю. Проблема была в этом --squash
. Вот тема, в которой объясняется, как выполняются слияния в GIT Как git узнает, какую версию строки оставить?.
Когда вы объединились с --squash
, поскольку коммиты git на самом деле неизменяемы, вы создали новый сжатый коммит с новым идентификатором. Когда Вы захотели слить PR2
обратно в мастер, содержимое файла было изменено в обоих местах. Для branchB
было несколько коммитов с некоторыми идентификаторами, а для master
был только один коммит с другим идентификатором, и некоторые файлы были изменены в обеих ветках, поэтому в основном git не знает, какая версия правильная. Вот почему не было конфликтов в случае branchC
, потому что история коммитов была одинаковой для branchB
и branchC
(здесь --squash
не делалось).
Для OP и будущих посетителей: обратите внимание, что не имеет значения, что сжатый коммит имеет те же текстовые изменения, что и исходная последовательность коммитов. Git видит две разные последовательности изменений и называет это конфликтом слияния.
Если бы содержимое этих двух веток было бы точно таким же, сама по себе разная история коммитов не создавала бы конфликт слияния.
так что в этом случае вы имеете в виду, что слияние branchC
с master
(после слияния PR1) учитывало кумулятивные изменения коммитов с B1 по C2? Эти изменения отличаются от просто A3 в отдельности.
Я имею в виду, что если бы вы сбрасывали branchC
на коммит B2
, чтобы изменения, сделанные в master
и branchC
, были точно такими же. Если бы вы объединили branchC
с мастером, git смог бы сделать это без конфликтов, даже несмотря на то, что история коммитов технически отличается. По крайней мере, мне удалось это сделать без конфликтов в ситуации, описанной выше.
Так что насчет того, когда branchC
находится в состоянии фиксации C2
и master
находится в стадии фиксации A3
, и вы пытаетесь объединить master
в branchC
. Почему git не определяет, что A3
идентично изменениям в коммитах B1
и B2
?
Сообщение, которое я вставил, объясняет это, я думаю. GIT на самом деле не смотрит на коммиты из истории. Он будет смотреть хэши последних изменений, и они не совпадут в точке. Поэтому он попытается сравнить файлы построчно и обнаружит, что различия действительно есть, и пометит их как конфликты.
@DominikWosiński, это ответ на мой первый вопрос. Что насчет второго? Почему мне приходилось разрешать некоторые конфликты вручную для PR2, а не для PR3? Все 3 запроса на включение были объединены с помощью опции --squash
.
Что такое PR3
в данном случае? :)
Это пул реквест с branchD
на master
, который я объединил после того, как слил пул реквест с branchC
на master
. На самом деле у меня было три ветки: branchB
, branchC
и branchD
. Я не ставил branchD
на картинке, чтобы было проще. Я упомянул об этом в своем вопросе.
Такая ситуация может возникнуть, если изменения в branchD
не конфликтуют с предком. Это означает, что файлы, измененные в branchD
, не совпадают с файлами, измененными в branchC
. В таком случае трехстороннее слияние может правильно их объединить.
Одно уточнение: ветка указывает на конкретный коммит и содержит все коммиты до него. Я отмечаю это, потому что там, где вы помечаете
branchB
иbranchC
, создается впечатление, что эти ветви начинаются именно там. Это неверно, потому что обе ветки начинаются с коммита A1. Я полагаю, вы имеете в виду, чтоbranchB
заканчивается на фиксации B2, аbranchC
заканчивается на фиксации C2.