Разрешение конфликта Git с двоичными файлами

Я использую Git в Windows (msysgit), чтобы отслеживать изменения в некоторых дизайнерских работах, которые я выполнял.

Сегодня я работал на другом ПК (с удаленным репозиторием brian), и теперь я пытаюсь объединить сделанные сегодня правки с моей обычной локальной версией на моем ноутбуке.

На моем ноутбуке я использовал git pull brian master, чтобы внести изменения в мою локальную версию. Все было хорошо, кроме основного документа InDesign - это видно как конфликт.

Версия на ПК (brian) - последняя, ​​которую я хочу сохранить, но я не знаю, какие команды говорят репо использовать эту.

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

Может кто-то указать мне верное направление?

Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
Принципы ООП в JavaScript
Принципы ООП в JavaScript
Парадигма объектно-ориентированного программирования имеет 4 основных принципа,
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Пройдите собеседование по Angular: Общие вопросы и ответы экспертов
Можете ли вы объяснить разницу между ngOnInit и конструктором в Angular?
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
491
0
193 729
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

Вы должны разрешить конфликт вручную (скопировав файл), а затем зафиксировать файл (независимо от того, скопировали ли вы его или использовали локальную версию), как это

git commit -a -m "Fix merge conflict in test.foo"

Обычно Git выполняет автоматическую фиксацию после слияния, но когда он обнаруживает конфликты, которые не может решить сам по себе, он применяет все найденные патчи, а остальные оставляет вам на разрешение и фиксацию вручную. Запись в блоге Страница Git Merge Man, Ускоренный курс Git-SVN или это может пролить свет на то, как это должно работать.

Редактировать: См. Сообщение ниже, на самом деле вам не нужно копировать файлы самостоятельно, но можно использовать

git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.txt

Чтобы выбрать нужную версию файла. Копирование / редактирование файла необходимо только в том случае, если вы хотите смешать обе версии.

Отметьте, пожалуйста, ответ мипади как правильный.

Спасибо за это. Я не был уверен, есть ли какой-то встроенный способ пометить файл как «правильный». Объясняет, почему я не смог найти несуществующую команду!

Kevin Wilson 10.11.2008 21:35

Да, это немного неинтуитивно - что-то вроде git resolve было бы неплохо, но также было бы дополнительным шагом ...

VolkA 10.11.2008 23:22

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

% git fetch

Это извлекает последние фиксации из удаленного репозитория (вам может потребоваться указать имя удаленной ветки, в зависимости от вашей настройки), но не пытается их объединить. Он записывает фиксацию в FETCH_HEAD

% git checkout FETCH_HEAD stuff/to/update

Это берет копию нужных мне двоичных файлов и заменяет то, что находится в рабочем дереве, версией, полученной из удаленной ветки. git не пытается выполнить какое-либо слияние, поэтому вы просто получаете точную копию двоичного файла из удаленной ветки. Как только это будет сделано, вы можете добавить / зафиксировать новую копию, как обычно.

Вы также можете решить эту проблему с помощью

git mergetool

Что заставляет git создавать локальные копии конфликтующего двоичного файла и запускать на них ваш редактор по умолчанию:

  • {conflicted}.HEAD
  • {conflicted}
  • {conflicted}.REMOTE

Очевидно, вы не можете с пользой редактировать двоичные файлы в текстовом редакторе. Вместо этого вы копируете новый файл {conflicted}.REMOTE поверх {conflicted}, не закрывая редактор. Затем, когда вы закроете редактор, git увидит, что недекорированная рабочая копия была изменена, и ваш конфликт слияния разрешен обычным способом.

Если файлы большие или вы вообще не хотите рисковать открывать двоичный файл в текстовом редакторе, вы можете нажать ctrl + c в приглашении mergetool («Hit return to start merge resolution tool»), и git оставит лишние файлы на месте. Затем вы можете изменить их или объединить во внешнем инструменте (полезно для двоичных форматов документов, таких как LibreOffice / OpenOffice / MSWord) и сохранить результат обратно с исходным именем файла. Чтобы сообщить git, что конфликт разрешен, укажите исходное имя файла git add, и затем вы можете завершить фиксацию слияния.

Felix 25.08.2015 00:54

Чтобы решить эту проблему, сохранив версию в вашей текущей ветке (игнорируйте версию из ветки, в которую вы выполняете слияние), просто добавьте и зафиксируйте файл:

git commit -a

Чтобы решить эту проблему путем перезаписи версии в текущей ветке версией из ветки, в которую вы выполняете слияние, вам необходимо сначала получить эту версию в свой рабочий каталог, а затем добавить / зафиксировать ее:

git checkout otherbranch theconflictedfile
git commit -a

Объяснил более подробно

Я предпочитаю этот вариант принятому ответу, потому что он более интуитивно понятен, особенно с учетом того, что значение этих «--our» и «--theirs» меняется местами в случае перебазирования.

Antony Hatchkins 22.05.2020 18:47
Ответ принят как подходящий

