撤回意外登记

时间:2009-04-14 14:04:35

标签: svn

你正在使用subversion并且在它准备好之前你不小心检查了一些代码。例如,我经常:a)检查一些代码,然后b)编辑一点,然后c)点击,输入重复上一个命令,不幸的是签到。

是否可以通过颠覆从服务器撤回这种意外登记?

11 个答案:

答案 0 :(得分:70)

请参阅SVNBook,特别是“撤消更改”部分,然后反向合并。

  

svn merge的另一个常见用途是回滚已经提交的更改。假设您正在愉快地处理/ calc / trunk的工作副本,并且您发现在更改integer.c的修订版303中所做的更改完全错误。它永远不应该被承诺。您可以使用svn merge来“撤消”工作副本中的更改,然后将本地修改提交到存储库。您需要做的就是指定反向差异:

     

$ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk

为了澄清,您的初始更改仍然在存储库中。但是你现在已经在以后的版本中撤回了它。即存储库已捕获所有更改(这实际上是您想要的!除非您已检入明文密码或类似密码!)

答案 1 :(得分:17)

注意:这可能不适用于当前版本的次级版本并且是一个不好的想法 - 但我已将其留在此处以供参考

NB: 通常,当您错误地检入时,您应该恢复提交 - 请参阅此问题的其他答案。但是,如果您想知道如何实际撤消提交的效果并将存储库更改为之前的状态,则下面会有一些解释:

这不是您通常想要的,但如果您确实想要从存储库中删除实际提交的版本,那么您可以按如下方式对存储库执行令人讨厌的回滚(这假设为$REV设置为您要删除的最新修订版本:

  • 首先备份您的存储库,因为这些更改可能会破坏它(并阅读下面的假设)
  • 将您的本地副本还原为以前的版本,以免混淆(svn revert -r $((REV-1))
  • 在存储库中,移除db/revs/$REVdb/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 .
  • 未提交其他后续修订
  • 您具有对存储库的文件系统的写入权限
  • 在执行上述操作时,您并不害怕有人试图访问它

当一个巨大的文件被提交到一个我不想永远留在历史(和镜像等)的存储库时,我已经完成了它;它绝不是理想或正常的做法......

答案 2 :(得分:14)

警告:接受的答案(由David Fraser提供)应与SVN 1.5存储库一起使用,但对于SVN 1.6,您还必须在下次提交之前删除db/rep-cache.db您会损坏您的存储库,直到您下次尝试完成结帐时才会意识到这一点。我看到后续的完整检查失败并出现“格式错误的表示标题”错误。

什么是rep-cache.db,你可能会问? documentation on the FSFS layout表示如果删除此文件,您将失去“代理共享功能”;但是,它将在您下次提交时重新创建。 Representation sharing was added in 1.6

答案 3 :(得分:12)

使用TortoiseSVN,选择显示日志并找到要还原到的修订版本。从上下文菜单中,选择“还原为此修订”。这会在您的工作副本中执行反向合并,因此您必须提交工作副本才能完成操作。

另见How do we keep track of our working copy's branch?: - )

答案 4 :(得分:6)

如果您的意思是,我如何干净地删除意外登记的历史记录: 这很难。

svn不允许您撤消任何内容,因为它会将修订版本保存为更改集。 但是,有一些工具可以让您在转储存储库时执行几乎任何操作。 你可以

  1. 转储你的回购。

  2. 使用svndumpfilter中的svn admin tools删除签到。

  3. 将它放回仓库。

  4. 但这可能完全破坏你的回购,所以永远不要试图这样做,除非你完全知道自己在做什么,并备份所有东西。

答案 5 :(得分:2)

你无法删除修订版 - 这里的几个答案似乎完全误解了你想要的内容。但是您可以更改签入消息以指示它是无意的。签到不花费太多,所以奇怪的额外一个没什么大不了的。

答案 6 :(得分:1)

是的,这正是Subversion的用途。

您需要做的只是将您的副本替换为SVN存储库中的先前版本。

有几种选择:

  1. 替换为修订版。
  2. 替换为网址
  3. 来自存储库的最新内容(但在您的情况下,您已经拥有最新版本)
  4. 替换为分支
  5. 但我强烈建议您在更换本地副本之前执行以下操作:

    1. 执行'与存储库/修订版/ URL比较'。

答案 7 :(得分:0)

我会怀疑它。源代码控制的一个主要思想是存储库不会丢失任何历史记录。您无法删除历史记录。你能做的最好的就是获得一个旧版本并用它覆盖当前版本。但是历史记录仍然会显示你的错误。

(Offtopic:你使用什么样的IDE做类似的事情?)

答案 8 :(得分:0)

您无法收回修订版本,您可以做的最多是恢复到之前的版本并再次签入。

答案 9 :(得分:0)

对此进行评论:这是我在存储库上执行的一系列命令,用于将其从修订版2恢复为修订版1.尽管如此,您还需要在结尾处进行检查。

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    

答案 10 :(得分:0)

有时需要在服务器上编辑存储库,例如,当您意外提交难以更改的密码时。这是一种我认为完全安全的方法(@David Fraser的回答导致了我的回购腐败)。注意,此方法只会删除回购结束时的修订,因此如果您立即发现错误,则最有用。

  1. 通知所有用户该回购邮件已脱机,并且他们需要从服务器创建新的结帐。
  2. 使repo脱机,获取备份副本并将主repo移动到名为reponame_old的安全位置。
  3. 将您的回购转储为单个文件表示,将不需要的修订保留在最后:
    • svnadmin dump -r 0:N > reponame.dump
    • e.g。 svnadmin dump -r 0:6610 > reponame.dump将删除转号6611以后
    • 请注意,repodump文件的大小可能是repo文件夹的两倍。
  4. 创建一个新的repo以将这些修订加载到:
    • svnadmin create reponame
  5. 将修剪过的修订集加载到新仓库中
    • svnadmin load reponame < reponame.dump
  6. 对您的新仓库(例如挂钩)应用任何必要的自定义并将其返回服务。
    • 我们正在使用VisualSVN服务器,因此必须恢复conf \ VisualSVN-WinAuthz.ini文件。
    • 在我们重新启动服务器之前,我们也看到了一些奇怪的行为,因此VisualSVN可以缓存repo状态; YMMV与其他主机设置。
  7. 不要忘记使用机密数据删除备份,或者将其放在安全的地方。
  8. 告诉所有用户从repo服务器执行新的svn checkout