当使用git merge将主题分支“B”合并为“A”时,我得到了一些冲突。我知道所有的冲突都可以用B的版本解决。

我知道git合并是我们的。但我想要的是类似git merge -s的东西。

为什么它不存在?如何在与现有git命令冲突合并后实现相同的结果?(git从B中检出所有未合并的文件)

仅仅丢弃分支A中的任何东西(合并提交点到树的B版本)的“解决方案”不是我想要的。


当前回答

我最近需要为两个共享共同历史的独立存储库执行此操作。我从:

Org/repository1主 Org/repository2主

我希望将repository2 master的所有更改应用到repository1 master,接受repository2所做的所有更改。在git的术语中,这应该是一个称为-s their的策略,但它不存在。要小心,因为-X their的名字就像你想要的那样,但它不是一样的(它甚至在手册页中这样说)。

我解决这个问题的方法是到repository2并创建一个新的分支repo1-merge。在那个分支中,我运行git拉git@gitlab.com:Org/repository1 -s ours,它合并得很好,没有问题。然后我把它推到遥控器上。

然后回到repository1并创建一个新的分支rep2 -merge。在该分支中,我运行git拉git@gitlab.com:Org/repository2 repo1-merge,它将与问题一起完成。

最后,您可能需要在repository1中发出合并请求,使其成为新的主节点,或者只是将其作为一个分支。

其他回答

请参阅Junio Hamano被广泛引用的答案:如果您要丢弃已提交的内容,那么只需丢弃提交,或者无论如何要将其排除在主历史记录之外。将来为什么要麻烦每个人从没有提供任何东西的提交中读取提交消息呢?

但有时会有管理要求,或者其他原因。对于那些你真的必须记录没有贡献的提交的情况,你想要:

(编辑:哇,我以前错了吗?这个是可行的。)

git update-ref HEAD $(
        git commit-tree -m 'completely superseding with branchB content' \
                        -p HEAD -p branchB    branchB:
)
git reset --hard

你想要的结果是什么并不完全清楚,所以在答案和他们的评论中有一些关于“正确”方法的困惑。我试着给出一个概述,并看到以下三个选项:

尝试合并并使用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提交树。

等价于'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}'

这并不一定能回答最初发帖者的问题,但我在这里遇到的情况是,我已经尝试了合并,但最终发生了冲突。通常我在IDE中管理冲突,但当我无法访问时,可以使用以下REGEX来查找并替换“their”内容的差异:

Replce <<<<<<< HEAD\n[^•>]+\n==========\n([^•>]+)>>>>>>> .+\n with \1

(以防其他人因为和我一样的原因登陆这个页面)。

如果你在分支A上,请:

git merge -s recursive -X theirs B

在git版本1.7.8上测试