Commit All Changes in a Solution Using NuGet PowerShell
When Visual Studio 2012 dropped support for macros, I lost a few of my favorite tools — for a while. John Robbins of Wintellect realized you could use PowerShell as a macro language and run your functions from the Package Manager (NuGet) Console. I ported over some macros at once, and have been happily using them ever since. (I still don’t know how to bind a hotkey to a “macro”… but I bound a key to the Package Manager Console, and created short aliases for my functions, so running them is not hard.)
One of my most-used functions is Tortoise-CommitSolution, to open the TortoiseSVN or TortoiseGit Commit dialog, and pass it all the paths in the solution. (This helps me to avoid the curse of the missed commit.) Below is the script I use for it.
First, check if you have the NuGet Package Manager installed. Open Visual Studio (2012 or 2013) and go to Tools, Library Package Manager, Package Manager Console. If this works, you’re all set.
But if there is no “Library Package Manager” submenu under the Tools menu, then you need to install it. Go to Tools, Extensions and Updates; click “Online”, and in the search box, type “nuget package manager”. The first hit should be “NuGet Package Manager”; go ahead and click Download and install it, and restart Visual Studio as prompted.
Now, to use Tortoise-CommitSolution, download the script and save it somewhere such as My Documents\WindowsPowerShell. Next, you’ll want to edit your profile to dot-source that script and to make a short alias for the function. To do this, type notepad $profile in the Package Manager Console. Add these two lines (adjusting the path in the first one to point at the place where you saved the script):
# Tortoise-CommitSolution by Adam Coyne <adam@coyne.nu># Add a convenient alias (like "Set-Alias commit Tortoise-CommitSolution") for this to your ${Env:HOME}\Documents\WindowsPowerShell\NuGet_profile.ps1functionTortoise-CommitSolution{[string[]]$projectpaths=Get-Project-All|foreach{[System.IO.Path]::GetDirectoryName($_.FullName)}$projectpaths+=$dte.Solution.FullNameif($projectpaths.length-gt0){$filename=Write-PathFile(Filter-PathArray($projectpaths))# Visual Studio is 32-bit, but I have 64-bit TortoiseSvn and TortoiseGit installed$programfiles=$Env:ProgramW6432if(!$programfiles){$programfiles=$Env:ProgramFiles}if(Get-LocalOrParentPath.svn$projectpaths[0]){&"$programfiles\TortoiseSVN\bin\tortoiseproc.exe"/command:commit/deletepathfile/pathfile:`"$filename`"/hwnd:$($dte.MainWindow.HWnd)}elseif(Get-LocalOrParentPath.git$projectpaths[0]){&"$programfiles\TortoiseGit\bin\tortoisegitproc.exe"/command:commit/deletepathfile/pathfile:`"$filename`"/hwnd:$($dte.MainWindow.HWnd)}}}# Filter out paths that are contained within another path, so modified files won't show up twice in the Commit dialog.functionFilter-PathArray([string[]]$paths){[string[]]$filteredprojectpaths=@()[string]$lastCommonParentPath="*"# an initial value that won't matchforeach($pin$paths|Sort-Object){if(-not$p.StartsWith($lastCommonParentPath)){$filteredprojectpaths+=$p$lastCommonParentPath=$p+"\"}}return$filteredprojectpaths}# Tortoise's pathfile contains paths delimited by line feeds and with a trailing line feed, and is formatted as Unicode with no BOM.functionWrite-PathFile([string[]]$files){$filename=[System.IO.Path]::GetTempFileName()$contents=[string]::join("`n",$files)+"`n"$bytes=[System.Text.Encoding]::Unicode.GetBytes($contents)Set-Content-Encodingbyte$filename$bytesreturn$filename}# From https://github.com/dahlbyk/posh-gitfunctionGet-LocalOrParentPath($path,$startPath='.'){$checkIn=Get-Item$startPathwhile($checkIn-ne$NULL){$pathToTest=[System.IO.Path]::Combine($checkIn.fullname,$path)if(Test-Path$pathToTest){return$pathToTest}else{$checkIn=$checkIn.parent}}return$null}