如何在Subversion中返回旧版本的代码?

时间:2009-05-02 08:35:43

标签: svn backport

我正和一位朋友一起开展一个项目,我想回到我们代码的旧版本并将其设置为当前版本。我该怎么做?

我在vs08上使用“anksvn”。

我的PC上有我想要的版本,但是提交失败了;我得到的信息是 “提交失败,文件或目录已过期。”

我的PC上也有subversion客户端。

14 个答案:

答案 0 :(得分:742)

基本上你需要“向后合并” - 在当前和以前的版本之间应用差异当前版本(所以最终得到的工作副本看起来像旧版本)然后提交再次。例如,从修订版150(当前)回到修订版140:

svn update
svn merge -r 150:140 .
svn commit -m "Rolled back to r140"

Subversion红皮书有good section about this

答案 1 :(得分:168)

您只能在subversion历史记录的 head 处提交新的更改。

您无法直接使用PC上的正确副本执行任何操作的原因是,其.svn个文件夹知道它是过去的代码,因此需要在任何提交之前进行更新。

找到好的修订号并恢复

  1. 查找所需旧版本的修订版号。通过以下方式获取当前版本:

    svn info --show-item revision
    # or
    svn log
    

    或使用:

    svn update -r <earlier_revision_number>
    

    检查项目的各种旧版本,直到找到正确的版本号。

  2. 记下好的修订号(假设123以下示例)。

  3. 更新到最新版本:

    svn update
    
  4. 撤消所需修订版本与最新版本之间的所有更改:

    svn merge -r HEAD:123 .
    svn commit "Reverted to revision 123"
    

    (与Jon Skeet上面的回答相同。)

  5. 如果找不到修订号

    如果找不到旧版本,而您只想提交PC上当前的文件:

    1. 制作好版本的副本(但没有任何.svn个文件夹):

      cd ..
      rsync -ai --exclude=.svn  project/  project-good/
      
    2. 现在确保您拥有最新版本:

      cd project
      svn update
      # or make a fresh checkout
      svn checkout <url>
      
    3. 将好的版本复制到工作副本的顶部。

      此命令将复制并删除工作树中不在好副本中的任何文件,但不会影响现有的.svn文件夹。

      cd ..
      rsync -ai --exclude=.svn --delete  project-good/  project/
      

      如果您没有rsync,可以使用cp -a,但还需要手动删除任何不需要的文件。

    4. 你应该能够提交你现有的东西。

      cd project
      svn commit "Reverted to good copy"
      

答案 2 :(得分:35)

只需使用此行

即可
  

svn update -r yourOldRevesion

您可以使用以下方式了解当前版本:

  

svn info

答案 3 :(得分:27)

使用合并撤消整个签到的标准方法非常有用,如果这是您想要做的。但有时,您只想恢复单个文件。没有合法的方法可以做到这一点,但有一个黑客:

  1. 使用svn log查找所需的版本。
  2. 使用svn的export子命令:

    svn export http://url-to-your-file@123 / tmp / filename

  3. (其中123是文件的正确版本的修订号。)然后移动或复制该单个文件以覆盖旧文件。检查修改后的文件,您就完成了。

答案 4 :(得分:8)

多一点老派

svn diff -r 150:140 > ../r140.patch
patch -p0 < ../r140.patch
然后是通常的

svn diff
svn commit

答案 5 :(得分:5)

我认为这是最合适的:

例如,如果提交的代码包含来自的修订版,则向后合并 rev 5612到5616,只是向后合并。它最终起作用。

例如:

svn merge -r 5616:5612 https://<your_svn_repository>/

它将包含一个返回到以前版本的合并代码,然后您可以提交它。

答案 6 :(得分:3)

这就是我为我所做的工作。

我想撤消我在特定时间执行的多次提交中的更改,并希望转到上一个提交点。

  1. 转到团队 - &gt;显示历史。
  2. 右键单击要忽略的修订版或范围。
  3. 选择“还原更改”选项。
  4. 这将运行反向合并,撤消工作副本中的更改。

    只需查看代码并提交。

