Есть ли "их" версия "git merge-s ours"?
при объединении ветви темы "B" в "A" с помощью git merge
, Я получаю какие-то конфликты. Я знаю, что все конфликты можно решить, используя версию в "B".
Я в курсе git merge -s ours
. Но то, что я хочу, это что-то вроде git merge -s theirs
.
почему он не существует? Как я могу достичь того же результата после конфликтующего слияния с существующим git
команды? (git checkout
каждый unmerged файл из B)
UPDATE: "решение" просто отбросить что-либо из ветви A (the merge commit point to B версия дерева) - это не то, что я ищу.
18 ответов
добавить до theirs
. Например:
git checkout branchA
git merge -X theirs branchB
все будет сливаться желаемым образом.
единственное, что я видел, вызывает проблемы, если файлы были удалены из branchB. Они появляются как конфликты, если что-то другое, чем git, сделало удаление.
исправление легко. Просто запустите git rm
С именем всех файлов, которые были удалены:
git rm {DELETED-FILE-NAME}
после этого -X theirs
должны работать, как ожидалось.
Of конечно, делать фактическое удаление с git rm
команда предотвратит конфликт от происходить в первую очередь.
Примечание: более длинная форма Также существует. Чтобы использовать его, замените:
-X theirs
С:
--strategy-option=theirs
возможное и проверенное решение для объединения branchB в нашу проверенную ветвь:
# 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
.
более старые версии git позволили Вам использовать стратегию слияния" их":
git pull --strategy=theirs remote_branch
но с тех пор это было удалено, как объясняется в этом сообщении Hamano Джунио (сопровождающий Git). Как отмечено в ссылке, вместо этого вы сделаете следующее:
git fetch origin
git reset --hard origin
остерегайтесь, однако, что это отличается от фактического слияния. Ваше решение, вероятно, вариант, который вы действительно ищете.
я использовал ответ от Павла Pladijs с тех пор. Я узнал, что вы можете сделать "нормальное" слияние, возникают конфликты, поэтому вы делаете
git checkout --theirs <file>
чтобы разрешить конфликт, используя ревизию из другой ветви. Если вы сделаете это для каждого файла, у вас будет такое же поведение, как и ожидалось от
git merge <branch> -s theirs
во всяком случае, усилия больше, чем было бы со стратегией слияния! (Это было протестировано с Git версии 1.8.0)
не совсем ясно, каков ваш желаемый результат, поэтому есть некоторая путаница в отношении "правильного" способа сделать это в ответах и их комментариях. Я пытаюсь дать обзор и увидеть следующие три варианта:
попробуйте объединить и использовать 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
это Павел Pladijs это делает (не требуя временной ветви).
Если вы находитесь на ветке делать:
git merge -s recursive -X theirs B
проверено на Git версии 1.7.8
при слиянии ветви темы "B" в "A" с помощью git merge я получаю некоторые конфликты. Я >знаю, что все конфликты могут быть решены с помощью версии "Б".
Я знаю о git merge-s ours. Но то, что я хочу, это что-то вроде git merge > - s их.
Я предполагаю, что вы создали ветвь master и теперь хотите слиться обратно в master, переопределяя любой из старых вещей в master. Именно это я и хотел сделать, когда наткнулся на это. должность.
делайте именно то, что вы хотите сделать, за исключением слияния одной ветви в другую. Я просто сделал это, и это сработало отлично.
git checkout Branch
git merge master -s ours
затем, checkout master и объединить свою ветку в нем (теперь он будет идти гладко):
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
в любом сценарии, о котором я знаю, не будет конфликтов, вам не нужно создавать дополнительные ветви, и это действует как обычная фиксация слияния.
это не играет хорошо с подмодулями, однако.
посмотреть широко цитируемый ответ Хунио Хамано: Если вы собираетесь отбросить зафиксированный контент, просто отбросьте фиксации или, по крайней мере, держите его вне основной истории. Зачем беспокоить всех в будущем, читая сообщения фиксации от коммитов, которым нечего предложить?
но иногда есть административные требования или, возможно, какая-то другая причина. Для тех ситуаций, когда вам действительно нужно записывать коммиты, которые ничего не вносят, вы хочу:
(edit: wow, мне удалось получить это неправильно раньше. Этот работает.)
git update-ref HEAD $(
git commit-tree -m 'completely superseding with branchB content' \
-p HEAD -p branchB branchB:
)
git reset --hard
этот использует команду git plumbing read-tree, но делает более короткий общий рабочий процесс.
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 для создания одной ветви как другой" как имитировать git merge -s theirs
, обратите внимание, что Git 2.15 (Q4 2017) теперь яснее:
документация для'
-X<option>
' для слияния был обманчиво написано, чтобы предположить, что"-s theirs
" существует, но это не так.
посмотреть совершить c25d98b (25 Sep 2017) by Junio C Hamano (gitster
).
(слитый Junio C Hamano -- gitster
-- на совершить 4da3e23, 28 сентября 2017)
слияние-стратегии: избегайте подразумевать, что"
-s theirs
" имеетсяописание
-Xours
опции слияния к слову это говорит читателям, что он очень отличается от-s ours
, что верно, но описание-Xtheirs
, что следует за ним небрежно говорит: "это противоположностьours
", давая ложные создается впечатление, что читатели также должны быть предупреждены, что это очень отличается от-s theirs
, которого на самом деле даже не существует.
-Xtheirs
это опционы применить к рекурсивной стратегии. Это означает, что рекурсивная стратегия все равно объединит все, что сможет, и вернется только к"theirs
" логика в случае конфликтов.
эти дебаты за уместность или нет theirs
слияние стратегия была возвращена недавно в этом сентябре. 2017 нити.
Он признает старые (2008) темы
короче говоря, предыдущее обсуждение можно резюмировать так: "мы не хотим"
-s theirs
- как это стимулирует неправильный рабочий процесс".
он упоминает псевдоним:
mtheirs = !sh -c 'git merge -s ours --no-commit && git read-tree -m -u ' -
Ярослав Гальченко еще раз пытается отстаивать эту стратегию,но Хунио С. Хамано добавляет:
как только вы решите, что их история является основной линией, вы предпочтете рассматривать свою линию развития как боковую ветвь и сделать слияние в этом направлении, т. е. первый родитель полученного слияния является фиксацией на их истории, а второй родитель-последним плохая история. Таким образом, вы в конечном итоге используете "
checkout their-history && merge -s ours your-history
" в держите первого родителя разумным.и в этот момент использовать "
-s ours
" больше не обходной путь из-за отсутствия "-s theirs
".
это правильная часть желаемой семантики, то есть с точки зрения сохранившейся канонической линии истории, вы хотите сохранить то, что она сделала, аннулируя то, что сделала другая линия истории.
это объединит ваш newBranch в существующий baseBranch
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 checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch
Это кажется неуклюжим, но это должно работать. Единственное, что мне действительно не нравится в этом решении, - история git будет запутанной... Но, по крайней мере, история будет полностью сохранена, и вам не нужно будет делать что-то особенное для удаленных файлов.
обновление
хотя второй ответ отвечает на исходный вопрос OP, он не отражает обновленного намерения вопроса OP.
то, что вы ищете не наоборот
простой и понятный (на мой взгляд) двухэтапный способ сделать это
git checkout branchB .
git commit -m "Picked up the content from branchB"
следовал по
git merge -s ours branchB
(который отмечает две ветви как Объединенные)
единственным недостатком является то, что он не удаляет файлы, которые были удалены в branchB из вашей текущей ветви. Простое различие между двумя ветвями впоследствии покажет, есть ли такие файлы.
этот подход также дает понять из журнала ревизий впоследствии, что было сделали - и то, что было задумано.
недавно мне нужно было сделать это для двух отдельных репозиториев, которые имеют общую историю. Я начал с:
Org/repository1 master
Org/repository2 master
Я хотел все изменения от repository2 master
для применения к repository1 master
, принимая все изменения, которые сделает repository2. В терминах git, это должны стратегия называется -s theirs
но его не существует. Будьте осторожны, потому что -X theirs
называется, как это было бы то, что вы хочу, но это не то же самое (это даже говорит так на главной странице).
то, как я решил это, было пойти в repository2
и сделать новую ветку repo1-merge
. В этой ветке я бежал git pull git@gitlab.com:Org/repository1 -s ours
и он сливается нормально без проблем. Затем я нажимаю на пульт.
тогда я возвращаюсь к repository1
и сделать новую ветку repo2-merge
. В этой ветви я бегу git pull git@gitlab.com:Org/repository2 repo1-merge
завершить с вопросами.
наконец, вам либо нужно будет выдать запрос на слияние в repository1
чтобы сделать его новым мастером, или просто сохранить его как ветку.
эквивалент (который сохраняет Родительский порядок) для "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}'