Разрешение конфликта Git с бинарными файлами
Я использую Git на Windows (msysgit), чтобы отслеживать изменения для некоторых дизайнерских работ, которые я делал.
Сегодня я работал на другом ПК (с удаленным репо brian
) и сейчас я пытаюсь объединить сделанные сегодня правки с моей обычной локальной версией на моем ноутбуке.
На моем ноутбуке я использовал git pull brian master
чтобы вытащить изменения в мою локальную версию. Все было хорошо, кроме основного документа InDesign - это выглядит как конфликт.
Версия на ПК (brian
) - последнее, что я хочу сохранить, но я не знаю, какие команды говорят репо об этом.
Я попытался напрямую скопировать файл на свой ноутбук, но это, кажется, нарушает весь процесс слияния.
Может кто-то указать мне верное направление?
9 ответов
git checkout
принимает --ours
или же --theirs
вариант для подобных случаев. Поэтому, если у вас конфликт слияния, и вы знаете, что просто хотите получить файл из ветви, в которую вы сливаете, вы можете сделать следующее:
$ git checkout --theirs -- path/to/conflicted-file.txt
использовать эту версию файла. Точно так же, если вы знаете, что хотите свою версию (а не ту, которая объединяется), вы можете использовать
$ git checkout --ours -- path/to/conflicted-file.txt
Вы должны разрешить конфликт вручную (перезаписать файл), а затем зафиксировать файл (независимо от того, скопировали ли вы его или использовали локальную версию) следующим образом
git commit -a -m "Fix merge conflict in test.foo"
Обычно Git автоматически выполняет коммитирование после слияния, но когда он обнаруживает конфликты, которые он не может решить самостоятельно, он применяет все обнаруженные патчи и оставляет остальное для разрешения и фиксации вручную. Страница Git Merge Man Page, Git-SVN Crash Course или эта запись в блоге могут пролить свет на то, как она должна работать.
Изменить: см. Пост ниже, вы на самом деле не должны копировать файлы самостоятельно, но можете использовать
git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.txt
выбрать версию файла, который вы хотите. Копирование / редактирование файла будет необходимо, только если вы хотите смешать обе версии.
Пожалуйста, отметьте ответ mipadis как правильный.
Вы также можете преодолеть эту проблему с
git mergetool
что приводит к git
для создания локальных копий конфликтующего двоичного файла и создания на них вашего редактора по умолчанию:
{conflicted}.HEAD
{conflicted}
{conflicted}.REMOTE
Очевидно, что вы не можете с пользой редактировать двоичные файлы в текстовом редакторе. Вместо этого вы копируете новый {conflicted}.REMOTE
подать {conflicted}
без закрытия редактора. Затем, когда вы закрываете редактор git
увидит, что недекорированная рабочая копия была изменена, и ваш конфликт слияния разрешен обычным способом.
Чтобы решить, сохранив версию в текущей ветке (игнорируйте версию из ветви, в которую вы объединяете), просто добавьте и зафиксируйте файл:
git commit -a
Чтобы решить эту проблему, перезаписав версию в вашей текущей ветке версией из ветви, в которую вы объединяете, вы должны сначала извлечь эту версию в ваш рабочий каталог, а затем добавить / зафиксировать ее:
git checkout otherbranch theconflictedfile
git commit -a
Ответ Мипади мне не помог, мне нужно было сделать следующее:
git checkout --ours path / to / file.bin
или, чтобы сохранить версию в:
git checkout - их путь / в / file.bin
затем
git add path / to / file.bin
И тогда я смог снова выполнить "git mergetool" и перейти к следующему конфликту.
От git checkout
документы
git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
--ours
--theirs
При проверке путей из индекса, проверьте этап # 2 (ours
) или № 3 (theirs
) для незавершенных путей.Индекс может содержать необъединенные записи из-за предыдущего неудачного слияния. По умолчанию, если вы попытаетесь извлечь такую запись из индекса, операция извлечения не будет выполнена и ничего не будет извлечено. С помощью
-f
будет игнорировать эти необработанные записи. Содержимое определенной стороны слияния можно извлечь из индекса с помощью--ours
или же--theirs
, С-m
изменения, внесенные в файл рабочего дерева, могут быть отклонены, чтобы заново создать исходный конфликтующий результат слияния.
Я столкнулся с похожей проблемой (желая получить коммит, включающий некоторые двоичные файлы, которые вызывали конфликты при объединении), но натолкнулся на другое решение, которое может быть полностью выполнено с использованием git (то есть не нужно вручную копировать файлы). Я подумал, что включу это сюда, так что, по крайней мере, я смогу вспомнить это в следующий раз, когда мне это понадобится.:) Шаги выглядят так:
% git fetch
Он выбирает последние коммиты из удаленного репозитория (вам может потребоваться указать имя удаленной ветви, в зависимости от ваших настроек), но не пытается объединить их. Записывает коммит в FETCH_HEAD
% git checkout FETCH_HEAD stuff/to/update
Это берет копию двоичных файлов, которые я хочу, и перезаписывает то, что находится в рабочем дереве с версией, извлеченной из удаленной ветви. git не пытается выполнить слияние, поэтому вы просто получаете точную копию двоичного файла из удаленной ветви. Как только это будет сделано, вы можете добавить / зафиксировать новую копию, как обычно.
Эта процедура предназначена для разрешения бинарных конфликтов после отправки запроса на загрузку в Github:
- Итак, на Github вы обнаружили, что ваш запрос на удаление конфликтует с двоичным файлом.
- Теперь вернитесь в ту же ветку git на вашем локальном компьютере.
- Вы (а) заново создаете / пересобираете этот двоичный файл и (б) фиксируете новый двоичный файл в той же самой ветке git.
- Вы снова толкаете эту самую ветку Git в Github.
На Github, по вашему запросу, конфликт должен исчезнуть.
Я сталкивался с двумя стратегиями управления diff / слиянием бинарных файлов с помощью Git на windows.
Tortoise git позволяет вам настраивать инструменты сравнения / слияния для разных типов файлов в зависимости от их расширений. См. 2.35.4.3. Дополнительные настройки Diff/Merge http://tortoisegit.org/docs/tortoisegit/tgit-dug-settings.html. Эта стратегия, конечно, зависит от наличия доступных инструментов сравнения / слияния.
Используя атрибуты git, вы можете указать инструмент / команду для преобразования вашего двоичного файла в текст, а затем позволить своему стандартному инструменту сравнения / слияния сделать свое дело. См. http://git-scm.com/book/it/v2/Customizing-Git-Git-Attributes. В статье даже приведен пример использования метаданных для сравнения изображений.
Я получил обе стратегии для работы с бинарными файлами моделей программного обеспечения, но мы пошли с git, так как конфигурация была простой.
Если двоичный файл представляет собой нечто большее, чем dll или что-то, что может быть отредактировано непосредственно, например, как изображение, или файл смешивания (и вам не нужно выбрасывать / выбирать один или другой файл), реальное слияние будет выглядеть примерно так:
Я предлагаю поискать разностный инструмент, ориентированный на ваш двоичный файл, например, есть несколько бесплатных для файлов изображений, например.
- npm install -g imagediff IIRC с https://github.com/uber/image-diff
- или питон https://github.com/kaikuehne/mirror.git
- есть и другие
и сравни их.
Если нет инструмента сравнения для сравнения ваших файлов, то, если у вас есть оригинальный генератор файла bin (то есть, существует редактор для него... как, например, blender 3d, вы можете вручную проверить эти файлы, а также посмотрите журналы и спросите другого человека, что вы должны включить) и выполните вывод файлов с помощью https://git-scm.com/book/es/v2/Git-Tools-Advanced-Merging
$ git show :1:hello.blend > hello.common.blend
$ git show :2:hello.blend > hello.ours.blend
$ git show :3:hello.blend > hello.theirs.blend
Я использую Git Workflow для Excel - приложение https://www.xltrail.com/blog/git-workflow-for-excel для решения большинства проблем слияния, связанных с моими двоичными файлами. Это приложение с открытым исходным кодом помогает мне продуктивно решать проблемы, не затрачивая слишком много времени, и позволяет мне без проблем выбрать нужную версию файла.
Мой случай выглядит как ошибка.... с помощью GIT 2.21.0
Я сделал тянуть... он жаловался на двоичные файлы:
warning: Cannot merge binary files: <path>
Auto-merging <path>
CONFLICT (content): Merge conflict in <path>
Automatic merge failed; fix conflicts and then commit the result.
И тогда ни в одном из ответов здесь не было никакого результата, который имел бы смысл.
Если я посмотрю, какой файл у меня сейчас... это тот, который я отредактировал. Если я сделаю либо:
git checkout --theirs -- <path>
git checkout --ours -- <path>
Я получаю вывод:
Updated 0 paths from the index
и у меня все еще есть моя версия файла. Если я произвожу, а затем оформлю заказ, вместо этого будет указано "1", но он все равно даст мне мою версию файла.
Git Mergetool говорит
No files need merging
и Git статус говорит
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Один из вариантов - отменить коммит... но мне не повезло, у меня было много коммитов, и этот плохой был первым. Я не хочу тратить время на это.
так что решить это безумие
Я только что побежал
git commit
который теряет удаленную версию и, вероятно, тратит место на хранение дополнительного двоичного файла... тогда
git checkout <commit where the remote version exists> <path>
который возвращает мне удаленную версию
затем снова отредактировал файл... и затем зафиксировал и нажал, что, вероятно, снова означает, что тратится место на другую копию двоичного файла.