65.9K
CodeProject is changing. Read more.
Home

TFS: Compare Changeset in ASP.NET C#

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (1 vote)

Feb 16, 2016

CPOL
viewsIcon

11292

How to compare the latest version with the previous version in C#

Introduction

In this post, I am going to demonstrate comparing changeset in C#. I will cover the following topics:

  1. Get history (list of all changeset)
  2. Download and compare files

For comparing two files, we use Winmerge.

TFS Demo

Take reference of the below DLLs.

DLL

 <table width="100%">  
     <tr>  
       <td>  
         <asp:Literal ID="litTfsParentFolderPath" runat="server" 
         Text="TFS Parent Folder Path"></asp:Literal></td>  
       <td>  
         <asp:TextBox ID="txtTfsParentFolderPath" runat="server" 
         Text="$/HBE/HBE/DEV1/Source/Business/Eligibility/*" 
         Enabled="false" Width="400px"></asp:TextBox>  
       </td>  
     </tr>  
     <tr>  
       <td>  
         <asp:Literal ID="litChildFolderName" runat="server" 
         Text="TFS Child Folder Name"></asp:Literal></td>  
       <td>  
         <asp:DropDownList ID="ddlChildFolders" runat="server" 
         Width="410px" OnSelectedIndexChanged="ddlChildFolders_SelectedIndexChanged" 
         AutoPostBack="true"></asp:DropDownList>  
       </td>  
     </tr>  
     <tr>  
       <td colspan="2">  
         <asp:GridView ID="grvChangeSetData" runat="server" 
         AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333"  
           GridLines="None" OnRowDataBound="grvChangeSetData_RowDataBound" 
           OnRowCommand="grvChangeSetData_RowCommand">  
           <AlternatingRowStyle BackColor="White" ForeColor="#284775" />  
           <Columns>  
             <asp:TemplateField HeaderText="Changeset Number" 
             HeaderStyle-Width="10%" ItemStyle-Width="10%" 
             ItemStyle-VerticalAlign="Top">  
               <ItemTemplate>  
                 <asp:Literal ID="litChangeSetNo" runat="server" 
                 Text='<%#Bind("ChangeSetNumber") %>'> </asp:Literal>  
               </ItemTemplate>  
               <HeaderStyle HorizontalAlign="Center" Width="10%"></HeaderStyle>  
               <ItemStyle VerticalAlign="Top" Width="10%"></ItemStyle>  
             </asp:TemplateField>  
             <asp:TemplateField HeaderText="Owner" HeaderStyle-Width="10%" 
             ItemStyle-Width="10%" ItemStyle-VerticalAlign="Top">  
               <ItemTemplate>  
                 <asp:Literal ID="litOwnerDisplayName" runat="server" 
                 Text='<%#Bind("OwnerDisplayName") %>'> </asp:Literal>  
               </ItemTemplate>  
               <HeaderStyle HorizontalAlign="Center" Width="10%"></HeaderStyle>  
               <ItemStyle VerticalAlign="Top" Width="10%"></ItemStyle>  
             </asp:TemplateField>  
             <asp:TemplateField HeaderText="Created Date" HeaderStyle-Width="10%" 
             ItemStyle-Width="10%" ItemStyle-VerticalAlign="Top">  
               <ItemTemplate>  
                 <asp:Literal ID="litCreateDate" runat="server" 
                 Text='<%#Bind("CreateDate") %>'> </asp:Literal>  
               </ItemTemplate>  
               <HeaderStyle HorizontalAlign="Center" Width="10%"></HeaderStyle>  
               <ItemStyle VerticalAlign="Top" Width="10%"></ItemStyle>  
             </asp:TemplateField>  
             <asp:TemplateField HeaderText="Comment" HeaderStyle-Width="10%" 
             ItemStyle-Width="10%" ItemStyle-VerticalAlign="Top">  
               <ItemTemplate>  
                 <asp:Literal ID="litComment" runat="server" 
                 Text='<%#Bind("Comments") %>'> </asp:Literal>  
               </ItemTemplate>  
               <HeaderStyle HorizontalAlign="Center" Width="10%"></HeaderStyle>  
               <ItemStyle VerticalAlign="Top" Width="10%"></ItemStyle>  
             </asp:TemplateField>  
             <asp:TemplateField HeaderText="Files" HeaderStyle-Width="10%" 
             ItemStyle-Width="10%" ItemStyle-VerticalAlign="Top">  
               <ItemTemplate>  
                 <asp:Repeater ID="rpFiles" runat="server" 
                 OnItemCommand="rpFiles_ItemCommand">  
                   <HeaderTemplate>  
                     <table width="100%">  
                   </HeaderTemplate>  
                   <ItemTemplate>  
                     <tr>  
                       <td>  
                         <asp:LinkButton ID="lnkFileName" runat="server" 
                         Text='<%# Bind("FileName") %>'  
                           CommandName="DownloadFile" CommandArgument='<%# Bind
                           ("CommandArgument") %>'></asp:LinkButton>  
                         <asp:LinkButton ID="lnkCompare" 
                         runat="server" Text="Compare"  
                           CommandName="CompareFile" CommandArgument='<%# Bind
                           ("CommandArgument") %>'></asp:LinkButton>  
                       </td>  
                     </tr>  
                   </ItemTemplate>  
                   <FooterTemplate>  
                     </table>  
                   </FooterTemplate>  
                 </asp:Repeater>  
               </ItemTemplate>  
               <HeaderStyle HorizontalAlign="Center" 
               Width="10%"></HeaderStyle>  
               <ItemStyle VerticalAlign="Top" 
               Width="10%"></ItemStyle>  
             </asp:TemplateField>  
           </Columns>  
           <EditRowStyle BackColor="#999999" />  
           <FooterStyle BackColor="#5D7B9D" 
           Font-Bold="True" ForeColor="White" />  
           <HeaderStyle BackColor="#5D7B9D" 
           Font-Bold="True" ForeColor="White" />  
           <PagerStyle BackColor="#284775" 
           ForeColor="White" HorizontalAlign="Center" />  
           <RowStyle BackColor="#F7F6F3" 
           ForeColor="#333333" />  
           <SelectedRowStyle BackColor="#E2DED6" 
           Font-Bold="True" ForeColor="#333333" />  
           <SortedAscendingCellStyle BackColor="#E9E7E2" />  
           <SortedAscendingHeaderStyle BackColor="#506C8C" />  
           <SortedDescendingCellStyle BackColor="#FFFDF8" />  
           <SortedDescendingHeaderStyle BackColor="#6F8DAE" />  
         </asp:GridView>  
       </td>  
     </tr>  
   </table>

