В настоящее время принято решение об этом трехмерном алгоритме слияния (возможно, с такими усовершенствованиями, как обнаружение переименования и обработка более сложной истории), в котором учитывается версия текущей ветви ('ours'), версия на объединенная ветвь («их»), а версия общего предка объединенных ветвей («предок») (с практической точки зрения) - лучший способ разрешить слияния. В большинстве случаев и для большей части уровня дерева дерева слияния (какая версия файла требуется) достаточно; редко приходится сталкиваться с конфликтами содержимого, а затем алгоритм diff3 достаточно хорош.
Чтобы использовать трехстороннее слияние, вам необходимо знать общий предок объединенных ветвей (co called base merge base). Для этого вам необходимо знать История между этими ветвями. То, что Subversion до (текущей) версии 1.5 отсутствовало (без сторонних инструментов, таких как SVK или svnmerge), было отслеживание слияния, т. Е. Запоминание для того, чтобы слияние зафиксировало, какие родители (что совершает) использовались в слиянии. Без этой информации невозможно правильно подсчитать общего предка при наличии повторных слияний.
Примите за счет следующей диаграммы:
---.---a---.---b---d---.---1
\ /
\-.---c/------.---2
(который, вероятно, получить искаженное ... было бы неплохо иметь возможность рисовать ASCII-арт диаграммы здесь).
Когда мы сливали коммиты 'b' и 'c' (создавая commit 'd'), общим предком была точка ветвления, commit 'a'. Но когда мы хотим объединить коммиты '1' и '2', теперь общим предком является commit 'c'. Не сохраняя информацию о слиянии, мы должны были бы ошибочно заключить, что это commit 'a'.
Subversion (до версии 1.5) и более ранние CVS, сделанные слиянием, потому что вам приходилось самостоятельно вычислять общего предка и давать информацию о предке вручную при выполнении слияния.
Git хранит информацию обо всех родителях фиксации (более одного родителя в случае слияния) в объекте commit. Таким образом вы можете сказать, что Git хранит DAG (прямой ациклический график) изменений, хранения и запоминания отношений между коммитами.
(я не уверен, как Subversion сделок с указанными ниже вопросами)
Кроме того, сливающихся в Git может иметь дело с двумя дополнительными вопросами осложнений: файл переименовывается (когда одна сторона переименованный файл , а другие нет, мы хотим получить переименование, и мы хотим получить изменения, применяемые к правильному файлу) и criss-cross объединяет (более сложная история, когда есть более одного общего предка).
- Файл переименовывает во время слияния управляется с помощью эвристического счет сходства на основе (как подобие содержимого файла и подобие имени пути учитывается) обнаружения переименования. Git определяет, какие файлы соответствуют друг другу в объединенных ветвях (и предках). На практике это работает достаточно хорошо для случаев реального мира.
- крест-накрест сливается см definition at revctrl.org wiki, (и наличие нескольких слияния база) управляются с помощью рекурсивной стратегии слияния, который генерирует один виртуальный общий предок.
В ответ на: «SVN сделал разветвление намного проще, сделав ветки действительно дешевыми». Вы уверены, что случайно не заменили Git на SVN? Я знаю, что одна из больших возможностей Git - это дешевое разветвление ... Я слышал, что ветвление в SVN - это кошмар, потому что большая часть из них является ручной (создайте новый каталог с разветвленным контентом и т. Д.). – Stunner