【发布时间】:2010-10-19 08:42:24
【问题描述】:
您正在使用 subversion 并且您不小心在一些代码准备好之前签入了它。例如,我经常:a) 签入一些代码,然后 b) 稍微编辑,然后 c) 敲击,回车重复上一个命令,不幸的是这是签入。
是否可以通过 subversion 从服务器中撤回这种意外签入?
【问题讨论】:
标签: svn
您正在使用 subversion 并且您不小心在一些代码准备好之前签入了它。例如,我经常:a) 签入一些代码,然后 b) 稍微编辑,然后 c) 敲击,回车重复上一个命令,不幸的是这是签入。
是否可以通过 subversion 从服务器中撤回这种意外签入?
【问题讨论】:
标签: svn
是的,这确实是 Subversion 的用途。
您需要做的只是将您的副本替换为 SVN 存储库中的先前版本。
有几种选择:
但我强烈建议您在替换本地副本之前执行以下操作:
【讨论】:
我会怀疑。源代码控制的主要思想之一是存储库不会丢失任何历史记录。您无法删除历史记录。您能做的最好的事情是获取旧版本并用它覆盖当前版本。但是历史日志仍然会显示你的错误。
(题外话:你正在使用什么样的 IDE 来做这样的事情?)
【讨论】:
使用 TortoiseSVN,选择 Show log 并找到要恢复到的版本。从上下文菜单中,选择恢复到此版本。这会对您的工作副本执行反向合并,因此您必须提交您的工作副本才能完成操作。
【讨论】:
请参阅SVNBook,特别是“撤消更改”部分,然后进行反向合并。
svn merge 的另一个常见用途是回滚已经提交的更改。假设您在 /calc/trunk 的工作副本上愉快地工作,并且您发现在修订版 303 中所做的更改(更改了 integer.c)是完全错误的。它不应该被提交。您可以使用 svn merge 来“撤消”工作副本中的更改,然后将本地修改提交到存储库。您需要做的就是指定一个反向差异:
$ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk
为了澄清,您的初始更改将仍然在存储库中。但是您现在在以后的修订中收回了它。即存储库已捕获您的所有更改(这确实是您想要的!除非您签入明文密码或类似密码!)
【讨论】:
您无法撤回修订,您最多只能恢复到先前的修订并再次签入。
【讨论】:
您无法删除修订 - 这里的几个答案似乎完全误解了您想要的内容。但是您可以更改签入消息以表明它是无意的。签到的费用并不高,所以多加一个也没什么大不了的。
【讨论】:
也对此发表评论:这是我在存储库上执行的一系列命令,用于将其从修订版 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
【讨论】:
如果您的意思是,我如何干净地删除意外签入的历史记录: 这很难。
svn 不允许您撤消任何操作,因为它将修订保存为变更集。 但是,有一些工具可以让您对存储库的转储执行几乎任何操作。 你可以:
转储您的存储库。
使用svn admin tools 中的svndumpfilter 来取消签入。
将其放回 repo。
但这可能会彻底毁掉你的 repo,所以永远不要尝试这样做,除非你完全知道自己在做什么并且已经备份了所有内容。
【讨论】:
注意:这可能不适用于当前版本的 SUBVERSION 并且是一个坏主意 - 但我将其留在这里以供参考
注意: 通常,当您错误地签入时,您应该只恢复提交 - 请参阅此问题的其他答案。但是,如果您想知道如何实际撤消提交的影响并将存储库更改为以前的样子,下面有一些解释:
这不是您通常想要的,但如果您真的想要从存储库中删除实际提交的版本,那么您可以按如下方式对存储库进行令人讨厌的回滚(假设$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 的存储库1.5.0(否则您必须手动编辑db/current 并更改修订号而不是运行svnadmin recover .)当一个巨大的文件被提交到一个我不想永远留在历史(和镜像等)中的存储库时,我已经做到了;这绝不是理想或正常的做法......
【讨论】:
警告:接受的答案(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.
【讨论】:
有时需要在服务器上编辑存储库,例如当您不小心提交了一个难以更改的密码时。这是我认为完全安全的方法(@David Fraser 的回答对我造成了回购损坏)。请注意,此方法只会从 repo 末尾删除修订,因此如果您立即发现错误,则最有用。
svnadmin dump -r 0:N > reponame.dumpsvnadmin dump -r 0:6610 > reponame.dump 将删除 6611 以后的版本svnadmin create reponamesvnadmin load reponame < reponame.dumpsvn checkout。【讨论】: