Git merge -s recursive -X ours vs git merge -s ours?

В man git -merge doc, git merge -s recursive -X ours:

Это не следует путать с нашей стратегией слияния, которая делает даже не смотрите на то, что содержит другое дерево. Он отбрасывает все, что делало другое дерево, объявляя, что наша история содержит все, что произошло в нем.

Я тестировал эти два, но не нашел разницы.

Есть ли пример, чтобы узнать, в чем разница между этими двумя?

Моя версия git git version 1.8.3.4

Ответ 1

Как говорится в man-странице, -s ours полностью игнорирует содержимое другой ветки. Это должно быть достаточно очевидным: независимо от того, что в другой ветке, дерево, прикрепленное к фиксации слияния, идентично дереву в объявлении HEAD до слияния.

Что -X ours делает более тонким: он использует "нашу" версию изменения только тогда, когда есть конфликт.

Здесь относительно простой пример.

Предположим, что вы находитесь на ветке br1, и вы просите слить в ветке br2. Мы сделаем их очень простыми, с фиксацией B (начало базы слияния для обеих ветвей), имеющее одно единственное commit K на ветке br1, и одно единственное commit L на ветке br2:

... - B - K   <-- HEAD=br1
        \
          L   <-- br2

Кроме того, разница от B до K состоит только из одного элемента:

  • изменить (уже существующий) файл f1: заменить первую строку dog на cat

Между тем разница от B до L состоит из:

  • изменить файл f1: заменить первую строку dog на poodle
  • изменить файл f2: заменить последнюю строку elephant на rhinoceros

Когда вы объединяете их без стратегии или параметров, в файле f1 (разные изменения в тех же строках) будет конфликт, но не в f2 (слияние будет принимать изменения в commit L, чтобы файл f2 изменился).

Если вы используете:

git merge -s ours br2

команда merge будет использовать "нашу" версию файла f1 (dog становится cat), а также наша версия файла f2 (elephant не изменена).

Если вы используете:

git merge -s recursive -X ours

команда merge найдет конфликт в файле f1 и решит его в пользу нашей версии - это то же самое, что и раньше, - но конфликт в файле f2 отсутствует, поэтому git будет использовать свои версия f2 (elephant становится rhinoceros).

(Этот простой пример не показывает, что произойдет, если есть два разных изменения в разных областях в f1 или f2.Если f1 достаточно длинный, и есть изменение в фиксации L дальше, чем "первая строка файла", слияние может забрать это изменение, так как оно не будет конфликтовать с изменением dog -to- cat.)

Ответ 2

Я не знаю каких-либо конкретных примеров, но разница в этом:

git merge -s recursive -X ours

Это означает "нормальное" слияние (стратегия recursive по умолчанию), а когда обнаружены конфликты, она пытается разрешить эти конфликты, автоматически используя фрагменты кода из объединенной ветки ( "ours" ), а не оставлять маркеры конфликта.

git merge -s ours

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