views:

382

answers:

1

We have a number of legacy projects that were recently added to TFS version control. Now the issue that we have is that each of our projects contain copies of common code that has been modified and maintained separatly from each other.

Is there a way to compare source from one solution in TFS to source in another solution on the same TFS server? - I can specify what folders and files to compare.

Restructuring the repository or conducting a major refactoring of the solutiosn is not an option at this time due to the size and nature of the solutions.

I'm also interested in any API's that exist to potentially automate this process.

Thanks!

+2  A: 

c:\temp> tf folderdiff /?

TF - Team Foundation Version Control Tool
Copyright (c) Microsoft Corporation.  All rights reserved.

Displays a visual representation of the differences between files in two server
folders, in a server folder and a local folder, or in two local folders.

tf folderdiff [sourcePath] targetPath [/recursive] [/noprompt]
              [/server:serverName:port] [/filter:filter]
              [/filterLocalPathsOnly]
              [/view:same,different,sourceOnly,targetOnly]

C:\temp> tf folderdiff 1 2 /noprompt

===========================================================================
Items That Exist Only in C:\temp\1
===========================================================================

C:\temp\1\baz

===========================================================================
Items That Exist Only in C:\temp\2
===========================================================================

C:\temp\2\bar

===========================================================================
Show Items That Have Different Contents
===========================================================================

C:\temp\1\quux - 
    C:\temp\2\quux

===========================================================================
Summary: 1 folders, 4 files, 1 source, 1 target, 1 different, 0 with errors
===========================================================================

Edit: if it wasn't obvious, the default view is sourceOnly + targetOnly + different. I had a file named "foo" with the same contents in both folders.

I realize a command line tool is not an API per se, but unfortunately it's the best option here. Otherwise you need to crawl the tree yourself -- there is no folder diff in the version control API. All you get is a 15+ confusing methods that operate on individual items.

On the plus side, if all of the files you want to compare are going to be checked in, that means you can do the computation without any costly disk I/O. (TFS stores a hash of every file's contents). Quick Powershell example:

function Compare-TfsDir([string] $dir1, [string] $dir2, [switch] $includeEqual)
{
    $dir1 = $dir1.ToLower()
    $dir2 = $dir2.ToLower()    
    filter Decorate($dir) 
    { 
        $_ | add-member noteproperty RelativePath $_.ServerItem.ToLower().Replace($dir, "") -passthru |
             add-member noteproperty HashString ($_.HashValue | %{ "{0:X2}" -f $_ } | join-string) -passthru
    }

    $items1 = $tfs.vcs.GetItems($dir1, $tfs.VCS_RecursionType::Full).Items | Decorate $dir1
    $items2 = $tfs.vcs.GetItems($dir2, $tfs.VCS_RecursionType::Full).Items | Decorate $dir2  

    $dirComp = compare -IncludeEqual -Property RelativePath $items1 $items2    
    "---Tree Comparison---"
    $dirComp | ? { $_.SideIndicator -ne "==" } | ft -auto RelativePath, SideIndicator

    $both = $dirComp | ? { $_.SideIndicator -eq "==" } | % { $_.RelativePath } | Linq-ToSet    
    filter InBoth { if ($both.Contains($_.RelativePath)) {$_} }
    $contentComp = compare -inc:$includeEqual -Property HashString, RelativePath `
                           ($items1 | InBoth) ($items2 | InBoth)

    "---Content Comparison---"
    $contentComp | ? { $_.SideIndicator -ne "<=" } | ft -auto RelativePath, SideIndicator
}

Unfortunately, doing something like this would take 5X as many lines of code if you need to support local vs server diffs.

Richard Berg