2012-03-06 60 views
0

我很抱歉如果這個問題以前被問過,但我的情況是一個相對特定的問題。我一直在我公司工作一段時間並使用SVN,但由於各種原因最近希望轉移到Git。如何將具有不一致分支結構的SVN導入到Git中?

我現在遇到的問題是我的公司使用非標準分支結構,不幸的是,有時過去,它甚至沒有一致的非標準分支結構。

自加入公司以來,我瞭解到的歷史是,我們使用一個主幹分支,從中創建發佈分支和功能分支。然而,這些分支的結構不僅僅是標準的trunk/branches/tags結構。我們有不同類型的分支的幾個子文件夾。例如,發佈分支去branches_release,配備在branches_feature樹枝等,如下所示:

branches_feature/featureA 
branches_release/2.0 

我想出如何使這個克隆/通過修改的Git回購的配置正確讀取的工作,使

branches = {branches_feature,branches_release}/*:refs/remotes/branches/* 

這在取得相應分支方面相對成功。我有一個問題是,當我公司首次啓動時,它使用更像是一個結構:

branches_feature/username/branchname 

不幸的是發現了這一點(硬盤的方式),我不得不「混帳SVN取」,發現所有這些遵循舊的分支約定的分支都已經崩潰了,所以在Git中,每個用戶都有一個分支,每個分支都存在於每個分支中。所以,

branches_feature/username/featureA 
branches_feature/username/featureB 

已經坍塌成:

branches_feature/username 

這顯然是不夠的正確轉載SVN回購的歷史,但我不知道如何修改配置的分支線封裝所有的這些分支仍然正確使用新的分支格式。我一直試圖用各種方式來操縱它,但是我最終會得到錯誤或者只是在嘗試中失敗。

如果任何人都可以提出一個很好的方法來適當地保留SVN回購的歷史,同時從SVN導入Git,我將不勝感激。

謝謝。

回答

1

TL; DR:對於除最瑣碎庫的話,你將永遠無法完全保留在git svn存儲庫中的版本庫中的內容。

我從my answer to a similar question適應這一點。

按照我的理解,你的Subversion樹看起來像這樣,在*表明,在顛覆歷史的某一時刻本來的工作副本的根文件夾:

/ 
|--branches_feature/ 
| |--featureA/  * 
| |--userB/   * 
| | |--featureB/ * (Possibly now deleted, but existed previously) 
| | `--featureC/ * 
| `--userC/   * 
|--branches_release/ 
| |--V1.0/   * 
| `--V2.0/   * 
`trunk/    * 

可悲的是,git svn能用特別合理的方式處理這樣的存儲庫。你不會得到一個Git倉庫,它擁有你的Subversion倉庫的所有分支,而且沒有它不應該擁有的分支。

你的選擇是這樣的:

  • 同時治療的branches_featurebranches_feature/userB作爲分支的文件夾。

    你最終會得到一些Git分支,如果你檢查它們,會給你一堆包含Subversion分支文件夾的文件夾,並且對這些文件夾的操作可能需要更長的時間,因爲獲取將會需要爲容器分支和真正的分支完成。由於Git很聰明,它至少會佔用極少的額外磁盤空間。

    我期望你.git/config有行像下面:

    branches = branches_feature/*:refs/remotes/branches/* 
    branches = branches_feature/userB/*:refs/remotes/branches/* 
    branches = branches_release/*:refs/remotes/branches/* 
    
  • 忽略一些分支的文件夾。只是不要告訴git svn他們,並繼續在歡樂的無知。

  • 挑選出你感興趣的分支機構,並手動接他們回家。如果你想要userB文件夾,你仍然需要注意你選擇的歷史記錄,但是,如果它的子分支已經被刪除,而你不想提取它們。

    在這裏,我希望你.git/config有線條的整個負載,如下面:

    fetch = branches_feature/featureA:refs/remotes/branches/featureA 
    fetch = branches_feature/userB/featureB:refs/remotes/branches/featureB 
    fetch = branches_feature/userC:refs/remotes/branches/userC 
    
  • 修補的git svn版本以某種方式使其能夠應付這種情況。如果您將它包含在將來的官方Git版本中,則可獲得獎勵積分。

+0

當然不會做任何git svn補丁(還)。我目前的計劃是做類似branches = branches_feature/{userA,userB}/*:refs/remotes/branches_feature/*。 (就像你的第一個解決方案)我擔心的是,如果我使用這種方法,是否會嘗試創建兩個分支,一個用於「userA」,另一個用於「userA/feature」。考慮到這種不確定性,我有點害怕開始......大聲笑。我將不得不最終雖然我猜... – 2012-03-07 04:36:33

+1

就是這樣,它不會; 'svn-remote.branches'只爲子目錄創建分支。與branch = branches/*的「標準」配置比較:refs/remotes/branches/*' - 你沒有得到一個叫做「branches」的分支,每個子目錄只有一個分支。 – 2012-03-07 10:40:27

+1

另外,請隨時嘗試!如果你不喜歡結果,從你的配置文件中刪除相關的行,並刪除你想從'.git/logs/refs/remotes','.git/refs/remotes'和'的.git/SVN /參/ remotes'。 – 2012-03-07 10:43:12

1

你當然可以處理這個問題,但你應該考慮你願意付出多少努力與回報相比。

如果您只是將轉換限制爲發佈分支和主幹,那麼功能分支的缺失會成爲主要問題?你應該仍然有提交(因爲他們會出現在合併),所以唯一不存在的提交是那些沒有合併回到主幹的提交。

如有必要,您可以稍後分別轉換您需要的功能分支,並使用git replacegit filter-branch將它們移植到位。

+0

這裏的問題是,我試圖完全替換SVN存儲庫(如果可以的話)。對於個人工作流程,甚至目前公司來說,發佈分支機構和主幹線就足夠了。但是,由於沒有以前的歷史記錄,我們無法殺掉舊的SVN回購。不過,我一定不會將此作爲選項排除。非常感激。 – 2012-03-06 19:23:57

+1

非常明白,我已經花費了很多精力在之前的遷移中遷移所有的東西,但我幾乎從未使用它。你可能會發現現有回購的'svn sync',tarballed(或者通過'svnadmin dump'和壓縮文件導出),並且在某些地方支持保護你的歷史記錄,而不會將所有功能分支行李帶到你的手中。你的另一個選擇是單獨拉取你需要的功能分支,比如@me_和建議。要記住的主要事情 - SVN不會去任何地方,所以只要你做了備份,你總是可以稍後返回一個你需要的導入。 – tjdett 2012-03-07 00:00:32

+0

是的,對於我自己,我並不太關心(老)歷史。我試圖說服我的公司從SVN切換到Git,我認爲對他們來說更大的問題是將歷史從現在分割開來。能夠適當地構建歷史將簡單地使我的論點更容易一些。管理者不會讓事情變得更容易(或更簡單),有時......哈哈。 – 2012-03-07 04:38:46

相關問題