Есть ли способ заставить Git лучше обрабатывать символические ссылки во время слияния?
Не совсем, нет.Если два добавленных файла имеют одинаковое содержимое, Git вообще не называет это конфликтом (я только что это проверил), и слияние завершается успешно.
В конечном счете, проблема заключается в том, чтосимволическая ссылка - это файл данных, целью которого является ссылка, которая представляет собой всего одну строку (без завершающей строки!).Однако операционная система с достаточной связью хранит эти данные специально и может только обращаться к ним специально.(Windows обычно не достаточно link-y и вместо этого сохраняет его в виде простого текстового файла.) Итак, предположим, что две символические ссылки в двух файлах для объединения, которые находятся в двух коммитах, отличаются от исходной символической ссылки.в исходном коммите:
merge base: file foo should be a symlink to bar/baz
--ours: file foo should be a symlink to our/name
--theirs: file foo should be a symlink to different/path
Поскольку все это одна строка, Git не может объединить эти два изменения, которые оба изменяют одну и ту же исходную строку - строка 1 является строкой only - изфайл базы слияния.Вы должны объединить их вручную.
(В вашем случае вообще нет записи на этапе 1, только этапы 2 и 3, следовательно, «конфликт добавления / добавления», который я называю максимумом конфликт уровня , который никогда не входит в низкоуровневый код слияния файлов. Приведенное ниже описание предназначено в большей степени для случаев конфликтов низкого уровня, которые также могут возникать, и где -X ours
или -X theirs
могут работать.конфликты высокого уровня, Git никогда не попадает в код обработки -X
.)
Когда я сделал git ls-files --stage
для каждой предполагаемой символической ссылки, он показывал режим как 100644 (т.е. простой файл, а не символическая ссылка).
Возможно, это ошибка.Замечу, что когда я попробовал это в качестве эксперимента, я не получил:
$ git ls-files --stage
100644 79f977c119cd6951428b04565177cb4e53dd4bc3 0 README
100644 fa49b077972391ad58037050f2a75f74e3671e92 0 newfile
120000 1b407f24bddc88f87d93302f462251bf881acbc9 2 newlink
120000 1de565933b05f74c75ff9a6520af5f9f8a5a2f1d 3 newlink
Обратите внимание на строки mode 120000
здесь.Символическая ссылка остается символической ссылкой и в моем рабочем дереве:
$ ls -l newlink
lrwxr-xr-x 1 torek torek 9 Feb 5 00:55 newlink -> newtarget
Если бы в базе слияния существовала третья (другая) символическая ссылка, я не уверен, что Git сохранит мой файл рабочего дерева какsymlink.
(я ожидаю, что git mergetool
приведет к извлечению этих двух файлов в виде простых файлов:
$ git checkout-index --temp --stage 2 newlink
.merge_link_OzyiFR newlink
, поэтому, если вы используете git mergetool
, это ошибка git mergetool
здесьДействительно, но это не должно быть в состоянии установить режим ввода индекса на 100644
.)
Если git rebase
или git merge
вызывает конфликты и изменяет символические ссылки на простые файлы,Есть ли лучший способ решить проблему, чем удаление каждого файла и воссоздание символической ссылки?
Не совсем, нет.Вы должны выбрать , какую ссылку (нашу или их), чтобы отдать предпочтение, если либо одно, либо даже третье значение (возможно, возвращаясь к базовой версии слияния или к еще одному пути).
Обратите внимание, что не получит конфликт слияния, если только одна «сторона» (наша или их) изменит цель ссылки.В этом случае либо база слияния с нашей совпадает, поэтому Git принимает их изменение, либо база слияния с их совпадает, поэтому Git принимает наши изменения - точно так же, как и для любого обычного файла.(См. раздел трехстороннего слияния git read-tree
документации .)
Логически -X ours
или -X theirs
должны разрешать конфликт автоматически, но только в случаенастоящее трехстороннее слияние.Когда возникает конфликт добавления / добавления (поскольку цели двух символических ссылок в двух коммитах с подсказками различаются, а символическая ссылка вообще отсутствует в базе), мы никогда не доберемся до этой точки, и -X
не сможет помочь.