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

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

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

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


当前回答

旧版本的git允许你使用“their”合并策略:

git pull --strategy=theirs remote_branch

但是这已经被删除了,正如Junio Hamano (Git维护者)在这条消息中解释的那样。正如链接中提到的,相反,你会这样做:

git fetch origin
git reset --hard origin

但是要注意,这与实际的合并不同。你的解决方案可能就是你真正在寻找的选项。

其他回答

要真正正确地进行合并,只从合并的分支获取输入,你可以这样做

Git merge——strategy=我们的ref-to-be-merge

Git diff——binary ref-to-be-merged | Git apply——reverse——index

Git提交—修改

在我所知道的任何场景中都不会有冲突,您不必创建额外的分支,它就像正常的合并提交一样。

然而,这在子模块中并不适用。

我解决了我的问题

git checkout -m old
git checkout -b new B
git merge -s ours old

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

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

这个答案是由Paul Pladijs给出的。为了方便起见,我只是把他的命令做了一个git别名。

编辑你的.gitconfig并添加以下内容:

[alias]
    mergetheirs = "!git merge -s ours \"$1\" && git branch temp_THEIRS && git reset --hard \"$1\" && git reset --soft temp_THEIRS && git commit --amend && git branch -D temp_THEIRS"

然后你可以“git merge -s their A”通过运行:

git checkout B (optional, just making sure we're on branch B)
git mergetheirs A

一个简单而直观的(在我看来)两步方法是

git checkout branchB .
git commit -m "Picked up the content from branchB"

紧随其后的是

git merge -s ours branchB

(将两个分支标记为合并)

唯一的缺点是它不能从当前分支中删除branchB中已删除的文件。然后,两个分支之间的简单区别将显示是否存在这样的文件。

这种方法还可以从之后的修订日志中清楚地看出所做的工作以及意图。