在SVN中恢复删除添加文件的历史记录
Recover history of delete-added file in SVN
在我的 SVN 主干中,我删除了一个目录并在一次提交中重新添加了它。
现在,尝试获取 "svn log" 我只看到该提交的历史记录,而没有我过去所做的所有更改。我知道这是有道理的,因为文件的删除和重新添加,但我想还原整个事情并恢复我的历史记录。我该怎么做?
其他信息和详细信息:
我在 SVN 的主干分支上工作。为了从主干更新分支,我使用普通差异手动更新文件,而不是使用 "svn merge" 命令。对于添加到主干的新文件,我在我的分支中手动 "svn add" 它们,删除相同 (svn rm)。
当我想将分支合并回主干时,我的一个同事建议我 "svn merge" 分支(我解决了这个过程中的很多冲突),然后 "svn merge --reintegrate" 从分支和提交的主干到后备箱。
在所有冲突的某个地方,我删除了整个目录,将其提交到分支,将其重新添加到分支并再次提交。
现在 "merge --reintegrate" 带来了该目录的删除 - 重新添加,并且提交导致所有历史记录消失。
我真的只想还原整个事情,这样我就可以开始干净了(这次我已经知道如何使提交正确,但我不知道如何还原和恢复历史记录)。
编辑:我试图获取一些我知道已从 this question 中删除的文件的日志。修订版 4129 是删除-重新添加,而 4120 是我最后一次编辑其中一个文件。
"svn log -r4129 file" 只列出了我最近的提交,没有历史记录。
"svn log -r4120 file" returns 一行“--------”。
我认为与该问题的主要区别在于我还在同一提交中重新添加了文件,而不是仅仅删除了。
您可以使用显示该目录的原始历史记录真正恢复它的唯一方法是使用在服务器上运行的 svnadmin dump/load 命令重新创建存储库。您执行的任何合并或其他常规 svn 命令只会导致在历史记录中已经存在的剪切之上进行更多额外的提交。也许这样的事情对你来说是可以接受的,但这不是你的问题。
因此,对于 svnadmin,您要做的是将存储库的内容转储到一个文件中,添加一个选项以仅包含目录被删除之前的修订版。然后将该转储文件加载到新的存储库中。然后,您将拥有删除发生之前的存储库。现在,理论上你应该能够将 delete/readd 之后的修订转储到 HEAD 并将它们加载回新的存储库,为你提供一个完美的新存储库而不会中断并包含最新的所有内容.这可能行不通,但这取决于跳过的修订中可能混入了哪些其他更改。
您可能想要阅读 svn 参考中的命令,但它可能看起来像这样:
svnadmin dump C:\Repositories\myrepo -r4128 > myrepo.dump
svnadmin load C:\Repositories\mynewrepo < myrepo.dump
svnadmin dump C:\Repositories\myrepo -r4130:HEAD --incremental > myrepo2.dump
svnadmin load C:\Repositories\mynewrepo < myrepo2.dump
In my SVN trunk, I deleted a directory and re-added it in a single commit.
糟糕,程序员!没有甜甜圈给你!
您所做的是创建一个完全不同但名称相同的目录。对你来说,它们看起来是一样的。对于Subversion来说,这两个目录没有任何关系。
为什么要删除旧目录并创建同名的新目录?
您想还原吗?在 svn log
中找到您删除和添加目录的修订版,然后尝试此操作:
$ svn merge -c -$rev
其中 $rev
是您在目录中删除并重新添加的日志中的修订。这是您可以删除您在 Subversion 中所做的任何更改的方法。
您可以在命令中指定多个-c $rev
。如果这会产生冲突,您可能需要采取稍微不同的策略。在那个版本中,您必须使用 pinning 来固定目录修订版,就像它在以前的版本中一样。假设您的日志显示您删除了修订版 12345 中的目录 foo
,现在您需要将其取回:
首先删除当前目录foo
:
$ svn delete foo
现在,将 foo
从修订 以前的 复制回那个目录仍然存在时的删除。由于在revision 12345被删除,我们需要从revision 12344复制过来:
$ svn cp $REPO_URL/trunk/foo@12344 .
这应该恢复旧副本。
Additional info and details: I was working on a branch of a trunk in SVN. For updating the branch from the trunk, I manually updated files with plain diffs, not using the "svn merge" command. For new files that were added to the trunk I manually "svn add" them in my branch, same for deletion (svn rm).
我要喝一杯...
你正在做的是合并,但没有告诉 Subversion 你做了合并。如果你现在在 Subversion 中进行合并,你会遇到一堆合并冲突,因为 Subversion 会看到文件的相同区域在分支和主干中都被更改。
当你向分支添加一个新文件时,它是一个与主干中的文件完全不同的文件。它可能具有相同的名称并位于同一目录中,但由于您已将其添加到分支中,因此无法将该文件上的主干更改合并到该分支中。
如果可能的话,删除分支上的文件,然后从主干上复制。这样,主干中的更改可以合并到分支中。
这让我们明白了一些非常非常重要的事情:不要通过添加来创建分支。始终从主干(或任何你分支的地方)复制分支。否则,该分支和主干不共享相同的历史记录。如果您还没有完成初始副本,您将永远无法使用 Subversion 合并。分支和主干没有共同的历史。
有时手动将更改添加到分支比从主干合并更容易。例如,分支上的更改与主干上的更改不同。在这种情况下,您可以使用 --record-only
让 Subversion 知道您还是进行了合并:
$ svn merge --record-only -r12345 $REPO/trunk .
以上将记录在分支上完成了变更集 12345 的合并,Subversion 不会尝试再次合并。
合并是你的朋友。不要试图绕过它。一旦您了解 Subversion 在分支和被合并的 branch/trunk 之间需要一个共同的祖先,Subversion 在合并方面做得很好。使用 svn cp
设置该关系。
在我的 SVN 主干中,我删除了一个目录并在一次提交中重新添加了它。 现在,尝试获取 "svn log" 我只看到该提交的历史记录,而没有我过去所做的所有更改。我知道这是有道理的,因为文件的删除和重新添加,但我想还原整个事情并恢复我的历史记录。我该怎么做?
其他信息和详细信息: 我在 SVN 的主干分支上工作。为了从主干更新分支,我使用普通差异手动更新文件,而不是使用 "svn merge" 命令。对于添加到主干的新文件,我在我的分支中手动 "svn add" 它们,删除相同 (svn rm)。 当我想将分支合并回主干时,我的一个同事建议我 "svn merge" 分支(我解决了这个过程中的很多冲突),然后 "svn merge --reintegrate" 从分支和提交的主干到后备箱。 在所有冲突的某个地方,我删除了整个目录,将其提交到分支,将其重新添加到分支并再次提交。 现在 "merge --reintegrate" 带来了该目录的删除 - 重新添加,并且提交导致所有历史记录消失。 我真的只想还原整个事情,这样我就可以开始干净了(这次我已经知道如何使提交正确,但我不知道如何还原和恢复历史记录)。
编辑:我试图获取一些我知道已从 this question 中删除的文件的日志。修订版 4129 是删除-重新添加,而 4120 是我最后一次编辑其中一个文件。 "svn log -r4129 file" 只列出了我最近的提交,没有历史记录。 "svn log -r4120 file" returns 一行“--------”。 我认为与该问题的主要区别在于我还在同一提交中重新添加了文件,而不是仅仅删除了。
您可以使用显示该目录的原始历史记录真正恢复它的唯一方法是使用在服务器上运行的 svnadmin dump/load 命令重新创建存储库。您执行的任何合并或其他常规 svn 命令只会导致在历史记录中已经存在的剪切之上进行更多额外的提交。也许这样的事情对你来说是可以接受的,但这不是你的问题。
因此,对于 svnadmin,您要做的是将存储库的内容转储到一个文件中,添加一个选项以仅包含目录被删除之前的修订版。然后将该转储文件加载到新的存储库中。然后,您将拥有删除发生之前的存储库。现在,理论上你应该能够将 delete/readd 之后的修订转储到 HEAD 并将它们加载回新的存储库,为你提供一个完美的新存储库而不会中断并包含最新的所有内容.这可能行不通,但这取决于跳过的修订中可能混入了哪些其他更改。
您可能想要阅读 svn 参考中的命令,但它可能看起来像这样:
svnadmin dump C:\Repositories\myrepo -r4128 > myrepo.dump
svnadmin load C:\Repositories\mynewrepo < myrepo.dumpsvnadmin dump C:\Repositories\myrepo -r4130:HEAD --incremental > myrepo2.dump
svnadmin load C:\Repositories\mynewrepo < myrepo2.dump
In my SVN trunk, I deleted a directory and re-added it in a single commit.
糟糕,程序员!没有甜甜圈给你!
您所做的是创建一个完全不同但名称相同的目录。对你来说,它们看起来是一样的。对于Subversion来说,这两个目录没有任何关系。
为什么要删除旧目录并创建同名的新目录?
您想还原吗?在 svn log
中找到您删除和添加目录的修订版,然后尝试此操作:
$ svn merge -c -$rev
其中 $rev
是您在目录中删除并重新添加的日志中的修订。这是您可以删除您在 Subversion 中所做的任何更改的方法。
您可以在命令中指定多个-c $rev
。如果这会产生冲突,您可能需要采取稍微不同的策略。在那个版本中,您必须使用 pinning 来固定目录修订版,就像它在以前的版本中一样。假设您的日志显示您删除了修订版 12345 中的目录 foo
,现在您需要将其取回:
首先删除当前目录foo
:
$ svn delete foo
现在,将 foo
从修订 以前的 复制回那个目录仍然存在时的删除。由于在revision 12345被删除,我们需要从revision 12344复制过来:
$ svn cp $REPO_URL/trunk/foo@12344 .
这应该恢复旧副本。
Additional info and details: I was working on a branch of a trunk in SVN. For updating the branch from the trunk, I manually updated files with plain diffs, not using the "svn merge" command. For new files that were added to the trunk I manually "svn add" them in my branch, same for deletion (svn rm).
我要喝一杯...
你正在做的是合并,但没有告诉 Subversion 你做了合并。如果你现在在 Subversion 中进行合并,你会遇到一堆合并冲突,因为 Subversion 会看到文件的相同区域在分支和主干中都被更改。
当你向分支添加一个新文件时,它是一个与主干中的文件完全不同的文件。它可能具有相同的名称并位于同一目录中,但由于您已将其添加到分支中,因此无法将该文件上的主干更改合并到该分支中。
如果可能的话,删除分支上的文件,然后从主干上复制。这样,主干中的更改可以合并到分支中。
这让我们明白了一些非常非常重要的事情:不要通过添加来创建分支。始终从主干(或任何你分支的地方)复制分支。否则,该分支和主干不共享相同的历史记录。如果您还没有完成初始副本,您将永远无法使用 Subversion 合并。分支和主干没有共同的历史。
有时手动将更改添加到分支比从主干合并更容易。例如,分支上的更改与主干上的更改不同。在这种情况下,您可以使用 --record-only
让 Subversion 知道您还是进行了合并:
$ svn merge --record-only -r12345 $REPO/trunk .
以上将记录在分支上完成了变更集 12345 的合并,Subversion 不会尝试再次合并。
合并是你的朋友。不要试图绕过它。一旦您了解 Subversion 在分支和被合并的 branch/trunk 之间需要一个共同的祖先,Subversion 在合并方面做得很好。使用 svn cp
设置该关系。