【发布时间】:2011-04-06 12:27:23
【问题描述】:
我们团队中的某个人不小心将包含密码的文件提交到了我们的存储库。密码不易更改。
有没有办法在拥有完全管理员权限的情况下删除此提交的所有痕迹?我不是在谈论恢复或删除,这显然会将密码保留在文件历史记录中。
【问题讨论】:
标签: svn
我们团队中的某个人不小心将包含密码的文件提交到了我们的存储库。密码不易更改。
有没有办法在拥有完全管理员权限的情况下删除此提交的所有痕迹?我不是在谈论恢复或删除,这显然会将密码保留在文件历史记录中。
【问题讨论】:
标签: svn
是的,但它不适合胆小的人。您必须使用 svnadmin dump 和 svnadmin load 重新创建您的存储库。
如果您选择这样做,第一步是阻止您的用户提交,并备份您的存储库。我还建议在您的存储库副本上逐步完成这些步骤;您可以使用rsync 将整个存储库目录复制到一个临时目录中,然后从那里开始工作。
对于这些说明,我将在临时目录中创建一个新存储库:
tmp, 502> svnadmin create example.repo
tmp, 503> svn co file://`pwd`/example.repo example
Checked out revision 0.
我创建了一个包含四个修订的文件,其中第三个需要删除:
example, 536> svn log test.txt
------------------------------------------------------------------------
r4 | kgregory | 2011-04-06 08:46:59 -0400 (Wed, 06 Apr 2011) | 1 line
post-bad commit
------------------------------------------------------------------------
r3 | kgregory | 2011-04-06 08:46:42 -0400 (Wed, 06 Apr 2011) | 1 line
bad revision
------------------------------------------------------------------------
r2 | kgregory | 2011-04-06 08:46:28 -0400 (Wed, 06 Apr 2011) | 1 line
good revision
------------------------------------------------------------------------
r1 | kgregory | 2011-04-06 08:46:02 -0400 (Wed, 06 Apr 2011) | 1 line
initial revision
------------------------------------------------------------------------
因此,我们需要转储坏版本之前和之后的修订,使用-r 标志来指定修订范围。第二个转储上的--incremental 标志很重要,因为它会告诉加载命令不要创建新文件。
请注意,我是从包含存储库的同一目录中运行这些命令的。
svnadmin dump -r 1:2 example.repo/ > pred.svndump
* Dumped revision 1.
* Dumped revision 2.
tmp, 552> svnadmin dump -r 4:4 --incremental example.repo/ > succ.svndump
* Dumped revision 4.
现在将原始存储库移开,并创建一个同名的空存储库:
tmp, 540> mv example.repo example.repo.bak
tmp, 541> svnadmin create example.repo
并导入转储文件的内容。
tmp, 569> svnadmin --quiet load example.repo < pred.svndump
tmp, 570> svnadmin --quiet --ignore-uuid load example.repo < succ.svndump
现在告诉大家删除他们的工作目录并重新检查。您应该会看到以下日志:
example, 574> svn log test.txt
------------------------------------------------------------------------
r3 | kgregory | 2011-04-06 08:46:59 -0400 (Wed, 06 Apr 2011) | 1 line
post-bad commit
------------------------------------------------------------------------
r2 | kgregory | 2011-04-06 08:46:28 -0400 (Wed, 06 Apr 2011) | 1 line
good revision
------------------------------------------------------------------------
r1 | kgregory | 2011-04-06 08:46:02 -0400 (Wed, 06 Apr 2011) | 1 line
initial revision
------------------------------------------------------------------------
有一个巨大警告:此过程假定自错误提交以来没有对文件进行任何提交(即,后续转储仅包含对其他文件的更改)。
如果不是这样,您仍然可以删除修订版,但工作量要大得多。您需要创建一个新的签入,其中包含文件的干净副本以及任何其他在损坏时随它更改的文件。然后创建多个转储文件,不包括包含错误文件的任何修订。
最后:我强烈建议进行几次试运行。从我的例子中的历史数字可以看出,我搞砸了几次。正如我在开始时所说,将 Subversion 存储库复制到临时目录很容易。当你这样做时,你可以继续尝试直到你做对了,然后将固定的存储库复制回原位。
【讨论】:
在FAQ查看答案
在某些特殊情况下,您可能希望销毁文件或提交的所有证据。 (也许有人不小心提交了一份机密文件。)这并不容易,因为 Subversion 被刻意设计为永远不会丢失信息。修订是相互依赖的不可变树。从历史中删除修订会导致多米诺骨牌效应,在所有后续修订中造成混乱,并可能使所有工作副本无效。
然而,该项目计划在某一天实施一个 svnadmin obliterate 命令,该命令将完成永久删除信息的任务。 (见第 516 期。)
与此同时,您唯一的办法是 svnadmin 转储您的存储库,然后通过 svndumpfilter(不包括错误路径)将转储文件传送到 svnadmin 加载命令中。有关这方面的详细信息,请参阅 Subversion 书籍的第 5 章。
【讨论】:
svndumpfilter 只知道如何包含或排除路径。除非您小心,否则该文件可能会完全消失。