2016-12-07 71 views
0

在这个主题上似乎有千变异,并且许多已被问到,但我似乎无法为我找到合适的解决方案。git:checkout vs merge vs ??为解决有利于我们选择的冲突

我有两条发展线,一条是关于我(我们)完成的“主人”,另一条是关于“their_new_stuff”的分支。两者都改变​​了大量的文件,触及同一地点的许多文件并产生冲突。

现在我需要将他们的工作合并到我们的工作中,并以下列方式处理冲突:对于99%的冲突,我可以简单地接受“我们的”。但是,我也需要他们所做的所有不相互冲突的改变,并且在一些关键冲突中,我需要接受他们的或者手工合并。了解哪些文件需要手动合并或合并需要人工检查。

我曾尝试以下:

尝试1:

git merge their_new_stuff 
# for each file with conflicts: 
    # if requires manual merge: 
     # do manual merge 
    # else: 
     git checkout --ours all/files/not/merged/by/hand.cc 

起初我以为这是我想要的,但是这并不工作,因为结帐用“我们”是完整文件结帐,并且不仅检出/解决冲突的部分。所以我失去了他们想要的非冲突性变化。

尝试2:

git merge -s recursive -Xours their_new_stuff 

这不起作用,因为它不允许单个文件合并。我需要知道哪里存在冲突,并且希望看到具有冲突标记的文件版本来帮助我进行手动合并,所以理想情况下,我会在合并失败后执行某些操作。

尝试3:然后我想我或许可以这样做:

git merge their_new_stuff 
# for each file with conflict: 
    # if file needs manual merge: 
     cp file file2 
git merge --abort 
git merge -s recursive -Xours their_new_stuff 
# for each file with manual merge: 
    cp file2 file 
    # merge by hand 

我认为这应该工作,但感觉很klugy。有没有一种“正确”的方式来做到这一点?理想情况下,我想做类似的事情:

git merge their_new_stuff 
# for each file with conflict 
    # if needs manual merge 
     # do manual merge 
    # else 
     # is there any command that does something like?: 
     git remerge -s recursive -Xours file 

实际上我想做合并,得到冲突标记。检查手动合并,如果不需要手动合并,请使用“-Xours”重新合并该文件。这可能吗?

+0

的Git确实有'混帐合并-file',你可以在每个文件的基础上使用。请注意,为了*要*使用它,您必须从基础(阶段1),本地('--ours')和其他(' - 他们')文件中提取(通常从索引的三个阶段)到普通的文件系统文件。请注意,'merge-file' *会带'-​​-ours'和'--theirs',它们具有'-X'风格的含义。 – torek

+0

@torek谢谢,不知道。这很有趣 - 我想我可以做一个''merge''来查看冲突,然后放弃,然后在“keep our”文件和''merge-file''上使用'merge-file --ours''没有''--ours''来获取“手动合并”文件中的冲突标记。如果更好的东西不会很快出现,请随时让这个答案,我会接受。 –

+0

您甚至不需要(也可能不想)中止合并:要将文件的三个索引版本提取到临时文件中,并且只有在文件保持未解析状态时,这些文件才保留在*索引中。 (另请参阅:'git ls-files --stage','git ls-files --unmerged'。) – torek

回答

1

Git是一个基于程序存储库的版本控制系统,这意味着改变状态在一个Git分支普遍适用于所有文件分支。这在概念上与其他VCS工具(如SVN)不同,在这些工具中可以操作和提交单个文件。 Git中没有任何概念作为单个文件合并。如果合并两个分支,那么全部为这些文件在合并期间需要协调。

两者都改变​​了大量的文件,触及同一地点的许多文件并产生冲突。

我相信这是你问题的根本原因。理想情况下,你和你的合作伙伴应该在代码库的不同领域工作,这样当你合并时,冲突最小。在我看来,大量的合并冲突意味着糟糕的分支设计和战略。在同一个Java类中工作的两个软件人员可能会导致合并冲突,在同一个方法中工作的两个人甚至更糟。尝试查看是否可以通过尽可能减少冲突的方式来分隔您的疑虑。

这就是说,关于你目前的问题,我只是建议你手动合并。如果你确信你想要的文件的父母任何一方的版本,然后使用下列之一:

git checkout --theirs <path/to/file.ext> 
git checkout --ours <path/to/file.ext> 
+0

感谢您的回答。是的,我知道合并是一个全新的概念,但我的印象(我是一个长期的mercurial用户,但是对git来说是新手)是git对于大块级合并有很多支持。我想这就是我需要学习的东西?虽然你的理想情况会很​​好,但这个项目并不是十几个开发者的情况。 99%的冲突实际上是一个改变了的构造函数接口,两个人实际上以几乎相同的方式改变了它。 –

+0

@EthanCoon根据我的经验,如果你不够聪明来解决一个丑陋的合并冲突,那么Git通常不是。是的,你可以尝试创建脚本来自动执行此操作,但在解决合并冲突时我总是偏执狂,而且总是手动执行。也许别人会给你一个不同的答案。 –

+0

我很聪明,我只是懒惰!一眼就能看出我想要“我们的”,但只是为了改变界面。由于checkout IS是文件明智的,而不是明智的,这是行不通的。如果文件只有接口更改冲突,那么解决所有有利于我们的冲突是可行的,但我似乎没有足够的智能来告诉git这样做。 –