答案 7 :(得分:2)

右键点击要还原的最高层级&gt;&gt; RevertRevert to Revision

答案 8 :(得分:1)

右键单击项目&gt;替换为&gt;修订版或网址&gt;选择要还原的特定修订版。

现在将本地更新代码版本提交到存储库。这会将代码库还原为特定版本。

答案 9 :(得分:1)

以前的大多数答案都使用了反向合并,这通常是正确的答案。然而,有一种情况(刚好发生在我身上)并不存在。

我做了一个小小的改动时意外地将带有Unix行结尾的文件更改为DOS行结尾,然后提交了它。这可以通过更改行结尾和再次提交,或通过反向合并来轻松撤消,但它具有使svn blame列出我的编辑作为文件的每一行的源的效果。 (有趣的是,Windows上的TortoiseSVN不受此影响;只有命令行svn blame。)

如果您想维护svn blame报告的历史记录,我认为您需要执行以下操作:

  • 删除文件并提交。
  • 在存储库中,将文件的上一个正确副本复制到头部,然后提交。
  • 恢复您想要保留的所有修改。

删除有点可怕,但请记住,您始终将文件保存在存储库中,因此恢复它并不是什么大问题。这里有一些代码来说明这些步骤。假设xxx是最后一个好副本的修订号。

svn rm svn+ssh://path/to/file
svn copy svn+ssh://path/to/file@xxx svn+ssh://path/to -m"Restore good copy"
svn update
<restore the edits>
svn commit -m"Restore edits"

请注意,对于存储库中的副本,目标必须是目录,而不是文件名。

答案 10 :(得分:0)

与旧版本同步并提交。这应该可以解决问题。

Here's也是撤消更改的解释。

答案 11 :(得分:0)

简而言之,Jon Skeet的答案几乎就是解决方案,但如果你像我一样,你可能需要一个解释。 Subversion手册将其称为

Cherry-Pick Merge

从手册页。

  
      
  1. 此表格被称为“挑选”。合并:   &#39; -r N:M&#39;是指历史上的差异    修订N和M之间的源分支。

         

    A&#39;反向范围&#39;可用于撤消更改。例如,何时    source和target指的是同一个分支,一个先前提交的分支    修订可以“撤消”。在反向范围中,N大于M in    &#39; -r N:M&#39;或者&#39; -c&#39;选项使用负数:&#39; -c -M&#39;    相当于&#39; -r M:&#39;。撤消这样的改变也是众所周知的    执行反向合并&#39;

  2.   
  
      
  • 如果源是文件,则会对其应用差异   file(用于反向合并早期更改)。除此以外,   如果源是目录,则目标默认为&#39;。&#39;。

         

    在正常使用中,工作副本应该是最新的,单一的    修订版,没有本地修改,也没有切换子树。

  •   

示例:

svn merge -r 2983:289 path/to/file

这将使用服务器的修订版289替换本地副本[2983](根据上面的引用,应与服务器同步 - 您的责任)。更改发生在本地,这意味着如果您有一个干净的结帐,那么可以在提交之前检查更改。

答案 12 :(得分:0)

此页面上有很多危险的答案。请注意,从SVN 1.6版开始,执行update -r可能会导致树冲突,从而迅速升级为潜在的数据丢失的卡夫式睡梦night,您正在其中搜索有关树冲突的信息。

还原到版本的正确方法是:

svn merge -r HEAD:12345 .

其中12345是版本号。不要忘记点。

答案 13 :(得分:-1)

以下对我有用。

我有很多本地更改,需要丢弃本地副本中的那些并检查SVN中的最后一个稳定版本。

  1. 检查所有文件的状态,包括被忽略的文件。

  2. Grep所有行以获取新添加和忽略的文件。

  3. //替换为<{1}}。

  4. 和rm -rf所有行。

    svn status --no-ignore | grep'^ [?I]'| sed“s / ^ [?I] //”| xargs -I {} rm -rf“{}”