将整个svn存储库回滚或还原到较旧的版本


75

我搞砸了我的SVN存储库,现在需要将整个存储库从版本28还原到24,并且不想处理差异或冲突。有没有一种快速简单的方法来做到这一点?我已经可以使用merge命令在没有问题的情况下还原单个文件-但在这种情况下,当我真正想要做的就是删除它们时,它想将所有文件从版本28添加回存储库中。

我在Linux机器(bash)上使用命令行。

谢谢

编辑

感谢您的所有帮助!我通过以下方式修复它:

svnadmin create /svnroot/<repo>.fixed
svnadmin dump -r 1:24 /svnroot/<repo> --incremental > dump.svn
svnadmin load /svnroot/<repo>.fixed < dump.svn

然后将旧存储库放置在备份位置,然后将固定存储库移至存储库。

再次感谢!

svn  revert 

3
只是想对此表示感谢。我正在学习svn并搞砸了一些目录的移动(事实证明我这样做是有原因的!),我希望它消失。您的问题为我省了很多麻烦。
AgentConundrum

谢谢,我相信这行得通,但是当您的存储库具有10k +的修订版时,它花费了很长时间。:(
Amir Pashazadeh 2014年

Answers:


26

签出svnadmin转储/加载。它会使用文件的每个版本创建一个文本文件。可以删除某个点之上/之下的所有内容,然后重新导入。

例如,参见在其他地方迁移存储库数据


2
我现在正在调查这个,谢谢。当然,我必然会在不使用管道的情况下意外地键入svnadmin dump,因此现在我的整个项目都被写入了stdin(并且不会用ctrl + c停止)...我不会再犯该错误了:p

好; 我现在走对了,谢谢!但是我该如何做才能保留我的修订呢?我写了一个perl脚本,对于1虽然24 “svnadmin的转储-r $ I:$ I + 1 <回购协议>>文件”,然后“svnadmin的负载<回购> <文件”,它只是犯修订1

1
更改历史记录时,请确保在重新加载备份时更改存储库的guid。否则,您可能将旧的工作副本与已更改的数据库一起使用,并在以后错误地破坏修订版本(因为它们是基于不再存在的版本的增量构建的)。
Bert Huijben 09年

25

您可能需要“反向”合并。请参见svn书的“撤消更改”部分。

例如svn merge -r 28:24 [svn的路径]


它不会删除在28中创建的文件。问题是我添加了一堆我不应该使用的文件。是的,我真的搞砸了。手动追逐需要删除的内容是不可能的。我只是想24后“删除”每逆转

2
抱歉-我一定不太了解您的问题。我曾在多个场合使用反向合并来摆脱新添加的(但错误地)添加的文件...(但您的情况一定有所不同吗?)(通常无法从svn存储库中删除修订版本-仅添加可修复的新文件)错误)。
luapyad

您需要做的就是将其合并,如答案所示,然后在(svn ci -m "Revering all changes back to revision X")中重新检查项目。仍然可以签出错误的修订,但是,这会将您想要的修订放回HEAD。
保罗·尼尔森·贝克

14

如果您有权访问SVN服务器,则只需编辑 path/db/current,将要还原的旧修订版本号(此处为24)放在此处,然后从中删除不再需要的修订文件(即25、26、27、28)path/db/revs/0/。在我不小心删除了存储库中的目录之后,至少今天对我有用。


到目前为止,这是最快最简单的操作,而我过去曾经使用过这个技巧。但是,这是个坏习惯,我永远不会在其他人正在使用的回购中或有重要数据的仓库中这样做。最好正确地使用管理工具。
Tynam

我不知道发生什么事情,但是我确实知道以后可能会造成麻烦,因为在这样做之后,我曾经对下一次提交有疑问。话虽如此,我已经成功完成了几次,当然您首先备份了您的仓库,对吗?(当然,一个明显的问题是,执行此操作后,旧的工作副本的回购状态缓存将与实际的回购不匹配,因此请务必在此之后立即进行新的签出并从中进行工作,否则很可能会导致不匹配导致提交问题。)
Tynam 2010年

哦,这很脏……但是好像可以用。但是,我必须跑步svnadmin recover /path/to/repo才能再次提交。
lxg

值得注意的是,只有在path/db/revs/0提交次数少于1000的情况下,文件才可以进入。如果您还有更多内容,则文件在中path/db/revs/X,其中X是提交号除以1000
迈克尔·菲尔斯

13

如果您确实需要擦除文件已经存在的“证据”,则需要执行上述的svndump / svnload操作。

在“正常”情况下,如果您犯了一个错误,则需要使用反向合并。这确保了r24之后撤消更改也可以还原,扩散等。

下面的命令应该可以撤消更改(您需要提交合并结果以反映存储库中的合并)

svn merge -r 28:24

1
哈哈,好吧,我可以详细介绍一下这不是一个“正常”情况,而是不想让自己进一步尴尬

1
“异常”的情况是,如果您提交了一些秘密信息,例如包含密码的文件或类似的东西;您希望将其完全删除。关于此的最新消息是“ svn
遗忘

6

如果您没有使用管理员权限,那么您就无法删除任何旧版本,但是您仍然可以使用一个非常简单的“ svn copy”命令将其隐藏得非常好(nickf和JesperE已经提到了这一点,但是以一种相当神秘的方式)

svn删除协议:// svnserver / some / resource
svn复制协议:// svnserver / some / resource @ 24协议:// svnserver / some / resource

就是这样,修订版25至28已从svn日志中完全消失。它根本不是黑客,它是一个安全且(几乎没有...)文档化的功能。

