Разрешение конфликта 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:

  1. Итак, на Github вы обнаружили, что ваш запрос на удаление конфликтует с двоичным файлом.
  2. Теперь вернитесь в ту же ветку git на вашем локальном компьютере.
  3. Вы (а) заново создаете / пересобираете этот двоичный файл и (б) фиксируете новый двоичный файл в той же самой ветке git.
  4. Вы снова толкаете эту самую ветку Git в Github.

На Github, по вашему запросу, конфликт должен исчезнуть.

Я сталкивался с двумя стратегиями управления diff / слиянием бинарных файлов с помощью Git на windows.

  1. Tortoise git позволяет вам настраивать инструменты сравнения / слияния для разных типов файлов в зависимости от их расширений. См. 2.35.4.3. Дополнительные настройки Diff/Merge http://tortoisegit.org/docs/tortoisegit/tgit-dug-settings.html. Эта стратегия, конечно, зависит от наличия доступных инструментов сравнения / слияния.

  2. Используя атрибуты git, вы можете указать инструмент / команду для преобразования вашего двоичного файла в текст, а затем позволить своему стандартному инструменту сравнения / слияния сделать свое дело. См. http://git-scm.com/book/it/v2/Customizing-Git-Git-Attributes. В статье даже приведен пример использования метаданных для сравнения изображений.

Я получил обе стратегии для работы с бинарными файлами моделей программного обеспечения, но мы пошли с git, так как конфигурация была простой.

Если двоичный файл представляет собой нечто большее, чем dll или что-то, что может быть отредактировано непосредственно, например, как изображение, или файл смешивания (и вам не нужно выбрасывать / выбирать один или другой файл), реальное слияние будет выглядеть примерно так:

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

и сравни их.

Если нет инструмента сравнения для сравнения ваших файлов, то, если у вас есть оригинальный генератор файла 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>

который возвращает мне удаленную версию

затем снова отредактировал файл... и затем зафиксировал и нажал, что, вероятно, снова означает, что тратится место на другую копию двоичного файла.

Другие вопросы по тегам