Странность с git сливается? - PullRequest
1 голос
/ 27 января 2020

Я новичок в git, так что всем это может показаться простым, и я просто не понимаю.

Я готовлюсь начать проект с 1 другим другом, и мы решил использовать git в качестве нашей системы контроля версий, поэтому мы проводили тесты, чтобы увидеть, как это будет работать. Вот что мы уже тестировали и где у нас проблемы:

У нас есть 3 ветви

  • Мастер
  • Мое имя
  • Friends Name

Хорошо, так что:

  1. Я создаю файл test.txt непосредственно в master, прежде чем создавать другие 2 ветви, и оставляю txt пустым.
  2. Мы создаем две другие ветви, и я извлекаю из своей ветки запись «Test 1» в строке 1 без других строк, затем фиксирую и объединяю ее с master.
  3. Мой друг извлекает свою ветку и пишет «Test» 2 "в строке 1 и" Исправление "в строке 3, затем он фиксирует и объединяет с мастером и получает ошибку слияния, потому что 1 был изменен на 2 в строке 1, а также потому, что было добавлено исправление.

Это немного упрощено по сравнению с тестами, которые мы проводим, но действительно ли git не достаточно умен, чтобы распознать разницу, когда было сделано такое простое изменение? Я вижу, что он спрашивает, должна ли строка 1 иметь 1 или 2, но почему он жалуется на добавление исправления на новую строку?

, и я не думаю, что это имеет значение, но мы пробовали то же самое тесты в Bash CLI для windows, Bash непосредственно в Linux, Github для рабочего стола, Gitkraken и Gmaster, все с одинаковыми результатами.

Edit, для ясности, вот здесь вывод о том, что я делал в терминале: я объяснил, что я делал в сообщениях фиксации, и хотя я не знаю, как отобразить конфликты слияния из терминала bash, здесь приведен снимок экрана с конфликтом, который он печатает в vscode: https://imgur.com/a/Yd6EXx2.

Также для большей ясности, когда создается .txt, есть 1 строка, я помещаю Test (число здесь) в эту предварительно созданную строку в обеих ветвях, и для ветки друзей я создал строки 2 и 3 и поставил исправление и строку 3.

1 Ответ

5 голосов
/ 27 января 2020

Git считает, что изменения вступают в конфликт друг с другом, если они вносят различные изменения в одну и ту же исходную исходную строку или , если два изменения "касаются" по краям. Причина последнего заключается в том, что Git не знает, в каком порядке их поместить.

То есть предположим, что, начиная с того же пустого файла test.txt, ваше изменение:

+Test 1

(то есть добавьте одну строку, читающую Test 1) и его изменение:

+Test 2
+Hotfix

Git не знает, стоит ли ставить вашу строку первой, за которой следуют две его строки или две его строки, за которыми следует ваша строка.

Вы сказали, что он что-то изменил, хотя и "строку 3". Строка 3 отсутствует. Возможно, исходный предположительно пустой файл был на самом деле одной пустой строкой? Тогда ваше изменение будет:

-
+Test 1

То есть уберет пустую строку и вставит строку, читающую Test 1. Его изменение теперь:

+Test 2

+Hotfix

(то есть оставьте пустую строку, но добавьте первую и третью строки). Это изменение вступает в конфликт, потому что вы изменили пустую строку, и он сохранил ее, или - если мы посмотрим на это немного по-другому - он добавил строку выше и ниже пустой строки, а вы изменили пустую строку. (Git не смотрит на измененные строки, а только на добавленные и / или удаленные строки, и это еще одна причина, почему изменения, которые примыкают - касаются краев вот так —Conflict.)

В любом случае, вы бы не получили конфликт слияния, если бы вы изменили линии, которые отличались или не «соприкасались» друг с другом. То есть предположим, что в исходном файле text.text указано:

This test file
has several
lines in it.

Вы вносите изменение, добавляющее Test 1 в top . Он вносит изменения, которые добавляют Test 2 и Hotfix внизу. Когда Git сравнивает версию файла, с которого вы оба начали - с его тремя строками - с вашей версией, с четырьмя строками, и с его версией, с пятью, Git видит, что ваше изменение вставить между «строкой 0» (верхняя часть файла) и строкой 1, а его изменение вставить после строки 3 перед «строкой 4» (нижней частью файла). Эти изменения не перекрывают , поэтому Git может применить оба изменения к исходному трехстрочному файлу и получить чтение из шести строк:

Test 1
This test file
has several
lines in it.
Test 2
Hotfix

Подумайте о объединить базу

Другой способ поместить все это: Git не добавляет свои изменения в вашу версию файла. Git также не добавляет ваши изменения в его версию файла. Git находит версию файла base merge .

Помните, что каждый коммит хранит полный, полный снимок каждого файла. Так что если Git может найти любой коммит, который у вас у обоих был до того, как вы начали работать, то какой бы файл мы ни задавали, Git имеет некоторую копию файла в этом коммите .

База слияния - это «лучший» коммит, с которого вы оба начали - тот, который ближе всего к тому, с чем вы оба закончили. Поскольку вы оба начали с одного и того же коммита, у вас обоих была одинаковая версия этого файла. Таким образом, Git может выполнять две операции git diff. Кто-то находит, что вы изменили. Другой находит, что он изменился. Задача Git состоит в том, чтобы объединить два набора изменений и применить эти объединенные изменения к копии base .

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

...