Вирішення конфлікту Git з бінарними файлами


464

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

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

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

Версія на ПК ( brian) - це остання версія, яку я хочу зберегти, але я не знаю, які команди вказують repo використовувати цю.

Я спробував безпосередньо скопіювати файл на свій ноутбук, але це, здається, порушило весь процес злиття.

Чи може хтось вказати мене в правильному напрямку?

Відповіді:


853

git checkoutприймає --oursабо --theirsваріант для таких випадків. Отже, якщо у вас конфлікт злиття, і ви знаєте, що просто хочете, щоб файл із гілки, в яку ви зливаєтеся, ви можете:

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

використовувати цю версію файлу. Так само, якщо ви знаєте, що хочете, щоб ваша версія (а не та, в яку об’єдналася), ви можете використовувати

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

47
Мені довелося виконати "git reset HEAD path / to / конфліктувати-file.txt" у файлі, перш ніж використовувати --ours, інакше це, здається, не матиме ефекту.
Zitrax

6
@Zitrax Ви відрізняли файл після запуску git checkout --ours? Сторінка man пропонує (IMHO), що замовлення --ours / - njihovo видалить зміну зі списку "і модифіковані, потребують об'єднання", і додасть її до індексу, і я вважаю, що це неправильно. Я вірю, що вам потрібно буде бігти git addпісля оформлення каси.
Тім Кітінг

15
Примітка. Ви все ще хочете зробити "git add configled-file.txt " та "git commit". Зручно, коли я спробував це, повідомлення про вчинення було попередньо заповнене приміткою про конфлікт.
Едвард Фолк

2
фразування "гілки, в яку ви зливаєтеся" небезпечно близька до "гілки, в яку ви зливаєтесь", я думаю, що краще просто відкинути прийменник: "гілка, яку ви зливаєте", що також відображатиме команду git (тобто git merge branch_name).
andrybak

13
Кілька важливих моментів, яких завжди не вистачає в поясненнях цієї теми. Виконуючи ребауз замість злиття, значення --theirі --oursзмінюються, тобто --their == поточно перевірена гілка та --ours - це гілка, як правило, віддалена гілка або специфікація шляху, яку ви намагаєтеся об'єднати в поточну відділення. В [space]--[space]опції усуває неоднозначність на шляху специфікацію між ім'ям гілки і шляхом специфікацією , що і трапляються, існує з тим же ім'ям (наприклад , ім'я існуючої гілки «а» і каталог існує під назвою «ABC»).
BoiseBaked

147

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

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

щоб вибрати версію потрібного файлу. Копіювати / редагувати файл буде потрібно лише в тому випадку, якщо ви хочете поєднати обидві версії.

Будь ласка, позначте відповідь mipadis як правильну.


1
Дякую за це. Я не був впевнений, чи існує якийсь вбудований спосіб позначити файл як "правильний". Пояснює, чому я не зміг знайти неіснуючу команду!
Кевін Вілсон

Так, це трохи неінтуїтивно - щось на кшталт git
resolution

120

Ви також можете подолати цю проблему

git mergetool

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

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

Очевидно, ви не можете корисно редагувати файли бінарних файлів у текстовому редакторі. Натомість ви копіюєте нове{conflicted}.REMOTE файл, {conflicted}не закриваючи редактор. Потім, коли ви закриєте редактор, gitви побачите, що незадекларована робоча копія була змінена і ваш конфлікт злиття вирішений звичайним чином.


8
Якщо файли великі або ви взагалі не хочете ризикувати відкриттям бінарного файлу в текстовому редакторі, ви можете натиснути ctrl + c у запиті mergetool (" Hit return to start merge resolution tool") і git залишить зайві файли на місці. Потім ви можете змінити їх або об'єднати у зовнішній інструмент (корисний для бінарних форматів документів, таких як LibreOffice / OpenOffice / MSWord) і зберегти результат назад до початкового імені файлу. Щоб повідомити git про вирішення конфлікту, git addоригінальне ім'я файлу, і ви зможете закінчити комісію об'єднання.
Фелікс

18

