开发者

Compare Mercurial Repos

I have a bunch of Mercurial repositories on my Windows workstation. We're a small shop, and on some days (usually bad ones) I may make changes / bug fixes in half a dozen or more of my projects. Some of these projects are in maintenance mode, they're only touched once a month or so. Of course, I sometimes get interrupted before I get to push to our central Hg server.

Is there an easy way to regularly compare a bunch of my repos with the central server? It should warn me if I have changes that haven't been pushed. Ideally, something that sits in the system tray and alerts along the lines of "Local change older than 48 hours not in remote repo."

I suppose I should just set up a script to go through my repos and compare them. I could get in the habit of running the script daily.

开发者_如何学C

Thoughts?


I use helper functions in my Powershell profile. They're easy enough in other scripting languages, though I wouldn't dare to do it in .bat or .cmd files.

I keep a file D:\repos.config with a list of the absolute paths of all the local repositories I want to quickly glance at for 3 things: status summary, incoming changes, outgoing changes. Examples that follow assume a file with these contents:

D:\repository1
D:\repository2
#D:\ignoredrepo
D:\repository3
D:\repository4

For checking the status, the script does $results = hg -R $path st to get the status list and then I count first-characters only, printing 1 line for the repo path and 1 line for status summary for each repository path (if there's anything to show):

----- D:\repository1
  M 1 - A 1
----- D:\repository4
  ? 3

For incoming/outgoing, I keep my [paths] in each repository's hgrc concistent so that the default is always the repository on our server, bb is the one on bitbucket, etc. I loop through the same list of paths, executing $results = hg -R $path $type $alias --template '{rev} {node|short} {desc|firstline}\n' for each.$typeis eitherinoroutdepending on which I've called and$aliasis the path alias that should be in each repo'shgrc(empty string fordefault,bb,backup, etc.). I do a little processing of$results, since the first 2 lines are not actual changesets. You'd probably want{date|age}or{date|shortdate}` in your template if you wanted to filter out anything less than 24 hours old.

This way I can write simply hgouts bb at the prompt and see concise output. Some repositories don't have a particular alias at all, so 2>$null helps prevent some abort: repository bb not found! messages.

----- D:\repository2
  150 f7364a6f78d2  integrate FooBar
  151 7a3d3d9fb0d0  fixes #1214; thingamajig wasn't getting closed
----- D:\repository4
  4 dd88f00d93ff  more changes to the doojiflopper

As for synchronizing multiple repositories, I'm satisfied enough with TortoiseHg 2.0 and its Repository Registry to help me do them 1 at a time after I use the script to tell me which ones I need to do. But it also wouldn't be terribly complicated to loop through the paths and hg -R $path pull -u or hg -R $path push en masse, or use bits of the script to selectively pull/push only what's needed that doesn't have changes in the working directory. It's just not something I've needed yet.

Edit: I took a bit of time to clean up the code just a little. The functions hghg is the status summary, and the functions hgins[alias] and hgouts[alias] are what I actually call from the prompt.

function hghg(){
    $repos = [io.file]::readalllines('D:\repos.config')
    $repos | % {
        if (!$_.startswith('#') -and (test-path $_)){
            hg-st $_
        }
    }
}

function hg-st($path){
    $x = hg -R $path st
    if ($x.length -gt 0){
        write-host "----- $_"
        $d = @{}
        $x | % {
            $c = $_[0]
            if (!$d.containskey($c)){
                $d[$c] = 0
            }
            $d[$c] += 1
        }

        $p = @()
        $d.keys | % {
            $cnt = $d[$_]
            $p += "$_ $cnt"
        }
        write-host ' ' ([string]::join(' - ', $p))
    }
}

function hgins($pathalias){
    hg-inouts 'in' $pathalias
}

function hgouts($pathalias){
    hg-inouts 'out' $pathalias
}

function hg-inouts($type, $pathalias){
    $repos = [io.file]::readalllines('D:\repos.config')
    $repos | % {
        if (!$_.startswith('#') -and (test-path $_)){
            hg-inout $type $_ $pathalias
        }
    }
}

function hg-inout($type, $source, $target){
    $x = hg -R $source $type $target --template '{rev} {node|short}  {desc|firstline}\n' 2>$null
    if ($x.count -gt 2 -and $x[2] -ne 'no changes found'){
        write-host "----- $source"
        $y = $x[2..($x.length - 1)]
        $y | % {write-host ' ' $_}
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