Git разрешает конфликт с помощью --ours / - theirs для всех файлов

113

Есть ли способ разрешить конфликт для всех файлов с помощью checkout --oursи --theirs? Я знаю, что вы можете сделать это для отдельных файлов, но не смог найти способ сделать это для всех.

exe163
источник
7
Работает git checkout --ours -- .? В .означает текущий каталог, когда применяются от корня рабочего каталога, так что это в основном означает весь рабочий каталог. Не уверен, что это сработает с --oursфлагом, и я не уверен, как он будет обрабатывать конфликты удаленных или переименованных файлов.
@Cupcake Я успешно его использовал. Может, это должен быть ответ?
Педро Гимено,

Ответы:

90

Просто выполните grep через рабочий каталог и отправьте вывод с помощью команды xargs:

grep -lr '<<<<<<<' . | xargs git checkout --ours

или

grep -lr '<<<<<<<' . | xargs git checkout --theirs

Как это работает: grepбудет выполнять поиск в каждом файле в текущем каталоге ( .) и подкаталогах рекурсивно ( -rфлаг) в поисках маркеров конфликта (строка '<<<<<<<')

-lили --files-with-matchesфлаг заставляет Grep выводить только имя файла , где была найдена строка. Сканирование останавливается после первого совпадения, поэтому каждый найденный файл выводится только один раз.

Совпавшие имена файлов затем поступают в xargs , утилиту , которая разбивает входной поток водопроводных в отдельные аргументы для git checkout --oursили--theirs

Подробнее по этой ссылке .

Поскольку было бы очень неудобно вводить это каждый раз в командной строке, если вы обнаружите, что часто используете его, было бы неплохо создать псевдоним для вашей оболочки по выбору: Bash - это обычный .

Этот метод должен работать как минимум в Git версии 2.4.x

Дмитрий
источник
15
Вместо grepping, думаю, тоже можно использовать git diff --name-only --diff-filter=U.
Thai
10
Также git status | grep both | awk '{print $3}' | xargs git checkout --[theirs|ours]. Быстрее, чем grepping, если у вас большой проект.
joshbodily
1
@joshbodily Приятно. У меня нет проектов, настолько огромных, что я бы заметил разницу, но я вижу, как это будет намного быстрее, особенно если несколько файлов изменились по сравнению с общим числом в каталоге - что должно быть в случае обычного совершает.
Дмитрий
1
Обратите внимание, что это не работает для конфликтов переименования / переименования, например,CONFLICT (rename/rename): Rename "a.txt"->"c.txt" in branch "HEAD" rename "a.txt"->"b.txt" in "master"
Борек Бернард
1
Еще один вариант: git status --porcelain | egrep '^UU' | cut -d ' ' -f 2 |xargs git checkout --[theirs|ours].
Zitrax
53

Вы можете -Xoursили -Xtheirsс git merge. Так:

  1. прервать текущее слияние (например, с git reset --hard HEAD)
  2. объединить, используя стратегию, которую вы предпочитаете ( git merge -Xoursили git merge -Xtheirs)

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: конечно, вы можете выбрать только один вариант, -Xoursили -Xtheirs, если вы используете другую стратегию, вы, конечно, должны идти файл за файлом.

Я не знаю, есть ли способ checkout, но я, честно говоря, не думаю, что это ужасно полезно: выбор стратегии с помощью команды checkout полезен, если вам нужны разные решения для разных файлов, в противном случае просто используйте подход стратегии слияния.

СпасибоForAllTheFish
источник
Спасибо, не знал, что у них есть "- наши" и "- их" для слияния. Кажется, что для слияния они на самом деле не являются частью стратегии «-s», а являются частью рекурсивных опций «-X». «-s» наша версия на самом деле просто заменяет все файлы без слияния, а их не существует.
exe163
Для git v1.9.4 нет опции --theirsили --ours-Option. Подход был бы git merge -s recursive -Xtheirs BRANCH.
fbmd 04
--theirsи --oursнедоступны ни с git 2.2.0. Либо мой ответ был неточным, либо они были доступны в более старой версии git (этот ответ довольно старый в эпоху ИТ). Правильный подход - с -X. Я обновляю соответственно
ThanksForAllTheFish
Начиная с версии 2.4.0 --ours и --theirs по-прежнему очень доступны git-scm.com/docs/git-checkout
Дмитрий
Пробовал это, и получил «автоматическое слияние не удалось, исправить конфликты». Эта команда явно работает не так, как задумано, и я рекомендую избегать ее - слишком много ошибок.
Адам
38

git checkout --[ours/theirs] .будет делать то, что вы хотите, до тех пор, пока вы находитесь в корне всех конфликтов. ours / theirs влияет только на не объединенные файлы, поэтому вам не нужно специально выявлять конфликты grep / find / etc.

Кори Петоски
источник
5
Для меня это не похоже на подкаталоги.
Дэниел Боуман,
5
Я понимаю error: path 'foo/bar/blah' does not have our version.
Робин Грин
Я использую git версии 2.16.2.windows.1, и у меня она отлично работает. Спасибо!
Pankwood
30
git diff --name-only --diff-filter=U | xargs git checkout --theirs

Кажется, делает свою работу. Обратите внимание, что для этого вам необходимо перейти в корневой каталог репозитория git.

Питер
источник
3
Я думаю, что это лучший ответ, чем тот, который получил наибольшее количество голосов, потому что (1) он применяется ко всем файлам, а не только к рабочему каталогу; и (2) у него не будет проблем с поиском маркеров конфликта. Команда 'git diff' здесь перечисляет все несвязанные пути, и это именно то, что мы хотим проверить.
bchurchill
Ницца! Меня всегда беспокоила надежность маркеров конфликтов grep
00-BBB
2
function gitcheckoutall() {
    git diff --name-only --diff-filter=U | sed 's/^/"/;s/$/"/' | xargs git checkout --$1
}

Я добавил эту функцию в файл .zshrc .

Используйте их так: gitcheckoutall theirsилиgitcheckoutall ours

iWheelBuy
источник