I believe that ideal setup for Mercurial is one project per repository. Most of time this is really good setup but occasionally it will cause problems. Whenever I need to do same thing on multiple repositories (e.g. push) there is an issue. Better said, there was an issue before I created HgAll script.
Script is written in PowerShell and does two things. First it traverses all directories bellow current (or defined) one and finds all mercurial repositories. Then it forwards whatever is on command line as parameter to hg command line utility. In effect it executes same command to each repository it finds.
HgAll [StartingFolder] [commands]
HgAll C:\Source summary
HgAll push all
First example will start search from C:\Source and execute “hg summary” command for any Mercurial folder found. Second example will start in current directory and execute “hg push all”.
You can download script here (or take a peek at source bellow):
$StartupLocation = (Get-Location -PSProvider FileSystem).ProviderPath
$Folder = $Null;
$Command = ""
foreach ($arg in $args) {
if ($Folder -eq $Null) {
if ((Test-Path -Path $arg -PathType Container) -eq $True) {
$Folder = (Resolve-Path -Path $arg).Path
$Command = ""
} else {
$Folder = $StartupLocation
$Command = $arg
}
} else {
if ($Command.length -ne 0) { $Command += " " }
$Command += $arg
}
}
if ($Command.length -eq 0) {
$Command = "summary"
}
function Traverse([string]$path) {
Write-Debug $path
$dirs = Get-ChildItem $path | Where {$_.psIsContainer -eq $true}
if ($dirs -ne $Null) {
foreach ($dir in $dirs) {
$hgsubdir = Join-Path -Path $dir.FullName -ChildPath .hg
if ((Test-Path -Path $hgsubdir -PathType Container) -eq $True) {
$hgdir = $dir.FullName
if ($Command.length -ne 0) {
Set-Location $hgdir
Write-Host
$result = Invoke-Expression "hg $Command 2>&1"
if (($LASTEXITCODE -ne 0) -or (!$?)) {
Write-Host $dir.Name
foreach ($line in $result) {
Write-Warning $line
}
} else {
Write-Output $dir.Name
foreach ($line in $result) {
Write-Host $line
}
}
}
} else {
Traverse($dir.FullName)
}
}
}
}
try {
Traverse($Folder)
} finally {
Set-Location $StartupLocation
}