【问题标题】:How do I return to an older version of our code in Subversion?如何在 Subversion 中返回旧版本的代码?
【发布时间】:2010-10-23 07:13:36
【问题描述】:

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

我在 vs08 上使用“anksvn”。

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

我的 PC 上也有 subversion 客户端。

【问题讨论】:

    标签: svn backport


    【解决方案1】:

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

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

    Subversion 红皮书有一个good section about this

    【讨论】:

    • 但合并不会覆盖我的更改和新修订。
    • 如果您使用的是 TortoiseSVN,请右键单击文件选择合并,然后合并一系列修订。在日志框中输入 140-150 并单击反向复选框。之后,像往常一样提交。这将执行与 Jon 的示例相同的操作。
    • 使用 eclipse 和 subclipse,您可以右键单击您的项目,Team/Show History,然后选择您想要“撤消”的修订,然后再次右键单击选择“Revert changes from Selected Revisions” "。
    • 要从头部修订中恢复,您也可以写svn merge -r HEAD:140
    • @DavGarcia 的 TortoiseSVN 说明不适合我,至少不能还原修订版中的所有文件(使用 TortoiseSVN 1.8.8)。右键单击该文件夹,选择 TortoisSVN->显示日志。选择要恢复的修订,右键单击“恢复此修订的更改”。提交更改。
    【解决方案2】:

    您只能在颠覆历史的头部提交新的更改。

    您无法直接使用 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 -m "Reverted to revision 123"
      

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

    如果找不到修订号

    如果您找不到旧副本,而您只想提交当前 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 -m "Reverted to good copy"
      

    【讨论】:

    • svn 不会将其解释为修改,我无法提交。
    • 我猜这个答案被那些找不到他们的修订号或欣赏主要解释的人赞成。我现在更新了答案以包含这两种方法。
    • svn commit -m "Reverted to good copy" ,你错过了 -m
    • @SalimShamim 谢谢,它已经失踪 12 年了。
    【解决方案3】:

    就用这条线

    svn update -r yourOldRevesion

    您可以通过以下方式了解您当前的修订:

    svn 信息

    【讨论】:

    • 这并不能解决问题。相反,这会产生提问者在提问时所处的状态。
    • 如果您不幸听从了这个建议,请运行:“svn resolve --accept working -R。”
    【解决方案4】:

    使用合并撤消整个签入的标准方法效果很好,如果这是您想要做的。但是,有时您想要做的只是还原单个文件。没有合法的方法可以做到这一点,但有一个 hack:

    1. 使用 svn log 找到你想要的版本。
    2. 使用svn的导出子命令:

      svn 导出http://url-to-your-file@123 /tmp/文件名

    (其中 123 是文件良好版本的修订号。)然后移动或复制该单个文件以覆盖旧文件。签入修改后的文件就完成了。

    【讨论】:

    • 使用 Tortoise-svn 我可以右键单击单个文件并将其合并。也应该有一种方法可以使用svn 来做到这一点?
    • svn cat -r 123 path-in-your-working-copy &gt; path-in-your-working-copy
    【解决方案5】:

    有点老派

    svn diff -r 150:140 > ../r140.patch
    patch -p0 < ../r140.patch
    

    然后是通常的

    svn diff
    svn commit
    

    【讨论】:

      【解决方案6】:

      我认为这是最合适的:

      向后合并,例如,如果提交的代码包含从 rev 5612 到 5616,只需向后合并即可。它对我有用。

      例如:

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

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

      【讨论】:

        【解决方案7】:

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

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

        1. 转到团队 -> 显示历史记录。
        2. 右键单击要忽略的修订版或修订版范围。
        3. 选择“还原更改”选项。

        这将运行反向合并,撤消工作副本中的更改。

        只需查看代码并提交即可。

        【讨论】:

          【解决方案8】:

          右键单击要还原的最高层级 >> RevertRevert to Revision

          【讨论】:

            【解决方案9】:

            之前的大多数答案都使用了反向合并,这通常是正确的答案。但是,有一种情况(这只是发生在我身上)并非如此。

            在进行小的更改时,我不小心将带有 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】:

              这个页面上有很多危险的答案。请注意,从 SVN 版本 1.6 开始,执行 update -r 可能会导致树冲突,这会迅速升级为潜在的数据丢失 kafkeresque 噩梦,您需要在谷歌上搜索有关树冲突的信息。

              恢复到某个版本的正确方法是:

              svn merge -r HEAD:12345 .
              

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

              【讨论】:

                【解决方案11】:

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

                Here's 也是撤消更改的说明。

                【讨论】:

                  【解决方案12】:

                  右键单击项目 > 替换为 > 修订或 URL > 选择要恢复的特定修订。

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

                  【讨论】:

                    【解决方案13】:

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

                    Cherry-Pick 合并

                    来自手册页。

                    1. 这种形式称为'cherry-pick'合并: '-r N:M' 指的是历史上的差异 版本 N 和 M 之间的源分支。

                      “反向范围”可用于撤消更改。例如,当 source 和 target 指的是同一个分支,一个先前提交的 修订可以“撤消”。在一个反向范围中,N大于M in '-r N:M',或 '-c' 选项与负数一起使用:'-c -M' 相当于'-r M:'。撤消这样的更改也是已知的 作为执行“反向合并”。


                    • 如果源是一个文件,那么差异将应用于该文件 文件(用于反向合并早期更改)。否则, 如果源是目录,则目标默认为 '.'。

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

                    例子:

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

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

                    【讨论】:

                      【解决方案14】:

                      以下内容对我有用。

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

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

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

                      3. 将那些替换为//

                      4. rm -rf 所有的行。

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

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2017-05-18
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多