当使用git merge将主题分支“B”合并为“A”时,我得到了一些冲突。我知道所有的冲突都可以用B的版本解决。
我知道git合并是我们的。但我想要的是类似git merge -s的东西。
为什么它不存在?如何在与现有git命令冲突合并后实现相同的结果?(git从B中检出所有未合并的文件)
仅仅丢弃分支A中的任何东西(合并提交点到树的B版本)的“解决方案”不是我想要的。
当使用git merge将主题分支“B”合并为“A”时,我得到了一些冲突。我知道所有的冲突都可以用B的版本解决。
我知道git合并是我们的。但我想要的是类似git merge -s的东西。
为什么它不存在?如何在与现有git命令冲突合并后实现相同的结果?(git从B中检出所有未合并的文件)
仅仅丢弃分支A中的任何东西(合并提交点到树的B版本)的“解决方案”不是我想要的。
当前回答
如果你在分支A上,请:
git merge -s recursive -X theirs B
在git版本1.7.8上测试
其他回答
这将合并现有的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
等价于'git merge -s their branchB'(保持父顺序)
在合并之前:
! !确保你处于清洁状态!!
进行合并:
git commit-tree -m "take theirs" -p HEAD -p branchB 'branchB^{tree}'
git reset --hard 36daf519952 # is the output of the prev command
我们做了什么? 我们创建了一个新的提交,它的两个父节点是我们的和他们的,提交的连接是他们的分支b
合并后:
更准确地说应该是:
git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'
类似的选项是——strategy-option(简称-X)选项,它接受他们的选项。例如:
git checkout branchA
git merge -X theirs branchB
但是,它更等于-X而不是-s。关键的区别在于-X执行常规的递归合并,使用所选的一方解决任何冲突,而-s则将合并更改为完全忽略另一方。
在某些情况下,使用-X their而不是假设的-s their的主要问题是删除文件。在这种情况下,只需运行git rm,并输入已删除文件的名称:
git rm {DELETED-FILE-NAME}
在那之后,他们的-X可能会像预期的那样工作。
当然,使用git rm命令执行实际删除操作将首先防止冲突的发生。
重新审视这个老问题,因为我刚刚找到了一个兼而有之的解决方案 简短而且——因为它只使用瓷器指令——容易理解。 明确地说,我想回答的问题在标题中提出 问题(实现git merge -s their),而不是问题体。在 换句话说,我想创建一个合并提交,它的树和 第二个父树:
# Start from the branch that is going to receive the merge.
git switch our_branch
# Create the merge commit, albeit with the wrong tree.
git merge -s ours their_branch
# Replace our working tree and our index with their tree.
git restore --source=their_branch --worktree --staged :/
# Put their tree in the merge commit.
git commit --amend
注意:git restore是git中引入的一个相当新的命令 2.23. Git帮助恢复警告
这个命令是实验性的。行为可能会改变。
我用多个版本的git (2.25.1, 2.30.2, 2.31.1, 2.34.1和2.35.1),并按预期工作。
你想要的结果是什么并不完全清楚,所以在答案和他们的评论中有一些关于“正确”方法的困惑。我试着给出一个概述,并看到以下三个选项:
尝试合并并使用B来处理冲突
这不是“他们版本的git merge -s ours”,而是“他们版本的git merge -X ours”(这是git merge -s递归-X ours的缩写):
git checkout branchA
# also uses -s recursive implicitly
git merge -X theirs branchB
这就是Alan W. Smith的回答所做的。
只使用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合并-我们的”。它的内容与之前的选项相同(即只有来自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
这就是Paul Pladijs的答案所做的(不需要一个临时分支)。
特殊情况
如果branchB的提交是branchA的祖先,git merge将不起作用(它只会退出,并显示“Already up to date.”这样的消息)。
在这种或其他类似/高级的情况下,可以使用低级命令git提交树。