При объединении тематической ветки «B» в «A» с помощью git merge
возникают некоторые конфликты. Я знаю, что все конфликты можно разрешить с помощью версии «Б».
Я знаю git merge -s ours
. Но я хочу что-то вроде git merge -s theirs
.
Почему его не существует? Как я могу добиться того же результата после конфликтующего слияния с существующими командами git
? (git checkout
каждый не объединенный файл из B)
ОБНОВЛЕНИЕ: «Решение» просто отбросить что-либо из ветви A (точка фиксации слияния для версии B дерева) - это не то, что я ищу.
См. Ответ SO команда git, чтобы сделать одну ветку похожей на другую для все текущих возможных способов имитировать git merge -s their
.
Таким образом, вы на самом деле не ищете git merge -s theirs
(этого можно легко достичь с помощью git merge -s ours
и временной ветки), так как наш полностью игнорирует изменения ветки слияния из ...
@Torek - считают ли разработчики Git В самом деле оскорбительным для который предоставление theirs
в дополнение к ours
??? Это симптом одной из основных проблем проектирования и разработки в Git: несогласованность.
@jww Проблема здесь не в том, что "git merge -s ours" оскорбительна, а в том, что это противоречит интуиции. Вы можете видеть из вопроса OP, что если такая функция будет добавлена, он будет использовать ее по ошибке, когда на самом деле он хочет сделать «git merge -s recursive -X theirs». Обычно возникает желание объединить другую ветку, перекрывая конфликты с версией в другой ветке, но полная перезапись текущей ветки другой веткой, полностью отбрасывающая текущие изменения, на самом деле является исключением.
Каждый должен внимательно проверить "обновление" OP, так как вопрос имеет отношение ничего такого к git merge -s ours
.
См. Также: git стратегии слияния
@ user3016982 каждый раз, когда в жизни приходилось сливаться, всегда хотелось брать "свою" версию
Итог: это git merge -X theirs
@ Z.Khullah Пожалуйста, не вводите людей в заблуждение, принятый ответ опасен, поскольку он, кажется, отвечает на какой OP разыскивается, а не на его вопрос (заголовок) на самом деле спрашивает. Многие ответы здесь стоит прочитать, чтобы полностью понять эту щекотливую точку в git.
Я настоятельно рекомендую @tshepang ответить ниже stackoverflow.com/a/18682314/1375031. На мой взгляд, это самое простое и правильное решение. Его использование эффективно решило мою аналогичную проблему. Перед объединением ветки на главном сервере объедините мастер в своей ветке с -s ours
. Возможно, подумайте об изменении принятого ответа, поскольку некоторые люди считают его неточным.
Я решил свою проблему с помощью
git checkout -m old
git checkout -b new B
git merge -s ours old
ветка «Б» от «старой» ветки
Более старые версии git позволяли использовать «их» стратегию слияния:
git pull --strategy=theirs remote_branch
Но с тех пор это было удалено, как объясняет в этом сообщении Хунио Хамано (сопровождающий Git). Как указано в ссылке, вместо этого вы должны сделать это:
git fetch origin
git reset --hard origin
Однако помните, что это отличается от фактического слияния. Вероятно, ваше решение - это тот вариант, который вы действительно ищете.
спасибо, я не полностью удовлетворен своим ответом, в старых версиях отсутствовала проверка других файлов. это было странно, добавляю, чтобы проверить их ... зафиксировать - потом поправить.
Я действительно вообще не понимаю объяснения Джунио Хамано. Как git reset --hard origin
- это решение для слияния их стиля? Если бы я хотел объединить BranchB с BranchA (как в ответе Алана В. Смита), как бы я сделал это с помощью метода reset
?
@James McMahon: Джунио С. Хамано не считает, что git reset --hard
выполняет слияние в «их» стиле. Конечно, git reset --hard
не создает никаких коммитов слияния или каких-либо коммитов в этом отношении. Его точка зрения состоит в том, что мы не должны использовать слияние заменяет все, что находится в HEAD, чем-то другим. Однако я не обязательно согласен.
Жаль, что theirs
был удален из-за неполного обоснования. Он не смог разрешить те случаи, когда код хорош, просто восходящий поток поддерживается на другой философской основе, так что в этом смысле это `` плохо '', поэтому каждый хочет идти в ногу со временем с восходящим потоком, но в то же время сохраните хорошие исправления кода [git и msysgit имеют этот «конфликт» из-за различных философий целевой платформы]
Также отсутствует вариант использования, с которым я застрял прямо сейчас, когда я делюсь веткой с кем-то еще, и мы оба одновременно подталкивали изменения (в разных файлах). Поэтому я хочу уничтожить все старые версии, которые у меня есть, и использовать вместо них его более новые. Он хочет сделать то же самое с файлами, которые я обновил. Нечего "сбрасывать". И решение для проверки каждый отдельный файл нецелесообразно, когда это ~ 20 файлов.
Я действительно не понимаю философии. Я просто использовал theirs
, потому что я случайно изменил некоторые файлы в двух отдельных ветвях и хотел отменить изменения одного без необходимости вручную делать это для каждого файла.
@szeitlin: Если файлы разные, конфликтов слияния не будет. Таким образом, вы сможете выполнить простое слияние, чтобы получить его изменения. Я что-то упускаю?
@SaiManojKumarYadlapati Сейчас я точно не помню, так как это было 3 (!) Года назад, но я думаю, это произошло из-за того, что нам сказали поделиться веткой, что было глупой идеей и в значительной степени противоречило цели ветвления git.
Добавьте опцию -X
к theirs
. Например:
git checkout branchA
git merge -X theirs branchB
Все сольется желаемым образом.
Единственное, что я видел, вызывает проблемы, это если файлы были удалены из ветки B. Они проявляются как конфликты, если удаление выполнялось не с помощью git.
Исправить легко. Просто запустите git rm
с именем всех удаленных файлов:
git rm {DELETED-FILE-NAME}
После этого -X theirs
должен работать должным образом.
Конечно, фактическое удаление с помощью команды git rm
в первую очередь предотвратит возникновение конфликта.
Примечание: также существует опция более длинной формы.
Чтобы использовать его, замените:
-X theirs
с:
--strategy-option=theirs
См. Другой ответ ниже для лучшего решения (Пол Пладийс) исходного вопроса.
Стоит отметить, что это не то же самое, что «стратегия слияния theirs
». -Xtheirs - это стратегия вариант, применяемая к рекурсивному стратегия. Это означает, что рекурсивная стратегия по-прежнему будет объединять все, что может, и будет возвращаться к «их» логике только в случае конфликтов. Хотя это то, что нужно в большинстве случаев, как описано выше, это не то же самое, что «просто взять все из ветки B как есть». Вместо этого он все равно выполняет настоящее слияние.
Он также работает с другими командами. Я только что сделал «git cherry-pick sha1 -X theirs». Спасибо!
@AlanWSmith Это не работает в случае переименованных файлов
Я запускаю git merge -X theirs branchB
git rm --ignore-unmatch $(git diff branchB --name-only)
Вторая команда автоматически удаляет все удаленные файлы.
Это ужасный ответ, потому что он выглядит правильным, но на самом деле неправильным. «git merge -X theirs» не делает то же, что и «git merge -s theirs». Он не заменяет текущую ветвь содержимым объединенной ветки. Предпочитает «свои» изменения, но только в случае конфликта. Следовательно, итоговый коммит может сильно отличаться от «их» ветки. Плакат с вопросами имел в виду не это.
@IvanKrivyakov, это просто ужасный ответ, потому что вопрос настолько ужасен, что OP хочет противоположность git merge -X ours
, а не противоположность git merge -s ours
. Этот ответ должен отражать, что вопрос на самом деле является недействительным.
@ user3338098: да, ты прав. Я перечитал вопрос, и это тоже не очень хорошо. К сожалению, основная причина недоразумений - не ответ и даже не вопрос. Авторы git решили дать одно и то же имя «наш» стратегии слияния и варианту стратегии слияния «рекурсивный». Путаница в этом случае практически неизбежна.
@Timur, это не то место, чтобы задавать вопрос, но какая команда ДОЛЖНА "просто взять все из ветки B как есть"?
@IgorNikiforov, если это решение не соответствует потребностям, возможно, что-то, состоящее из нескольких команд git, может работать, как в других ответах ниже.
Ответ @tshepang ниже stackoverflow.com/a/18682314/1375031 кажется наиболее простым и правильным ответом, сначала слейте мастер с вашей веткой, тогда при обратном слиянии не возникнет конфликта.
Этот ответ действительно нужно переписать. Как следует из отмеченных выше комментариев, это совсем не так, как описывает ответ. Я только что произвел слияние с -X theirs
и в итоге закончил слитым мусором изменений в README
из обеих веток. Большая часть ответа неверна, особенно: «Все будет сливаться желаемым образом ... Единственное, что я видел, вызывая проблемы, - это если файлы были удалены из веткиB».
Возможное и проверенное решение для слияния BranchB с нашим проверенным branchA:
# in case branchA is not our current branch
git checkout branchA
# make merge commit but without conflicts!!
# the contents of 'ours' will be discarded later
git merge -s ours branchB
# make temporary branch to merged commit
git branch branchTEMP
# get contents of working tree and index to the one of branchB
git reset --hard branchB
# reset to our merged commit but
# keep contents of working tree and index
git reset --soft branchTEMP
# change the contents of the merged commit
# with the contents of branchB
git commit --amend
# get rid off our temporary branch
git branch -D branchTEMP
# verify that the merge commit contains only contents of branchB
git diff HEAD branchB
Чтобы автоматизировать его, вы можете обернуть его в сценарий, используя в качестве аргументов branchA и branchB.
Это решение сохраняет первый и второй родительский элемент фиксации слияния, как и следовало ожидать от git merge -s theirs branchB
.
Q: Зачем нужен branchTEMP? Не могли бы вы просто git reset --soft branchA
?
@ cdunn2001: Как-то я подумал то же самое, но нет. Обратите внимание, что изменения git reset --hard
, на которые указывает branchA
.
@ tsuyoshi-ito: Понятно. Правда. Но все будет проще, если вы просто объедините branchA
в branchB
. При желании легко перемотать вперед A и сбросить B. Единственный недостаток состоит в том, что ^
и ^^
поменяны местами. Мне нравится ответ Шьяма здесь.
Я думаю, что с помощью git reset --soft HEAD@{1}
вы можете добиться того же, что и создание новой ветки. Используя это вместо git reset --soft branchTEMP
, вы можете отказаться от git branch branchTEMP
и git branch -D branchTEMP
.
У меня не работает аппаратный сброс, потому что тогда я не могу хранить историю в своей ветке A.
извините за глупый вопрос, но почему этот метод лучше -xtheirs? каковы преимущества / недостатки
@ chrispepper1989 -x их влияет только на конфликты, если наш кусок может быть применен чисто, он пройдет до результирующего слияния. В этом случае, как показано последней командой, мы получаем слияние совершенно идентичный с branchB, независимо от того, были ли конфликты или нет.
@Patrick: использование сброса не сработает, так как фиксация слияния будет потеряна; branchTEMP можно избежать, сохранив идентификатор коммита слияния вместо tmp=`git rev-parse HEAD`
, а затем используя его вместо branchTEMP
... или даже лучше посмотрите ответы Сьеги и Thoutbeckers ниже, чтобы узнать о еще более кратких (и идиоматических) способах достижения этой цели без временной ветки.
@UncleZeiv благодарим вас за объяснение, поэтому в основном выполнение «их» сохранит неконфликтные изменения и файлы, в результате которых получится код int, который не идентичен извлеченному коду.
@ UsAaR33 - лучшее решение, но с 2 коммитами, чтобы завершить работу, вы можете добавить: git rebase --interactive --preserve-merges HEAD~2
и получить только 1 коммит
вы только что сэкономили мне часы (в буквальном смысле), разрешая 1300+ файлов один за другим <3
Это гениально !!! Со вчерашнего дня бился головой о пропавших без вести файлах из другой ветки. Большое спасибо.
Если вы находитесь в ветке A, сделайте:
git merge -s recursive -X theirs B
Проверено на git версии 1.7.8
С этого момента я использовал ответ Пола Пладийса. Я выяснил, можно сделать "нормальное" слияние, возникают конфликты, так что вы делаете
git checkout --theirs <file>
чтобы разрешить конфликт, используя ревизию из другой ветки. Если вы сделаете это для каждого файла, у вас будет такое же поведение, как вы ожидаете от
git merge <branch> -s theirs
В любом случае, усилий больше, чем было бы со стратегией слияния! (Это было протестировано с версией git 1.8.0)
было бы здорово, если бы можно было получить список файлов. Например, git ls-files --modified | xargs git add
, я хотел сделать это для добавления с обеих сторон слияния: /
На самом деле git возвращает добавленные с обеих сторон файлы с git ls-files --modified
, поэтому я думаю, что это также жизнеспособное решение.
Спасибо, что добавили это тоже. Чаще всего это не требуется на файловой основе. Кроме того, в самом низу git status отображается «Unmerged Paths». Чтобы получить список неразрешенных путей, я использую этот псевдоним: git config --global alias.unresolved '!git status --short|egrep "^([DAU])"'
что означает -X
и в чем разница между -X
и -s
? не могу найти ни одного документа.
Это объединит вашу новую ветку в существующую базовую ветку
git checkout <baseBranch> // this will checkout baseBranch
git merge -s ours <newBranch> // this will simple merge newBranch in baseBranch
git rm -rf . // this will remove all non references files from baseBranch (deleted in newBranch)
git checkout newBranch -- . //this will replace all conflicted files in baseBranch
Я бы предложил добавить git commit --amend
в конец вашего примера, иначе пользователи могут увидеть фиксацию слияния с git log
и предположить, что операция завершена.
См. Широко цитируемый ответ Джунио Хамано: если вы собираетесь отбросить зафиксированный контент, просто откажитесь от фиксации или, во всяком случае, не допускайте его в основную историю. Зачем беспокоить всех в будущем, читая сообщения о коммитах из коммитов, которым нечего предложить?
Но иногда есть административные требования или, может быть, какая-то другая причина. Для тех ситуаций, когда вам действительно нужно записывать коммиты, которые ничего не вносят, вам нужно:
(редактировать: вау, мне удавалось сделать это неправильно раньше. Это работает.)
git update-ref HEAD $(
git commit-tree -m 'completely superseding with branchB content' \
-p HEAD -p branchB branchB:
)
git reset --hard
When merging topic branch "B" in "A" using git merge, I get some conflicts. I >know all the conflicts can be solved using the version in "B".
I am aware of git merge -s ours. But what I want is something like git merge >-s their.
Я предполагаю, что вы создали ветку от мастера и теперь хотите слиться обратно с мастером, переопределив любые старые вещи в мастере. Это именно то, что я хотел сделать, когда наткнулся на этот пост.
Делайте именно то, что вы хотите, за исключением того, что сначала слейте одну ветвь с другой. Я только что сделал это, и это отлично сработало.
git checkout Branch
git merge master -s ours
Затем выполните проверку мастера и объедините в нем свою ветку (теперь все пройдет гладко):
git checkout master
git merge Branch
Спасибо. Это должен быть принятый ответ, самый простой и правильный. Если ваша ветка отстает / конфликтует с мастером, то ее задача - слить все и заставить все работать, прежде чем слить все обратно в мастер.
Чтобы действительно правильно выполнить слияние, которое принимает ввод Только из ветки, которую вы объединяете, вы можете сделать
git merge --strategy=ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply --reverse --index
git commit --amend
В любом известном мне сценарии конфликтов не будет, вам не нужно создавать дополнительные ветки, и это действует как обычная фиксация слияния.
Однако это не очень хорошо работает с подмодулями.
Что здесь делает -R?
Таким образом вы потеряете историю файлов, «перемещенных и измененных». Я прав?
-R равно --reverse, я обновил ответ, чтобы он был более самодокументированным.
Это не сработает, если файлы, которые вы пытаетесь объединить, удалены во входящей ветке.
Не совсем ясно, каков ваш желаемый результат, поэтому в ответах и их комментариях есть некоторая путаница относительно «правильного» способа сделать это. Я пытаюсь дать обзор и вижу следующие три варианта:
Попробуйте объединить и используйте B для конфликтов
Это нет, «их версия для git merge -s ours
», но «их версия для git merge -X ours
» (сокращение от git merge -s recursive -X ours
):
git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB
Вот что, например, Ответ Алана В. Смита делает.
Использовать контент только из B
Это создает фиксацию слияния для обеих веток, но отменяет все изменения из branchA
и сохраняет только содержимое из branchB
.
# Get the content you want to keep.
# If you want to keep branchB at the current commit, you can add --detached,
# else it will be advanced to the merge commit in the next step.
git checkout branchB
# Do the merge an keep current (our) content from branchB we just checked out.
git merge -s ours branchA
# Set branchA to current commit and check it out.
git checkout -B branchA
Обратите внимание, что слияние теперь фиксирует первый родительский элемент из branchB
и только второй из branchA
. Вот что, например, Gandalf458 ответ делает.
Используйте контент только из B и соблюдайте правильный родительский порядок
Это настоящая «их версия для git merge -s ours
». Он имеет то же содержимое, что и в предыдущем варианте (то есть только из branchB
), но порядок родителей правильный, то есть первый родительский элемент происходит от branchA
, а второй - от branchB
.
git checkout branchA
# Do a merge commit. The content of this commit does not matter,
# so use a strategy that never fails.
# Note: This advances branchA.
git merge -s ours branchB
# Change working tree and index to desired content.
# --detach ensures branchB will not move when doing the reset in the next step.
git checkout --detach branchB
# Move HEAD to branchA without changing contents of working tree and index.
git reset --soft branchA
# 'attach' HEAD to branchA.
# This ensures branchA will move when doing 'commit --amend'.
git checkout branchA
# Change content of merge commit to current index (i.e. content of branchB).
git commit --amend -C HEAD
Это то, что делает Ответ Пола Пладийса (без временной ветки).
Более чистая версия варианта 3: git checkout branchA; git merge -s ours --no-commit branchB; git read-tree -um @ branchB; git commit
@jthill: Хотя ваша версия более лаконична, в ней также используется команда низкого уровня ("сантехника") read-tree
, к которой средний пользователь git может не привык (по крайней мере, я не ;-)). Решения в ответе используют только высокоуровневые («фарфоровые») команды, которые должны знать большинство пользователей git. Я предпочитаю их, но тем не менее спасибо за вашу версию!
Можете ли вы объяснить предпоследний шаг (checkout branchA)? Похоже, его там быть не должно.
@ Патрик, этот шаг обязателен. Если вы его пропустите, вы получите тот же коммит, но у вас не будет ветки, указывающей на этот коммит. Таким образом, как только вы переключитесь на другую фиксацию / ветвь, фиксация, выполненная с помощью последней команды (…commit --amend…
), будет «потеряна». Я планирую добавить к этому ответу графические пояснения, как только у меня будет время… ;-)
Здесь используется дерево чтения команды сантехники git, но в целом рабочий процесс сокращается.
git checkout <base-branch>
git merge --no-commit -s ours <their-branch>
git read-tree -u --reset <their-branch>
git commit
# Check your work!
git diff <their-branch>
Я думаю, что на самом деле вам нужно:
git checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch
Это кажется неуклюжим, но должно работать. Единственное, что мне действительно не нравится в этом решении, так это то, что история git будет сбивать с толку ... Но, по крайней мере, история будет полностью сохранена, и вам не нужно будет делать что-то особенное для удаленных файлов.
Совсем недавно мне понадобилось сделать это для двух отдельных репозиториев, имеющих общую историю. Я начал с:
Org/repository1 master
Org/repository2 master
Я хотел, чтобы все изменения из repository2 master
были применены к repository1 master
, приняв все изменения, которые внесет repository2. С точки зрения git, эта должен является стратегией -s theirs
, НО ее не существует. Будьте осторожны, потому что -X theirs
назван так, как вы хотите, но это то же самое НЕТ (это даже сказано на странице руководства).
Я решил это сделать, перейдя на repository2
и создав новую ветку repo1-merge
. В этой ветке я запустил git pull [email protected]:Org/repository1 -s ours
, и он отлично сливается без проблем. Затем я нажимаю на пульт.
Потом возвращаюсь к repository1
и делаю новую ветку repo2-merge
. В этой ветке я запускаю git pull [email protected]:Org/repository2 repo1-merge
, который решит проблемы.
Наконец, вам нужно будет либо отправить запрос на слияние в repository1
, чтобы сделать его новым мастером, либо просто оставить его как ветку.
Why doesn't it exist?
Хотя я упоминал в «команда git, чтобы сделать одну ветку похожей на другую», как моделировать git merge -s theirs
, обратите внимание, что Git 2.15 (Q4 2017) теперь более понятен:
The documentation for '
-X<option>
' for merges was misleadingly written to suggest that "-s theirs
" exists, which is not the case.
См. совершить c25d98b (25 сентября 2017 г.), автор: Junio C Hamano (gitster
).
(Merged by Junio C Hamano -- gitster
-- in commit 4da3e23, 28 Sep 2017)
merge-strategies: avoid implying that "
-s theirs
" existsThe description of
-Xours
merge option has a parenthetical note that tells the readers that it is very different from-s ours
, which is correct, but the description of-Xtheirs
that follows it carelessly says "this is the opposite ofours
", giving a false impression that the readers also need to be warned that it is very different from-s theirs
, which in reality does not even exist.
-Xtheirs
- это вариант стратегии, применяемый к рекурсивной стратегии. Это означает, что рекурсивная стратегия по-прежнему объединяет все, что может, и будет возвращаться к логике «theirs
» только в случае конфликтов.
Эти дебаты относительно уместности стратегии слияния theirs
были недавно возобновлены в этой ветке за сентябрь 2017 г..
Подтверждает старые (2008) темы
In short, the previous discussion can be summarized to "we don't want '
-s theirs
' as it encourages the wrong workflow".
В нем упоминается псевдоним:
mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -
Ярослав Гальченко еще раз пытается отстаивать эту стратегию, но Хунио К. Хамано добавляет:
The reason why ours and theirs are not symmetric is because you are you and not them---the control and ownership of our history and their history is not symmetric.
Once you decide that their history is the mainline, you'd rather want to treat your line of development as a side branch and make a merge in that direction, i.e. the first parent of the resulting merge is a commit on their history and the second parent is the last bad one of your history. So you would end up using "
checkout their-history && merge -s ours your-history
" to keep the first-parenthood sensible.And at that point, use of "
-s ours
" is no longer a workaround for lack of "-s theirs
".
It is a proper part of the desired semantics, i.e. from the point of view of the surviving canonical history line, you want to preserve what it did, nullifying what the other line of history did.
Джунио добавляет, как прокомментировал Майк Битон:
git merge -s ours <their-ref>
effectively says 'mark commits made up to<their-ref>
on their branch as commits to be permanently ignored';
and this matters because, if you subsequently merge from later states of their branch, their later changes will be brought in without the ignored changes ever being brought in.
Это полезный ответ, но в нем не упоминается один ключевой момент, который я только что понял из ответа Джунио С. Хамано: git merge -s ours <their-ref>
фактически говорит, что `` отметьте коммиты, сделанные до <their-ref> в своей ветке, как фиксации навсегда игнорируется '; и это имеет значение, потому что, если вы впоследствии выполните слияние из более поздних состояний их ветки, их более поздние изменения будут внесены без внесения игнорируемых изменений.
@MikeBeaton Спасибо. Я включил ваш комментарий в ответ для большей наглядности.
Эквивалент (который сохраняет родительский порядок) для 'git merge -s theirs branchB'
!!! Убедитесь, что вы в чистом состоянии !!!
Сделайте слияние:
git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command
Что мы сделали ? Мы создали новый коммит, у которого два родителя - наш и их, и продолжение коммита - BranchB - их
Точнее:
git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'
Простой и интуитивно понятный (на мой взгляд) двухэтапный способ сделать это:
git checkout branchB .
git commit -m "Picked up the content from branchB"
с последующим
git merge -s ours branchB
(который отмечает две ветви как объединенные)
Единственным недостатком является то, что он не удаляет файлы, которые были удалены в ветке B, из вашей текущей ветки. Простое различие между двумя ветвями впоследствии покажет, есть ли такие файлы.
Этот подход также дает понять из журнала изменений впоследствии, что было сделано и что было задумано.
это может быть правильным для исходного вопроса, однако OP обновил вопрос в 2008 году таким образом, что этот ответ неверен.
@ user3338098 Да, очень жаль, что они оставили вводящий в заблуждение заголовок и просто добавили не очень заметное обновление в конец тела вопроса .... потому что это отвечает делает, правильно ответьте на вопрос заголовка.
Полностью согласен с @RomainValeri
Такой ответ дал Пол Пладийс. Я просто взял его команды и для удобства создал псевдоним git.
Отредактируйте свой .gitconfig и добавьте следующее:
[alias]
mergetheirs = "!git merge -s ours \"\" && git branch temp_THEIRS && git reset --hard \"\" && git reset --soft temp_THEIRS && git commit --amend && git branch -D temp_THEIRS"
Затем вы можете выполнить команду git merge -s theirs A, выполнив:
git checkout B (optional, just making sure we're on branch B)
git mergetheirs A
Также см. Этот ответ: stackoverflow.com/questions/928646/… - тривиально изменить пример, чтобы использовать версию B вместо A.