【问题标题】:Recover history of delete-added file in SVN恢复SVN中删除添加文件的历史
【发布时间】:2015-06-11 00:01:15
【问题描述】:

在我的 SVN 主干中,我删除了一个目录并在一次提交中重新添加了它。 现在,尝试获取“svn log”,我只看到该提交的历史记录,没有我过去所做的所有更改。我知道这是有道理的,因为删除和重新添加文件,但我想恢复整个事情并恢复我的历史。我该怎么做?

其他信息和详细信息: 我在 SVN 的一个主干分支上工作。为了从主干更新分支,我手动更新了带有普通差异的文件,而不是使用“svn merge”命令。对于添加到主干的新文件,我在我的分支中手动“svn add”它们,对于删除(svn rm)也是如此。 当我想将分支合并回主干时,我的一个同事建议我“svn merge”分支(我解决了这个过程中的很多冲突),然后“svn merge --reintegrate”分支中的主干和提交到主干。 在所有冲突的某个地方,我删除了整个目录,将其提交到分支,将其重新添加到分支并再次提交。 现在“merge --reintegrate”带来了该目录的delete-readdition,提交导致所有历史记录消失。 我真的只是想恢复整个事情,所以我可以从头开始(我已经知道如何使提交正确,但我不知道如何恢复和恢复历史记录)。

编辑:我试图获取一些我知道已从this question 删除的文件的日志。修订版 4129 是删除-重新添加,而 4120 是我最后一次编辑其中一个文件。 “svn log -r4129 file”只列出了我的最新提交,没有历史记录。 “svn log -r4120 file”返回一行“--------”。 我认为与该问题的主要区别在于我还在同一个提交中重新添加了文件,而不仅仅是删除。

【问题讨论】:

  • 对不起,我误会了你。我以为您只是想查看历史记录,但您希望存储库看起来好像您的删除从未发生过,对吗?我不相信有办法做到这一点。
  • @PatrickQuirk 是的,这就是我想要的。我相信应该离开,考虑到如果我在整个混乱之前“svn up”进行修订,我可以查看我的正确历史。我正在寻找类似的东西:“svn up -r1000(1001 是错误的提交);svn commit -m“restored history”
  • @bahrep 建议的 svn 日志对我不起作用(请参阅上面的编辑)。我认为这是因为我在同一次提交中重新添加了文件,而不仅仅是删除了它。
  • 为什么不使用“cherry pick merge”撤销有问题的修订? svn merge -c -revNumber . 更多关于反向“樱桃采摘”的信息可以在这里找到:svnbook.red-bean.com/en/1.6/…

标签: svn


【解决方案1】:

在我的 SVN 主干中,我删除了一个目录并在一次提交中重新添加了它。

糟糕,程序员!没有甜甜圈给你!

您所做的是创建一个完全不同但名称相同的目录。对你来说,它们看起来一样。对 Subversion 来说,这两个目录没有任何关系。

为什么要删除旧目录并创建一个同名的新目录?

你想恢复吗?在svn log 中找到您删除和添加目录的修订版,然后试试这个:

$ svn merge -c -$rev

其中$rev 是日志中您删除并添加回目录的修订版。这是您可以删除您在 Subversion 中所做的任何更改的方法。

您可以在命令中指定多个-c $rev。如果这会产生冲突,您可能需要采取稍微不同的策略。在那个版本中,您必须使用 pinning 来固定目录修订版,就像它在以前的版本中一样。假设您的日志显示您在修订版 12345 中删除了目录 foo,现在您需要将其取回:

首先,删除当前目录foo

$ svn delete foo

现在,当该目录仍然存在时,将 foo 从修订版previous 复制回删除。由于在12345修订版中被删除,我们需要从修订版12344复制:

$ svn cp $REPO_URL/trunk/foo@12344 .

这应该会恢复旧副本。

其他信息和详细信息:我在 SVN 中的主干分支上工作。为了从主干更新分支,我手动更新了带有普通差异的文件,而不是使用“svn merge”命令。对于添加到主干的新文件,我在我的分支中手动“svn add”它们,对于删除(svn rm)也是如此。

我要喝一杯……

你正在做的是合并,但没有告诉 Subversion 你做了合并。如果你现在在 Subversion 中进行合并,你会遇到一堆合并冲突,因为 Subversion 会看到文件的同一区域在分支和主干中都被更改。

当您将新文件添加到分支时,它与主干中的文件完全不同。它可能同名且在同一个目录中,但由于您已将其添加到分支中,因此您无法将该文件上的主干中的更改合并到该分支中。

如果可能,删除分支上的文件,然后从主干复制它。这样,主干中的更改可以合并到分支中。

这让我们非常非常重要:不要通过添加来创建分支。始终从主干(或您要从其分支的任何地方)复制分支。否则,该分支和主干不共享相同的历史记录。如果您还没有完成初始副本,您将永远无法使用 Subversion 合并。分支和主干没有共同的历史。

有时手动将更改添加到分支而不是从主干合并它更容易。例如,分支上的更改与主干上的更改不同。在这种情况下,你可以使用--record-only 让 Subversion 知道你已经完成了合并:

 $ svn merge --record-only -r12345 $REPO/trunk .

上面会记录在分支上完成了变更集 12345 的合并,Subversion 不会再尝试合并。

合并是您的朋友。不要试图绕过它。一旦您了解 Subversion 在分支和被合并的分支/主干之间需要一个共同的祖先,Subversion 在合并方面做得非常好。使用svn cp 设置该关系。

【讨论】:

  • 非常感谢您的提示。看起来我刚开始把整个事情搞得一团糟,绝对是在那里吸取的教训。幸运的是,我们将在大约一周后将存储库切换到 GIT,GIT 设法忽略了所有问题,并正确显示了所有历史记录。
【解决方案2】:

您可以使用该目录显示的原始历史记录来真正恢复它的唯一方法是使用在服务器上运行的 svnadmin dump/load 命令重新创建存储库。您执行的任何合并或其他普通 svn 命令只会导致在历史记录中已经存在的剪辑之上增加更多额外的提交。也许你可以接受这样的事情,但这不是你的问题。

因此,使用 svnadmin,您要做的就是将存储库的内容转储到文件中,并添加一个选项以仅包含目录被删除之前的修订版。然后将该转储文件加载到新的存储库中。然后你就拥有了删除发生之前的存储库。现在,从理论上讲,您应该能够从删除/读取到 HEAD 之后再次转储修订版并将其加载回新存储库,从而为您提供一个完美的新存储库而不会中断并包含最新的所有内容。这可能不起作用,但取决于跳过的修订版中可能混入了哪些其他更改。

您可能想阅读 svn 参考中的命令,但它可能看起来像这样:

svnadmin 转储 C:\Repositories\myrepo -r4128 > myrepo.dump
svnadmin 加载 C:\Repositories\mynewrepo

svnadmin 转储 C:\Repositories\myrepo -r4130:HEAD --incremental > myrepo2.dump
svnadmin 加载 C:\Repositories\mynewrepo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 2017-04-13
    • 1970-01-01
    • 2017-09-16
    • 2018-10-06
    相关资源
    最近更新 更多