git checkout
имеет --ours
возможность проверить версию файла, который вы имели локально (в отличие --theirs
от версии, которую вы извлекли). Вы можете перейти, .
чтобы git checkout
сказать это, чтобы проверить все в дереве. Затем вам нужно пометить конфликты как разрешенные, что вы можете сделать git add
, и зафиксировать свою работу после того, как закончите:
git checkout --ours . # checkout our local version of all files
git add -u # mark all conflicted files as merged
git commit # commit the merge
Обратите внимание .
на git checkout
команду. Это очень важно и легко пропустить. git checkout
имеет два режима; один, в котором он переключает ветви, и другой, в котором он извлекает файлы из индекса в рабочую копию (иногда сначала вытягивая их в индекс из другой ревизии). Это отличает то, передали ли вы имя файла; если вы не передали имя файла, он пытается переключить ветки (хотя, если вы не передаете и ветку, он просто попытается снова проверить текущую ветку), но он отказывается это делать, если есть измененные файлы. что это повлияет. Итак, если вы хотите поведение, которое будет перезаписывать существующие файлы, вам нужно передать .
или имя файла, чтобы получить второе поведение git checkout
.
Это также хорошая привычка иметь при передаче имени файла смещение --
, например git checkout --ours -- <filename>
. Если вы этого не сделаете, а имя файла совпадает с именем ветви или тега, Git подумает, что вы хотите проверить эту ревизию вместо того, чтобы проверить это имя файла, и, таким образом, использовать первую форму checkout
команды ,
Я немного подробнее расскажу о том, как конфликты и слияния работают в Git. Когда вы объединяете чужой код (который также происходит во время извлечения; извлечение - это, по сути, извлечение, за которым следует слияние), существует несколько возможных ситуаций.
Самое простое, что вы на одной ревизии. В этом случае вы «уже в курсе», и ничего не происходит.
Другая возможность состоит в том, что их ревизия просто является вашей наследницей, и в этом случае у вас по умолчанию будет «быстрое слияние», при котором ваше HEAD
обновление будет обновлено до их фиксации, без слияния (это можно отключить, если вы очень хочу записать слияние, используя --no-ff
).
Затем вы попадаете в ситуации, когда вам действительно нужно объединить две ревизии. В этом случае есть два возможных результата. Во-первых, слияние происходит чисто; все изменения находятся в разных файлах или в одних и тех же файлах, но достаточно далеко друг от друга, чтобы оба набора изменений можно было применить без проблем. По умолчанию, когда происходит чистое слияние, оно автоматически фиксируется, хотя вы можете отключить это с помощью, --no-commit
если вам нужно отредактировать это заранее (например, если вы переименуете функцию foo
в bar
, а кто-то еще добавит новый код, который вызывает foo
, она слится чисто , но создайте сломанное дерево, так что вы можете захотеть очистить его как часть коммита слияния, чтобы избежать каких-либо битых коммитов).
Последняя возможность состоит в том, что существует реальное слияние и возникают конфликты. В этом случае Git будет делать столько слияния , как он может, и создавать файлы с маркерами конфликтов ( <<<<<<<
, =======
и >>>>>>>
) в вашей рабочей копии. В индексе (также известном как «промежуточная область»; место, в котором хранятся файлы git add
перед их фиксацией), у вас будет 3 версии каждого файла с конфликтами; Существует исходная версия файла от предка двух ветвлений, которые вы объединяете, версия HEAD
(с вашей стороны слияния) и версия из удаленной ветки.
Чтобы разрешить конфликт, вы можете либо отредактировать файл, который находится в вашей рабочей копии, удалив маркеры конфликта и исправив код, чтобы он работал. Или вы можете проверить версию с одной или других сторон слияния, используя git checkout --ours
или git checkout --theirs
. После того, как вы поместили файл в нужное вам состояние, вы указываете, что завершили слияние файла, и он готов к фиксации с помощью git add
, а затем вы можете зафиксировать слияние с git commit
.