如何在SVN中找到两个分支的共同祖先?

时间:2010-10-25 14:14:52

标签: svn

想象一下,你有一个很大的SVN树,遍布整个地方。有树干,有树枝,树枝有枝等等。所以,树上有两个树枝,你怎么能找到共同的祖先呢?

我知道您可以简单地获取完整的日志并对其进行比较,但如果您的主干有75,000个修订版(并且大部分时间您将主干与另一个主干进行比较,可能是遥远的分支),它会变得有点慢。

该过程将自动进行,因此您可以手动建议不易完成的事情。

已添加:忘了说,我需要实时完成。不像10ms那样是“实时”,而是“在等待输出的人生气之前”的“实时”。如果它低于10秒,那就太好了。

4 个答案:

答案 0 :(得分:9)

我想这就是你需要的东西

  

svn log -v --stop-on-copy

将返回以下

  

r43477 |用户名| 2010-09-21 13:19:58 +0530(周二,21   2010年9月)| 1行更改路径:A   / trunk / re / XXX(来自   /支链/释放/ post_XXX /重/ XXX:43476)

通过此,您可以确定此分支是当前的祖先 科。如果你结合维克多尼科莱特提到的逻辑你 将能够实时获得结果。

答案 1 :(得分:2)

查看树根的日志。分支操作将表示为复制操作,因此您可以重建从哪里复制的完整祖先树。让代码在一夜之间运行,第二天早上你将拥有完整的复制树,然后你可以使用它来识别你的分支的共同祖先。

下次,您可以从上次处理的修订版本恢复工作。

答案 2 :(得分:1)

对于OP来说有点晚了,但是我需要同样的东西并且找不到答案。以下Powershell脚本适合我。

基本上,我们为每个要比较的路径获取修订号列表(最多可选修订限制以避免获取整个历史记录),然后逐步查找列表以查找匹配的修订号。列表自然按降序修订号顺序排序。

param ([string]$path1, [string]$path2, [int]$rev = 0)

if ($path1 -eq "" -or $path2 -eq "") { "Specify two svn paths to compare."; break }

$revs1 = new-object System.Collections.Generic.List``1[System.Int32]
svn log -r HEAD:$rev $path1 | %{ if ($_ -match "^r(\d+)") { $revs1.Add($matches[1]) } }

$revs2 = new-object System.Collections.Generic.List``1[System.Int32]
svn log -r HEAD:$rev $path2 | %{ if ($_ -match "^r(\d+)") { $revs2.Add($matches[1]) } }

$i1 = 0
$i2 = 0

while ($true) {
  if ($revs1[$i1] -eq $revs2[$i2]) { $revs1[$i1]; break }
  elseif ($revs1[$i1] -gt $revs2[$i2]) { do { $i1 += 1} until ($i1 -eq $revs1.Count -or $revs1[$i1] -le $revs2[$i2]) }
  else { do { $i2 += 1} until ($i2 -eq $revs2.Count -or $revs2[$i2] -le $revs1[$i1]) }
  if ($i1 -eq $revs1.Count -or $i2 -eq $revs2.Count) { "No common base revision found - try increasing limit."; break }
}

答案 3 :(得分:1)

在寻找 git merge-base 的svn中的等价物时,我点击了这篇文章。还有什么简单的方法吗?

然后这是一个可能的解决方案: 使用git-svn克隆repo,运行 git-merge-base 提供两个分支。瞧!