...
+ AnotherLocation
|--- copiedfile.txt
|--- unwantedfile.txt
+ TheProject
|--- copiedfile.txt
|--- otherfile.txt
...
您想让TheProject
拥有自己的新存储库。因此,您将存储库转储到文件中,并使用svndumpfilter仅包括TheProject
,因为这是您在HEAD修订版中看到的项目名称。
svndumpfilter include /TheProject < input.dump > output.dump
很不幸,你从svndumpfilter得到了这个错误。
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
从AnotherLocation
复制到TheProject
。因此我们必须包括这个文件,否则我们无法将其复制到`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的工具,专门用于从子版本库中提取文件和文件夹。它还可以从子版本库中删除(或抹掉)文件,以及将版本库分成两个部分,同时保证不会错过任何文件。Subdivision的亮点在于它拥有整个版本库的内存视图,并运行所需的算法来解决我们在上面示例中遇到的所有问题。这意味着您只提取正确的文件时获得必要的细粒度,同时节省用户时间,因为操作只需一次完成。
# 原始svn路径 git svn clone http://server/path/to/clone orig # 要放置您的分支的SVN svnadmin create new # 添加一个条目,否则git svn会出错... 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 # 克隆我们的克隆 git clone file:///path/to/orig abc cd abc # 设置svn路径到svn repo git svn init file:///path/to/new # 拉取数据(我们的一个提交) git svn fetch # 显示分支 git branch -a # 准备要推送的git存储库 git rebase --onto remotes/git-svn --root master # 最后推送到新的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。