是否有一种简单的方法可以在存在特定文件的svn存储库中找到所有路径(标签和分支)?
我知道在trunk上检查文件的版本以及删除时的文件,所以我需要在这两个版本之间找到文件上方的所有分支,标签和可能的其他路径副本。
答案 0 :(得分:2)
我最终在powershell中处理整个日志:
$repository = 'http://REPOSITORY/url'
$badPaths = @( '/paths/to/first/commit/of/files/to/track' )
function Delete-Nodes
{
param([xml]$xml, [string]$xpath)
$nodes = $xml.SelectNodes($xpath);
for ($i = $nodes.Count -1; $i -ge 0; $i--)
{
$nodes[$i].ParentNode.RemoveChild($nodes[$i]) *>$null
}
}
[Console]::OutputEncoding = New-Object -typename System.Text.UTF8Encoding
Measure-Command { [xml]$all_revs = svn log $repository -r1:HEAD -v --xml }
$all_revs.SelectNodes('//logentry').Count
$badPathXpath=[string]::Join(' or ', ($badPaths | % { "text()='$_'" }))
Delete-Nodes -xml $all_revs -xpath "//path[@action='M']"
Delete-Nodes -xml $all_revs -xpath "//path[@action='A' and not($badPathXpath) and not(@copyfrom-path)]" # For additions we only care about our bad paths or any copies (from those)
Delete-Nodes -xml $all_revs -xpath "/log/logentry/paths[not(descendant::path)]"
Delete-Nodes -xml $all_revs -xpath "/log/logentry[not(descendant::paths)]"
$monitoredPaths = @{}
foreach ($logentry in $all_revs.log.logentry)
{
foreach ($path in $logentry.paths.path)
{
$used = $true
$action = $path.action
$from_path = $path.Attributes['copyfrom-path'].Value
$from_rev = $path.Attributes['copyfrom-rev'].Value
$revision = $logentry.revision
$value = $path.InnerText
if ($action -eq 'A' -and -not $from_path)
{
if (($badPaths | % { $value.StartsWith($_) } | Where { $_ } ).Count -gt 0)
{
$monitoredPaths[$value] = New-Object PSObject -Property (@{ 'Added' = $revision; 'Deleted' = $null })
}
else
{
$used = $false
}
}
elseif ($monitoredPaths.Count -gt 0 -and $from_path -and -not $monitoredPaths.ContainsKey($value))
{
$paths = $monitoredPaths.Keys | Where-Object { $val = $monitoredPaths[$_]; ($from_path -eq $_ -or $_.StartsWith("$from_path/") -or $from_path.StartsWith("$_/")) -and ($from_rev -ge $val.Added -and (-not $val.Deleted -or $val.Deleted -gt $from_rev) ) }
if ($paths.Count -gt 0)
{
foreach ($copied_path in $paths)
{
if ($copied_path.StartsWith("$from_path/"))
{
$sub_directory = $copied_path.SubString($from_path.Length)
$newPath = "$value$sub_directory"
}
else
{
$newPath = "$value"
}
if (($monitoredPaths.Keys | Where-Object { $newPath.StartsWith("$_/") -and -not $monitoredPaths[$_].Deleted }).Count -eq 0)
{
$monitoredPaths[$newPath] = New-Object PSObject -Property (@{ 'Added' = $revision; 'Deleted' = $null })
}
else
{
$used = $false
}
}
}
else
{
$used = $false
}
}
elseif ($action -eq 'D' -and $monitoredPaths.ContainsKey($value))
{
$monitoredPaths[$value].Deleted = $revision
}
elseif ($action -eq 'D')
{
$used = $false
foreach ($path in ($monitoredPaths.Keys | Where-Object { $_.StartsWith("$value/") -and -not $monitoredPaths[$_].Deleted }))
{
$monitoredPaths[$path].Deleted = $revision
$used = $true
}
}
else
{
$used = $false
}
if (-not $used)
{
$logentry.paths.RemoveChild($path) *>$null
}
}
}