当前位置:  开发笔记 > 开发工具 > 正文

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

如何解决《是否有"他们的"版本的"gitmerge-sours"?》经验,为你挑选了11个好方法。

当使用主题分支"B"合并到"A"时git merge,我会遇到一些冲突.我知道使用"B"中的版本可以解决所有冲突.

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

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

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



1> Alan W. Smit..:

添加-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


值得注意的是,这与"合并策略"他们的"合并策略"并不相同.-Xtheirs是应用于递归_strategy_的策略_option_.这意味着递归策略仍然可以合并任何东西,并且只有在发生冲突时才会回归到"他们的"逻辑.虽然这是大多数情况下需要的,但这与"只从分支B中取出所有内容"不同.无论如何,它确实是真正的合并.
这是一个可怕的答案,因为它看起来是正确的,但实际上是错误的."git merge -X他们的"*不会做"git merge -s theirs"会做什么.它不会将当前分支替换为合并分支的内容.它更喜欢"他们的"变化,但仅在发生冲突的情况下.因此,结果提交可能与"他们的"分支完全不同.这不是问题海报的想法.
请参阅下面的其他答案,以获得原始问题的更好解决方案(Paul Pladijs).
@ user3338098:是的,你是对的.我重新阅读了这个问题,这也不是那么好.不幸的是,混淆的根本原因不是答案,甚至不是问题.git作者的设计选择是为合并策略赋予"我们的"同名,并选择合并策略"递归".在这种情况下的混乱实际上是不可避免的.
它也适用于其他命令.我刚做了一个'git cherry-pick sha1 -X他们的'.谢谢!
@IvanKrivyakov这只是一个可怕的答案,因为这个问题太可怕了,OP希望与`git merge -X our`相反,而不是'git merge -s our`的反面.这个答案应该反映*问题*实际上*无效*.

2> Paul Pladijs..:

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


@ chrispepper1989 _-x theirs_只影响_conflicts_,如果我们的hunk可以干净利用,它将通过生成的合并.在这种情况下,如最后一个命令所示,无论是否存在冲突,我们都会获得与branchB完全相同的合并.
@ cdunn2001:不知怎的,我想到了同样的事情,但没有.请注意,`git reset --hard`会更改`branchA`指向的内容.
很抱歉问一个愚蠢的问题,但为什么这种方法更好-usheirs?有什么优点/缺点
@UncleZeiv感谢您的解释,所以基本上做"他们的"将保持无冲突的更改和文件导致int代码与提取的代码不同.

3> Pat Notz..:

较旧版本的git允许您使用"他们的"合并策略:

git pull --strategy=theirs remote_branch

但是这已被删除,正如Junio Hamano(Git维护者)在此消息中所解释的那样.如链接中所述,您可以这样做:

git fetch origin
git reset --hard origin

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


令人遗憾的是,他们的'他们的'被删除了,因为理由是不完整的.它无法允许代码良好的那些实例,只是上游维持在不同的哲学基础上,所以在这个意义上是"坏",所以人们确实希望与上游保持同步,但是同时保留好的代码"修复"[git&msysgit因为它们不同的目标平台的哲学而具有这种"冲突"的一部分]
我真的不明白Junio Hamano的解释.如何`git reset --hard origin`是他们风格合并的解决方案?如果我想将BranchB合并到BranchA中(就像在Alan W. Smith的回答中那样),我将如何使用`reset`方法?
@James McMahon:Junio C Hamano的观点不是`git reset --hard`做了"他们的"式合并.当然,`git reset --hard`不会创建任何合并提交,也不会创建任何提交.他的观点是_we不应该使用merge_来替换HEAD中的任何东西.不过,我不一定同意.
我真的不明白这个哲学.我只是使用了`theirs`,因为我不小心改变了两个独立分支中的一些文件,并且想要丢弃一个文件的更改,而不必为每个文件手动执行.

4> musicmatze..:

我从现在开始使用Paul Pladijs的答案.我发现,你可以做一个"正常"合并,发生冲突,所以你这样做

git checkout --theirs 

通过使用来自其他分支的修订来解决冲突.如果对每个文件执行此操作,则会产生与预期相同的行为

git merge  -s theirs

无论如何,努力比合并策略更多!(这是用git版本1.8.0测试的)



5> siegi..:

目前还不完全清楚你期望的结果是什么,所以对于在答案和评论中这样做的"正确"方式存在一些困惑.我尝试概述并查看以下三个选项:

尝试合并并使用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

请注意,现在合并提交第一个父级是来自branchB且仅来自第二个父级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的回答(不需要临时分支).



6> elmarco..:

我解决了我的问题

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



7> rafalmag..:

如果你在分支A上做:

git merge -s recursive -X theirs B

测试了git版本1.7.8



8> Gandalf458..:

当使用git merge在"A"中合并主题分支"B"时,我会遇到一些冲突.我>知道使用"B"中的版本可以解决所有冲突.

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

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

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

git checkout Branch
git merge master -s ours

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

git checkout master
git merge Branch



9> thoutbeckers..:

要真正正确地执行合并,需要合并您正在合并的分支的输入即可

git merge --strategy=ours ref-to-be-merged

git diff --binary ref-to-be-merged | git apply --reverse --index

git commit --amend

在我知道的任何场景中都不会发生冲突,您不必进行额外的分支,它就像普通的合并提交一样.

但是,这对子模块不起作用.



10> jthill..:

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

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

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

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



11> VonC..:

为什么不存在?

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

-X误写了“ ”用于合并的文档以表明-s theirs存在“ ”,事实并非如此。

参见Junio C Hamano()提交的commit c25d98b(25 Sep 2017 )。(通过合并JUNIOÇ滨野- -提交4da3e23,2017年9月28日)gitster
gitster

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

-Xours合并选项的描述带有括号,告诉读者它与完全不同-s ours,这是正确的,但-Xtheirs随后的描述却粗心地说“这与ours” 相反,给读者以错误的印象请注意,它与根本不同-s theirs,实际上甚至不存在。

-Xtheirs是应用于递归策略的策略选项。这意味着递归策略仍将合并所有可能的内容,并且仅theirs在发生冲突时才退回到逻辑上。

有关theirs合并策略是否相关的争论最近在2017年9月的这个话题中引起了人们的注意。
它承认较旧的(2008)线程

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

它提到了别名:

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

雅罗斯拉夫·哈尔琴科(Yaroslav Halchenko)再次尝试倡导该策略,但Junio C. Hamano补充说:

我们和他们之所以不对称的原因是因为你是你而不是他们-我们历史及其历史的控制和所有权不是对称的。

一旦确定他们的历史是主线,您就希望将您的开发线视为分支,并在该方向上进行合并,即,产生的合并的第一个父项是对他们的历史的提交,第二个父母是您历史上的最后一个坏人。因此,您最终将使用“ checkout their-history && merge -s ours your-history”来保持初婚年龄。

在这一点上,使用“ -s ours”不再是缺少“ -s theirs” 的解决方法。
它是所需语义的适当部分,即,从尚存的规范历史路线的角度来看,您想要保留它所做的事情,而使其他历史路线所做的事情无效

Junio补充说,正如Mike Beaton所说:

git merge -s ours 有效地说:“标记提交在其分支上被弥补为永久忽略的提交”;
这很重要,因为如果您随后从其分支的较后状态进行合并,则将引入其较后的更改,而不会引入被忽略的更改

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有