[Филиалы master
и branch2
] отличаются только на 1 строку для комментария:
Мастер имеет комментарий: // test 00
branch2 имеет комментарий: // test 99
Это ... не бесполезно, но также не совсем используется ful информация. Когда вам интересно, что будет делать git merge
, содержание подсказок каждой ветви не является ключом к ответу. Точнее, они необходимы, но крайне недостаточны.
Во-первых, помните, что коммиты содержат файлы. Я предполагаю, что когда вы говорите «master
имеет X, а branch2
имеет Y», вы действительно имеете в виду: Все файлы в коммитах с подсказками, обозначенные master
и branch2
соответственно, идентичны, за исключением некоторых файлов F , у которого есть какая-то строка L , текст которой отличается: эта строка читает //test 00
в master
и //test 99
в branch2
.
То есть, если бы мы нарисовали график коммитов, он мог бы выглядеть так:
o--o--X <-- master
/
...--o--*
\
o--Y <-- branch2 (HEAD)
(Существуют и другие возможные фигуры, но вывод из git merge
предполагает, что это было очень похоже на это. Имя HEAD
прикреплено к branch2
, потому что это то, что вы извлекли.)
Здесь я использовал X
и Y
для обозначения фактических хеш-идентификаторов коммитов подсказок ветвей master
и branch2
. Поскольку каждый коммит содержит хэш-идентификатор своего непосредственного родительского коммита, мы можем работать в обратном направлении от последнего коммита master
к предыдущему коммиту master
, а оттуда предыдущего коммита , и так далее. Мы также можем начать с коммита Y
и двигаться назад. Когда мы двинемся назад одновременно с обоих коммитов, мы в конечном итоге достигнем некоторой точки соединения: коммит *
, а не один из раундов o
коммитов.
Первая такая точка соединения очень особенная для git merge
, потому что это база слияния . База слияния - это ключ к пониманию того, что git merge
собирается делать.
Цель объединения - объединить работу , а не просто сделать две одинаковые ветви. Чтобы объединить проделанную работу, Git должен выяснить что за работа была . Работа состоит из всех изменений, сделанных с общей отправной точки . База слияния является той общей отправной точкой.
Git теперь будет выполнять две отдельные команды git diff
. Можно сравнить коммит *
с коммитом X
, чтобы увидеть, что «они» - кем бы они ни были - делали на ветке master
. Другой сравнит коммит *
с коммитом Y
, чтобы увидеть, что вы сделали в вашей ветке branch2
. То есть:
git diff --find-renames <hash-of-*> <hash-of-Y> # what did we change, on branch2?
git diff --find-renames <hash-of-*> <hash-of-X> # what did they change, on master?
Git затем объединяет два набора изменений и применяет объединенные изменения к содержимому commit *
.
Поскольку вы, в branch2
, очевидно, сделали все то же, что и они, в master
, , за исключением для изменения строки L файла F , объединенные изменения будут такими же, за исключением этой строки. Вопрос теперь: кто изменил линию?
Допустим, что в *
строка читается как //test 00
. Затем вы изменили строку, поэтому Git примет ваше изменение, и в результате получится, что строка L файла F будет читать //test 99
.
Но, скажем, вместо этого в *
строка читается как //test 99
. Затем они изменили строку, поэтому Git примет их изменение, и в результате получится, что строка L файла F будет читать //test 00
.
Наконец, возможно, что в *
строка прочитала что-то еще полностью. В этом случае вы и они изменили одну и ту же строку 1132 * файла того же самого файла , но на две разные вещи. В этом случае git merge
объявит, что существует конфликт, и остановится и оставит беспорядок, который вы должны устранить. Поскольку этого не произошло, очевидно, что это не так.
Проверка файла покажет вам, какие изменения были сохранены в Git, и, в свою очередь, покажет, как выглядит линия в базе слияния. Или вы можете найти базу слияния самостоятельно и проверить эту версию этого файла в этом конкретном коммите. Но, учитывая то, что вы нам сказали, мы не можем предсказать, какая строка вошла в коммит слияния.