如果“ resource”是目录,则必须从最后一个URL删除它:

svn复制协议:// svnserver / some / directory @ 24协议:// svnserver / some /

(否则,您将其复制到内部)


如果该svn copy prot://srv/path/proj ...命令给您类似“ svn:E170000:...与...不在同一个存储库中”的错误,则可以通过执行svn checkout prot://srv/path/proj@321 coolverthen来解决它svn copy coolver/proj prot://srv/path/。#ftw!
MarkHu

5

对于使用TortoiseSVN的任何人,解决方案都很简单:

  • 查看更改日志
  • 右键单击要回滚到的修订...
  • ...选择“还原到此修订版”
  • 提交您的更改

此方法保留版本历史记录(即您还原的所有修订版)。


我或多或少使用了您在这里所说的内容,因为保留了版本历史记录,但是我所做的是删除工作副本的源代码,然后选择“将项目更新到修订版”(因为“还原到此修订版”没有退出)修订后创建的文件)。对于tortoiseSVN用户而言,绝佳的解决方案:)
Ignacio Rubio 2014年

我很确定问题在于删除历史记录
MarcH 2014年

这个选项在TortoiseSVN中不存在,至少在2018
。– Rockin4Life33 '18

3

您可以对特定修订进行新签出。http://svnbook.red-bean.com/en/1.1/re04.html

svn co path/to/my/repo -r 24

我已经做过了,但是它拒绝作为新的修订版本重新提交到存储库。有可能这样做吗?即将修订版29复制到修订版24?

是。svn copy命令可以执行repo-> repo复制。检查“ svn帮助副本”以获取确切的语法。
JesperE

2

如果应用程序的文件夹结构没有更改,请签出旧修订,然后将.svn文件夹从最新修订替换为签出的旧修订。现在,您可以提交“旧”版本。


2
老实说,这听起来像是对我的黑客。
桑德·里肯

不幸的是,文件夹结构发生了重大变化,否则我将手动删除需要删除的内容。感谢您的输入。

1
我同意这是黑客。但这是一次性的情况,因此我不确定是否会寻找最优雅的解决方案。快速而简单的事情就足够了。

1

如果您确实要从存储库中完全删除文件,则需要对文件进行svndump,过滤掉不需要的revs和/或文件路径,进行新的回购,然后将过滤后的转储svn加载到新文件中资料库。您需要仔细阅读在执行任何此操作之前,您有关存储库维护的SVN书籍部分,并确保在确定新仓库具有所需的东西之前,不要删除现有的仓库


1

请问您svn del最顶层的目录,然后是svn copy它们:

svn copy svnurl@version svnurl 

0

我讨厌这样说,但是这是我发现自己使用svn存储库备份的情况。

您可以将某个修订版本的文件复制到存储库中的新目录吗?


备份SVN本身听起来很愚蠢,但这听起来像是我首先应该做的事情:/

我的svn存储库已损坏,这很不好玩。我经常进行备份,并将副本放在银行的保险箱中。

备份是一种很好的做法,但是在这种情况下,无需从备份还原。
桑德·里肯

0

这就是我要开始做的。残酷,是的,但这是唯一保证完全忽略冲突保持修订历史记录不变的唯一方法。

  cd /scratchdir 
  svn co -r good svn://repository
  cd /hosed_project
  svn up -r HEAD
  cat >> /tmp/cp.sh 
  ORIG=$1
  TARG=$( echo $ORIG | sed 's/\/scratchdir\///' ); 
  cp $ORIG /hosed_project/$TARG;
  ^D
  chmod u+x /tmp/cp.sh
  find /scratchdir -not -wholename "*/.svn*" -exec /tmp/cp.sh {} \;

请注意,这不是IMO的“常规”方式,常规方法是从旧版本创建分支,然后将该分支合并回到头部。(至少这是它过去的工作方式)

编辑:上面的代码未经测试,请不要逐字运行


0

我还不确定是否可以正常工作,因为我还没有在实际生产中使用它,但是我刚刚在一个测试存储库上尝试了一下(我复制了我的一个生产库),它似乎可以正常工作。

当您在存储库中时,请使用以下命令:

svn update -r 24 trunk

其中24是修订版本号,而trunk是您想要更新(或恢复为该修订版本号)的文件/文件夹。

在我的测试中,对几个文件进行了更新和(重新)添加,并且在执行提交后,我没有收到任何警告。然后,我用一些伪文本修改了一个文件,并尝试了另一次提交,并且只有所述文件在修改后的列表中弹出。看来效果不错!

再说一次,我以前没有在现场制作中使用它,所以如果我错了,请提出建议。我很想知道这是否也是可行的方法,因为我可以看到自己在(不久的将来)需要这样做。

-戴夫


这只会将您的工作副本更新为该较旧的版本,并且如上所述无法提供提交此副本的方法。
桑德·里肯

你确定吗?我已经在测试环境中尝试过了,看来还可以吗?我可能是错的。

如果文件在r24之后进行了修订,并且您对其进行了修改,则svn将无法提交对其所做的任何更改,并要求您先将其更新为HEAD
Wim Coenen,2009年

0
Example:
    Rev 100 all is working great        
    Rev 101 somebody really corrupted the dir structure and / or merged in bad changes, etc.
    Rev 102 You delete /trunk
    Rev 103 You copy /trunk@100 to HEAD
        You now have a /trunk that reflects only Rev 100 and 103. Not 101 or 102.

svn del svn://[RepoName]/trunk -m "removing issue in HEAD"
svn copy svn://[RepoName]/trunk@100 svn://[RepoName]/trunk -m "Copy of correct revision of trunk to HEAD"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.