如何將倉庫中的一個目錄提升成到頂層,成為頂層的 Repositories? 我的結論是“無通解”、並且有風險!
例如: 將Repositories6 中 SVN:Repositories6/Rep6_Folder1 目錄,提升一級成為一個頂層的 SVN: Rep6_New
網絡上傳播的方法,經過測試,步驟是這樣的:
用svnadmin dump命令導出文件,過濾數據:用 Svndumpfilter 命令過濾出需要的數據;然后直接編輯導出的文件!這一步是有風險的,除非數據庫中數據,只有最簡單的相互依賴關系。
網絡上一般給出的編輯文件的方法是,將文件中的這一段文字刪除掉,如下:
Node-path: 將要去掉的目錄名
Node-kind: dir
Node-action: add
Prop-content-length: 10
Content-length: 10
將文件中所有的:
Node-path: 將要去掉的目錄名/
替換成
Node-path:
將文件中所有的
Node-copyfrom-path: 將要去掉的目錄名/
替換
Node-copyfrom-path:
備注:如果導出的文件非常大,Windows下編輯超大文件工具,UltraEdit可能都不好用了,可以借用 Linux(Cygwin) 的 sed 或 ed。
如上編輯之后,將編輯過的文件,倒入到新建的Repositories庫中 (svnadmin load),成為頂層的庫文件。以上就是網傳的方法。
然而,Repositories庫中數據可能有着更復雜的相互依賴關系,例如:
希望要提升的目錄(也包括文件)可能曾經被修改過名字,甚至刪除掉,又重建,你需要仔細查看log,才能知道來龍去脈,上面說的方法,不一定就那么簡單,一蹴而就,一旦搞錯了就會混亂不堪。
最可靠的方法,就是損失掉以往的版本信息,導出export干凈的Head版本的數據,添加、並提交到(頂層)新庫中。原來的下層目錄,還是放在那里好了,不要動它了。
實驗記錄:
停止 SVN 服務
希望實現:
Repositories6/Rep6_Folder1 目錄提升一級成為一個頂層的Repositories ,New_Rep6(新創建的一個空的Repositories),如圖:
導出Repositories
svnadmin dump Repositories6 > DumpRep6
過濾導出文件
Svndumpfilter include Rep6_Folder1 < DumpRep6 > DumpFold1
會發現問題,導出的文件中,沒有有用的數據:
E:\Repositories>Svndumpfilter include Rep6_Folder1 < DumpRep6 > DumpFold1
Including prefixes:
'/Rep6_Folder1'
Revision 0 committed as 0.
……
Revision 11 committed as 11.
Revision 12 committed as 12.
svndumpfilter: E200003: Invalid copy source path '/folder1'
原因是 Rep6_Folder1 是由 folder1 改名而來的(刪除&重建)。看日志:
svndumpfilter 命令中使用包含 include 方式是不行的,因為Rep6_Folder1 原本的名字是 floder1(改名過)。這是版本控制的是根,被過濾掉了,Rep6_Folder1就沒有根了。改用排除法 exclude 過濾導出:
Svndumpfilter exclude Rep6_Folder2 < DumpRep6 > DumpFold1
Svndumpfilter exclude Rep6_Folder2 < DumpRep6 > DumpFold1
E:\Repositories>Svndumpfilter exclude Rep6_Folder2 < DumpRep6 > DumpFold1
Excluding prefixes:
'/Rep6_Folder2'
Revision 0 committed as 0.
……
Revision 23 committed as 23.
Dropped 7 nodes:
'/Rep6_Folder2'
'/Rep6_Folder2/0sizeFile.txt'
'/Rep6_Folder2/R6F2'
'/Rep6_Folder2/R6F2F1.txt'
'/Rep6_Folder2/R6F2F2.txt'
'/Rep6_Folder2/Rep6_Folder1'
似乎是OK了,但是還是有陷阱,如果同一級別的目錄還有其它的目錄,使用中又被刪除掉了,也會一並的導入出來了。(示例中的確如此,見下文。需要仔細查看日志,發現這類問題,可以對過濾出的文件,反復的過濾。)
下一步編輯 DumpFold1 文件 。 將遇到一些棘手的問題。還是需要仔細查看日志。
然后導入到新建的 Repositories 中:
Svnadmin load NEW_Rep6 < DumpFold1
導入編輯過后的文件,不一定會成功,導入可能時會遇到一些問題,需要反復幾次的編輯修改文件。
例如,可能遇到如下問題:
E:\Repositories>Svnadmin load NEW_Rep6 < DumpFold1
<<< Started new transaction, based on original revision 2
* editing path : Text_BigEndian.txt ...svnadmin: E200014: Checksum mismatch for '/Text_BigEndian.txt':
expected: 9c74ac67638e44e4c8073f608b0655a7
actual: 513155e38d1b941b086234ec289ed6da
這時,你還需要去修改編輯導出的文件,將revision2 的 Text-content-md5:后綴的數字, 修改成上面報告出來的 actual 值。
導入后的截圖如下:
可以發現, 明顯有一個問題 :多出了一個 Rep4_Folder目錄。這是一個曾經被添加的目錄,然后又刪除掉了(有意預留的“炸彈”)。這是編輯處理文件不完善造成了遺留。需要仔細看日志,搞清楚數據之間的邏輯關系,也可以將編輯或過濾掉不需要的文件,可以用 Svndumpfilter 再次過濾一次或多次。
導致上面效果,編輯導出的文件方法附如下:(細節部分,嫌煩忽略)
替換掉folder1/
替換掉Rep6_Folder1/
刪除下面一段:
Revision-number: 1
Prop-content-length: 137
Content-length: 137
K 10
svn:author
V 16
VisualSVN Server
K 8
svn:date
V 27
2018-05-25T02:04:35.731309Z
K 7
svn:log
V 25
Created folder 'folder1'.
PROPS-END
Node-path: folder1
Node-kind: dir
Node-action: add
Prop-content-length: 10
Content-length: 10
PROPS-END
刪除下面一段
Node-path: Rep6_Folder1
Node-kind: dir
Node-action: add
Node-copyfrom-rev: 12
Node-copyfrom-path: folder1
Content-length: 0
Node-path: folder1
Node-action: delete
Content-length: 0
Revision-number: 14
Prop-content-length: 112
Content-length: 112
K 8
svn:date
V 27
2018-06-25T02:37:34.462649Z
K 7
svn:log
V 38
This is an empty revision for padding.
PROPS-END
然后按照導入失敗的提示修改 Text-content-md5 后面的數字。前文已描述過了。