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

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

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

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

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

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

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
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

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

Как разрешить конфликты слияния в репозитории Git?
Могу ли я проверить конфликтное состояние файла во время разрешения конфликта слияния в Git?
Не могу заставить конфликт слияния появиться локально, но Azure devops говорит, что у меня конфликт?
Git merge commit потерял родителя, теперь мне снова нужно разрешать старые конфликты
Ошибка Databricks: невозможно выполнить слияние, так как несколько исходных строк совпали и попытались изменить одну и ту же целевую строку в разностной таблице конфликтующим образом
GitLab говорит, что конфликты слияния должны быть разрешены, но конфликтов нет
Git/Bitbucket – Как объединить новую ветку с мастером, не меняя HEAD?
Почему в моем мерж-реквесте отображаются «дополнения», которые уже есть в моей целевой ветке в GitLab?
Исправление плохого разрешения конфликтов после неправильного слияния из master в мою ветку функций
Как я могу решить эту проблему конфликта yarn.lock?