本文主要介绍通过svnadmin的转存(dump)和恢复(load)命令解决SVN错误提交版本的清除问题。主要包括以下几个方面:

  • svnadmin命令
  • 备份并记录错误的版本号
  • 转储版本仓库
  • 创建新的版本仓库
  • 恢复仓库转储文件
  • 检出新的版本仓库
  • 更新日志缓存

本文使用的软件版本:

  • FreeBSD 13.0
  • subversion 1.14.0
  • TortoiseSVN 1.12.2(Windows 64-bit)

Subversion(SVN)是一个自由开源的版本控制系统,通过建立中心版本仓库(Repository)存储所有文件和目录的版本和修改信息,记录谁、什么时候、以及为什么发生更改等,允许在任何时候提取这些文件的历史版本的所有信息。Subversion是一个通用的系统,可用来管理任何类型的文件,其中包括程序源码。Subversion还可以用于多人共同工作的场景,通过对版本和分支的集中式管理实现资源共享和工作协同。

通常,SVN是用来管理文档版本的,所以,不管是正确的版本还是错误的版本都会被记录在仓库里,即使文档中含有一些不必要或者不正确的内容,这才算是一个完整的版本控制。然而在有些情况下,由于操作不慎或者考虑不周,一不小心就会在文档目录中提交了错误的文档,比如一个无需入库的文档、一个含有敏感信息的文档、或者一个巨大的程序安装包等。这些误提交的文档虽然可以在后面的版本中进行删除,但是却在存储仓库中留下永久的身影,任何时候都可通过版本号提取出这些无关的文件。特别是这些文件还占用了很大的存储空间,这对于一个合格的仓库管理员来说简直就不能忍,必欲除之而后快。

如下图中显示的是一个SVN文档仓库的版本日志,可以看到在第95版本处新增加了一个文件,但是这个文件却是不必要的,那么怎么才能将这个文件彻底地从仓库中删除呢?

虽然SVN中没有专门删除仓库文件的命令,但是可以通过将SVN特定版本导出并恢复的方法来实现仓库文件的彻底删除。

1 svnadmin命令

svnadmin是SVN仓库的管理工具,一般都会随着SVN服务器一起安装。命令用法如下:

# svnadmin SUBCOMMAND REPOS_PATH [options] [args]

其中:

SUBCOMMAND为具体的管理命令,通常有help、create、hotcopy、dump、load等;

REPOS_PATH为需要管理的仓库的本地路径。

[options] [args]为可选的参数与选项,与具体的命令有关。

2 备份并记录错误的版本号

开始之前,一定要记得备份,以免操作失误导致仓库的永久破坏。备份可以使用tar、7-zip等打包压缩工具,或者直接拷贝到U盘等。

下一个重要的任务就是记录错误的版本号,使用TortoiseSVN的“show log”命令将日志信息显示出来仔细核对,找到需要清除的版本号记录在纸上。如图中显示的是一个SVN文档仓库的版本日志,可以看到在第95版本处新增加了一个文件,并且在96、104、105版本中对其进行了更改,但是这个文件却是不必要的。要删除这个文件,其后所有涉及这个文件的版本也必须记录下来一起删除,所以这一步一定要细心!

TortoiseSVN删除分支后merge还能选到 svn删除错误提交的版本_经验分享

3 转储版本仓库

使用dump命令转储版本仓库,使用时有两个参数比较重要。一个是--revision,用于设置需要转储的版本号,多个连续版本可以用冒号隔开;另外一个是--incremental,用于设置增量格式转储,也就是只转储当前版本中增加的内容。在控制台输入如下两条命令:

# svnadmin dump Textbook -r 1:94 --incremental > Textbook_1-94.dump
# svnadmin dump Textbook -r 97:103 --incremental > Textbook_97-103.dump

 命令执行结果如下:

TortoiseSVN删除分支后merge还能选到 svn删除错误提交的版本_运维_02

 这两条命令分别增量转储了1-94和97-103版本的内容,跳过了95、96和104、105版本,这4个版本正是需要删除的历史版本。当然,第一条命令中对版本1进行增量转储没有多少意义。

4 创建新的版本仓库

使用svnadmin的create命令创建一个新的仓库。

# svnadmin create Textbook

如果还想使用原来的仓库名,可以先将旧仓库文件夹重命名后再创建新仓库。

5 恢复仓库转储文件

使用load命令恢复版本仓库,使用时将前面转储的文件进行输入重定向就可以了。在控制台输入如下两条命令:

# svnadmin load Textbook < Textbook_1-94.dump
# svnadmin load Textbook < Textbook_97-103.dump

这两条命令一定要按照顺序来输入,这也是为什么在两个转储文件名后面加上版本号后缀的原因。最后一条命令执行结果如下:

# svnadmin load Textbook < Textbook_97-103.dump
<<< Started new transaction, based on original revision 97
     * editing path : C++??????/?13? ??????.docx ... done.

------- Committed new rev 95 (loaded from original rev 97) >>>

<<< Started new transaction, based on original revision 98
     * editing path : C++??????/?13? ??????.docx ... done.

------- Committed new rev 96 (loaded from original rev 98) >>>

<<< Started new transaction, based on original revision 99
     * editing path : C++??????/?13? ??????.docx ... done.

------- Committed new rev 97 (loaded from original rev 99) >>>

<<< Started new transaction, based on original revision 100
     * editing path : C++??????/??.docx ... done.

------- Committed new rev 98 (loaded from original rev 100) >>>

<<< Started new transaction, based on original revision 101
     * editing path : Python????/?7? ???????.docx ... done.

------- Committed new rev 99 (loaded from original rev 101) >>>

<<< Started new transaction, based on original revision 102
     * editing path : Python????/?7? ???????.docx ... done.

------- Committed new rev 100 (loaded from original rev 102) >>>

<<< Started new transaction, based on original revision 103
     * editing path : Python????/?7? ???????.docx ... done.

------- Committed new rev 101 (loaded from original rev 103) >>>

6 检出新的版本仓库

回到客户端,使用TortoiseSVN重新CheckOut新的版本仓库。

对于使用http协议访问的SVN仓库,由于HTTP服务器对SVN仓库进行缓存,所以可能会出现检出失败的错误:

TortoiseSVN删除分支后merge还能选到 svn删除错误提交的版本_运维_03

 这时只需将HTTP服务重启即可。如在FreeBSD下使用如下命令重启Apache服务器

# service apache24 restart

重启完成后就可成功检出了。

7 更新日志缓存

使用TortoiseSVN的“show log”命令将新库的日志信息显示出来,发现原来的105个版本只剩下101个版本,其中的4个版本被彻底清除了。

TortoiseSVN删除分支后merge还能选到 svn删除错误提交的版本_运维_04

 仔细核对后发现,95版本似乎还是最初的内容,好象已经清除的版本还在,难道是哪里出错了?这其实也是缓存惹的祸。TortoiseSVN会将中心版本库中的内容全部缓存在本地,这样就不用每次都去向服务器请求数据了。

打开TortoiseSVN的“settings”设置对话框,在“Saved Data”中清除日志消息。

 

TortoiseSVN删除分支后merge还能选到 svn删除错误提交的版本_运维_05

然后,在“Log Caching”“Cached Repositories”中选中仓库的URL,点击“Update”按钮,连接到远程仓库并下载缺失的日志数据。

TortoiseSVN删除分支后merge还能选到 svn删除错误提交的版本_运维_06

 清除了缓存以后,再次查看日志时,一切都正常了。