2010-01-15 3 views
167

У меня есть локальные файлы, я вытаскиваю из удаленной ветви, и есть конфликты. Я знаю, что хотел бы сохранить локальные изменения и игнорировать удаленные изменения, вызывающие конфликты. Есть ли команда, которую я могу использовать, чтобы сказать «отметьте все конфликты как разрешенные, используйте локальные»?Как я могу удалить удаленные изменения и пометить файл как «разрешенный»?

+0

Ответ, приведенный ниже, был очень освещен для меня. Есть несколько тонких моментов, которые сделали для меня действительно ясными, я рекомендую всем пользователям, не являющимся экспертами GIT, прочитать все комментарии ниже сообщения ниже и поблагодарить Брайана! – BoomTownTech

ответ

286

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 команда.

Я расскажу о том, как конфликты и merging работают в Git. Когда вы сливаетесь в чей-то код (что также происходит во время pull, pull - это по существу выборка, за которым следует слияние), существует несколько возможных ситуаций.

Проще всего то, что вы в той же ревизии. В этом случае вы «уже обновлены», и ничего не происходит.

Другая возможность заключается в том, что их пересмотр является просто вашим потомком, и в этом случае вы по умолчанию будете иметь «ускоренное слияние», в котором ваш HEAD будет просто обновлен до их фиксации без какого-либо слияния (это может быть отключен, если вы действительно хотите записать слияние, используя --no-ff).

Затем вы попадаете в ситуации, когда вам действительно нужно объединить две ревизии. В этом случае возможны два возможных результата. Во-первых, слияние происходит чисто; все изменения находятся в разных файлах или находятся в одних и тех же файлах, но достаточно далеко друг от друга, что оба набора изменений могут быть применены без проблем. По умолчанию, когда происходит чистое слияние, оно автоматически фиксируется, хотя вы можете отключить его с помощью --no-commit, если вам нужно его предварительно отредактировать (например, если вы переименовали функцию foo на номер bar, а кто-то еще добавляет новый код, который вызывает foo, он будет сливаться чисто, но создает сломанное дерево, поэтому вы можете очистить его как часть слияния, чтобы избежать каких-либо сломанных коммитов).

Окончательная возможность заключается в том, что существует реальное слияние, и есть конфликты.В этом случае Git будет выполнять как можно больше слияния и создавать файлы с маркерами конфликтов (<<<<<<<, ======= и >>>>>>>) в вашей рабочей копии. В индексе (также называемом «промежуточной областью», где файлы хранятся на git add перед их выполнением), у вас будет 3 версии каждого файла с конфликтами; есть оригинальная версия файла от предка двух разделяемых вами ветвей, версия от HEAD (ваша сторона слияния) и версия из удаленной ветви.

Чтобы разрешить конфликт, вы можете либо отредактировать файл, который находится в вашей рабочей копии, удалив маркеры конфликтов и зафиксировав код, чтобы он работал. Или вы можете проверить версию с одной или с другой стороны слияния, используя git checkout --ours или git checkout --theirs. После того, как вы поместили файл в нужное вам состояние, вы укажете, что вы закончили слияние файла, и он готов к фиксации с использованием git add, а затем вы можете совершить слияние с git commit.

+7

Вы должны, вероятно, отметить, что 'git add -all' добавляет все файлы в репозиторий, поэтому это может добавить больше файлов, чем предполагалось, если ваши шаблоны' .gitignore' находятся в идеальном состоянии. 'git add -u', вероятно, более подходит для этой ситуации, вы с меньшей вероятностью будете иметь право редактировать отслеживаемые файлы, которые вы не хотите добавлять при разрешении слияния. –

+0

К сожалению, извините. Это то, что я имел в виду. Исправил его сейчас. –

+1

Спасибо за подробный ответ. Я фактически попробовал git checkout -ours и получил сообщение об ошибке (которое я не помню сейчас). Файлы, о которых идет речь, - dll (у нас есть некоторые из них, которые мы делали в stash, сторонние ссылки в основном), и я хотел просто сказать: «ОК, моя копия - это те, которые я хочу, но ошибка была чем-то вроде« не может проверяться при слиянии », ..... Я буду держать эту статью ссылкой и в следующий раз, когда это произойдет, попробуйте еще раз и посмотрите, работает ли она, или если я могу опубликовать это сообщение. Еще раз спасибо – BoomTownTech

14

Удостоверьтесь в происхождении конфликта: если это результат git merge, см. answer.

Но если это результат git rebase для того, чтобы отбрасывать удаленных (их) изменения и использовать местные изменения, вы должны сделать:

git checkout --theirs -- . 

См «Why is the meaning of “ours” and “theirs” reversed"» в см., как ours и theirs меняются местами во время переустановки (поскольку ветвь upstream проверяется).

Смежные вопросы