Saikat Sur
Saikat Sur

Reputation: 109

How to export TFS changeset files to a destination Folder

I want to export TFS source files of a particular changeset and/or multiple changesets in a series. Files should be exported to say D:\myTFSExport folder. This is not the existing mapped folder.

The purpose: I want to extract and review the CODEs of Build that contains these changesets after the Code are uploaded into TFS.

The following command of TFS Power Tool does not have any option for mentioning Destination folder.

tfpt getcs /changeset:changesetNo

Thanks in advance

Upvotes: 9

Views: 6294

Answers (2)

AntonK
AntonK

Reputation: 2310

How to extract a list of changesets

I had exactly this requirement in order to create patches for releases. I couldn't find anything in tfs or tfs power tools to do this, so I wrote my own.

To use, the syntax is a follows:

GetTfsChangeSet.exe TfsServerUrl changsetIdList fileOutputPath [merge]

where:

  • TfsServerUrl: The TFS server Url
  • changsetIdList : comma separated list of changesets
  • fileOutputPath: Output path (does not need to be mapped)
  • merge: With Merge param, combines all changesets into one folder. Without the param, each change set is output to a different folder.

e.g.

GetTfsChangeSet.exe http://asdpwiap017:8080/tfs 1233,4555,3332 c:\deploy merge

Create a console application solution.

Add these assembly references:

  • Microsoft.TeamFoundation.Client
  • Microsoft.TeamFoundation.Common
  • Microsoft.TeamFoundation.VersionControl.Client

Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace GetTfsChangeSet
{
    class Program
    {
        static void Main(string[] args)
        {

            if (args.Length < 3)
            {
                Console.WriteLine("Usage:");
                Console.WriteLine("GetTfsChangeSet.exe TfsServerUrl changsetIds fileOutputPath [merge]");
                Console.WriteLine();
                Console.WriteLine("where:");
                Console.WriteLine("- changsetIdList : comma separated list of changesets");
                Console.WriteLine("- merge: With Merge param, combines all changesets into one folder. Without the param, each change set is output to a different folder.");
                Console.WriteLine();
                Console.WriteLine("e.g.");
                Console.WriteLine(@"GetTfsChangeSet.exe http://asdpwiap017:8080/tfs 1233,4555,3332 c:\deploy merge");

                //Console.ReadKey();
                return;
            }

            string teamProjectCollectionUrl = args[0]; // "http://asdpwiap017:8080/tfs";
            var changesets = args[1].Split(',');
            string outputDir = args[2];
            bool mergeChangeSets = args.Length >= 4 && args[3].ToLower().Equals("merge");

            if (mergeChangeSets)
            {
                Console.WriteLine("Merge changesets " + args[1]);
            }

            TfsTeamProjectCollection teamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(teamProjectCollectionUrl));
            string downloadPath = "";

            if (mergeChangeSets)
            {
                downloadPath = args[1].Replace(',', '-');
                if (downloadPath.Length > 30)
                {
                    downloadPath = downloadPath.Substring(0, 15) + "..." + downloadPath.Substring(downloadPath.Length-15);
                }
                downloadPath = Path.Combine(outputDir, downloadPath);
            }


            foreach (var changesetStr in changesets.OrderBy(c=>c))
            {
                var changeset = Convert.ToInt32(changesetStr);
                if (!mergeChangeSets)
                {
                    downloadPath = Path.Combine(outputDir, changeset.ToString());
                }

                var files = GetFilesAssociatedWithBuild(teamProjectCollection, changeset, downloadPath);

                Console.WriteLine(string.Format("ChangeSet {0}: {1} files extracted.", changeset, files.Count));
            }

            Console.WriteLine("Done.");
            //Console.ReadKey();
        }

        private static List<string> GetFilesAssociatedWithBuild(TfsTeamProjectCollection teamProjectCollection, int changesetId, string downloadPath)
        {
            List<string> files = new List<string>();
            VersionControlServer versionControlServer = teamProjectCollection.GetService(typeof(VersionControlServer)) as VersionControlServer;
            Changeset changeset = versionControlServer.GetChangeset(changesetId);
            if (changeset.Changes != null)
            {
                foreach (var changedItem in changeset.Changes)
                {
                    var item = changedItem.Item;
                    if (item.ItemType != ItemType.File || item.DeletionId != 0)
                        continue;

                    var outFilename = Path.Combine(downloadPath, item.ServerItem.Replace("$/", "").Replace("/", @"\"));
                    item.DownloadFile(outFilename);

                    files.Add(outFilename);
                }
            }
            return files;
        }
    }
}

Upvotes: 16

Giulio Vian
Giulio Vian

Reputation: 8343

You can simply add another workspace that maps to the D:\myTFSExport folder and use

tf get $/MyProject /version:Cnnnn /recursive

Where nnnn is the desired changeset number.

Upvotes: 0

Related Questions