2014-02-22 135 views
1

我在家裏使用Arch Linux倉庫中的git版本1.8.5.3,以及在Ubuntu 13.10中使用git版本1.8.1.2。在工作中,我們使用svn,所以我使用git svn處理它。合併兩個git-svn倉庫與常規git提交頂部

我在工作和家中使用git svn檢出了svn存儲庫。包含git-svn-id的提交消息是相同的。作者和日期也一樣。但是,由此產生的提交散列不一樣。

git svn fetch && git svn rebase 

工作正常。然而,如果我試圖通過git在兩個倉庫之間合併一些倉庫的提交,git自然不能檢測到父母並且吐出合併錯誤。

我在想,這隻能是由於哈希計算的變化。這也會打破其他git倉庫,所以可能這是一個連接到git svn的問題。

第一編輯

git log --pretty=raw 

表現出不同的父母,所有的提交。這解釋了不同的哈希值,但這是如何發生的呢?原來,如果我回到第一次提交,他們確實有相同的父母,因此是正確的哈希值。所以沿途某處,某事一定改變...

第二編輯

發現使用

git merge-base branch1 branch2 

的提交以下是SVN合併分支中的最後共同提交哈希值。這是預期的行爲?

第三編輯

什麼工作是使用

git cherry-pick hash 

和應用提交一個接一個......

更新

我的全部故障。我在工作時檢查了整個svn回購,但只有家中的箱子。這就是爲什麼從兩個svn分支合併開始,提交哈希是不同的。

+0

嘗試使用'git log --pretty = raw ...'轉儲所有提交信息並仔細比較結果。通常,如果兩個提交的_all_屬性重合,則提交SHA1也會重合。 – user3159253

+0

哦整齊,不知道。事實上,父母對於所有提交都是不同的...... – mxm

+0

>這是預期的行爲嗎? - 可能。 SVN和GIT合併在本質上是不同的。 Git將一組提交標記爲父提交,並且該提交沒有優先級。與此同時,SVN有「假合併」 - 合併提交在分支樹中佔有一席之地,合併提交被記錄在提交元信息中。 – user3159253

回答

4

我知道這種情況,我自己通過git-svn和一些同事一起使用SVN倉庫。

你基本上有兩種選擇:

簡單的方法是通過SVN只共享代碼。這是一個簡單的解決方案,因爲您只能將Git用作具有強大本地功能的高級SVN客戶端。這裏唯一警告的是:永遠不要經常重新提交已經進入SVN的提交!或者使用等效的rebase操作。 Git-svn在內部使用git-rebase來同步在沒有本地副本注意的情況下進入SVN的更改,並且必須對本地提交進行重新排序。

如果您決定通過Git共享代碼是一個好主意,而不涉及SVN,事情會變得更加複雜。

首先,您應該首先從SVN克隆存儲庫。這個存儲庫應該是每個人的主人,它應該包含遠程SVN分支,以及SVN中每個可能需要的分支的本地跟蹤分支。如果您需要它們,您也可以稍後創建它們。

要將存儲庫導入新機器,請將整個repo目錄(包括.git目錄)複製到新機器。

要共享代碼,請在某處創建一個遠程Git倉庫,並將其添加爲每個本地倉庫中的新遠程倉庫。然後你可以推。

小心不要推動跟蹤SVN的分支!現在,您的代碼共享世界被分爲兩種分支:分支是Git專用的。然後你可以把它推到你想要的任何其他Git倉庫。或者分支正在跟蹤SVN分支。那麼你絕對不能將它推到任何地方去分享代碼。

使用僅限Git的分支,適用於Git的常規規則:在重新綁定推入的任何內容時(例如,不要重新分配!),請務必小心。

對於SVN分支,事情是不同的。我自己的工作流程是這樣的:

git checkout master 
git add stuff 
git commit 
git push     // regular GIT workflow until here... 
git checkout svntrunk  // name of the local branch tracking SVN trunk 
git svn fetch    // get all updates from SVN in any branch 
git svn rebase   // update trunk in local svntrunk tracking branch 
git merge master --no-ff // merge local master to SVN - fast-forward is not allowed 
          // because SVN has no way of be alike - your changes have 
          // to be a regular commit in the SVN branch 
git svn dcommit   // move that commit into SVN repo 
git svn tag v0.0.1-alpha // optional, but tagging in SVN only works after dcommit 
git checkout master  // back to work 

更新所涉及的SVN分支使用變基操作的一個分支。因此,應用通常的關於推動重新設計的分支的Git規則,很明顯這是行不通的!所以不要推SVN跟蹤分支。不要拉他們。只有他們本地,並從SVN更新他們。

這兩個分支的工作流程不是很好。它允許你通過Git與你的同事共享代碼,但它使每個必須在SVN存儲庫中的分支翻倍。取決於有多少人合併,svn跟蹤分支將包含許多提交,其實際上是他們的合併提交,但是您的本地Git repo不會將它們識別爲合併。所以你本地Git倉庫中的SVN分支只知道你的合併。

如果你的一些同事直接使用SVN而不使用Git,情況會變得更糟。這樣,您還必須將svntrunk中的更改合併到master。我沒有這方面的經驗,但我會說在這種情況下,最好避免通過Git共享代碼,並保持單一的git-svn回購情況。否則它會非常雜亂。