撤回意外检查
你正在使用颠覆,你不小心检查了一些代码之前准备好了。 例如,我经常:a)签入一些代码,然后b)编辑一下,然后c)点击,进入重复以前的命令,不幸的是一个签入。
是否有可能从服务器收回这样的意外登记颠覆?
注意:这可能不适用于当前的版本,是一个坏的想法 – 但我已经把它留在这里的信息
注意: 通常当你错误地登记了,你应该恢复提交 – 看到这个问题的其他答案。 但是,如果您想知道如何实际撤消提交的效果并将存储库更改为之前的版本,则有以下解释:
这不是你通常想要的,但是如果你真的想从存储库中删除实际提交的版本,那么你可以在存储库上做一个令人讨厌的回滚(假设$REV
被设置为最新版本,你正在删除):
- 首先备份您的存储库,因为这些更改可能会破坏它(并阅读下面的假设)
- 恢复你的本地副本到以前的版本,所以它不会感到困惑(
svn revert -r $((REV-1))
) - 在存储库中,删除
db/revs/$REV
和db/revprops/$REV
- 在存储库中,删除
db/current
和(对于subversion 1.6或更高版本)db/rep-cache.db
,然后运行svnadmin recover .
- (可能)调整
db/rep-cache.db
的权限以防止尝试写入只读数据库错误
这一切都假定:
- 您正在使用基于
fsfs
的存储库 - Subversion版本大于
1.5.0
(否则,您必须手动编辑db/current
并更改版本号,而不是运行svnadmin recover .
) - 没有其他后续修订已经提交
- 您有权访问存储库的文件系统
- 当你这样做的时候,你并不害怕别人试图访问它
当一个庞大的文件被提交给一个我不想永远留在历史中的库(和镜像等)时,我已经做到了这一点。 这不是理想的或正常的做法…
看到SVNBook ,特别是“撤消改变”部分,并反向合并。
svn合并的另一个常见用途是回滚已经提交的更改。 假设你在/ calc / trunk的工作副本上愉快地工作,并且发现修改303中更改的方式改变了integer.c,这是完全错误的。 它从来不应该犯下。 你可以使用svn merge来“撤销”你的工作副本中的改变,然后提交本地修改到版本库。 你所需要做的就是指定一个相反的区别:
$ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk
为了澄清,您的初始更改仍将存储在存储库中 。 但是你现在已经在以后的版本中收回了。 即存储库已经捕获了所有的变化(这真的是你想要的!除非你已经检查了明文密码或类似的!)
警告 :接受的答案(由David Fraser)应该与SVN 1.5版本库一起工作,但对于SVN 1.6,您还必须在下次提交之前删除db/rep-cache.db
,否则您将损坏版本库 ,直到下一次你尝试一个完整的结帐。 我已经看到后续完整的检出失败,“格式错误的表示标题”错误。
什么是rep-cache.db,你可能会问? 有关FSFS布局的文档说,如果删除此文件,将会失去“代表共享function”; 但是,它将在您下一次提交时重新创build。 代表分享是在1.6中增加的 。
使用TortoiseSVN,select显示日志并find您想要恢复的修订。 从上下文菜单中,select恢复到此修订版本。 这将执行反向合并到您的工作副本,所以您将不得不提交您的工作副本来完成操作。
另请参见我们如何跟踪我们的工作副本的分支? 🙂
如果你的意思是,我该如何清除一个意外检查的历史:这是困难的。
svn不允许你撤销任何东西,因为它将修改保存为变更集。 但是,有一些工具可以让您在存储库的转储中执行几乎任何操作。 你可以 :
-
转储您的回购。
-
使用svn admin工具中的 svndumpfilter来摆脱login。
-
把它放回回购。
但是,这可以完全毁掉你的回购,所以千万别试图这样做,除非你完全知道你在做什么,并且备份了所有东西。
是的,这真是Subversion的用武之地。
你需要做的只是将你的副本replace为SVN版本库中的以前版本。
有几个选项:
- replace为修订版。
- 用URLreplace
- 最新的存储库(但在你的情况下,你已经有了最新的)
- replace为分支
但我强烈build议您在更换本地副本之前执行以下操作:
- 做一个'比较库/修订/ URL'。
你不能删除修订 – 这里的几个答案似乎是完全误解你想要的。 但是,您可以更改签入消息以表明它是意外的。 Checkins不会花费太多,所以再多加一个也没什么大不了的。
我会怀疑的。 源代码控制的一个主要思想是存储库不会丢失任何历史logging。 您不能删除历史logging。 你可以做的最好的是得到一个旧版本,并用这个覆盖当前的版本。 但历史日志仍然会显示你的错误。
(Offtopic:你用什么样的IDE做类似的事情?)
你不能收回修订版本,你可以做的最多的是恢复到之前的修订版本,并做另一个签入。
也可以对此进行评论:这是我在版本库中执行的一系列命令,将其从修订版本2恢复到版本1.尽pipe如此,还是需要在最后签入。
Last login: Mon Apr 13 16:01:34 on ttys004 [wlynch@orange ~] cd /tmp [wlynch@orange /tmp] svnadmin create foo [wlynch@orange /tmp] svn co file:///tmp/foo foo-repo Checked out revision 0. [wlynch@orange /tmp] cd foo-repo/ [wlynch@orange foo-repo] ls [wlynch@orange foo-repo] touch blah [wlynch@orange foo-repo] touch repl [wlynch@orange foo-repo] touch bar [wlynch@orange foo-repo] svn add * A bar A blah A repl [wlynch@orange foo-repo] svn ci Adding bar Adding blah Adding repl Transmitting file data ... Committed revision 1. [wlynch@orange foo-repo] echo "hi" > bar [wlynch@orange foo-repo] echo "oh no" > blah [wlynch@orange foo-repo] svn ci Sending bar Sending blah Transmitting file data .. Committed revision 2. [wlynch@orange older-foo] svn diff -r 1:2 file:///tmp/foo Index: bar =================================================================== --- bar (revision 1) +++ bar (revision 2) @@ -0,0 +1 @@ +hi Index: blah =================================================================== --- blah (revision 1) +++ blah (revision 2) @@ -0,0 +1 @@ +oh no [wlynch@orange foo-repo] svn diff -r 1:2 file:///tmp/foo | patch -R patching file bar patching file blah
有时候需要在服务器上编辑回购,例如,当你意外提交了一个难以改变的密码的时候。 这里有一个我认为是完全安全的方法(@David Fraser的回答为我造成了repo腐败)。 注意,这种方法只会删除回购结束时的修订版,所以如果您立即注意到您的错误,那么这将非常有用。
- 通知所有的用户,回购是脱机,他们将需要从服务器创build一个新的结帐。
- 使回购离线,采取一个备份副本,并将主要回购移动到一个名为reponame_old的安全位置。
- 将您的repo转储到单个文件表示forms,将不需要的修订版本保留在最后:
-
svnadmin dump -r 0:N > reponame.dump
- 例如
svnadmin dump -r 0:6610 > reponame.dump
将删除6611以上 - 请注意,repodump文件可能是您的repo文件夹大小的两倍。
-
- 创build一个新的repo来加载这些修订版本到:
-
svnadmin create reponame
-
- 将修剪后的一组修订加载到新的回购中
-
svnadmin load reponame < reponame.dump
-
- 将任何必要的自定义应用到您的新回购(例如挂钩)并将其返回到服务。
- 我们正在使用VisualSVN服务器,因此必须恢复conf \ VisualSVN-WinAuthz.ini文件。
- 在重启服务器之前,我们也看到了一些奇怪的行为,所以VisualSVN可能会caching回购状态。 YMMV与其他托pipe设置。
- 不要忘记用秘密数据删除备份,或者把它放在安全的地方。
- 告诉所有的用户从回购服务器做一个新的
svn checkout
。