PowerShell,AnkhSVN和Subversion

I've been up to my ears in PowerShell (podcast) this last week at work. It continues to rock my world. I've been doing some automation work using Subversion not as source control but as a quasi-journaled file system.

上周我一直在上PowerShell (播客)。 它继续震撼我的世界。 我一直在使用Subversion做一些自动化工作,而不是将Subversion用作源日志文件系统

There's a number of ways one could use Subversion from PowerShell, but I kind of want it as integrated as possible. I'm still trying out a few things. Here's what I've got so far...

可以使用多种方法从PowerShell中使用Subversion,但我有点希望它尽可能地集成。 我仍在尝试一些事情。 到目前为止,这就是我所得到的...

Via SVN.exe

通过SVN.exe

One could just use svn.exe, the command-line client. There's some obscure switches to remember, but Arild, the guy that wrote AnkhSVN (Subversion support within Visual Studio) has written a PowerShell tabcompletion script that gives one completion for svn.exe commands.

可以只使用命令行客户端svn.exe。 有一些难以理解的开关要记住,但是写AnkhSVN (Visual Studio中的Subversion支持)的人Arild已经编写了一个PowerShell tabcompletion脚本,该脚本为svn.exe命令提供了一个完成功能

So you might type svn c[TAB] and get svn cat then [TAB] and get svn checkout, etc. Clever and cool but it just extends the command line tool with help.

因此,您可以输入svn c [TAB]并获取svn cat,然后输入[TAB]并获取svn checkout,等等。聪明又酷,但是它只是在帮助下扩展了命令行工具。

Via TortoiseProc (the command line that comes with TortoiseSVN)

通过TortoiseProc( TortoiseSVN随附的命令行)

One could use the TortoiseProc without it being in the PATH with a script like this (stolen from Brad Wilson). This isn't that interesting of a script as the file could just be in the PATH, but it is an example of a decent pattern for calling tools that have discoverable paths (via the registry, etc) but aren't in the PATH proper.

可以将TortoiseProc放在这样的脚本中,而不必将它放在PATH中(从Brad Wilson窃取)。 这不是一个有趣的脚本,因为文件可能仅位于PATH中,但这是一个不错的模式的示例,该模式用于调用具有可发现路径(通过注册表等)但不在PATH中正确的工具。

if ($args.Length -lt 1) {
    write-host "usage: tsvn <command>"
    return
}

如果($ args.Length -lt 1){ 写主机“用法:tsvn <命令>” 返回}

if ((test-path "HKLM:\Software\TortoiseSVN") -eq $false) {
 write-host -foregroundColor Red "Error: Could not find TortoiseProc.exe"
 return
}

如果((测试路径“ HKLM:\ Software \ TortoiseSVN”)-eq $ false){ write-host -foregroundColor红色“错误:找不到TortoiseProc.exe” 返回}

$tortoiseKey = get-itemproperty "HKLM:\Software\TortoiseSVN"

$ tortoiseKey = get-itemproperty“ HKLM:\ Software \ TortoiseSVN”

if ($tortoiseKey -eq $null) {
 write-host -foregroundColor Red "Error: Could not find TortoiseProc.exe"
 return
}

如果($ tortoiseKey -eq $ null){ write-host -foregroundColor红色“错误:找不到TortoiseProc.exe” 返回}

$tortoise = $tortoiseKey.ProcPath

$ tortoise = $ tortoiseKey.ProcPath

if ($tortoise -eq $null) {
 write-host -foregroundColor Red "Error: Could not find TortoiseProc.exe"
 return
}

如果($ tortoise -eq $ null){ write-host -foregroundColor红色“错误:找不到TortoiseProc.exe” 返回}

$commandLine = '/command:' + $args[0] + ' /notempfile /path:"' + ((get-location).Path) + '"'
& $tortoise $commandLine

