“git merge -s theirs”需要 - 但我知道它不存在 [英] "git merge -s theirs" needed -- but I know it doesn't exist

查看:529
本文介绍了“git merge -s theirs”需要 - 但我知道它不存在的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些远程仓库,我想合并在一起。这些存储库中的一些子树是远程唯一的(它们包含特定于主机的数据),其他子树包含所有远程数据共享的数据。



我想要做的是,对每个遥控器运行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和一个自定义的mergetool来完成一些魔术,只需将$ REMOTE文件复制到$ MERGED即可,我已经阅读了链接我有一个他们的版本的git merge -s我们的?,在这个网站的帖子和Junio Hamano的文章引用解释为什么git merge -s theirs是一个坏主意,但不是这样的情况我。我重视旧的历史,但我需要跳船,并跟随远程站点上的变化,当一个发生。在本地站点上不进行新的工作。它只需要形成一个所有远程站点的组合,从一个更改时上次轮询的远程的最新共同文件。



感谢您提供任何帮助

解决方案

非常感谢@VonC建议使用 merge = custom-driver 文件中的 / strong>属性。虽然这将工作,我不愿污染我的工作空间.git文件,虽然我可以使用 $ git_DIR / info / attributes 以避免污染, m需要2个规则来捕获点文件和非点文件。



经过一些实验,我设法得到一个解决方案与 merge.default 配置变量(在 gitattributes(5)联机帮助页中提及)。我错过的诀窍是 merge.default 接受您之前定义的自定义驱动程序的名称;您不必直接向其提供自定义命令。这是对我有用...



首先定义您的复制合并自定义驱动程序。您可以直接使用shell命令;没有必要使用外部脚本(只要确保你的shell元字符引用正确):

  git config merge。 copy-merge.name'复制合并'
git config merge.copy-merge.driver'mv%B%A'

请注意,mv在成功时返回0,失败时返回1,满足将success合并回git的条件。



git所有合并都是复制合并:

  git config merge.default copy-merge 

Hey 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路径/ / copy-merge / in / path / to / normal-merge / in 
echo'* merge'> .gitattributes
echo'。* merge'>> .gitattributes

警告:乱丢您的工作树与大量的.gitattributes文件必然导致混乱,特别是如果你还在其他目录中使用诸如* .bin -merge之类的方法强制所有.bin文件的合并都会由于冲突而失败。对于这类事情,最好使用 $ GIT_DIR / info / attributes


I have a number of remote repositories that I want to merge together. Some of the subtrees in those repositories are unique to the remote (they contain data that is host-specific), other subtrees contain data that is (supposed to be) common across all remotes.

What I want to do, essentially, is run "git pull " for each remote. This will fast-forward the local master branch along the tracking branch for the remote master for host-specific files that have changed on the remote, and will do nothing for the common files because they will not have changed.

A change in a common file (call it F, with the change being F') shouldn't be a problem, even if it only happens on one remote at first. git-merge will Do The Right Thing and give me a copy of F' in my composite workspace, which is what I want. The problem comes if the same common file changes in a different way on another remote (call it F"). git-merge will give me a composite of F' and F", which isn't what I want. All I want is F".

When I worked with ClearCase we called this a copy-merge. The result of the merge was always an exact copy of the contributor. This sounds a lot like "git merge -s theirs" would be, except that it doesn't exist.

I wondering whether I can cook something up with "git-read-tree -m --trivial" to get the fast-forward merges out of the way, then do some magic with git-merge and a custom mergetool that simply copies the $REMOTE file to $MERGED. But even with that I don't see how I can stop git-merge from compositing F' and F" if it things the merge is trivial.

I've read the link Is there a "theirs" version of "git merge -s ours"? on this site, and the post by Junio Hamano it references explaining why "git merge -s theirs" is such a bad idea, but this isn't the case for me. I do value the old history, but I need to jump ship and follow the change on the remote site when one happens. No new work is done on the local site. It simply needs to form a composite of all the remote sites, taking the latest "common" file from the last polled remote when one changes.

Thanks in advance for any help you can give me.

解决方案

Many thanks to @VonC for suggesting the use of the merge=custom-driver attribute in the .gitattributes file. While this will work, I'm reluctant to pollute my workspace with .git files, and while I could use $GIT_DIR/info/attributes to avoid the pollution, I'm bothered by the need for 2 rules to catch dot-files and non-dot files.

After a bit of experimentation I managed to get a solution with the merge.default configuration variable (mentioned in the gitattributes(5) manpage) working. The trick I missed was that merge.default takes the name of a custom driver you have defined previously; you don't give it the custom command directly. Here's what works for me...

First define your copy-merge custom driver. You can use shell commands directly; there's no need for an external script (just make sure you get your shell meta-character quoting right):

git config merge.copy-merge.name   'Copy Merge'
git config merge.copy-merge.driver 'mv %B %A'

Note that mv returns 0 on success, 1 on failure, meeting the criteria for reporting merge "success" back to git.

Now tell git that ALL merges are copy-merges:

git config merge.default copy-merge

Hey Presto! Job done. git merge <branch> will now copy-merge everything so the branch you're on contains exact copies of all files on <branch>. QED.

If you want to do a non-copy-merge then simply reset the default merge driver:

git config --unset merge.default

If you do want to be more selective then leave merge.default unset and use attributes as @VonC says:

cd path/to/copy-merge/in
echo '* merge=copy-merge'  >  .gitattributes
echo '.* merge=copy-merge' >> .gitattributes

Do this at the top of every subtree you want to copy-merge in. If there's a sub-subtree that you DON'T want to copy-merge in, you can turn it off again:

cd path/to/copy-merge/in/path/to/normal-merge/in
echo '* merge'  >  .gitattributes
echo '.* merge' >> .gitattributes

WARNING: littering your working tree with lots of .gitattributes files is bound to lead to confusion, especially if you also use things like "*.bin -merge" in other directories to force all merges of .bin files to fail with conflicts. It may be better to use $GIT_DIR/info/attributes for this sort of thing, as it has the highest precedence.

这篇关于“git merge -s theirs”需要 - 但我知道它不存在的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