9

Using Visual Studio 2008 tools,

I am trying to get an ASCII diff of change sets 14318 and 14317.

I can do so using GUI:

tf changeset 14318

and then select a file and right-click and select compare with previous version. However, this is a bit tedious and it is GUI-based. My task at hand is to back-port many changes into a different branch. I would like to automate the testing (say using Python), making sure that I did it correctly. Well, for educational purposes I will make all changes by hand without looking at the solution, and then I will compare the two changes and try to look for any differences. Here is what I love about tf - I can type:

tf changeset 14318 > out.txt&&notepad out.txt

to view the details of what files were affected.

Similarly, I wish to get an out.txt with all the differences saved in it. I am pretty sure that I can handle the Python part. I definitely want to know how to do it using the tf.exe tool, but if you also happened to know other tricks for accomplishing this (some cool 3rd party tool, or PowerShell script, then please let me know as well).

Thank you!

Oh, by the way, I checked this: http://msdn.microsoft.com/en-us/library/6fd7dc73(VS.80).aspx

And I tried this:

tf diff 14318 14317

And I have gotten this error: File (or folder) c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\14318 does not exist.

Now thank you.

EDIT: Are there any tools at all that can do this?

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
Hamish Grubijan
  • 10,562
  • 23
  • 99
  • 147

2 Answers2

27

You're just not using the correct syntax when calling it. In this case, it tried to do a diff between your working copy, and the base repository version, of (non-existing) files 14318 and 14317.

What you need to do instead is to use a changeset range in /version, like this:

tf diff $/Foo /version:C14317~C14318 /recursive /format:unified > foo.diff

Note that you can use ~ with any other version specs - labels, dates etc. See here for details.

Pavel Minaev
  • 99,783
  • 25
  • 219
  • 289
  • Thanks! And how would I do a diff on current version (local) and the latest, or unmodified? Many thanks! – Hamish Grubijan Jan 30 '10 at 19:20
  • If you don't specify the range, but just a single version, then your local version will be compared to the one you've specified - i.e. `/version:C1000` compares local version to the one after changeset 1000. The most recent version can be specified by `/version:T`. The base version for your local one is `/version:W` (note that all those are also usable in ranges, so `/version:C1000~T` is perfectly valid). As well, you can use local file paths instead of TFS server paths. – Pavel Minaev Jan 30 '10 at 21:34
  • I think this does exactly what I want! Why don't people vote your answer up damn it? – Hamish Grubijan Jan 30 '10 at 22:56
  • 2
    Pavel, for some reason the command is running very slowly on me. The /recursive option slows it down too. There is a lot of code. How do I speed it up? In theory the change-set numbers should be everything I need if I am specifying both. I thought it would be like a dictionary lookup - e.g. fast. – Hamish Grubijan Feb 01 '10 at 15:14
  • 1
    Without `/recursive`, you'll only get the diff for the directory itself. I would expect it to run slow if you have a lot of code there, because it pretty much has to do a diff on every single file in the tree. Yes, I'd expect it to do a fast dictionary lookup on changeset number, but then multiply that by N files, and it may not be all that fast anymore... – Pavel Minaev Feb 01 '10 at 22:01
  • 2
    TFS2010 is most certainly not doing a dictionary lookup -- I have a changeset that altered 4 files (there are several thousand unchanged files in that directory) and this command takes about 30 seconds. – jnnnnn Nov 23 '12 at 01:10
  • 1
    Doesn't look like this has improved in TFS2012. Impossible to use on our ~7GB of files, tf.exe takes forever. It's been hours since I started a diff and I'm still waiting for the first line of output to show up... – SvenS May 06 '14 at 09:22
1

Here is a PowerShell (V2) script, extending from Pavel's answer, this will be more performant, because we find the files that have changed, then get tf to diff them individually:

Write-Host "Checking if TFS snap-in has been added..." -ForegroundColor green

# Find all TFS snapins.
$snapins = Get-PSSnapin -Registered | Where-Object { $_.Name -like "*TeamFoundation*" } 

foreach($snapin in $snapins)
{ 
    # Add snapin if not already added.
    $exists = Get-PSSnapin | Where-Object { $_.Name -eq $snapin.Name } 
    if (!$exists)
    {
        Write-Host "Adding Snapin " $snapin.Name -ForegroundColor green 
        Add-PSSnapin $snapin.Name 
    }
    else
    {
        Write-Host "Snapin already added." -ForegroundColor green
    }
}



# Get TFS Server object reference.
$tfs_server = Get-TfsServer -Name $/<serverName>/<RepoDir>

# Get list of changed files 
$changes_from_changeset = Get-TfsChangeset -ChangesetNumber 829 | Select -Expand Changes | % { $_.Item.ServerItem }
#$changes_from_changeset

foreach($change in $changes_from_changeset)
{
    &"C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe" diff $change /version:829~T /format:unified
}
Russell
  • 17,481
  • 23
  • 81
  • 125
  • Thanks, what are the pre-requisites if any for running this? – Hamish Grubijan Aug 30 '10 at 13:12
  • You will need to have TFS Power tools installed to use TF.exe, and have PowerShell Version 2.0 installed. The Power tools will include a PowerShell snapin, which is used at the start of the script. – Russell Aug 31 '10 at 02:01
  • 1
    Nice starting point, though if anyone tries to reproduce this on an x64 machine, make sure to change "C:\Program Files\" to "C:\Program Files (x86)\". Also, this needs to be executed in a mapped directory so Get-TfsChangeset can find the server ($tfs_server is never used). Finally, if you want to know the difference between two versions, it's not enough to diff all files contained in the first changeset. Changes outside these files may affect them. You will want to include all files that changed between the first and the second version, perhaps restricted to a particular folder. – SvenS May 06 '14 at 10:57