2010-07-03 77 views
3

我有一個SVN倉庫,裏面有很多目錄。現在我想克隆這個存儲庫,只留下一個特定的目錄。當然,我不需要在這個新的存儲庫中修改其他目錄。我該怎麼做?謝謝。如何克隆SVN存儲庫的一部分?

+0

+1,瞭解如何拆分Subversion存儲庫對於程序員來說是一項重要技能(如果您使用的是Subversion)。 – 2010-07-03 07:57:37

回答

0

另一種可能性是git svn clone,它只提取感興趣的目錄。然後它可以推到一個新的SVN回購。這簡單嗎?不,但如果您無法訪問服務器,則非常方便。我確信有更好的方法 - 但這種方式可以確保您不會意外推到原始的svn回購站。

 

    # original svn path 
    git svn clone http://server/path/to/clone orig 
    # SVN to put just your branch in 
    svnadmin create new 
    # add one entry, or git svn errors out... 
    svn co file:///path/to/new new.wd 
    mkdir new.wd/null 
    svn add new.wd/null 
    svn ci -m"add null" new.wd/null 
    # clone our clone 
    git clone file:///path/to/orig abc 
    cd abc 
    # set up svn path to the svn repo 
    git svn init file:///path/to/new 
    # pull data in (our one commit) 
    git svn fetch 
    # show the branches 
    git branch -a 
    # Prep the git repot for the push 
    git rebase --onto remotes/git-svn --root master 
    # finally push to the new svn repo. 
    git svn dcommit 

沒有我能找到如何做到這一點,所以我想出了這個。你可能需要像下面這樣svn donf文件:

 

    svn_repo="$(pwd)/new" 
    user="myusername" 
    echo '[/]' >> $svn_repo/conf/authz 
    echo "$user = rw" >> $svn_repo/conf/authz 
    echo '[users]' >> $svn_repo/conf/passwd 
    echo "$user = test" >> $svn_repo/conf/passwd 
    echo 'password-db = passwd' >> $svn_repo/conf/svnserve.conf 
    echo "svn repo is file://$svn_repo" 
    svn co file://$svn_repo svn.wd 

在上面的例子中,myusername的密碼是test。

0

傳統的做法是將存儲庫轉儲到轉儲文件中,使用svndumpfilter根據需要包含或排除文件,然後將過濾的轉儲文件加載到新的存儲庫中。這種方法適用於簡單的更改,例如從存儲庫中刪除一些文件。

當存儲庫包含文件移動和副本時,事情會變得更加困難。

讓我們舉一個最簡單的例子,叫做MyProject的項目文件夾在歷史記錄中的某個過去時間已被重命名爲TheProject。另一個名爲TheProject/copiedfile.txt的文件隨後從位置AnotherLocation複製到TheProject下。一個基本的樹結構可能看起來像這樣。

... 
+ AnotherLocation 
|--- copiedfile.txt 
|--- unwantedfile.txt 
+ TheProject 
|--- copiedfile.txt 
|--- otherfile.txt 
... 

你想TheProject有它自己的新的存儲庫。因此,您將存儲庫轉儲到文件並使用svndumpfilter僅包含TheProject,因爲這是您在HEAD修訂版中看到的項目的名稱。

svndumpfilter include /TheProject <input.dump> output.dump 

你不幸從過濾流得到這個錯誤

svndumpfilter: E200003: Invalid copy source path '/MyProject' 

那是因爲TheProject曾經被稱爲MyProject,並在過去的一些修訂更名。由於重命名本質上是一個刪除和複製,因此svndumpfilter找不到創建TheProject的副本的來源,並且正確地出現錯誤。因此,我們用下面的命令,其中包括MyProject以及

svndumpfilter include /TheProject /MyProject <input.dump> output.dump 

Svndumfilter現在與其他錯誤出現重試。

svndumpfilter: E200003: Invalid copy source path '/AnotherLocation/copiedfile.txt' 

是的,這是因爲copiedfile.txt被複制從AnotherLocationTheProject。所以我們也必須包含這個文件,否則我們不可能把它複製到`TheProject'中。讓我們再試一次。

svndumpfilter include /TheProject /MyProject /AnotherLocation/copiedfile.txt <input.dump> output.dump 

操作成功!看來第三次幸運!

讓我們嘗試將我們過濾的轉儲文件加載到存儲庫。

svnadmin create newrepo 
svnadmin load newrepo < output.dump 

沒有這麼幸運!加載過程中出現以下錯誤

* editing path : AnotherLocation/copiedfile.txt ...svnadmin: E160013: File not found: transaction '1-1', path '/AnotherLocation/copiedfile.txt' 

啊!這是因爲我們忘記了包括需要AnotherLocation因爲它是copiedfile.txt

svndumpfilter include /TheProject /MyProject /AnotherLocation <input.dump> output.dump 

好這個命令的作品父文件夾和加載也適用。不幸的是,我們現在也包含了/AnotherLocation/unwantedfile.txt。由此得出結論,使用svndumpfilter include實際上並不奏效,因爲它不能提供我們之後的粒度。我們必須使用svndumpfilter exclude來做所有事情,試圖排除我們不需要的所有內容,從而最終得到我們需要的文件。可以說,它充滿了自己的一系列問題。例如,很容易排除存儲庫中實際需要的文件。如果人們想要一個這樣的例子,我可以擴展這個答案。

必須有更好的方法。事實證明,這是一個商業產品。我們開發了一個名爲Subdivision的工具,專門從Subversion版本庫中提取文件和文件夾。它還可以刪除(或刪除)來自Subversion存儲庫的文件,以及將存儲庫分成兩部分,同時保證兩個存儲庫之一沒有文件被遺漏。 Subdivision的亮點在於,它擁有整個存儲庫的內存視圖,並運行所需的算法來解決上述示例中遇到的所有問題。這意味着您只需在保存用戶時間的情況下提取正確文件所需的粒度,因爲操作一次完成即可完成。

相關問題