Как Git принимает решение о конфликтах? - программирование

Как Git принимает решение о конфликтах?

Когда я выхожу из GitHub, когда кто-то из команды модифицировал определенный файл, команда Git показывает, что существуют неразрешенные конфликты, которые Git не удалось исправить. Я открываю Perforce или Visual Studio 2012, чтобы исправить конфликты, и графические инструменты показывают мне, что конфликтов нет и быстро выполняется слияние.

Имеет ли Git средство внутреннего обнаружения/слияния конфликтов, которое не зависит от вашего набора mergetool/difftool?

Или он использует настроенные инструменты для автоматического слияния и обнаружения неразрешимых конфликтов?

Мой сценарий странный, Git показывает, что он не может авторизоваться, но графические инструменты не показывают проблем.

4b9b3361

Ответ 1

Git имеет внутреннюю систему слияния, которая не зависит от difftool. В любом случае вы можете указать merge strategy с помощью параметра -s, из руководства:

-s <strategy>
--strategy=<strategy>

Использовать заданную стратегию слияния; могут быть предоставлены более одного раза, чтобы указать их в том порядке, в котором они должны быть проверены. Если нет -s вместо этого используется встроенный список стратегий (gitmerge-recursive при объединении одной головы, git merge-octopus в противном случае).

Стратегии идут от простого FastForward до Octopus при слиянии большого количества деревьев. Проверьте asnwer, чтобы узнать, как работают разные стратегии merge.

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

Ответ 2

Как Атропо заявляет в своем ответе,

Git имеет внутреннюю систему слияния, которая не зависит от difftool.

Итак, Git решает, когда изменение вызывает конфликт самостоятельно, а не используя какие-либо внешние инструменты для сравнения или слияния, которые вы используете (которые, вероятно, используют собственные стратегии обнаружения и разрешения конфликтов).

Согласно ответ VonC на Что представляет собой конфликт слияния в Git? (выделение мое)

Я не думаю, что алгоритм слияния имеет что-то особенное с Git: это классический трехсторонний алгоритм слияния (не Codeville one), который можно использовать с несколькими стратегиями (по умолчанию: рекурсия или разрешение или осьминог). Результатом является довольно простой процесс объединения, который описан здесь.
Любая потребность в визуализации затем делегируется сторонним средствам слияния/разметки.

В статье Википедии он ссылается на объяснение 3-way merge таким образом (внимание мое):

Трехстороннее слияние выполняется после автоматического анализа различий между файлом "A" и файлом "B", а также с учетом происхождения или общего предка обоих файлов. Это грубый метод слияния, но очень широко применимый, поскольку для восстановления изменений, которые необходимо объединить, требуется только один общий предок.

Трехстороннее слияние использует предок измененных файлов для идентификации блоков контента, которые были изменены ни в одной, ни в обеих производных версиях. Блоки, которые не изменились, остались такими же, как и они. Блоки, которые изменились только при использовании одной производной, которая изменила версию. Если блок изменен в обеих производных, измененная версия используется, если она имеет одинаковое содержимое с обеих сторон, но если изменения отличаются, то она помечена как конфликтная ситуация и остается для разрешения пользователем.

Трехстороннее слияние реализуется вездесущей программой diff3 и является центральной новинкой, которая позволила перейти от блокировки файлов основанные на управлении версиями, для систем контроля версий слияния. Он широко используется Система параллельных версий (CVS).

В статье также говорится о Рекурсивная трехсторонняя слияния, которую я вижу в Git много:

Широкое использование инструментов контроля версий с трехсторонним слиянием привело к возникновению случаев, когда простота трехстороннего слияния вызывает ложные конфликты и иногда молча возобновляет отмененные изменения. Примеры таких ситуаций включают criss-cross merges и трехсторонние конфликты переименований.

Проблемы трехстороннего слияния возникают в ситуациях, когда два производных состояния не имеют уникального последнего общего предка (LCA). Чтобы справиться с этими проблемами, рекурсивное трехстороннее слияние конструирует виртуального предка, сначала слияние неидеальных предков. Этот метод используется инструментом Git.

Рекурсивное трехстороннее слияние может использоваться только в ситуациях, когда инструмент имеет знания об общей генерации DAG (направленного ациклического графика) производных, подлежащих объединению. Следовательно, он не может использоваться в ситуациях, когда производные или слияния не полностью определяют их родителя (ов).

Ответ 3

Да, многие IDE и инструменты объединения будут выполнять автоматические разрешения конфликтов поверх git собственных.

Как видно из git help merge-file, git алгоритм разрешения конфликтов на складе для текстовых файлов довольно прост: diff chunks конфликтует, если они изменяют соседние строки. Если git не может автоматически разрешить конфликт таким образом, он помещает маркер текстового конфликта в формат, который был стандартным с дней RCS, и что среда IDE может забирать и работать (даже если она не работает не знаю о git):

<<<<<<<< Version identifier 1
Foo
=======
Bar
>>>>>>>> Version identifier 2

Я не использую Visual Studio, но быстрый Google сообщает мне, что у него есть функция автоматического разрешения конфликтов. (Я сам использую kdiff3, у которого свой собственный алгоритм автоматического разрешения конфликтов)

Ответ 4

Опубликовать здесь - лучший ответ, который я видел в стратегиях слияния git. И да, вы можете выбрать, какой из них вы хотите с помощью -s option

Но вы сомневаетесь, почему другие инструменты, такие как Visual Studio, сливают его, когда git не может. Visual Studio может иметь довольно агрессивную стратегию слияния - "функция автоматического слияния обычно не будет использовать какой-либо контент из вашей старой версии, потому что настройки по умолчанию для функции автоматического слияния благоприятствуют самому последнему файлу" см. здесь для получения дополнительной информации.

Чтобы узнать больше о инструменте слияния, который поставляется с VS 2012, см. эту публикацию, где Брайан Гарри погружается в то, как они считают "Минимальные конфликты" при слиянии "в качестве ключевой функции.

Что касается Perforce, я подозреваю, что у них есть аналогичная стратегия слияния - соединитель git to p4 должен использовать стратегии слияния perforce, чтобы понять, и я уверен, что они также более агрессивны.

"наш" может быть аналогичной агрессивной стратегией слияния в git.

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