Put the below code in .cs file:

 using System;  
 using System.Collections.Generic;  
 using System.Collections.ObjectModel;  
 using System.Configuration;  
 using System.Diagnostics;  
 using System.Linq;  
 using System.Net;  
 using System.Text;  
 using System.Web;  
 using System.Web.UI;  
 using System.Web.UI.WebControls;  
 using Microsoft.TeamFoundation;  
 using Microsoft.TeamFoundation.Client;  
 using Microsoft.TeamFoundation.Framework.Client;  
 using Microsoft.TeamFoundation.Framework.Common;  
 using Microsoft.TeamFoundation.VersionControl.Client; 
 namespace TFSDemo  
 {  
   public partial class _Default : Page  
   {  
     #region Properties  
     public TfsTeamProjectCollection teamProjectCollection  
     {  
       get { return GetTFS(); }  
     }  
     public string GetTFSPath  
     {  
       get { return ConfigurationManager.AppSettings["URI"]; }  
     }  
     public string GetUser  
     {  
       get { return ConfigurationManager.AppSettings["User"]; }  
     }  
     public string GetPassword  
     {  
       get { return ConfigurationManager.AppSettings["Password"]; }  
     }  
     public string GetDomain  
     {  
       get { return ConfigurationManager.AppSettings["Domain"]; }  
     }  
     #endregion  
     #region PageLoad  
     protected void Page_Load(object sender, EventArgs e)  
     {  
       if (!IsPostBack)  
       {  
         BindSubFolders();  
       }  
     }  
     #endregion  
     #region Events  
     
     protected void ddlChildFolders_SelectedIndexChanged(object sender, EventArgs e)  
     {  
       try  
       {  
         string filePath = ddlChildFolders.SelectedItem.Value.ToStringSafe();  
         List<SubFolderChangeSet> listChangeSet = GetChangeSetBySubFolderName(filePath);  
         grvChangeSetData.DataSource = listChangeSet.Distinct().Select(x => x);  
         grvChangeSetData.DataBind();  
       }  
       catch (Exception ex)  
       {  
         throw ex;  
       }  
     }  
     protected void grvChangeSetData_RowDataBound(object sender, GridViewRowEventArgs e)  
     {  
       if (e.Row.RowType == DataControlRowType.DataRow)  
       {  
         Repeater rpFiles = e.Row.FindControl("rpFiles") as Repeater;  
         if (rpFiles != null)  
         {  
           rpFiles.ItemCommand += new RepeaterCommandEventHandler(rpFiles_ItemCommand);  
           List<Change> listChangeset = ((e.Row.DataItem) as SubFolderChangeSet).listChange;  
           List<FileNames> listFileName = new List<FileNames>();  
           if (listChangeset != null && listChangeset.Count > 0)  
           {  
             foreach (Change change in listChangeset)  
             {  
               FileNames file = new FileNames();  
               file.ChangeSetNumber = ((e.Row.DataItem) as SubFolderChangeSet).ChangeSetNumber;  
               file.FileName = change.Item.ServerItem.Substring
               (change.Item.ServerItem.LastIndexOf('/') + 1);  
               file.CommandArgument = file.ChangeSetNumber + "@" + file.FileName;  
               listFileName.Add(file);  
             }  
             rpFiles.DataSource = listFileName;  
             rpFiles.DataBind();  
           }  
         }  
       }  
     }  
     protected void rpFiles_ItemCommand(object source, RepeaterCommandEventArgs e)  
     {  
       if (e.CommandName.Equals("DownloadFile", StringComparison.OrdinalIgnoreCase))  
       {  
         string[] args = e.CommandArgument.ToStringSafe().Split('@');  
         if (args != null && args.Length > 0)  
         {  
           int changesetId = args[0].ToIntSafe();  
           VersionControlServer vcs = GetVersionServer(teamProjectCollection);  
           if (vcs != null)  
           {  
             Changeset cs = vcs.GetChangeset(changesetId);  
             foreach (Change ch in cs.Changes)  
             {  
               string filename = ch.Item.ServerItem.Substring
               (ch.Item.ServerItem.LastIndexOf('/') + 1);  
               if (filename.Equals(args[1].ToStringSafe(), StringComparison.OrdinalIgnoreCase))  
               {  
                 ch.Item.DownloadFile(System.IO.Path.GetTempPath() +  
                            ch.Item.ChangesetId +  
                            ch.Item.ServerItem.Split('/')[  
                              ch.Item.ServerItem.Split('/').Length - 1]);  
               }  
             }  
           }  
         }  
       }  
       if (e.CommandName.Equals("CompareFile", StringComparison.OrdinalIgnoreCase))  
       {  
         string[] args = e.CommandArgument.ToStringSafe().Split('@');  
         if (args != null && args.Length > 0)  
         {  
           int changesetId = args[0].ToIntSafe();  
           VersionControlServer vcs = GetVersionServer(teamProjectCollection);  
           if (vcs != null)  
           {  
             Changeset cs = vcs.GetChangeset(changesetId);  
             string matchFile = string.Empty;  
             string filePath = string.Empty;  
             filePath = System.IO.Path.GetTempPath();  
             //filePath = Server.MapPath("~//TFSFiles");  
             foreach (Change ch in cs.Changes)  
             {  
               string filename = ch.Item.ServerItem.Substring
               (ch.Item.ServerItem.LastIndexOf('/') + 1);  
               if (filename.Equals(args[1].ToStringSafe(), StringComparison.OrdinalIgnoreCase))  
               {  
                 matchFile = ch.Item.ServerItem.ToStringSafe();  
                 ch.Item.DownloadFile(filePath +  
                            ch.Item.ChangesetId +  
                            ch.Item.ServerItem.Split('/')[  
                              ch.Item.ServerItem.Split('/').Length - 1]);  
               }  
             }  
             if (!string.IsNullOrWhiteSpace(matchFile))  
             {  
               Item item = vcs.GetItem(matchFile);  
               item.DownloadFile(filePath + changesetId + "-New-" + 
               matchFile.Split('/')[matchFile.Split('/').Length - 1]);  
               var winmerge = Process.Start(@"C:\Program Files (x86)\WinMerge\WinMergeU.exe",  
                         String.Format("{0}{1} {0}{2}", filePath,  
                                @"\" + changesetId + matchFile.Substring
                                (matchFile.LastIndexOf('/') + 1), 
                                @"\" + changesetId + "-New-" +  
                                matchFile.Substring(matchFile.LastIndexOf('/') + 1)));  
             }  
           }  
         }  
       }  
     }  
     protected void grvChangeSetData_RowCommand(object sender, GridViewCommandEventArgs e)  
     {  
     }  
     #endregion  
     #region PrivateMethods  
     private TfsTeamProjectCollection GetTFS()  
     {  
       TfsTeamProjectCollection tpc = null;  
       try  
       {  
         Uri tfsUri = new Uri(GetTFSPath);  
         TfsConfigurationServer configurationServer = 
         TfsConfigurationServerFactory.GetConfigurationServer(tfsUri);  
         configurationServer.Credentials = new NetworkCredential(GetUser, GetPassword, GetDomain);  
         configurationServer.Authenticate();  
         ReadOnlyCollection<CatalogNode> collectionNodes = 
         configurationServer.CatalogNode.QueryChildren(new[] 
         { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None);  
         foreach (CatalogNode collectionNode in collectionNodes)  
         {  
           Guid collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);  
           tpc = configurationServer.GetTeamProjectCollection(collectionId);  
         }  
       }  
       catch (Exception ex)  
       {  
         throw ex;  
       }  
       return tpc;  
     }  
     private VersionControlServer GetVersionServer(TfsTeamProjectCollection teamProjectCollection)  
     {  
       return teamProjectCollection.GetService<VersionControlServer>();  
     }  
     private void BindSubFolders()  
     {  
       try  
       {  
         if (teamProjectCollection != null)  
         {  
           VersionControlServer vcs = GetVersionServer(teamProjectCollection);  
           var subFolders = vcs.GetItems(txtTfsParentFolderPath.Text.ToStringSafe());  
           List<string> listSubFolders = new List<string>();  
           foreach (var item in subFolders.Items)  
           {  
             listSubFolders.Add(item.ServerItem);  
           }  
           ddlChildFolders.DataSource = listSubFolders;  
           ddlChildFolders.DataBind();  
         }  
       }  
       catch (Exception ex)  
       {  
         throw ex;  
       }  
     }  
     private List<SubFolderChangeSet> GetChangeSetBySubFolderName(string filePath)  
     {  
       List<SubFolderChangeSet> listChangeset = new List<SubFolderChangeSet>();  
       try  
       {  
         var vsStore = teamProjectCollection.GetService<VersionControlServer>();  
 
         var histories =  
             vsStore.QueryHistory( 
                 filePath,  
                 VersionSpec.Latest, default(int), 
                 RecursionType.Full, null, null, null, Int32.MaxValue, true, false, true);  
         foreach (Changeset history in histories)  
         {  
           SubFolderChangeSet sbfChangeSet = new SubFolderChangeSet();  
           sbfChangeSet.ChangeSetNumber = history.ChangesetId;  
           sbfChangeSet.Owner = history.Owner;  
           sbfChangeSet.OwnerDisplayName = history.OwnerDisplayName;  
           sbfChangeSet.Comments = history.Comment;  
           listChangeset.Add(sbfChangeSet);  
           sbfChangeSet.listChange = new List<Change>();  
           sbfChangeSet.listChange.AddRange(history.Changes);  
           foreach (Change change in history.Changes)  
           {  
             sbfChangeSet.CreateDate = change.Item.CheckinDate;  
           }  
         }  
       }  
       catch (Exception ex)  
       {  
         throw ex;  
       }  
       return listChangeset;  
     }  
     #endregion  
   }  
   #region Classes  
   public class SubFolderChangeSet  
   {  
     public int ChangeSetNumber { get; set; }  
     public string Owner { get; set; }  
     public string OwnerDisplayName { get; set; }  
     public string Comments { get; set; }  
     public DateTime CreateDate { get; set; }  
     public List<Change> listChange { get; set; }  
   }  
   public class FileNames  
   {  
     public int ChangeSetNumber { get; set; }  
     public string FileName { get; set; }  
     public string CommandArgument { get; set; }  
   }  
   #endregion  
 }