我想要合并多个远程存储库。这些存储库中的一些子树对于远程控制器是唯一的(它们包含特定于主机的数据),其他子树包含在所有远程控制器中共同的(应该是)通用的数据。
基本上,我想要做的是为每个遥控器运行“git pull”。这将使远程主服务器的跟踪分支上的本地主分支快进到远程主服务器上已更改的特定于主机的文件,并且对公共文件不执行任何操作,因为它们不会更改。
公共文件中的更改(称为F,更改为F')应该不是问题,即使它最初只发生在一个远程上。 git-merge将做正确的事情并在我的复合工作区中给我一个F'的副本,这就是我想要的。如果同一个公共文件在另一个遥控器上以不同的方式改变(称之为F“),问题就出现了.git-merge将给我一个F'和F”的组合,这不是我想要的。我想要的只是F“。
当我使用ClearCase时,我们将其称为复制合并。合并的结果始终是贡献者的精确副本。这听起来很像“git merge -s theirs”,但它不存在。
我想知道我是否可以用“git-read-tree -m -trivial”来做一些事情来快速合并,然后用git-merge和一个自定义合并工具做一些魔术将$ REMOTE文件复制到$ MERGED。但即便如此,我也看不出如何通过合成F'和F来阻止git-merge,如果合并的话很简单。
我已经阅读了这个网站上的Is there a "theirs" version of "git merge -s ours"?链接,Junio Hamano的帖子引用了解释为什么“git merge -s theirs”是一个坏主意,但对我来说情况并非如此。我确实重视旧的历史,但我需要跳出船并在发生事件时跟踪远程站点上的更改。本地站点上没有新工作。它只需要形成所有远程站点的组合,从最后一个轮询的远程站点获取最新的“公共”文件。
提前感谢您提供的任何帮助。
答案 0 :(得分:8)
非常感谢@VonC建议在 .gitattributes 文件中使用 merge = custom-driver 属性。虽然这样可行,但我不愿意用.git文件污染我的工作区,虽然我可以使用 $ GIT_DIR / info / attributes 来避免污染,但我因为需要2个规则来捕获点文件和非点文件而感到困扰。
经过一些实验,我设法获得了一个解决方案,其中包含 merge.default 配置变量(在 gitattributes(5)联机帮助页中提到)。我错过的技巧是 merge.default 获取您之前定义的自定义驱动程序的名称;你不直接给它自定义命令。这对我有用......
首先定义复制合并自定义驱动程序。您可以直接使用shell命令;不需要外部脚本(只需确保你的shell元字符引用正确):
git config merge.copy-merge.name 'Copy Merge'
git config merge.copy-merge.driver 'mv %B %A'
请注意,mv在成功时返回0,在失败时返回1,满足将合并“成功”报告回git的标准。
现在告诉git所有合并都是复制合并:
git config merge.default copy-merge
嘿Presto!任务完成。 git merge< branch> 现在将复制合并所有内容,以便您所在的分支包含< branch>上所有文件的精确副本。 QED。
如果您想进行非复制合并,则只需重置默认合并驱动程序:
git config --unset merge.default
如果您确实想要更具选择性,请保留 merge.default 取消设置并使用@VonC所说的属性:
cd path/to/copy-merge/in
echo '* merge=copy-merge' > .gitattributes
echo '.* merge=copy-merge' >> .gitattributes
在要复制合并的每个子树的顶部执行此操作。如果存在您不想复制合并的子树,则可以再次将其关闭:
cd path/to/copy-merge/in/path/to/normal-merge/in
echo '* merge' > .gitattributes
echo '.* merge' >> .gitattributes
警告:使用大量.gitattributes文件乱丢你的工作树一定会导致混淆,特别是如果你在其他目录中也使用“* .bin -merge”之类的东西强制.bin文件的所有合并失败冲突。为这类事情使用 $ GIT_DIR / info / attributes 可能更好,因为它具有最高优先级。
答案 1 :(得分:3)
前几天遇到这个问题:
http://seanius.net/blog/2011/02/git-merge-s-theirs/
git merge -s ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply -R --index
git commit -F .git/COMMIT_EDITMSG --amend
答案 2 :(得分:2)
(更新2011:
答案“ git command for making one branch like another ”列出所有 模拟git合并的可能方式 - 他们的)
对于您要复制合并的特定文件/树,您可以设置 gitattributes value ,就像我在此SO question中提到的那样,定义自定义合并驱动程序。
与merge属性关联的脚本将确保始终将远程文件保留为合并结果(有关说明,请参阅此SO answer,尽管情况相反 - 保留本地版本。)
echo * merge=keepTheir > dirWithCopyMerge\.gitattributes
git config merge.keepTheir.name "always keep theirduring merge"
git config merge.keepTheir.driver "keepTheir.sh %O %A %B"
通过在要复制合并的子树上设置.gitattribute,并以“* merge=keepTheir
”作为其内容,您可以将自定义合并驱动程序有效地归属于该子树的所有文件(注意在这里使用'*
'通配符。)
将keepTheir.sh改为:
mv -f $3 $2
exit 0
您不必修改任何“默认”合并驱动程序,只对自己想要的文件应用自己的合并驱动程序。
答案 3 :(得分:2)
在Git的1.7.1版本中,您可以传递“他们的”策略来合并和“-Xtheirs”参数。
git merge -Xtheirs otherBranch
不确定这是否适用于你想要做的事情,但它可能值得一试。
答案 4 :(得分:0)
经过大量的研究,经历了所有的SO噪音,并再次了解git
(它有没有结束?),我相信这个答案是最大的噪音 - 实现自定义--strategy theirs
模拟合并驱动程序的免费且最佳方式。可按需使用,不需要gitattributes
垃圾。
对于这是--strategy theirs
模拟还是最平滑可用的checkout --theirs .
冲突解决方法,我实际上还是有点头晕。也许他们是等同的,但我必须诊断一些结果图才能完全理解,现在没时间了。
向@kbro道具做正确的事情追逐细节,并在https://stackoverflow.com/a/1911370/35946
中非常接近 [git:master]
是shell提示符显示。
<强> SETUP 强>
$ [git:master] git config merge.theirs.name 'simulate `-s theirs`'
$ [git:master] git config merge.theirs.driver 'cat %B > %A' # same as `mv` or `cp`, matter of taste
使用强>
$ [git:master] GIT_CONFIG_PARAMETERS="'merge.default=theirs'" git merge develop
奖励:ALIAS
$ [git:master] git config alias.merge-theirs \!GIT_CONFIG_PARAMETERS=\""'"merge.default=theirs"'"\"\ git\ merge
使用:ALIAS
$ [git:master] git merge-theirs develop
请注意GIT_CONFIG_PARAMETERS
的引号结构,因为它必须能够获取多个复杂值。获得BONUS命令行需要付出努力才能弄明白。
PS GIT_CONFIG_PARAMETERS
必须是SO上保密最好的秘密,我们几乎已经完成2016年,https://stackoverflow.com/search?q=git_config_parameters有1(一)个结果(1)