如何更好地恢复文件到之前的SVN版本?

167

我不小心向SVN存储库提交了太多文件,并改变了一些我原本不想改变的东西。 (叹气)为了将它们恢复到之前的状态,我能想到的最好方法是

svn rm l3toks.dtx
svn copy -r 854 svn+ssh://<repository URL>/l3toks.dtx ./l3toks.dtx

天哪!没有更好的方法吗?为什么我不能像这样写:

svn revert -r 854 l3toks.dtx

好的,我只使用v1.4.4版本,但我大致浏览了1.5分支的更改列表,没有看到任何直接相关于此的内容。我有错过什么吗?


编辑: 我猜我表述不够清楚。我不想进行反向合并,因为那样我就会失去我确实想要做出的更改!假设fileAfileB都被修改了,但我只想提交fileA; 如果意外输入:

svn commit -m "small change"

现在我想回滚fileB,因为提交了两个文件。相对合并似乎没有比我上面提到的步骤更容易实现此任务。


可能是如何还原SVN提交?的重复问题。 - Vadzim
9个回答

242
svn merge -r 854:853 l3toks.dtx
或者
svn merge -c -854 l3toks.dtx

这两个命令是等效的


5
谢谢您的留言。我想表达一个观点——假设我当前版本是855,我想将某个文件回滚到版本854。如果我执行svn merge -c -854 my.file,然后执行svn diff,看起来显示的是854之前的版本(也就是853);只有当我执行svn merge -c 854 myfile(没有加上“-”符号),它才会让myfile回滚到854版本。再次感谢,祝好! - sdaau
11
为什么第一个选项对我非常有效,而第二个选项完全不起作用? - skybondsor
7
不要忘记在反向合并后提交,我经常会忘记 :) - Vineeth Pradhan
13
因为没有说明这两个命令的区别,所以真的应该扣 1 分。回答很差。 - Angry Dan
4
"-c M" 相当于 "-r <M-1>:M",而 "-c -M" 的意思是相反的:"-r M:<M-1>"。 - ErichBSchulz
显示剩余8条评论

34

6
鼓励添加外部资源链接,但请在链接周围加上一些背景信息,以便您的其他用户了解它是什么以及为什么存在。始终引用重要链接的最相关部分,以防目标站点无法访问或永久下线。 - user2084795

32

很抱歉浪费了一些空间来重申之前给出的答案 - 但这是我总是遇到麻烦的事情。

假设我已将本地文件更新为最新修订版本,即854。那么,我想获取旧版本 - 比如说851修订版的文件版本。

复制会起作用:

svn copy -r 851 svn+ssh://<repository URL>/l3toks.dtx ./l3toks.dtx

.. 不过,我懒得用grep查找repo的URL :)

更新似乎可能会起作用:

svn up -r 851 ./l3toks.dtx

... 然而,它也将本地副本标记为“最近检出”或者“在线修订版本相同”(例如在Tortoise/RabbitVCS中您会看到一个绿色的OK勾号)- 这意味着您不能执行 svn ci -m "rolled back to r 851" :简单地因为本地的subversion可执行程序不会注意到任何本地更改,并且不会上传任何内容到在线存储库中。

并且,如前所述,反向合并可以起作用 - 但在这种情况下,不应依赖于快捷语法; 而应明确说明:

svn merge -r HEAD:851 l3toks.dtx
--- Reverse-merging r854 through r852 into 'l3toks.dtx':
U    l3toks.dtx
我必须承认 - 我永远不会理解句子“将r854到r852反向合并到文件中”意味着“刚刚得到了文件的r851,并覆盖了之前本地所保存的内容 - 并且它与最新在线版本不同,因此可以将其作为新的‘回滚’版本在线检查”,但我猜想(并希望 :) )这就是它的作用 :)

在此之后,可以使用svn diff来快速确保我们已在本地获取了正确的修订版本;而且,在Tortoise / RabbitVCS中将使用红色惊叹号标记该文件(即与最新提交的版本不同),因此这次可以运行svn ci -m“回滚到r 851”

还要注意,如果您在反向合并后改变主意(即,无论如何您都想继续工作在最新的HEAD修订版本上,这里是854 - 在您本地回滚到851之后,但尚未提交回滚),则不应使用svn up,因为它只会显示已经“在修订版本854处”;而应改用svn revert --recursive .或类似的命令...

干杯!

参考:如何使用Subversion回滚更改 - Jacob Wright - Flex,AIR,PHP等。

编辑:...显然,可以通过以下方式实现与svn merge -r HEAD:851 l3toks.dtx完全相同的效果:

svn export -r 851 l3toks.dtx
A    l3toks.dtx
Export complete.

2
你应该始终优先选择 svn export,因为它可以完全满足你的需求——检出特定版本的文件。而反向合并则会尝试将你本地的更改与指定版本进行合并,这是一项复杂而疯狂的操作,如果不小心就容易出错! - Falco
1
我在反向合并方面遇到了问题。与其弄清原因,我只是尝试了导出,结果完美解决了。我强烈建议仅使用导出。您可以使用--force来覆盖目录。只要记住它会覆盖所有更改。 - Nick
非常好的解释,说明了实际发生的情况!我经常使用AnkhSVN和TortoiseSVN,但我没有看到任何地方可以利用“svn export” - 我是错过了什么还是这些GUI中没有实现? - Conrad
@Conrad,你可以通过在AnkhSVN中点击“导出...”和在TortoiseSVN中从存储库上下文(右键单击)菜单中选择“导出”来使用它。 - nitinr708

10

最近我不得不回滚到特定的版本来调试一个旧版本构建,效果神奇:

svn up -r 3340 (or what ever your desired revision number)

由于我不关心本地更改(在恢复之前已检入所有我关心的内容),因此我必须使用"tc"选项解决所有冲突。

回到主干版本也很简单:

svn up

5
你需要的是“反向合并”。你应该查看SVN书中有关合并函数的文档(正如luapyad或更准确地说,该帖子的第一位评论者所指出的那样)。如果你正在使用Tortoise,你也可以进入日志视图,右键单击并选择“还原此版本的更改”,这样就可以撤销你犯的错误。

4

svn合并将合并修订版本,而不是还原它们。例如,如果您在HEAD版本中添加了一些内容,然后将其与先前的修订版本合并,则更改将保留。

我使用svn cat然后将其重定向到文件中:

svn cat -r 851 l3toks.dtx > l3toks.dtx

然后你在该文件中有851个内容,可以将其检查并重新提交。

4

反向合并正是您所需要的(参见luapyad的回答)。只需将合并应用于错误提交的文件而不是整个目录即可。


4
如果您只想撤消上一次的签入,可以使用以下方法:
svn merge -r head:prev l3toks.dtx

那样的话,您就不必寻找当前和先前的版本号。

3
如果你使用带有SVN插件的Eclipse IDE,可以按照以下步骤进行回滚:
1. 右键单击要回滚的文件(如果是误删并想要添加回来的文件,则右键单击它们所在的文件夹) 2. 选择“Team> Switch” 3. 选择“Revision”单选按钮,并输入要回滚到的版本号。点击确定 4. 进入同步透视图 5. 选择要回滚的所有文件 6. 在所选内容上右键单击,选择“Override and Commit...”
这将把文件恢复到你想要的版本。请注意,SVN会将更改视为新提交。也就是说,更改会获得一个新的版本号,旧版本和新版本之间没有链接。你应该在提交注释中指定将这些文件回滚到特定版本。

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