TL;DR
В вашем Git недостаточно информации, чтобы превратить патч в трехстороннее слияние. Без незавершенного трехстороннего слияния в вашем индексе вашему git mergetool
не за что будет цепляться. Возможно, вам придется вручную применить патч.
(Помните, что индекс здесь также называется индексом и кэшем, и он используется для разрешения конфликтов во время трехстороннего слияний. В случаях, когда не требуется трехстороннее слияние, в индексе хранятся только те файлы, которые вы создаете для следующего git commit
. Во время конфликтного слияния в индексе сохраняется еще больше файлов.)
Если вы git fetch
из одного репозитория (тот, что в 1
) в другой (2
), вы можете git cherry-pick
выполнить рассматриваемую фиксацию, как max630 предложено в комментарии. То есть, находясь в репозитории 2, вы можете либо добавить репозиторий 1 в качестве удаленного:
git remote add <name> <path-to-repo-1>
а затем git fetch
из него, как и с любого другого удаленного устройства, или вы можете использовать старый (стиль Git 1.5) синтаксис git fetch <path>
для временного получения всех доступных объектов из репо-1, а затем выбрать вишню по хэш-идентификатору.
Если это по-прежнему не работает (но будет) или неудобно по какой-либо другой причине, вам придется установить исправление вручную. Рассмотрите возможность использования git apply --reject
с последующей ручной очисткой.
Длинная
Это сообщение об ошибке говорит нам — хорошо, говорит мне — что происходит:
fatal: sha1 information is lacking or useless (path/to/conflicted/file).
Вы используете git format-patch
и git am
для переноса одного исправления1 из одного репозитория Git в другой, так же, как люди обычно используют (или использовали в прошлом) git format-patch
для исправления по электронной почте между сайтами, которые не имеют другого сетевого подключения. Когда Git делает такой патч, он включает в набор изменений для самой фиксации строку index
над каждым патчем файла:
diff --git a/Documentation/RelNotes/2.17.0.txt b/Documentation/RelNotes/2.17.0.txt
index 7001dbbf8..c828d3734 100644
Эта строка указателя предоставляет — по крайней мере потенциально — информацию, необходимую Git для создания полного трехэтапного слияния, если это возможно. Добавление --full-index
к параметрам исправления формата делает строку index
длиннее:
index 7001dbbf88b7ea5822eb0b798ac983505c57b3dc..c828d37345224550540a1665aaed2566d5bcb40e 100644
Теперь два хэша стали значительно лучше; это может помочь в некоторых случаях. Но что они являются?
Эти два хэш-идентификатора представляют собой хэш-идентификаторы больших двоичных объектов файлов, хранящихся в репозитории, — фактическое содержимое файлов «до» и «после». Фрагменты различий, которые следуют за этой строкой, дают инструкции: если вы измените эти строки в исходном BLOB-объекте (файле), используя эти строки замены, вы превратите исходный BLOB-объект — содержимое с левым хэшем. — в новый большой двоичный объект, содержимое которого названо правым хешем.
Когда вы передаете этот diff в git apply
,2, возможно, что файл в HEAD
больше не соответствует или даже сильно напоминает в некоторых частях "исходный блоб" в патче. В этом случае строки контекста не будут совпадать и/или раздел «до» нигде в файле не появится. Прямое применение патча становится невозможным.
Если вы указали флаг --3way
или -3
для git apply
— и git am
делает это — Git теперь может использовать информацию в строке index
. Поскольку первый хеш — это хэш большого двоичного объекта фактического содержимого файла в репозитории, создавшем набор изменений, ваш собственный Git может просмотреть ваш собственный репозиторий, чтобы узнать, есть ли у вас большой двоичный объект с этим хэш-идентификатором. . Если это так, у вас уже есть исходный файл.3 Git может просто извлечь этот файл и исправить его на месте, чтобы создать «после исправления». версия.
Теперь в Git есть все три версии файла: базовая версия, полученная с помощью хэш-идентификатора «до» и случайно найденная в вашем репозитории; "их" версия, полученная путем применения патча к базовой версии; и «наша» версия, которая является файлом в текущем или HEAD
коммите. Таким образом, Git теперь может поместить все три версии в ваш индекс, и теперь возможно трехстороннее слияние.
С другой стороны, возможно, что хэш-идентификатор большого двоичного объекта в строке index
не соответствует ни одному объекту в вашем репозитории. В этом случае у вас нет «до» версии файла. Невозможно сделать трехстороннее слияние. Или возможно, хотя и маловероятно,4, что у вас есть укороченный хеш большого двоичного объекта, который соответствует более чем одному большому двоичному объекту в вашем репозитории. В этом случае у вас может быть версия файла "до", но Git не знает наверняка и не будет пытаться определить, является ли какое-либо из этих больших двоичных объектов правильным.
В любом случае, поскольку у вашего Git недостаточно информации для попытки трехстороннего слияния, он не пытается пытаться, оставляя вас в этой ситуации. В конце концов, используя git fetch
и git cherry-pick
, вы можете получить настоящее трехстороннее слияние. Истории даже не должны быть связаны, так как вишневый выбор заставляет базу слияния быть родителем выбираемого коммита.
1Это также работает для набора исправлений, но директивы format-patch показывают, что это всего лишь одно исправление.
2Обратите внимание, что git am
— это, по сути, просто оболочка, которая запускает git apply
для каждого патча, за которым следует git commit
результата.
3Помните, что Git работает исходя из того, что поскольку вы загружаете патч в git am
, у вас нет копии другого репозитория. Кто-то еще отправил вам по электронной почте патч. Только у они есть этот репозиторий; у вас есть только ваш репозиторий. Здесь это не так — у вас есть оба репозитория, но Git этого не знает!
4Вероятность зависит от количества объектов BLOB-объектов в вашем репозитории и длины укороченного хэша. В Git теперь есть код для автоматического выбора подходящей длины сокращенного хэша, но это работает на основе количества объектов в репозитории, в котором создается разница, а не на количестве объектов в принимающем репозитории. . Если принимающий репозиторий значительно больше, отправитель может не предложить достаточно длинный хэш. Более старые версии Git также не имеют этого автоматического вычисления и по умолчанию просто безоговорочно используют 28-битный хэш; это может быть слишком коротко.
person
torek
schedule
06.04.2018
git-am
, кажется, использует совсем другую реализацию, чем выбор вишни, и, по моему опыту, работает намного хуже. Неужели нельзя получить из исходного репозитория, а затем использовать обычный выбор вишни? - person max630   schedule 06.04.2018