Выберите стратегию слияния 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.

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


person Steven Wexler    schedule 30.05.2013    source источник
comment
@AbeVoelker Не думаю, что это решит мою проблему. Я хочу выбрать стратегию слияния для определенных файлов. Кроме того, обратите внимание, что я буду знать, какую стратегию слияния использовать, когда я нахожусь в своей перебазировке и смотрю, какие файлы столкнулись с конфликтами и каковы конфликты.   -  person Steven Wexler    schedule 30.05.2013
comment
Я отредактировал этот вопрос, сделав его более общим: stackoverflow.com/questions/278081/. Может быть, мы можем закрыть этот вопрос как дубликат? Это уместно?   -  person    schedule 30.05.2013
comment
@TheShadow Это кажется мне разумным.   -  person Steven Wexler    schedule 30.05.2013
comment
Я не был уверен, уместно ли изменить заголовок другой вопрос о том, что я сделал, потому что я убрал часть о разрешении двоичных файлов. Я вернул другой вопрос к тому, что было раньше, так что этот текущий вопрос все еще добавляет ценности.   -  person    schedule 30.05.2013


Ответы (4)


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

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 изменения, внесенные в файл рабочего дерева, можно отменить, чтобы воссоздать исходный конфликтующий результат слияния.

person Community    schedule 30.05.2013
comment
Можно ли принять их для всех файлов, оставшихся без объединения? - person aslakjo; 20.12.2013
comment
@aslakjo git rebase -s recursive -X <ours/theirs> или git merge -s recursive -X <ours/theirs>. Имейте в виду, что для перебазирования наши и их изменяются от того, что они есть во время слияния. Возможно, вы могли бы просто использовать глобус файла / оболочки, например git checkout --theirs -- *.txt. - person ; 12.04.2014
comment
Эта команда не работает, если ‹paths› является подмодулем. - person user239558; 12.01.2015
comment
Большое спасибо, @Cupcake, неожиданное обращение ours/theirs с rebase сводило меня с ума !! (Теперь это имеет смысл, когда я думаю о том, как на самом деле работает rebase, но совсем не интуитивно.) - person Dan Lenski; 19.02.2016
comment
В целом, @DanLenski rebase - это просто действительно сложный инструмент, который люди могут сначала понять, но как только вы поймете, как он работает, вы сможете делать с ним всевозможные действительно мощные вещи. - person ; 23.02.2016
comment
Да, мне нравится думать о себе как о каком-то опытном пользователе rebase, но мне неловко сказать, что я никогда не догадывался об обратном изменении _2 _ / _ 3_ и всегда буду делать это сложным способом (фиксация за фиксацией), пока я не прочитайте это. - person Dan Lenski; 23.02.2016
comment
В Windows с использованием Git Bash мне нужно было использовать / \ (прямая косая черта, обратная косая черта) в качестве разделителя пути, например git checkout --ours -- **/\*.csproj. Я понятия не имею, почему, и не могу найти ответ в Google. Может ли кто-нибудь указать мне на объяснение? Использование чего-либо еще не удается; Я пытался. *.csproj, **/*.csproj, **\/*.csproj. - person Vincent Sels; 16.05.2017
comment
Я делаю это, затем git add, затем rebase --continue, и снова оказываюсь в той же ситуации, не могу выйти из цикла. - person Mehdi; 12.07.2017
comment
каким-то образом git checkout не влияет на поэтапные файлы для меня - person Tin Man; 22.04.2018
comment
@VincentSels на самом деле вам нужно замаскировать символ *, иначе оболочка попытается расширить его. так что в вашем случае git checkout --outs -- "**/*.csproj" будет делать то, что вы имеете в виду. То же самое верно, например, для git lfs track "*.jpg". Если в вашем CWD есть файлы jpg без кавычек, будут отслеживаться только они. - person eFloh; 26.04.2018
comment
@TinMan git работает очень тихо при использовании git checkout --ours/--theirs -- <path>. Не забудьте после этого сделать git add <path>, тогда вы увидите результаты, которые ищете - person 2Toad; 11.12.2018
comment
ОСТОРОЖНО, использование checkout [--ours|--theirs] -- file полностью перезапишет file либо: из нашей ветки, либо из объединяемой ветки. Это как-то опасно, так как вы могли правильно объединить куски на file, которые вы будете отбрасывать! Вы хотите применить стратегию ours или theirs только к конфликтующим фрагментам в файле! См. этот ответ или jakub.g для решения, учитывающего этот момент. - person Totor; 30.11.2020


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

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

person jakub.g    schedule 25.08.2016
comment
Что касается неконфликтных изменений, которые будут потеряны - это относится только к файлам, в которых есть неконфликтные изменения в определенных строках в другом месте того же файла, или ко всем изменениям из всех файлов в выровненных историях? - person ktamlyn; 08.03.2018
comment
@ktamlyn под неконфликтными изменениями я имел в виду изменения в том же файле. Например, есть два измененных фрагмента (части) в example.txt в версии ours, один является конфликтным (также изменен в версии theirs), другой не является конфликтующим. Если вы сделаете git checkout --theirs example.txt, он просто вслепую прочитает весь файл в theirs ревизии, и неконфликтная часть различий будет потеряна. - person jakub.g; 14.03.2018
comment
Спасибо! Для меня это было необходимым пояснением, хотя изменения в том же файле имеют наибольший смысл в данном контексте. - person ktamlyn; 21.03.2018
comment
Это должен быть принятый ответ, хотя на самом деле он не дает ответа, но указывает на важную проблему в другом предлагаемом решении. - person tomasyany; 07.11.2018
comment
Если вы хотите вернуться к исходному конфликтующему файлу, вы можете запустить git checkout --merge <path>. - person Andrew Keeton; 17.10.2019

цитируя @ user456814 из комментария выше:

git rebase -s recursive -X <ours/theirs>
or
git merge -s recursive -X <ours/theirs>

Имейте в виду, что для перебазирования наши и их изменяются от того, что они есть во время слияния.

@ user456814 дал этот полезный ответ в комментариях к принятому ответу еще в 2014 году. Я вспоминаю его здесь как вики сообщества, чтобы упростить поиск, оценку, обновление и т. д., поскольку комментарии в этом отношении ограничены.

person Community    schedule 23.03.2021