2016-04-24 90 views
1

我和一位朋友正在使用VS 2013 Express和Git编写一个用C#编写的项目(而不是 VS Git Plugin,请注意)以及我们遇到了问题。我们的工作流程是这样设置的:我们有一个中央仓库,每个仓库都有自己的仓库分支,我们分别处理。当我们完成个人工作时,我们会推送到中央存储库。当我们想要与中央存储库同步时,我们拉动。VS 2013 C#和Git:.csproj文件在合并时不会合并

问题是,当我们拉,csproj文件随机更新。有时它们会正确更新,自上次拉出后添加的文件在VS中正常显示,而其他时间则完全不影响csproj文件。

这很奇怪,因为csproj在其他地方得到了正确更新,包括中央存储库,它只是在我们拉动时有时无法正确更新。

在我们的.gitattributes文件中,我们有.csproj设置为merge=union

我们在拉动时执行的命令是git pull upstream,其中upstream只是远程指向我们的中央存储库。

任何想法?

+1

您是否习惯于在尝试拉取或合并之前确保将本地.csproj文件正确保存到磁盘(通过执行“全部保存”或类似操作)? –

+0

@MattiVirkkunen是的,我们是。 – user3002473

+0

除非您显示一些错误示例,否则不清楚发生了什么。但为什么你使用'merge = union'?这肯定会最终导致问题,即使这不是你现在看到的问题。 –

回答

4

我会把它作为回答,基于Edward Thomson's comment,其中包含此链接到Merge conflicts in csproj files (haacked.com/archive/2014/04/16/csproj-merge-conflicts)。请注意,我对Visual Studio,C#或Windows一无所知,但我确实知道git。 :-)

问题是,当我们拉,csproj文件随机更新。有时它们会正确更新,自上次拉出后添加的文件在VS中正常显示,而其他时间则完全不影响csproj文件。

首先,让我们做一些简短的复习笔记:

  1. git pull只是git fetch其次是git merge。您可以告诉Git改为执行rebase。这可能是一个好主意,这取决于你的开发流程,但不会改变这个特殊的问题,因为...
  2. 没有在其他的Git合并使得提交,但...
  3. 其他几个命令,包括git rebase,使用合并机器
  4. 推(git push从来没有没有任何合并,所以你只会看到“我和别人做了什么事情后”让我得到新东西的问题。即使那样,你是否看到问题依赖于你和别人做了什么。这是因为git mergegit rebase所使用的合并机器并不那么聪明。

现在让我们来看看下面的问题,这(基于链接)是这些*.csproj文件包含XML:结构化数据的git的内置面向文本的合并操作不能合并正确。

变化冲突时,在输出git diff,开发了两种不同线(分支或提交被合并)制成不同变化到单个文件的相同区域。一个典型的例子出现在两个编辑不同意拼写的文件中。举例来说,我前一段时间使这个变化:

diff --git a/plates.tex b/plates.tex 
index 09939ca..3dfc610 100644 
--- a/plates.tex 
+++ b/plates.tex 
@@ -15,7 +15,7 @@ that I took on a trip to parts of Australia in February of 2010 
\end{plate*} 
The kangaroo is probably the most widely known marsupial. 
There are actually four species of large kangaroo: 
-the red, the eastern and western gray, and the antilopine. 
+the red, the eastern and western grey, and the antilopine. 
There are also smaller tree-kangaroos and rat-kangaroos. 

\begin{plate*}[h] 

如果我与别人谁做出了不同的改变任何在差异中显示的行合并这一点,但留下“灰色”与拼写信a,我会得到一个冲突。举例来说,如果我的编辑都坚持这个词拼写“ kangaru ”,这些变化会冲突:

Auto-merging plates.tex 
CONFLICT (content): Merge conflict in plates.tex 
Automatic merge failed; fix conflicts and then commit the result. 

当混帐遇到冲突的更改,其通常的反应是简单地宣布,有冲突和停止。它给你留下一个工作树版本包含冲突的文件标记<<<<<<<=======>>>>>>>周围的冲突双方(连同|||||||基础版本以上当且仅当设置merge.conflictstylediff3):

\end{plate*} 
<<<<<<< HEAD 
The kangaru is probably the most widely known marsupial. 
There are actually four species of large kangaru: 
the red, the eastern and western gray, and the antilopine. 
There are also smaller tree-kangarus and rat-kangarus. 
||||||| merged common ancestors 
The kangaroo is probably the most widely known marsupial. 
There are actually four species of large kangaroo: 
the red, the eastern and western gray, and the antilopine. 
There are also smaller tree-kangaroos and rat-kangaroos. 
======= 
The kangaroo is probably the most widely known marsupial. 
There are actually four species of large kangaroo: 
the red, the eastern and western grey, and the antilopine. 
There are also smaller tree-kangaroos and rat-kangaroos. 
>>>>>>> master 

\begin{plate*}[h] 

虽然如此,但这是的默认行为。您可以通过命令行开关.gitattributes文件更改默认值。

您选择的union合并,the git documentation has been improved a bit

union

润3路文件级合并为文本文件,而是采取从两个版本的线条,而不是让冲突标记。这往往会以随机顺序在结果文件中留下添加的行,并且用户应验证结果。如果您不了解其含义,请不要使用它。

(粗体矿)。然而,这里的简短版本是,git会相信合并成功(它的确实成功了),但是会通过生成无效的XML文件来实现。在链接的haacked.com网页上有关于*.csproj文件如何出错的示例,但对于任何联合合并而言通常都是如此:它不够聪明,无法获得正确的结果,并且在很少的地方它是合理的驱动程序。在某些情况下手动调用它会很有意义,然后查看文件并手动进行修复,但由于它只是成功并让合并继续,所以您必须非常小心地将它放入.gitattributes

理想情况下,我们希望有一个理解的XML格式一个.csproj文件的意图合并驱动器(XML格式单独不足以作为标记的语义不依赖于语法)。由于我不在Windows上使用VS,所以我只能引用这个骇客。com文章:

另一种方法是为Git编写合适的XML合并驱动程序,但这是一个相当大的挑战,因为我的同事Markus Olsson可以证明这一点。如果这很容易,或者甚至是中等难度,那就已经完成了。尽管我不知道我们是否将它限制在常见的.csproj问题中,我们是否可以编写一个不完美但足够处理常见合并冲突的程序?也许。

如果内容与示例XML一样简单,我认为这样的驱动程序不会太困难,所以我怀疑它们会变得更加复杂。

+0

梦幻般的回答,真正清除了我对'union'合并策略的所有困惑。非常感谢! – user3002473