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

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

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

更新:只是丢弃分支 A 中的任何内容(树的 B 版本的合并提交点)的“解决方案”不是我正在寻找的。

有帮助吗?

解决方案

-X 选项添加到他们的。例如:

git checkout branchA
git merge -X theirs branchB

所有东西都会以所需的方式合并。

我见过的唯一问题是文件是否从branchB中删除。如果git之外的其他东西都被删除,它们就会显示为冲突。

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

git rm {DELETED-FILE-NAME}

之后, -X他们的应该按预期工作。

当然,使用 git rm 命令进行实际删除可以防止冲突首先发生。


注意:还存在更长的表单选项。要使用它,请替换:

-X theirs

使用:

--strategy-option=theirs

其他提示

一种可行且经过测试的解决方案,用于将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

要自动化它,您可以使用branchA和branchB作为参数将其包装到脚本中。

此解决方案保留了合并提交的第一个和第二个父级,正如您所期望的 git merge -s the 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 our ”的“他们的版本”但是他们的 git merge -X our &quot; (这是 git merge -s recursive -X our 的缩写):

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 merge -s our &quot;的真实版本。它具有与之前选项相同的内容(即仅来自 branchB 的内容),但父项的顺序是正确的,即第一个父来自 branchA ,第二个来自 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版本上测试

  

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

     

我知道我们的git merge -s。但我想要的是像git merge&gt; -s他们的东西。

我假设你创建了一个master的分支,现在想要合并回master,覆盖master中的任何旧东西。这正是我在遇到这篇文章时想要做的事情。

完全按照你想做的去做,除了先将一个分支合并到另一个分支。我刚刚这样做了,效果很好。

git checkout Branch
git merge master -s ours

然后,结帐主人并将你的分支合并进去(现在会很顺利):

git checkout master
git merge Branch

要真正正确地执行合并,只需要从您正在合并的分支中输入 ,您就可以

git merge --strategy =我们的参与合并

git diff --binary ref-to-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

为什么它不存在?

虽然我在“git 命令使一个分支像另一个分支一样“如何模拟 git merge -s theirs, ,请注意 Git 2.15(2017 年第 4 季度)现在更加清晰:

' 的文档-X<option>``因为合并被误导地暗示了“-s theirs”存在,但事实并非如此。

提交 c25d98b (2017 年 9 月 25 日) 朱尼奥·C·滨野(gitster).
(合并于 朱尼奥·C·滨野—— gitster --提交 4da3e23, ,2017 年 9 月 28 日)

合并策略:避免暗示“-s theirs“存在

的描述 -Xours 合并选项的括号说明,告诉读者它与 -s ours,这是正确的,但是 -Xtheirs 随之而来的是,粗心地说:“这与 ours“给人一种错误的印象,即读者还需要警告它与 -s theirs, ,实际上根本不存在。

-Xtheirs 是一个 策略选择 应用于递归策略。这意味着递归策略仍然会合并任何它可以合并的东西,并且只会回退到“theirs“发生冲突时的逻辑。

关于相关性或不相关性的争论 theirs 合并策略最近被带回来 在这个九月2017年主题.
它承认 较旧的 (2008) 线程

简而言之,前面的讨论可以概括为“我们不希望”-s theirs’因为它鼓励了错误的工作流程”。

它提到了别名:

mtheirs = !sh -c 'git merge -s ours --no-commit $1 && git read-tree -m -u $1' -

雅罗斯拉夫·哈尔琴科试图再次倡导这一战略, 但朱尼奥·C.滨野补充道:

我们的历史和他们的历史之所以不对称,是因为你是你而不是他们——我们的历史和他们的历史的控制和所有权是不对称的。

一旦你决定他们的历史是主线,你宁愿将你的发展线视为一个侧分支,并朝那个方向进行合并,即生成的合并的第一个父级是对其历史记录的提交,第二个父级是历史记录中最后一个错误的提交。所以你最终会使用“checkout their-history && merge -s ours your-history“保持第一父母的明智。

那时,使用“-s ours“不再是缺乏”的解决方法-s theirs".
它是所需语义的适当部分,即从幸存的规范历史线的角度来看,你想要保留它所做的事情,取消另一条历史线所做的事情.

这个使用git plumbing命令读取树,但缩短了整体工作流程。

git checkout <base-branch>

git merge --no-commit -s ours <their-branch>
git read-tree -u --reset <their-branch>
git commit

# Check your work!
git diff <their-branch>

这会将你的newBranch合并到现有的baseBranch

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 checkout -B mergeBranch branchB
git merge -s ours branchA
git checkout branchA
git merge mergeBranch
git branch -D mergeBranch

这看起来很笨拙,但应该有效。唯一认为我真的不喜欢这个解决方案的是git历史会让人感到困惑......但至少历史记录会完全保留下来,你不需要为删除的文件做些特别的事情。

等效(保留父顺序)为'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

我们做了什么?  我们创建了一个新的提交,我们和他们的两个父母和他们的提交的contnet是branchB - 他们的

合并后:

更确切地说:

git commit-tree -m "take theirs" -p HEAD -p 'SOURCE^{commit}' 'SOURCE^{tree}'

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他们的A”。通过运行:

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

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

  • 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 使其成为新的主控,或者只是将其保留为分支。

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

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

接着是

git merge -s ours branchB

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

唯一的缺点是它不会从当前分支中删除已在branchB中删除的文件。之后两个分支之间的简单差异将显示是否存在任何此类文件。

这种方法也从修订日志中明确了之后所做的事情以及目标是什么。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top