git checkout -m old
git checkout -b new B
git merge -s ours old
0
这将在现有的baseBranch中合并你的newBranch
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
48
等价(保持父订单)'git merge -s the branchB'
合并前:
!确保你处于干净状态!
合并:
git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command
不要忘记记下合并的提交ID,因为在下次硬重置后它将不可用 . (如果你忘了不会造成任何伤害,但你必须重新硬复位回 A 并重新开始) .
git reset --hard B (this is what we want the merge to look like (the merge can now only be referenced by the commit id `2345678`))
git reset --soft 2345678 (without changing any files go back to the merge)
git commit --amend (branch B is now the final version of the merge)
现在我们有
* 3456789 (HEAD->A) Merge branch 'B' into A (correctly ignores changes from 0123456)
|\
* | 0123456 (origin/A)
| * 1234567 (origin/B, B)
|/
* ??????? (common root)
$ diff HEAD B
[... no changes ...]
git push
DONE
当一位同事将我的更改 A 应用到他的独立分支 B 而不合并时,我需要这样做,这使我能够接受他在我的分支上的修改 .
# 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
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
git update-ref HEAD $(
git commit-tree -m 'completely superseding with branchB content' \
-p HEAD -p branchB branchB:
)
git reset --hard
0
可行且经过测试的解决方案将branchB合并到我们的签出分支A:
# 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
18 回答
我从现在开始使用Paul Pladijs的答案 . 我发现,你可以做一个“正常”合并,发生冲突,所以你这样做
通过使用来自其他分支的修订来解决冲突 . 如果对每个文件执行此操作,则会产生与预期相同的行为
无论如何,努力比合并策略更多! (这是使用git版本1.8.0测试的)
要真正正确地执行合并,只需要合并您正在合并的分支的输入,您可以这样做
git merge --strategy=ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply --reverse --index
git commit --amend
在我知道的任何场景中都不存在冲突,您不必进行额外的分支,它就像普通的合并提交一样 .
但是,这对子模块不起作用 .
我解决了我的问题
这将在现有的baseBranch中合并你的newBranch
等价(保持父订单)'git merge -s the branchB'
合并前:
!确保你处于干净状态!
合并:
我们做了什么 ?我们创建了一个新的提交,我们和他们的两个父母和他们的提交的contnet是branchB - 他们的
合并后:
更确切地说:
较旧版本的git允许您使用“他们的”合并策略:
但是这已被删除,正如Junio Hamano(Git维护者)在此消息中所解释的那样 . 如链接中所述,您可以这样做:
但要注意,这与实际合并不同 . 您的解决方案可能是您真正想要的选择 .
这个使用git plumbing命令读取树,但缩短了整体工作流程 .
虽然我在“git command for making one branch like another”中提到如何模拟
git merge -s theirs
,但请注意Git 2.15(2017年第4季度)现在更清晰:见commit c25d98b(2017年9月25日)Junio C Hamano (gitster) .
(由Junio C Hamano合并 - gitster - in commit 4da3e23,2017年9月28日)
-Xtheirs
是应用于递归策略的策略选项 . 这意味着递归策略仍然可以合并任何东西,并且只有在发生冲突时才会回退到“theirs
”逻辑 .关于
theirs
合并策略是否有针对性的辩论最近被提起in this Sept. 2017 thread .它承认older (2008) threads
它提到了别名:
Yaroslav Halchenko试图再次倡导该战略,but Junio C. Hamano adds:
更新
虽然第二个答案回答了OP的原始问题,但它没有反映OP问题的更新意图 .
您正在寻找的是与_272000_命令相反的_272000_命令的反面,
git merge -s recursive -X ours
命令是git merge -s recursive -X theirs
原始答案
给予原始分支
将分支B合并为A而忽略分支A的状态,然后首先进行常规合并
这导致了
不要推送这个合并,因为提交ID会改变(并且这两种方式都是错误的)现在我们可以将
ours
策略更改为theirs
策略不要忘记记下合并的提交ID,因为在下次硬重置后它将不可用 . (如果你忘了不会造成任何伤害,但你必须重新硬复位回
A
并重新开始) .现在我们有
DONE
当一位同事将我的更改
A
应用到他的独立分支B
而不合并时,我需要这样做,这使我能够接受他在我的分支上的修改 .将
-X
选项添加到theirs
. 例如:一切都会以理想的方式融合 .
我见过的唯一一件事就是问题是否从branchB删除文件 . 如果除了git之外的其他东西都被删除,它们就会显示为冲突 .
修复很容易 . 只需运行
git rm
,其中包含已删除的任何文件的名称:之后,
-X theirs
应该按预期工作 .当然,使用
git rm
命令进行实际删除可以防止冲突首先发生 .注意:还存在较长的表单选项 . 要使用它,请替换:
有:
目前还不完全清楚你期望的结果是什么,所以对于在答案和评论中这样做的“正确”方式存在一些困惑 . 我尝试概述并查看以下三个选项:
Try merge and use B for conflicts
这不是“
git merge -s ours
" but the "他们的版本为git merge -X ours
的他们的版本”(这是git merge -s recursive -X ours
的缩写):这就是例如Alan W. Smith's answer的确如此 .
Use content from B only
这会为两个分支创建合并提交,但会丢弃
branchA
中的所有更改,并仅保留branchB
中的内容 .请注意,合并提交第一个父项现在是来自
branchB
,而第二个来自branchA
. 这就是例如Gandalf458's answer呢 .Use content from B only and keep correct parent order
这是真正的“他们的
git merge -s ours
版本” . 它具有与之前选项相同的内容(即仅来自branchB
),但父母的顺序是正确的,即第一个父亲来自branchA
,第二个来自branchB
.这就是Paul Pladijs's answer所做的(不需要临时分支) .
我假设你创建了一个master的分支,现在想要合并回master,覆盖master中的任何旧东西 . 当我遇到这篇文章时,这正是我想要做的 .
完全按照你想做的去做,除了先把一个分支合并到另一个分支 . 我刚刚这样做了,效果很好 .
然后,checkout master并合并你的分支(它现在会很顺利):
一个简单直观的(在我看来)两步走的方法是
其次是
(这标志着两个分支合并)
唯一的缺点是它不会从当前分支中删除已在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
中发出合并请求以使其成为新的主服务器,或者只是将其保留为分支 .请参阅Junio Hamano's widely cited answer:如果您要丢弃已提交的内容,只需丢弃提交,或者无论如何都要将其保留在主历史之外 . 为什么在将来阅读提交来自无提供的提交的消息时会困扰每个人?
但有时候有行政要求,或者其他一些原因 . 对于那些你真的必须记录没有贡献的提交的情况,你想要:
(编辑:哇,我以前设法弄错了 . 这个有效 . )
可行且经过测试的解决方案将branchB合并到我们的签出分支A:
要自动化它,您可以使用branchA和branchB作为参数将其包装到脚本中 .
此解决方案保留合并提交的第一个和第二个父级,就像您对
git merge -s theirs branchB
的期望一样 .如果你在分支A上做:
测试了git版本1.7.8
我想你真正想要的是:
这看起来很笨拙,但应该有效 . 唯一认为我真的不喜欢这个解决方案的是git历史会让人感到困惑......但至少历史将被完全保留,你不需要为删除的文件做些特别的事情 .