Щоб вирішити проблему, зберігаючи версію у вашій поточній гілці (ігноруйте версію з гілки, в яку ви об'єднуєтесь), просто додайте та введіть файл:

git commit -a

Щоб вирішити проблему, замінивши версію у вашій поточній гілці та версію з гілки, в яку ви об'єдналися, потрібно спочатку завантажити цю версію у свій робочий каталог, а потім додати / ввести її:

git checkout otherbranch theconflictedfile
git commit -a

Пояснюється більш докладно


1
Я віддаю перевагу такому варіанту над прийнятою відповіддю, оскільки він більш інтуїтивний, особливо зважаючи на те, що значення тих "- своїх" та "- їхніх" змінюється в разі відмови.
Ентоні Хеткінс

11

Відповідь mipadi не дуже працювала для мене, мені потрібно було це зробити:

git checkout - ваш шлях / до / file.bin

або, щоб зберегти версію об'єднання в:

git checkout - їх шлях / до / file.bin

тоді

git додати шлях / до / file.bin

І тоді мені вдалося знову зробити "git mergetool" і продовжити наступний конфлікт.


6

Від git checkoutдок

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...

--ours
--theirs
Перевіряючи шляхи з індексу, перевірте етап №2 ( ours) або №3 (theirs ) для безперебійних шляхів.

Індекс може містити незаряджені записи через попереднє невдале злиття. За замовчуванням, якщо ви спробуєте перевірити такий запис з індексу, операція оформлення каси завершиться невдало, і нічого не буде перевірено. Використання -fбуде ігнорувати ці незареєстровані записи. Вміст з певної сторони злиття можна перевірити з індексу за допомогою --oursабо --theirs. З -m, зміни, внесені до файлу робочого дерева, можуть бути відхилені, щоб відновити вихідний конфліктний результат злиття.


4

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

% git fetch

Це вибирає останні віддані комісії з віддаленого сховища (можливо, вам потрібно буде вказати назву віддаленої гілки залежно від вашої установки), але не намагається їх об'єднати. Він записує фіксацію в FETCH_HEAD

% git checkout FETCH_HEAD stuff/to/update

Для цього потрібна копія бінарних файлів, які я хочу, і перезаписується те, що знаходиться в робочому дереві, з версією, отриманою з віддаленої гілки. git не намагається робити злиття, тому ви просто отримаєте точну копію бінарного файлу з віддаленої гілки. Після цього ви можете додати / ввести нову копію так само, як звичайну.


4

Ця процедура полягає у вирішенні конфліктів бінарних файлів після того, як ви надіслали Github запит на витягнення:

  1. Тож у Github ви виявили, що у вашому запиті на виклик є конфлікт у двійковому файлі.
  2. Тепер поверніться до тієї ж гілки git на вашому локальному комп’ютері.
  3. Ви (a) повторно зробите / перетворите цей бінарний файл знову і (b) зафіксуєте отриманий бінарний файл у цій самій гітці git.
  4. Потім ви знову натискаєте цю саму гіт-гіт до Github.

У Github, на ваш запит на притягнення, конфлікт повинен зникнути.


Саме ця процедура мені потрібна
Huifang Feng

2

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

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

і порівняти їх.

Якщо там не існує різного інструменту для порівняння ваших файлів, то якщо у вас є оригінальний генератор бін-файлу (тобто існує редактор для нього ... як 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


1

Я зіткнувся з двома стратегіями управління різними / об'єднаними бінарними файлами з Git на windows.

  1. Tortoise git дозволяє налаштувати інструменти diff / merge для різних типів файлів на основі їх розширень. Див. 2.35.4.3. Розширені налаштування відмінності / об'єднання http://tortoisegit.org/docs/tortoisegit/tgit-dug-settings.html . Ця стратегія, звичайно, спирається на наявні підходящі інструменти різного / злиття.

  2. Використовуючи атрибути git, ви можете вказати інструмент / команду для перетворення вашого бінарного файлу в текст, а потім дозволити вашому інструменту diff / spajanje за замовчуванням зробити це річ. Див. Http://git-scm.com/book/it/v2/Customizing-Git-Git-Attributes . У статті навіть наведено приклад використання метаданих для розходження зображень.

У мене були обидві стратегії роботи з бінарними файлами моделей програмного забезпечення, але ми працювали з черепаховим git, оскільки конфігурація була простою.


0

Я використовую Git Workflow для Excel - https://www.xltrail.com/blog/git-workflow-for-excel, щоб вирішити більшість моїх бінарних файлів, пов'язаних з проблемами злиття. Цей додаток з відкритим кодом допомагає мені продуктивно вирішувати проблеми, не витрачаючи занадто багато часу, і дозволяє мені вишнево без будь-якої плутанини вибрати правильну версію файлу.


0

мій випадок здається помилкою .... за допомогою 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>команди, яка робить те саме.
Андрій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.