Remove ***NO_CI*** changesets from merge candidates

by Ewald Hofman 26. July 2009 23:34

A common scenario when you use TFS and Team Build, is that you want to update your build number during that process. There is the AssemblyInfoTask to accomplish that, but the downside of this approach is that it will create an extra changeset on every build. When you use a braching strategy, then it makes the merge process harder because there are these polluting ***NO_CI*** changesets.

Fortunately there is the possibility to discard these changeset from the merge candidate list. The application that is shown below let you remove those changesets automatically.

using System;
using System.Diagnostics;
using System.IO;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
 
namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            if (args.Length != 3)
            {
                Console.WriteLine(AppUsage());
                return;
            }
 
            const string tf = @"c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\tf.exe";
            string tfsServer = args[0];
            string sourcePath = args[1];
            string targetPath = args[2];
 
            // Get a reference to our Team Foundation Server.           
            var tfs = new TeamFoundationServer(tfsServer);
 
            // Get a local path for the Tfs server. This is required by the TF command.
            string localPath = GetFirstLocalFolder(tfs);
 
            // Iterate through all merge candidates
            foreach (MergeCandidate candidate in GetMergeCandidates(tfs, sourcePath, targetPath))
            {
                // Skip all changesets that are not commented with ***NO_CI***
                if (candidate.Changeset.Comment != "***NO_CI***")
                    continue;
 
                // Discard the ***NO_CI changeset from the merge candidates
                Console.WriteLine(Execute(tf, localPath,
                                          string.Format("merge /discard /recursive /version:C{0} \"{1}\" \"{2}\"",
                                                        candidate.Changeset.ChangesetId, sourcePath, targetPath)));
                Console.WriteLine(Execute(tf, localPath,
                                          string.Format(
                                              "checkin /recursive /noprompt /comment:\"***NO_CI***\" /override:\"Discard the ***NO_CI*** changeset from the merge candidates.\" \"{2}\"",
                                              candidate.Changeset.ChangesetId, sourcePath, targetPath)));
            }
        }
 
        /// <summary>
        /// Displays how the app should be used.
        /// </summary>
        private static string AppUsage()
        {
            return "Start the application with 3 arguments: " + Environment.NewLine +
                   @"- The url of the Tfs Server (eg http:\\MyServer:8080" + Environment.NewLine +
                   @"- The path of the source branch (eg $/MyTeamProject/MySourceBranch)" + Environment.NewLine +
                   @"- The path of the target branch (eg $/MyTeamProject/MyTargetBranch)";
        }
 
        /// <summary>
        /// Returns the list of all merge candidates.
        /// </summary>
        private static MergeCandidate[] GetMergeCandidates(TeamFoundationServer tfs, string sourcePath,
                                                           string targetPath)
        {
            var versionControl = (VersionControlServer) tfs.GetService(typeof (VersionControlServer));
            return versionControl.GetMergeCandidates(sourcePath, targetPath,
                                                     RecursionType.Full);
        }
 
        /// <summary>
        /// Returns the local path of the first workspace.
        /// </summary>
        private static string GetFirstLocalFolder(TeamFoundationServer tfs)
        {
            var versionControl = (VersionControlServer) tfs.GetService(typeof (VersionControlServer));
            Workspace[] workspaces = versionControl.QueryWorkspaces(null, null, Environment.MachineName);
 
            return (workspaces.Length > 0 && workspaces[0].Folders.Length > 0)
                       ? workspaces[0].Folders[0].LocalItem
                       : null;
        }
 
        /// <summary>
        /// Runs the TF command
        /// </summary>
        private static string Execute(string fileName, string localPath, string arguments)
        {
            var pi = new ProcessStartInfo
                         {
                             FileName = fileName,
                             Arguments = arguments,
                             UseShellExecute = false,
                             ErrorDialog = false,
                             CreateNoWindow = true,
                             RedirectStandardOutput = true,
                             WorkingDirectory = localPath
                         };
 
            Process p = Process.Start(pi);
 
            // Read the redirected output.
            using (StreamReader sr = p.StandardOutput)
            {
                return sr.ReadToEnd();
            }
        }
    }
}

Tags: , ,

Team Build | Version Control | VSTS 2008

Powered by BlogEngine.NET 1.6.1.0
Theme by Mads Kristensen


ClusterMap

Widget Statistics not found.

There is an error in XML document (0, 0).X

Recent comments

Comment RSS