My shop uses TFS & is generally happy with it with the exception of the lack of local repository commits/reverts. I\'m starting to use Mercurial locally myself to help manag
Here's a powershell script I've been using to work with TFS & hg. To use you'll need to create a hg repository in your TFS folder (commit the files from TFS into it), clone this repository and work on the new repository. Once happy you can run "hgtfs.ps1 push" to push the changes back into TFS from your mercurial repository.
hgtfs.ps1:
param([parameter(Position=0, Mandatory=$true)][string] $action)
$HGDirectory = Get-Location
$TfsDirectory = @(hg paths | where-object { $_.StartsWith("default = ") })[0].SubString(10)
# Pull from TFS
function pull
{
# Todo pull changes one by one brining who did it and the comment into HG
# tf history . /recursive /format:brief /noprompt /version:300~1000 /sort:ascending
# tf properties . /recursive
# Add the changes from TFS into the TFS HG repository
Set-Location $TfsDirectory
tf get . /recursive
hg commit -A -m "Update from TFS"
# Pull / merge the changes from TFS's HG repository
Set-Location $HGDirectory
hg pull
hg merge --tool internal:fail
hg commit -m "Merged from TFS"
""
"The you have the following conflicts which need resolving"
hg resolve -l | write-host -foregroundcolor "red"
#thg commit
}
# Push to TFS
function push
{
Set-Location $HGDirectory
hg push
Set-Location $TfsDirectory
$FilesModified = @()
$FilesRenamed = @{} # Key: old file name .... Val: new file name
$FilesRemoved = @()
$FilesAdded = @()
# Work out what changes have taken place
"Calculating the changes which have been made in HG..."
tfpt scorch /exclude:.hg,*.user | out-null
$AllChanges = hg status --rev .:tip -A
for($i = 0; $i -lt $AllChanges.length ; $i++)
{
$type = $AllChanges[$i].SubString(0, 2)
$fileName = $AllChanges[$i].SubString(2)
switch($type)
{
"M " # Modified files
{
$FilesModified += $fileName
}
"A " # New Files
{
$nextType = $null
$nextFileName = $null
if($AllChanges.length -gt ($i+1))
{
$nextType = $AllChanges[$i+1].SubString(0, 2)
$nextFileName = $AllChanges[$i+1].SubString(2)
}
if($nextType -eq " ")
{
# we have a rename
$FilesRenamed[$nextFileName]=$fileName
$i++
}
else
{
# we're adding the file
$FilesAdded += $fileName
}
}
"R " # Removed
{
if($FilesRenamed.ContainsKey($fileName))
{
continue
}
$FilesRemoved += $fileName
}
"C " # Same
{
continue
}
default
{
"Unknown HG status line: "+$AllChanges[$i]
return -1
}
}
}
# perform the TFS operations
"Renaming files in TFS..."
foreach($file in $FilesRenamed.Keys) {
tf checkout $file | out-null
tf rename $file $FilesRenamed[$file] | out-null
}
"Checking out for edit in TFS..."
foreach($file in $FilesModified) { tf checkout $file | out-null }
"Removing files from TFS..."
foreach($file in $FilesRemoved) { tf delete $file | out-null }
# perform the Mercural update
"Pulling changes out of HG...."
hg update --rev .:tip --clean
# perform any POST TFS operations
"Adding new files to TFS..."
foreach($file in $FilesAdded) { tf add $file }
"Cleaning up..."
tfpt uu /noget
tf checkin
}
if ($action -eq "push") { push }
elseif ($action -eq "pull") { pull }
else { "Unknown action ... please supply 'push' or 'pull'" }
# return to our starting point
Set-Location $HGDirectory