Слияние с git — как понять, где заканчивается «новый» код?

Другой пользователь на моем git создал ветку и не может понять, как ее объединить через eclipse. Поэтому я объединяю его с master.

Начать :

git pull origin master
git pull origin garbage (this is what his branch is named)

Я получаю конфликт слияния в файле. Обычно я могу понять это, если написал весь код, но в этом случае я не могу. Это выглядит так:

<<<<<<<<<<<HEAD
//a bunch of code
=========
>>>>>>>>>>> A bunch of numbers (I'm assuming the hash of the new branch)
//code that I didn't write
//the rest of the code

Не могу найти разрыв между code I didn't write и rest of code. Разве не должна быть еще одна строка ======== после «нового» кода? Каков наилучший способ объединить это?


person Brydon Gibson    schedule 12.11.2016    source источник


Ответы (3)


Этот конкретный стиль конфликта показывает только две части конфликта, но на самом деле их три, просто одну обычно нужно отбросить.

Помните, что существует «базовая» версия файла и две подсказки. Базовая версия — это то, с чего вы начали работу до внесения своих изменений в master, и он начал с того же самого. базовую версию до того, как он внес свои изменения. Вот что делает базовую версию «базовой»: у вас обоих был один и тот же файл в той же форме некоторое время назад.

С тех пор — с этой общей базы — Git смотрит на это как «вы сделали какое-то количество коммитов (хотя бы 1, возможно, много), и он сделал несколько коммитов (хотя бы один, возможно, много)»:

          o--o--A   <-- you (master)
         /
...--o--*
         \
          o--o--o--B   <-- him

Чтобы объединить эти изменения, Git запускает сравнение с * (базовое) на A (ваше master) и второе сравнение с * на B (его garbage, которое вы обычно будете называть origin/garbage). Git обнаружил какой-то конфликт между «то, что вы сделали» и «что он сделал», и поместил это в объединенный (в основном законченный) файл, используя маркеры конфликта:

[there might be stuff up here too]
<<<<<<<<<<< HEAD
//a bunch of code
=========
>>>>>>>>>>> A bunch of numbers (I'm assuming the hash of the new branch)
//code that I didn't write
//the rest of the code

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

Допустим, например, что Git ошибочно решил, что вы оба сохранили 17-ю полностью пустую строку, потому что в вашем новом файле рядом с ней есть пустая строка, а в его новом файле рядом с ней пустая строка (хотя на самом деле это просто < em>случайное совпадение). Затем Git смог решить, что все, что он делал после этой пустой строки, не конфликтовало, так что это в вашем объединенном файле, но не помечено маркером конфликта.

Между тем, Git решил, что из-за этой «сохраненной» пустой строки вы добавили первый раздел // a bunch of code, чего он не сделал. (Возможно, на самом деле это было в исходном файле, но когда Git неправильно синхронизировался, он оказался «выглядящим новым». Или он действительно мог быть совершенно новым.)

После этой части, между начальными шевронами <<< и строкой ===, Git включает код, который, по его мнению, он добавил: это все, что находится после строки === до строки >>>. (В этом случае он думает, что он ничего не добавлял сюда: возможно, он думает, что он удалял что-то, например, пустую строку.)

Остальной код, включая // code that [you] didn't write, либо уже был в базе, либо Git смог добавить его, не увидев конфликта.

Я считаю, что лучше установить merge.conflictstyle на diff3. Это меняет то, как Git вставляет две конфликтующие секции в основной файл: он вставляет ту часть, которую может обработать самостоятельно, затем маркер <<<<<<<, затем то, что, по его мнению, вы добавили, если что, затем ряд вертикальных полос |||||||, затем базовый код, который, по мнению Git, необходимо заменить, затем маркер =======, затем его код, затем закрывающий маркер >>>>>>>.

Git считает вероятным, что вы избавитесь от базового кода и будете использовать тот или иной из разделов HEAD или других разделов кода ветвления, или, возможно, даже сочетание HEAD и прочего. Но если раздел base окажется полной чушью, вы сразу же поймете, что Git синхронизировался с чем-то поддельным, например, с пустыми строками и строками, состоящими только из }.

person torek    schedule 12.11.2016
comment
Спасибо, это действительно помогает объяснить процесс слияния git. - person Brydon Gibson; 12.11.2016

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

person HaroldSer    schedule 12.11.2016

Ты можешь попробовать

git слияние

git mergetool запускает одну из нескольких утилит слияния для разрешения конфликтов слияния. Обычно он запускается после git merge.

Установите какой-нибудь инструмент слияния, например kdiff3 или meld, который поможет вам слить.

person root    schedule 12.11.2016