Geeks With Blogs

News




View Tarun Arora's profile on LinkedIn

profile for Tarun Arora at Stack Overflow, Q&A for professional and enthusiast programmers

Tarun Arora - Visual Studio ALM MVP ALM, Agile, Automation, Performance Testing, Software QA, Cloud, ...

 

I will be covering three things in this blog post

  • Get the history i.e. all change sets of an item programmatically using the TFS API.
  • Download the change sets programmatically using the TFS API
  • Use WinMerge to compare those change sets programmatically

1. How do i get the history of a file using TFS API?

The VersionControlServer Class exposes the QueryHistory method that gets you all changesets that have impacted a file or folder you are querying for.

public IEnumerable QueryHistory(
    string path, // The local path to an item for which history will be queried. This parameter can include wildcards
    VersionSpec version, // The version of the item for which history will be queried.
    int deletionId, // The unique deletion ID for the item, if it is deleted. Otherwise, specify 0
    RecursionType recursion, // A flag describing whether history will be recursively queried
    string user, // The user for whom history will be queried. Specify null for any user
    VersionSpec versionFrom, // The earliest version for which history will be queried. Specify null to begin with the first changeset
    VersionSpec versionTo, // The latest version for which history will be queried. Specify null to end with the latest changeset
    int maxCount, // The maximum number of history entries to return. Specify Int32.MaxValue to get all changes
    bool includeChanges, // A flag that describes whether the individual item changes will be included with the changesets. Otherwise, only changeset metadata is included
    bool slotMode // A flag that describes how history entries are searched.
}

Example: Query the history of file TfsRepository.cs placed in the source control at ‘$/Temp_UK_1/Development/Prod/Source/TfsWorkspaceManager/TfsWorkspaceManager/TfsRepository.cs’

var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("https://tfs2010:8080/defaultcollection"));
    var vsStore = tfs.GetService<VersionControlServer>();

    var histories =
        vsStore.QueryHistory( //filepath
                    "$/Temp_UK_1/Development/Prod/Source/TfsWorkspaceManager/TfsWorkspaceManager/TfsRepository.cs",
                    VersionSpec.Latest, 0, RecursionType.OneLevel, null, null, null, Int32.MaxValue, true, false, true);
    
    foreach (Changeset history in histories)
    {
        // Break to see what values history has
    }   

 

Histories is IEnumerable, as we enumerate we convert history to type changeset. Let’s see the results,

image

There are two overloads,

  • bool includeDownloadInfo: A flag that describes whether to get the information necessary to download the change sets from the server
  • bool sortAscending: A flag that describes whether to sort the results in ascending order. Specify false to not sort the results.

2. Download the files in the changeset programmatically

The Item Class exposes the DownloadFile Method that downloads the content for this version of the item.

Example: Download all changesets of the TfsRepository.cs file to Windows Temp folder.

public static void DownloadHistoryChangesetsToTempFolder()
{
    var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("https://tfs2010:8080/defaultcollection"));
    tfs.EnsureAuthenticated();
    var vsStore = tfs.GetService<VersionControlServer>();

    var histories =
           vsStore.QueryHistory( //filepath
                    "$/Temp_UK_1/Development/Prod/Source/TfsWorkspaceManager/TfsRepository.cs",
                    VersionSpec.Latest, 0, RecursionType.OneLevel, null, null, null, Int32.MaxValue, true, false, true);

    foreach (Changeset history in histories)
    {
       foreach (Change change in history.Changes)
       {
           change.Item.DownloadFile(System.IO.Path.GetTempPath() + change.Item.ChangesetId + 
                                      change.Item.ServerItem.Split('/')[change.Item.ServerItem.Split('/').Length - 1]);
       }
    }
}

Screen shot of the windows temp folder,

image

 

3. Compare the downloaded versions programmatically using WinMerge

Download and Install WinMerge. WinMerge is an Open Source differencing and merging tool for Windows. WinMerge can compare both folders and files, presenting differences in a visual text format that is easy to understand and handle. You can read more about how to change the default Compare and Merge tool in Team Foundation Sever in my earlier blog post here.

Example: Compare the earlier downloaded history versions of TfsRepository.cs from the windows temp folder

WinMerge command line access with a bunch of useful arguments. You can do WinMergeU.exe /? to get the details of the arguments.

WinMerge[U] [/r] [/e] [/f filter] [/x] [/s] [/ul] [/ur] [/u] [/wl] [/wr] [/minimize] [/maximize] [/dl leftdesc] [/dr rightdesc] leftpath rightpath [outputpath]

WinMerge[U] conflictfile

 

public static void CompareTwoChangeSets()
{
    var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("https://tfs2010:8080/defaultcollection"));
    tfs.EnsureAuthenticated();
    var vsStore = tfs.GetService<VersionControlServer>();

    var histories =
               vsStore.QueryHistory( //filepath
                   "$/Temp_UK_1/Development/Prod/Source/TfsWorkspaceManager/TfsWorkspaceManager/TfsWorkspaceManager/TfsRepository.cs",
                   VersionSpec.Latest, 0, RecursionType.OneLevel, null, null, null, Int32.MaxValue, true, false, true);

        foreach (Changeset history in histories)
        {
            foreach (Change change in history.Changes)
            {
                change.Item.DownloadFile(System.IO.Path.GetTempPath() +
                                            change.Item.ChangesetId +
                                            change.Item.ServerItem.Split('/')[
                                                change.Item.ServerItem.Split('/').Length - 1]);
        }
    }

    var winmerge = Process.Start(@"C:\Program Files (x86)\WinMerge\WinMergeU.exe",
                                        String.Format("{0}{1} {0}{2}", System.IO.Path.GetTempPath(),
                                                      @"\36TfsRepository.cs", @"\37TfsRepository.cs"));
}

So, i am starting a Process to consume the WinMergeU.exe and passing the 2 versions of the file that i want to compare. You can also use the following arguments,

  • /r compares all files in all subfolders (recursive compare). Unique folders (occurring only on one side) are listed in the compare result as separate items. Note that including subfolders can increase compare time significantly. Without this parameter, WinMerge lists only files and subfolders at the top level of the two target folders. It does not compare the subfolders.
  • /dl specifies a description in the left side title bar, overriding the default folder or filename text. For example: /dl "Version 1.0" or /dl WorkingCopy. Use quotation marks around descriptions that contain spaces.
  • /dr specifies a description in the right side title bar, just like /dl.

Screen Shot of execution of the above method,

image

 

 

Share this post :
Posted on Saturday, July 23, 2011 10:18 PM TFS2010 , TFS API | Back to top


Comments on this post: TFS SDK: Compare Changesets programmatically

# re: TFS SDK: Compare Changesets programmatically
Requesting Gravatar...
Thanks Dude..Very Helpful
Left by Murt.. on Mar 20, 2012 3:27 AM

# re: TFS SDK: Compare Changesets programmatically
Requesting Gravatar...
Thanks for the article. I have a question. Is there a way to save the compare's result in a pdf, or txt? What function or property can be used to save the changes between both changeset files? Thanks for the help.
Left by Christian Solis on Jan 11, 2013 3:48 PM

comments powered by Disqus

Copyright © Tarun Arora [Microsoft MVP] | Powered by: GeeksWithBlogs.net | Join free