2011-06-14 161 views
2

我们最近有一个问题,在切换SVN工作副本的过程中,TortoiseSVN或AnkhSVN(我无法确定哪个)崩溃。我们的开发人员并没有意识到切换是不完整的,并且一切都很好,直到将分支合并回主干,在那里我们了解到一些变更已经提交给主干,并且一些变更已经提交到分支。如何判断SVN工作副本中的所有目录是否位于同一个存储库根目录?

幸运的是,这实际上并没有影响任何东西,但我担心这种情况可能会在将来再次发生,我需要一种快速的方法来测试工作副本中哪些子目录指向的存储库。现在,在Linux中,我可以很快地破解一个shell脚本来确定这一点,但是我目前不知道如何在Windows中找到它。

如果我必须(并且放心,我会分享它,如果我这样做),我并不完全反对使用SharpSVN一起黑客攻击,但我想知道是否可以节省一些时间,在TortoiseSVN或AnkhSVN功能为我做。

回答

3

如果你可以使用PowerShell使用类似如下:

gci -Recurse | ?{ $_.psIsContainer -eq $true} | %{svn info $_.fullname} | select-string -Pattern "PATH:|URL:" 

对于每一个文件夹在你的工作拷贝,它会显示路径,并从回购的URL。如果某个文件夹切换到分支,您可以看到该URL和路径。

您可以轻松地调整它来打印只属于您的当前分支(或主干)

忽略未版本控制的文件夹以外的路径和URL很简单:

(svn status $_.fullname) -notmatch "\?") 

所以整个事情将是:

gci | ?{ $_.psIsContainer -eq $true -and ((svn status $_.fullname) -notmatch "\?")} | %{svn info $_.fullname} | select-string -Pattern "PATH:|URL:" 

您需要有一个命令行svn客户端,如SlikSVN或CollabnetSVN和路径。

+0

几乎在那里,当我想出如何将目录与当前根进行比较并忽略未版本化的目录时,我将编辑您的文章。 – 2011-06-14 16:39:53

+0

@Raskolnikov - 我已经更新过滤出未版本控制的文件夹 – manojlds 2011-06-14 17:09:48

+0

谢谢,我与win32svn一起工作 - http://sourceforge.net/projects/win32svn/ – 2011-06-16 08:32:03

1

如果您可以在Linux中创建脚本,您可能需要将cygwin放在客户端上,以便您可以访问bash脚本。或者,也许perl,因为他们有自己的Windows安装。 UnxUtils也相当不错http://unxutils.sourceforge.net/

1

@manojlds答案是相当合理的,但我的测试很快显示出一些问题。首先,虽然它正确地过滤掉了非SVN文件夹,但是它不是,而是处理孙子。 svn status命令在这样的项目上有一个“不是工作副本”消息。请记住,Get-ChildItem不会因为文件夹不是Subversion文件夹而停止从文件夹下潜;它注意到这个事实,但继续挖掘,所以你也必须处理后代。

接着,在忽略项svn info命令梁木(即上的文件夹的属性svn:ignore)该投诉“不是一个版本资源”

最后,它可以过滤掉太多:它是依靠svn status输出一个问号开头的行(表示未版本控制)当且仅当指定的文件夹实际上是在未版本控制。然而,由于svn status一个文件夹包括其后代的所有,如果任何后代项的版本控制目录未受版本控制(文件或文件夹),svn status包括无版本状态指示灯,问号,引起版本的文件夹,然后被条件错误地忽略。图中的顶部窗格显示,如果没有未受版本控制的后代,则根的两个孩子都会报告正常状态。在将资源文件夹添加为未版本控制的后代(底部窗格)后,svn status中的报告现在包含未版本控制的子代。

svn status includes all descendants

一个更好的解决方案可实现GET-EnhancedChildItem,可从我的开源CleanCode库(cmdlet的从我的API bookshelf,开辟文档PowerShell的音量,或者去下载链接获取代码)。这种增强GET-ChildItem已经知道如何分离版本的文件,以及如何只注重文件夹,所以你必须编写的代码要简单得多(再加上它不会从上述缺点):

Get-EnhancedChildItem -Svn -Recurse -ContainersOnly | 
    % {svn info $_.fullname} | 
    select-string -Pattern "^(PATH|URL):" 

–ContainersOnly选项使该过滤器隔离文件夹,就像前面的代码所做的:

filter FilterContainersOnly() 
{ 
    if ($_.PSIsContainer) { $_ } 
} 

–Svn选项启用此过滤器可以解决前面的代码的不足之处:

filter FilterSvn() 
{ 
    # Check just the current item (depth => empty); 
    # force it to report even if up-to-date (verbose => true); and 
    # wrap stderr into stdout (2>&1) for the next step. 
    $svnStatus = (svn status --verbose --depth empty $_.fullname 2>&1) 

    # Item is non-Svn with status of "?" (unversioned) or "I" (ignored). 
    # Descendants, which are still traversed, cause "svn status" to fail, 
    # and those of course are also non-Svn. 
    $svnFilter = ($svnStatus -notmatch "^[?I]|is not a working copy") 

    if ($svnFilter) { $_ } 
} 
+0

非常感谢您的回应,尽管主题的年龄。我实际上并没有使用SVN(因为我已经被Mercurial的这种甜蜜的警笛称为不可能发生这种问题的诱惑),但是你的回应似乎很有帮助。希望这对希望解决这个问题的其他人有帮助。 – 2011-11-24 00:24:52

相关问题