2016-04-24 89 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