Git checkout принимает вариант --ours или --theirs для подобных случаев. Итак, если у вас есть конфликт слияния, и вы знаете, что вам просто нужен файл из ветки, в которую вы сливаете, вы можете сделать:

$ git checkout --theirs -- path/to/conflicted-file.txt

Чтобы использовать эту версию файла. Точно так же, если вы знаете, что хотите свою версию (а не ту, которая объединяется), вы можете использовать

$ git checkout --ours -- path/to/conflicted-file.txt

Мне пришлось запустить 'git reset HEAD path / to / Conflict-file.txt' в файле перед использованием --ours, иначе это, похоже, не имело никакого эффекта.

Zitrax 13.10.2011 17:48

@Zitrax Вы изменили файл после запуска git checkout --ours? На странице руководства предлагается (IMHO), что checkout --ours / - theirs удалит изменение из списка «оба изменено, нужно объединить» и добавит его в индекс, и я думаю, что это неверно. Я считаю, что вам нужно будет запустить git add после оформления заказа.

Tim Keating 14.05.2013 01:06

Примечание: вы по-прежнему хотите использовать «git add конфликтующий-файл.txt» и «git commit». К счастью, когда я попробовал это, сообщение фиксации было предварительно заполнено примечанием о конфликте.

Edward Falk 26.07.2014 02:34

Фраза «ветка, в которую вы сливаетесь» опасно близка к «ветке, в которую вы сливаетесь», я думаю, что было бы лучше просто отбросить предлог: «ветка, которую вы объединяете», что также отражало бы команду git (т.е. git merge branch_name).

andrybak 07.06.2016 15:12

Пара важных моментов, которых всегда не хватает в объяснениях по этой теме. При выполнении rebase вместо слияния значения --their и --ours меняются местами, то есть --their == текущая проверенная ветка, а --ours - это ветка, обычно удаленная ветка или спецификация пути, в которую вы пытаетесь слиться. текущая ветка. Параметр [space]--[space] устраняет неоднозначность в спецификации пути между именем ветки и спецификацией пути, которые существуют с одним и тем же именем (например, существующее имя ветки - «abc», а каталог существует с именем «abc»).

BoiseBaked 09.12.2016 19:54

Если вы уже знаете, что вам нужна ветвь весь - не конкретные файлы - тогда обратите внимание, что вы можете просто указать, например, git checkout --ours .… и если вы хотите все этих изменений git add ., прежде чем продолжить то, что вы делали. (перебазирование, слияние, сбор вишен и т. д.)

PDK 11.04.2017 14:42

Я так сильно хотел этим воспользоваться, так как слышал об этом методе, но у меня он не сработал? Пытался разрешить конфликт в двух файлах .png. Разница показала двоичную разницу. Кто-нибудь знает, почему в таком случае это не сработало?

ArielSD 16.01.2018 19:18

Даже после git checkout --theirs я получаю warning: Cannot merge binary files: при попытке git pull.

René Nyffenegger 09.04.2018 20:40

Это не работает, если файл был удален в одном репо.

Sören 11.12.2018 23:30

С git checkout документы

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>... --ours --theirs When checking out paths from the index, check out stage #2 (ours) or #3 (theirs) for unmerged paths. The index may contain unmerged entries because of a previous failed merge. By default, if you try to check out such an entry from the index, the checkout operation will fail and nothing will be checked out. Using -f will ignore these unmerged entries. The contents from a specific side of the merge can be checked out of the index by using --ours or --theirs. With -m, changes made to the working tree file can be discarded to re-create the original conflicted merge result.

Ответ mipadi не совсем сработал для меня, мне нужно было сделать это:

git checkout --ours path/to/file.bin

Или, чтобы сохранить объединяемую версию:

git checkout --theirs path/to/file.bin

Потом

git add path/to/file.bin

А потом я снова смог выполнить "git mergetool" и перейти к следующему конфликту.

Я столкнулся с двумя стратегиями управления различием / объединением двоичных файлов с помощью 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#_manual_remerge

$ 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 for Excel - приложение https://www.xltrail.com/blog/git-workflow-for-excel для решения большинства проблем слияния, связанных с моими двоичными файлами. Это приложение с открытым исходным кодом помогает мне эффективно решать проблемы, не тратя слишком много времени, и позволяет мне выбирать правильную версию файла без каких-либо затруднений.

Эта процедура предназначена для разрешения конфликтов двоичных файлов после того, как вы отправили запрос на перенос в Github:

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

В Github по вашему запросу на вытягивание конфликт должен исчезнуть.

Мой случай кажется ошибкой .... используя 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

И у меня все еще есть моя версия файла. Если я rm, а затем оформлю заказ, вместо этого он скажет 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>

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

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

В моем случае после попытки git checkout --ours <path> я получил Updated 0 paths from the index . Я исправил это с помощью команды git add <path>, которая делает то же самое.

Andriy 07.03.2020 16:30

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