$ commandLine ='/ command:'+ $ args [0] +'/ notempfile / path:“'+(((get-location).Path)+'”' &$ totoise $ commandLine

Use NSvn.Core directly, in-process, from PowerShell

在PowerShell中直接在进程中使用NSvn.Core

The most attractive option to me was to find a way to talk to Subversion directly using something in-process. These last two options would require "shelling out" to non-PowerShell things. I was hoping to update Subversion from within ASP.NET for some Admin stuff, and while I could use System.EnterpriseServices to manage identity, I didn't want to have new processes firing up for a number of obvious reasons.

对我来说,最有吸引力的选择是找到一种使用过程中的东西直接与Subversion对话的方法。 最后两个选项将需要对非PowerShell进行“脱壳”。 我希望从ASP.NET中更新一些管理方面的Subversion,虽然我可以使用System.EnterpriseServices来管理身份,但由于许多明显的原因,我不想启动新进程。

Deep in AnkhSVN is a great little .NET library called NSvn that did just want I needed. It doesn't appear to be distributed outside of Ankh, but I just took it from the latest install.  It's got no docs but Reflector to the rescue got me this PowerShell script that I called get-fromsvn.ps1.

AnkhSVN的深处是一个名为NSvn的小型.NET库,它确实只是想要我需要的。 它似乎没有分发到Ankh之外,但我只是从最新安装中获取了它。 它没有任何文档,但是Reflector进行了抢救,使我得到了这个名为get-fromsvn.ps1的PowerShell脚本。

param ([string]$svnurl       = $(read-host "Please specify the path to SVN"),
       [string]$svnlocalpath = $(read-host "Please specify the local path")
      )

参数([string] $ svnurl = $(读取主机“请指定SVN的路径”), [string] $ svnlocalpath = $(读取主机“请指定本地路径”) )

if ([System.IO.Path]::IsPathRooted($svnlocalpath) -eq $false){  throw "Please specific a local absolute path"}[System.Reflection.Assembly]::LoadFrom((join-Path $GLOBAL:someGlobalPath -childPath NSvn.Common.dll))[System.Reflection.Assembly]::LoadFrom((join-Path $GLOBAL:someGlobalPath -childPath NSvn.Core.dll))

if([[System.IO.Path] :: IsPathRooted($ svnlocalpath)-eq $ false){抛出“请指定本地绝对路径”}} [System.Reflection.Assembly] :: LoadFrom(((-Path $ GLOBAL: someGlobalPath -childPath NSvn.Common.dll))[System.Reflection.Assembly] :: LoadFrom((join-Path $ GLOBAL:someGlobalPath -childPath NSvn.Core.dll))

$PRIVATE:svnclient = new-object NSvn.Core.Client
$PRIVATE:svnclient.AuthBaton.Add( [NSvn.Core.AuthenticationProvider]::GetWindowsSimpleProvider() )
if ((test-Path $svnlocalpath) -eq $true )
{
  write-progress -status "Updating from $svnurl" -activity "Updating Working Copy"
  $PRIVATE:svnclient.Update($svnlocalpath, [NSvn.Core.Revision]::Head, $true)
}
else
{
  write-progress -status "Checkout from $svnurl" -activity "Updating Working Copy"
  $PRIVATE:svnclient.Checkout($svnurl, $svnlocalpath, [NSvn.Core.Revision]::Head, $true)
}

$ PRIVATE:svnclient =新对象NSvn.Core.Client $ PRIVATE:svnclient.AuthBaton.Add([NSvn.Core.AuthenticationProvider] :: GetWindowsSimpleProvider()) 如果((test-Path $ svnlocalpath)-eq $ true) { write-progress-状态“从$ svnurl更新”-活动“更新工作副本” $ PRIVATE:svnclient.Update($ svnlocalpath,[NSvn.Core.Revision] :: Head,$ true) } 其他{ write-progress-状态“从$ svnurl检出”-活动“更新工作副本” $ PRIVATE:svnclient.Checkout($ svnurl,$ svnlocalpath,[NSvn.Core.Revision] :: Head,$ true) }

This script lets me checkout/update from Subversion happily. There's still some voodoo I need to work out like getting progress updates...

该脚本使我可以愉快地从Subversion检出/更新。 我仍然需要解决一些伏都教,例如获取进度更新...

(How do you do a delegate from within PowerShell if a .NET Assembly needs a delegate with a certain signature? This library will call me back with status updates I'd like to broker to write-progress)

(如果.NET程序集需要具有特定签名的委托,您如何在PowerShell中执行委托?该库将通过状态更新回叫我,我希望将其更新为代理进行写入)

...but it gets 90% of what I need from an in-process call to Subversion from PowerShell. I know Arild Fines is not only the author of this library but a fan of PowerShell as well. Perhaps he'll help me either update this script, or better yet, write a PSSnapin to use Subversion as first-class cmdlets with progress and detailed logging. It'd be as useful, if not more so, than the SVN PSDriveProvider he's been messing with.

...但是从PowerShell向Subversion的进程内调用中获得了90%的需求。 我知道Arild Fines不仅是该库的作者,而且还是PowerShell的粉丝。 也许他会帮助我更新此脚本,或者更好的是,编写PSSnapin以将Subversion用作具有进度和详细日志记录的一流cmdlet。 如果不是更多的话,它会比他一直在使用的SVN PSDriveProvider有用。

UPDATE: Arild Fines posted a solution to my question. I agree that the syntax for delegates is poo and I hope the PowerShell team takes that feedback. ;) The syntax for events, however, is quite elegant.

更新:Arild Fines发布了我的问题的解决方案。 我同意代表的语法是公安的,我希望PowerShell团队能得到反馈。 ;)事件的语法非常优雅。

The addition of two lines gives me the write-progress and event notification support I wanted:

两行的添加为我提供了我想要的写进度和事件通知支持:

param ([string]$svnurl       = $(read-host "Please specify the path to SVN"),
       [string]$svnlocalpath = $(read-host "Please specify the local path")
      )

参数([string] $ svnurl = $(读取主机“请指定SVN的路径”), [string] $ svnlocalpath = $(读取主机“请指定本地路径”) )

if ([System.IO.Path]::IsPathRooted($svnlocalpath) -eq $false)
{
  throw "Please specific a local absolute path"
}

如果([System.IO.Path] :: IsPathRooted($ svnlocalpath)-eq $ false) { 抛出“请指定本地绝对路径” }

[System.Reflection.Assembly]::LoadFrom((join-Path $GLOBAL:someGlobalPath -childPath NSvn.Common.dll))
[System.Reflection.Assembly]::LoadFrom((join-Path $GLOBAL:someGlobalPath -childPath NSvn.Core.dll))

[System.Reflection.Assembly] :: LoadFrom((join-Path $ GLOBAL:someGlobalPath -childPath NSvn.Common.dll)) [System.Reflection.Assembly] :: LoadFrom((join-Path $ GLOBAL:someGlobalPath -childPath NSvn.Core.dll))

$PRIVATE:svnclient = new-object NSvn.Core.Client

$ PRIVATE:svnclient =新对象NSvn.Core.Client

$PRIVATE:notificationcallback = [NSvn.Core.NotificationDelegate]{
        Write-Progress -status ("{0}: {1}" -f ($_.Action, $_.Path)) -activity "Updating Working Copy"
    }
$PRIVATE:svnclient.add_Notification($notificationcallback)   

$ PRIVATE:notificationcallback = [NSvn.Core.NotificationDelegate] { 写入进度-状态(“ {0}:{1}” -f($ _。Action,$ _。Path))-活动“更新工作副本” } $ PRIVATE:svnclient.add_Notification($ notificationcallback)

$PRIVATE:svnclient.AuthBaton.Add( [NSvn.Core.AuthenticationProvider]::GetWindowsSimpleProvider() )
if ((test-Path $svnlocalpath) -eq $true )
{
  write-progress -status "Updating from $svnurl" -activity "Updating Working Copy"
  $PRIVATE:svnclient.Update($svnlocalpath, [NSvn.Core.Revision]::Head, $true)
}
else
{
  write-progress -status "Checkout from $svnurl" -activity "Updating Working Copy"
  $PRIVATE:svnclient.Checkout($svnurl, $svnlocalpath, [NSvn.Core.Revision]::Head, $true)
}

$ PRIVATE:svnclient.AuthBaton.Add([NSvn.Core.AuthenticationProvider] :: GetWindowsSimpleProvider()) 如果((test-Path $ svnlocalpath)-eq $ true) { write-progress-状态“从$ svnurl更新”-活动“更新工作副本” $ PRIVATE:svnclient.Update($ svnlocalpath,[NSvn.Core.Revision] :: Head,$ true) } 其他{ write-progress-状态“从$ svnurl检出”-活动“更新工作副本” $ PRIVATE:svnclient.Checkout($ svnurl,$ svnlocalpath,[NSvn.Core.Revision] :: Head,$ true) }

I hope more people in the community start digging into PowerShell and seeing how truly powerful it is to have .NET at the command line.

我希望社区中的更多人开始研究PowerShell,并了解在命令行中拥有.NET的真正强大之处。

翻译自: https://www.hanselman.com/blog/powershell-ankhsvn-and-subversion

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值