VS 2013 C# 和 Git:拉取时不合并 .csproj 文件 [英] VS 2013 C# and Git: .csproj files don't merge upon pulling

查看:21
本文介绍了VS 2013 C# 和 Git:拉取时不合并 .csproj 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Me and a friend are working on a project written in C# using VS 2013 Express with Git (not the VS Git Plugin, mind you), and we're running into a problem. Our workflow is setup like this: we have a central repository, and we each have our own fork of the repository that we work on separately. When our individual work is done we push to the central repository. When we want to sync with the central repository, we pull.

问题是我们pull的时候,csproj文件随机更新.有时他们会正确更新并且自上次拉取后添加的文件正确显示在 VS 中,而其他时候 csproj 文件完全不受影响.

The problem is that when we pull, the csproj files randomly update. Sometimes they properly update and the files that have been added since the last pull properly show up in VS, and other times the csproj file is completely unaffected.

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

It's strange because the csproj gets updated properly everywhere else, including the central repository, it just sometimes doesn't update properly when we pull.

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

In our .gitattributes file we have .csproj set to merge=union.

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

The command we perform when pulling is git pull upstream where upstream is just a remote pointing to our central repository.

有什么想法吗?

推荐答案

我会把这个作为答案,基于 Edward Thomson 的评论,其中包含指向 合并 csproj 文件中的冲突 (haacked.com/archive/2014/04/16/csproj-merge-conflicts).请注意,我对 Visual Studios、C# 或 Windows 一无所知,但我了解 git.:-)

I'll put this in as an answer, based on Edward Thomson's comment, which contains this link to Merge conflicts in csproj files (haacked.com/archive/2014/04/16/csproj-merge-conflicts). Please note that I know nothing about Visual Studios, C#, or Windows, but I do know about git. :-)

问题是我们pull的时候,csproj文件随机更新.有时他们会正确更新并且自上次拉取后添加的文件正确显示在 VS 中,而其他时候 csproj 文件完全不受影响.

The problem is that when we pull, the csproj files randomly update. Sometimes they properly update and the files that have been added since the last pull properly show up in VS, and other times the csproj file is completely unaffected.

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

First, let's do a few brief review notes:

  1. git pull 只是 git fetch 后跟 git merge.你可以告诉 Git 做一个 rebase 代替.根据您的开发流程,这可能是个好主意,但不会改变这个特定问题,因为......
  2. Git 中没有其他任何东西可以提交,但是......
  3. 其他几个命令,包括 git rebase,使用合并 machinery.
  4. 推送 (git push) 从不 进行任何合并,因此您只会在在我和其他人都做了某事后获取新东西"中看到问题;案件.即便如此,您是否看到问题在很大程度上取决于您和其他人的所作所为.这是因为 git mergegit rebase 使用的合并机制并不那么聪明.
  1. git pull is just git fetch followed by git merge. You can tell Git to do a rebase instead. This may be a good idea depending on your development flow, but won't change this particular problem, because ...
  2. Nothing else in Git makes merge commits, but ...
  3. Several other commands, including git rebase, use the merge machinery.
  4. Pushing (git push) never does any merging, so you will only see the problem in the "get me new stuff after both I and someone else did something" case. Even then, whether you see the problem depends quite heavily on what you and the someone-else did. This is because the merge machinery, used by both git merge and git rebase, is just not that smart.

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

Now let's take a look at the underlying problem, which (based on the link) is that these *.csproj files contain XML: structured data that git's built-in text-oriented merge operations cannot merge correctly.

当在git diff 输出中,两条不同的开发线(正在合并的分支或提交)对同一区域进行不同 更改时,更改会发生冲突 单个文件.一个经典的例子出现在文件中,当两个编辑器不能就拼写达成一致时.例如,我前段时间做了这个改动:

Changes conflict when, in the git diff output, two different lines of development (the branches or commits being merged) made different changes to the same region of a single file. One classic example occurs in files when two editors cannot agree on spelling. For instance, I made this change some time ago:

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.
 
 egin{plate*}[h]

如果我将其与对差异中显示的任何行进行不同更改但留下灰色"的其他人合并用字母 a 拼写,我会遇到冲突.例如,如果我的编辑坚持将单词拼写为kangaru",更改就会发生冲突:

If I were to merge this with someone else who made a different change to any of the lines shown in the diff, but left "grey" spelled with the letter a, I would get a conflict. For instance, if my editor were to insist that the word be spelled "kangaru", the changes would conflict:

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

当 git 遇到冲突的更改时,它通常的反应是简单地声明存在冲突并停止. 它为您留下包含冲突标记的文件的工作树版本 <<<<<<< ======== >>>>>>> 围绕冲突的双方(以及基础版本之上的 |||||| 当且仅当您设置 merge.conflictstylecode> 到 diff3):

When git encounters conflicting changes, its usual reaction is to simply declare that there is a conflict and stop. It leaves you with a work-tree version of the file containing conflict markers <<<<<<< ======= >>>>>>> surrounding both sides of the conflict (along with ||||||| above the base version if and only if you set merge.conflictstyle to diff3):

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

egin{plate*}[h]

再说一次,这是默认行为.您可以通过命令行开关.gitattributes文件更改默认值.

Again, though, this is the default behavior. You can, through command line switches or a .gitattributes file, change the default.

您选择了 union 合并,并且 git 文档有所改进:

You selected the union merge, and the git documentation has been improved a bit:

联合

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

Run 3-way file level merge for text files, but take lines from both versions, instead of leaving conflict markers. This tends to leave the added lines in the resulting file in random order and the user should verify the result. Do not use this if you do not understand the implications.

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

(boldface mine). The short version here, though, is that git will believe the merge succeeded (well, it did succeed) but will do so by producing an invalid XML file. There are examples on the linked haacked.com page of exactly how this goes wrong for the *.csproj files, but this is generally true of any union merge: it's not smart enough to get the right result and there are few places where it is a reasonable driver. It would make some sense to invoke it manually in some cases, then review the file and make any fixups by hand, but since it just succeeds and lets the merge proceed, you must be very careful with putting it in .gitattributes.

理想情况下,我们希望有一个合并驱动程序能够理解 XML 格式.csproj 文件的意图(仅 XML 格式不足以满足标记与语法无关).由于我没有在Windows上使用VS,所以只能再次引用haacked.com的文章:

Ideally, we would like to have a merge driver that understood XML formatting and the intent of a .csproj file (XML formatting alone is not sufficient as the semantics of the markup are not tied to the syntax). Since I do not use VS on Windows, I can only quote the haacked.com article again:

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

Another way would be to write a proper XML merge driver for Git, but that’s quite a challenge as my co-worker Markus Olsson can attest to. If it were easy, or even moderately hard, it would have been done already. Though I wonder if we limited it to common .csproj issues could we write one that isn’t perfect but good enough to handle common merge conflicts? Perhaps.

如果内容像示例XML一样简单,我觉得这样的驱动不会太难,所以我怀疑它们会变得更复杂.

If the contents are as simple as the example XML, I think such a driver would be not too difficult, so I suspect they get more complicated.

这篇关于VS 2013 C# 和 Git:拉取时不合并 .csproj 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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