Выберите стратегию слияния Git для определенных файлов ( "наш", "мой", "их" )

Я нахожусь в середине перезагрузки после git pull --rebase. У меня есть несколько файлов с конфликтами слияния. Как я могу принять "свои" изменения или "мои" изменения для определенных файлов?

$ git status
# Not currently on any branch.
# You are currently rebasing.
#   (fix conflicts and then run "git rebase --continue")
#   (use "git rebase --skip" to skip this patch)
#   (use "git rebase --abort" to check out the original branch)
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:  CorrectlyMergedFile
#
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add <file>..." to mark resolution)
#
#       both modified: FileWhereIWantToAcceptTheirChanges
#       both modified: FileWhereIWantToAcceptMyChanges

Обычно я просто открываю файл или инструмент слияния и вручную принимаю все "свои" или "мои" изменения. Тем не менее, я подозреваю, что мне не хватает удобной команды git.

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

Ответ 1

Для каждого конфликтуемого файла вы можете указать

git checkout --ours -- <paths>
# or
git checkout --theirs -- <paths>

Из git checkout docs

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

--ours
--theirs
При проверке путей из индекса проверьте этап №2 (ours) или # 3 (theirs) для несвязанных путей.

Индекс может содержать несвязанные записи из-за предыдущего неудачного слияния. По умолчанию, если вы попытаетесь проверить такую ​​запись из индекса, операция проверки завершится неудачно, и ничего не будет проверено. Использование -f будет игнорировать эти несвязанные записи. Содержимое с определенной стороны слияния можно проверить из индекса с помощью --ours или --theirs. С помощью -m изменения, внесенные в рабочий файл дерева, могут быть отброшены, чтобы повторно создать исходный конфликтный результат слияния.

Ответ 2

Несмотря на то, что на этот вопрос дан ответ, приводя пример о том, что означает "их" и "наш" в случае git rebase vs merge. См. эта ссылка

Git Rebase
theirs на самом деле является текущей ветвью в случае rebase. Таким образом, приведенный ниже набор команд фактически принимает ваши текущие изменения ветвления по удаленной ветке.

# see current branch
$ git branch
... 
* branch-a
# rebase preferring current branch changes during conflicts
$ git rebase -X theirs branch-b

Git Слияние
Для слияния значение theirs и ours отменяется. Таким образом, чтобы получить тот же эффект во время слияния, т.е. Сохраняйте текущие изменения ветки над объединенной удаленной ветвью.

# assuming branch-a is our current version
$ git merge -X ours branch-b  # <- ours: branch-a, theirs: branch-b

Ответ 3

Обратите внимание, что git checkout --ours|--theirs полностью перезапишет файлы, выбирая версию theirs или ours, которая может быть или не быть тем, что вы хотите сделать (если у вас есть какие-либо несогласованные изменения, исходящие из с другой стороны, они будут потеряны).

Если вместо этого вы хотите выполнить трехстороннее слияние в файле и разрешить только конфликтующие hunks с помощью --ours|--theirs, а сохранить неконфликтные hunks. с обеих сторон, вы можете прибегнуть к git merge-file; см. подробности в этом ответе.