是否有 “他们的” 版本的“git merge -s ours”?

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

我知道git merge -s ours 。但是我想要的是git merge -s theirs东西。

为什么不存在?与现有git命令发生冲突合并后,如何获得相同的结果? ( git checkout B 中所有未合并的文件)

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

答案

-X选项添加到theirs 。例如:

git checkout branchA
git merge -X theirs branchB

一切都将以所需的方式合并。

我所见的唯一引起问题的原因是文件是否从 branchB 中删除。如果除 git 以外的其他操作删除,它们将显示为冲突。

修复很容易。只需使用已删除文件的名称运行git rm

git rm {DELETED-FILE-NAME}

之后, -X theirs应该可以按预期工作。

当然,使用git rm命令进行实际删除将首先避免发生冲突。


注意 :还存在一个较长格式的选项。要使用它,请替换:

-X theirs

与:

--strategy-option=theirs

将 BranchB 合并到我们已签出的 BranchA 中的可行且经过测试的解决方案:

# 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

但这已被删除,正如Junio Hamano (Git 维护者)在此消息中所解释的。如链接中所述,您可以执行以下操作:

git fetch origin
git reset --hard origin

但是请注意,这与实际合并不同。您的解决方案可能是您真正想要的选择。

从现在开始,我一直使用 Paul 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

这就是艾伦 · 史密斯(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

请注意,合并现在提交的第一个父对象是来自branchBbranchB ,只有第二个父对象来自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

这就是Paul Pladijs 的回答 (不需要临时分支)。

我用解决了我的问题

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

如果您在分支机构 A 上,请执行以下操作:

git merge -s recursive -X theirs B

在 git 版本 1.7.8 上测试

当使用 git merge 在 “A” 中合并主题分支 “B” 时,出现一些冲突。我知道所有冲突都可以使用 “B” 中的版本解决。

我知道 git merge -s 我们的。但是我想要的是 git merge> -s 他们的东西。

我假设您创建了 master 分支,现在想合并回 master,覆盖 master 中的所有旧内容。这正是我遇到这篇文章时想要做的。

确切地执行您要执行的操作,除了首先将一个分支合并到另一个分支中。我只是这样做了,效果很好。

git checkout Branch
git merge master -s ours

然后,结帐 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

据我所知,在任何情况下都不会发生冲突,您不必进行其他分支,并且它的行为就像普通的合并提交一样。

但是,这在子模块中不能很好地发挥作用。

请参见Junio Hamano 广为引用的答案 :如果您要丢弃已提交的内容,请丢弃已提交的内容,或者至少将其排除在主要历史记录之外。为什么将来要打扰每个人都从没有提供内容的提交中读取提交消息?

但是有时会有管理要求,或者可能还有其他原因。对于那些您真的必须记录不起作用的提交的情况,您需要:

(编辑:哇,我以前设法弄错了吗。这个有效。)

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