Skip to content

Instantly share code, notes, and snippets.

@ohmonster
Last active February 13, 2020 18:07
Show Gist options
  • Select an option

  • Save ohmonster/eeb5326792022264f868118e4b098a29 to your computer and use it in GitHub Desktop.

Select an option

Save ohmonster/eeb5326792022264f868118e4b098a29 to your computer and use it in GitHub Desktop.
TFS command line merging, simplified
Import-Module $pathToMergeManifest.psd1
#Define your branches here
Add-Type -TypeDefinition @"
public enum BranchName
{
Dev,
Test,
Prod
}
"@
#Define your standard projects here
Add-Type -TypeDefinition @"
public enum ProjectName
{
WebSite,
Databases,
APIs
}
"@
Add-Type -TypeDefinition @"
public enum Format
{
Brief,
Detailed
}
"@
#The url to the collection on your TFS server
$collection=
$comment=''
$tfsContent = tf workspaces /collection:$collection /format:detailed | Select-String -Pattern "$/:" -SimpleMatch | %{$_ -Replace "\$/: ",""}
<#
.SYNOPSIS
The command will
1) Merge code for a specified changeset or changeset range for a specific project
It also copies the comment associated with the first changeset in your merge to the clipboard.
If you do not see your files in the Pending Changes portion of the TFS GUI, close any solutions you have open and check again.
.DESCRIPTION
Streamlined command-line merges for Perfect-Vision tfs changesets
This commandlet makes
Merge-Code Dev Test 23426
Functionally equivalent to
tf vc merge /recursive $/PTNWebAll/Dev $/PTNWebAll/Test /version:C23426~C23426
#be nice and list your enums for anyone that may use the get-help commmand
.PARAMETER Source
Source branch, may be one of: Dev,Test,Prod
.PARAMETER Target
Target branch, may be one of: Dev,Test,Prod
.Parameter First
The changeset number of the first changeset in the range
.PARAMETER Last
The changeset number of the last changeset in the range. If ommitted, it will merge only the first changeset
#be nice and remind people of the enums and what you've set for the default
.PARAMETER ProjectName
One of blah, blah, or blah. Default is Blah.
.PARAMETER Force
Ignores the merge history and merges the specified changes from the source into the destination, even if some or all these changes have been merged before.
If combined with the Discard flag, will resolve any merge conflicts to retain the code in the target branch.
.PARAMETER Discard
If present, tfs does not perform the merge operation, but updates the merge history to track that the merge occurred. This discards a changeset from being used for a particular merge.
.PARAMETER LocalPath
The local path to where you keep tfs files on your system. It attempts to find a workspace path mapped to your system. If not you'll have to specify.
.PARAMETER tfExePath
The full path to tf.exe on your system.
.LINK
https://docs.microsoft.com/en-us/azure/devops/repos/tfvc/use-team-foundation-version-control-commands?view=azure-devops
.LINK
https://github.com/ohmonster/MonstrousPowerShell/tree/master/TFS
#>
function Merge-Code{
[CmdletBinding(PositionalBinding=$true)]
Param(
[Parameter(Position=0,Mandatory=$true)]
[BranchName]$Source,
[Parameter(Position=1,Mandatory=$true)]
[BranchName]$Target,
[Parameter(Position=2,Mandatory=$true)]
[int]$First,
[Parameter(Position=3,Mandatory=$false)]
[int]$Last=$First,
[Parameter(Mandatory=$false)]
#define a default project to make merges faster for the things you use most
[ProjectName]$Project="WebSite",
[Parameter(Mandatory=$false)]
[Switch]$Force,
[Parameter(Mandatory=$false)]
[Switch]$Discard,
[Parameter(Mandatory=$false)]
[String]$LocalPath= "$tfsContent",
[Parameter(Mandatory=$false)]
#tfsExe path -- my box has VS 2017 Professional. Yours may be elsewhere
[String]$tfExePath = "c:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/tf"
)
#"$Source $Target $First $Last $Discard"
$private:sourcePath = "$LocalPath/$Project/$Source"
$private:targetPath = "$LocalPath/$Project/$Target"
$private:changesets = "C"+$First + "~C" + $Last
if ($Force -And $Discard )
{
& $tfExePath vc merge /recursive $Local:sourcePath $Local:targetPath /version:$changesets /force /conservative /noPrompt
& $tfExePath vc resolve $Local:targetPath /recursive /auto:KeepYours /noPrompt
}
elseif ($Force)
{
& $tfExePath vc merge /recursive $Local:sourcePath $Local:targetPath /version:$changesets /force
}
elseif ($Discard)
{
& $tfExePath vc merge /recursive $Local:sourcePath $Local:targetPath /version:$changesets /discard
}
else {
#Write-Host "$tfExePath vc merge /recursive $Local:sourcePath $Local:targetPath /version:$changesets"
& $tfExePath vc merge /recursive $Local:sourcePath $Local:targetPath /version:$changesets
}
$private:info = & $tfExePath changeset $First /collection:$collection /noPrompt | Select-String -Pattern "Comment:" -Context 1
$comment=$info.Context.PostContext
Set-Clipboard $comment
}
<#
.SYNOPSIS
View Pending Changes
.PARAMETER Format
Brief or Detailed
.PARAMETER tfExePath
The full path to tf.exe on your system. If tf.exe isn't found at the default path
.LINK
https://docs.microsoft.com/en-us/azure/devops/repos/tfvc/use-team-foundation-version-control-commands?view=azure-devops
.LINK
https://github.com/ohmonster/MonstrousPowerShell/tree/master/TFS
#>
function Merge-Status{
Param(
[Parameter(Mandatory=$false)]
[Format]$Format = 'Detailed',
[Parameter(Mandatory=$false)]
[String]$tfExePath = "c:/Program Files (x86)/Microsoft Visual Studio/2017/Professional/Common7/IDE/CommonExtensions/Microsoft/TeamFoundation/Team Explorer/tf"
)
& $tfExePath vc status /collection:$collection /format:$Format
}
Export-ModuleMember -Function Merge-Code, Merge-Status
@{
RootModule='mergeFunction.psm1'
ModuleVersion = '0.8'
GUID = '068efa03-fca4-4d59-9c6d-61e05a733701'
Author = 'Nita Daniel'
Copyright = '2020 Nita Daniel'
Description = 'Shorthand functions for performing tf merges at work'
PowerShellVersion='5.0'
FunctionsToExport=@(
'Merge-Code','Merge-Status'
)
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @()
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
# ProjectUri ='https://github.com/ohmonster/MonstrousPowerShell/tree/master/TFS'
# ReleaseNotes of this module
# ReleaseNotes = ''
} # End of PSData hashtable
} # End of PrivateData hashtable
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment