从svn仓库中删除带有完整历史记录的文件

37

有没有办法从svn仓库中删除文件,包括其所有历史记录?当我想要摆脱存储在仓库中的大型二进制文件时,就会出现这个问题。

我知道只有一种方法可以帮助解决这个问题:

  1. 使用svnadmin工具导出repo的所有内容。
  2. 使用grep过滤导出的文件。Grep应该使用文件名并将其写入另一个导出的文件中。
  3. 使用svnadmin导入最后一个导出的文件。

但是这太复杂和不可靠了。也许还有其他的解决方案吗?

4个回答

33

使用svndumpfilter命令使这变得更加简单。细节在subversion文档这里中有详细说明。基本上,为了避免冲突(在此处解释),它会对一个repo dump进行处理,并重新执行每次提交,包括或排除给定的文件前缀。基本语法:

svndumpfilter exclude yourfileprefix < yourdump > yournewdump

可能问题的提问者想要使用Exclude,但您也可以使用Include来提取仓库的子树,使其成为自己的代码库。

Subversion中的最新修订版(非常元)也可以接受glob模式。最近我需要从仓库中删除所有的pdf文件,像这样很容易完成:

svndumpfilter exclude --pattern '*.pdf' < dump > dump_nopdfs

通过调用svndumpfilter helpsvndumpfilter help exclude可以找到更多的使用信息。


整个过程应该是这样的:svnadmin dump > myDump; svndumpfilter exclude myFile < myDump > newDump; cat newDump | svnadmin load myRepositoryURL; 对吗? - Shawn
13
好的,我尝试了一下,这个过程看起来是这样的:svnadmin dump 仓库路径 > old.dump; svndumpfilter exclude 文件前缀 < old.dump > new.dump; rm -rf 仓库路径; svnadmin create 仓库路径; svnadmin load 仓库路径 < new.dump; 主要的区别在于,在加载筛选后的转储文件之前,您必须删除并重新创建仓库。请注意,path_to_repository 是服务器上仓库的路径,而不是您的工作副本的路径。 - Shawn
是的,可以这样做,但是您可以省略临时文件。您可以按以下方式执行:svnadmin create path_to_NEW_repository; svnadmin dump path_to_CURRENT_repository | svndumpfilter exclude file_prefix | svnadmin load path_to_NEW_repository; 当然,您必须为 web 配置 NEW 存储库。测试它。如果一切正常,则检查闲置或关闭 www,将 CURRENT 重命名为 OLD,然后将 NEW 重命名为 CURRENT,启用访问。如果一切正常,您可以备份旧目录以备任何需要,并恢复先前的 Web 配置。不要在没有考虑清楚的情况下删除任何源数据 :) - Znik

6
但这太过复杂和不可靠了。
我不知道为什么这不能被认为是可靠的。但是,如果你想完全摆脱文件、历史记录以及所有与之前版本相关的影响,那么只有一种方法可以做到,而且这种方法确实很复杂。这是正确的。SVN是一个目标明确的工具:绝对不能丢失任何文件,即使它已经被删除了。强制它做出相反的事情应该是困难的。

4
我遇到了类似的问题,不同之处在于我需要删除多个文件而不仅仅是一个文件,而且我们使用的是不支持--pattern指令的Subversion 1.6版本。
--备份当前的SVN。
$ cp -R /svn  /svnSAVE

-- 转储代码库

$ svnadmin dump /svn/root > svnDump

-- 在不包含非常大的文件的情况下创建新的转储。
$ svndumpfilter exclude "/path/file.csv" < svnDump > newSvnDump0
-- {note: should see a message like this}:
--          Dropped 1 node:
--                  '/path/file.csv'

-- 在不包含另一个非常大的文件的情况下创建另一个新的转储。
$ svndumpfilter exclude "/path/anotherFile.csv" < newSvnDump0 > newSvnDump1

-- 移除旧版的 SVN
$ rm -rf /svn

-- 重新创建 SVN 目录

$ mkdir -p /svn/root

-- 重新创建SVN

$ svnadmin create /svn/root

-- 使用该dump重新填充最新的代码库
$ cat newSvnDump1 | svnadmin load /svn/root

-- 将从已保存副本中的conf文件更新到新副本中...

$ cp /svnSAVE/root/conf/* /svn/root/conf

现在代码库中不应该包含两个大文件 "file.csv" 和 "anotherFile.csv"。

0

我同意McDowell的提议,但我建议你考虑用简单包含已删除条目哈希值的文本文件替换大文件。

如果你不小心将一个构建目录中的大量.o文件检入,这种方法可能不适用。但是,如果你从一个包含你需要的一堆二进制工件和你不需要的一堆二进制工件的目录中删除一堆二进制工件,你就有很高的风险犯下昂贵的错误。至少要考虑从主干和大多数分支中将它们删除,但是留下一个特性分支,其中包含原始二进制文件的哈希值的占位符文本文件。这样至少足以找出发生了什么事,验证不应被删除的迷路副本是否为正确的文件,并将其重新放回版本控制。

当然,在你考虑执行任何这些操作之前,一定要将整个代码库备份到像几个M-Discs这样的只读存储介质中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接