515

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

我在 vs08 上使用“anksvn”。

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

我的 PC 上也有 subversion 客户端。

4

14 回答 14

818

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

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

Subversion 红皮书对此有很好的部分

于 2009-05-02T08:38:28.500 回答
180

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

您无法直接使用 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"
    
于 2009-05-02T09:43:51.200 回答
35

只需使用此行

svn update -r yourOldRevesion

您可以通过以下方式了解您当前的版本:

svn信息

于 2013-03-27T13:21:28.240 回答
28

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

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

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

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

于 2009-07-02T20:39:44.910 回答
8

有点老派

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

然后通常

svn diff
svn commit
于 2013-09-02T10:53:15.687 回答
5

我认为这是最适合的:

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

例如:

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

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

于 2013-04-13T07:42:41.477 回答
3

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

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

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

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

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

于 2014-02-28T20:08:13.787 回答
2

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

于 2009-05-02T08:40:04.037 回答
2

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

在进行小改动时,我不小心将带有 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"

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

于 2017-05-24T12:48:18.260 回答
1

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

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

svn merge -r HEAD:12345 .

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

于 2019-04-12T16:11:12.460 回答
0

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

也是撤消更改的解释。

于 2009-05-02T08:38:09.780 回答
0

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

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

于 2016-09-06T13:11:08.983 回答
0

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

樱桃采摘合并

从手册页。

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

    “反向范围”可用于撤消更改。例如,当源和目标引用同一分支时,可以“撤消”先前提交的修订。在反向范围内,'-r N:M' 中的 N 大于 M,或者'-c' 选项与负数一起使用:'-c -M' 等价于 '-r M:'。撤消这样的更改也称为执行“反向合并”。


  • 如果源是文件,则差异将应用于该文件(对于反向合并早期更改很有用)。否则,如果源是目录,则目标默认为“.”。

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

例子:

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

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

于 2018-05-23T11:09:37.347 回答
-1

以下对我有用。

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

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

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

  3. 用 替换那些//

  4. rm-rf 所有行。

    svn status --no-ignore | grep '^[?I]' |  sed "s/^[?I] //" | xargs -I{} rm -rf "{}"
    
于 2014-03-24T11:47:16.377 回答