Source

Tfs2Hg / Tfs2Hg / HgUtility.cs

Full commit
using System;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.TeamFoundation.VersionControl.Client;

namespace Tfs2Hg
{
    public class HgUtility
    {
        private readonly string repositoryPath;
        private readonly string hgCommand;

        public HgUtility(string repositoryPath) :  this(repositoryPath, "hg.exe")
        {
        }

        public HgUtility(string repositoryPath, string hgCommand)
        {
            this.repositoryPath = repositoryPath;
            this.hgCommand = hgCommand;
        }

        public void UpdateHgIgnore(string ignoreSpec)
        {
            FileInfo hgIgnoreFile = new FileInfo(Path.Combine(repositoryPath, ".hgignore"));
            StringBuilder fileBuilder = new StringBuilder();
            bool writeFile = false;
            if (hgIgnoreFile.Exists)
            {
                fileBuilder.AppendLine(File.ReadAllText(hgIgnoreFile.FullName));
            }
            else
            {
                fileBuilder.AppendLine("syntax: glob");
                writeFile = true;
            }

            Regex re = new Regex(@"^\s*" + Regex.Escape(ignoreSpec) + @"\s*$", RegexOptions.Multiline);
            if (!re.IsMatch(fileBuilder.ToString()))
            {
                writeFile = true;
                fileBuilder.AppendLine(ignoreSpec);
            }

            if (writeFile)
                File.WriteAllText(hgIgnoreFile.FullName, fileBuilder.ToString());
        }

        public int CommitToHg(Changeset changeset)
        {
            Console.WriteLine("Committing changes to Mercurial server");
            Directory.SetCurrentDirectory(repositoryPath);

            string output;
            string comment = String.IsNullOrEmpty(changeset.Comment) ? "(no comment)" : changeset.Comment;
            string user = changeset.Committer.Split('\\').Last();
            
            double creationTimestamp = Math.Floor(changeset.CreationDate.ToTimestamp());
            double utcOffsetSeconds = 0 - TimeZone.CurrentTimeZone.GetUtcOffset(changeset.CreationDate).TotalSeconds;
            string date = String.Format(CultureInfo.InvariantCulture, "{0:0} {1}", creationTimestamp, utcOffsetSeconds);
            
            string arguments = String.Format(@"commit --addremove --message ""C{0} - {1}"" --date ""{2}"" --user ""{3}""", changeset.ChangesetId, comment.Replace("\"", "\\\""), date, user);

            int returnCode = Tools.ExecuteCommand(hgCommand, arguments, out output);
            Console.WriteLine(output);

            if (returnCode == 0 || output.StartsWith("nothing changed"))
            {
                Console.WriteLine("Commit OK");
                return 0;
            }
            else
            {
                Console.WriteLine("Commit failed - exiting");
                return returnCode;
            }
        }

        public int Initialize()
        {
            Console.WriteLine("Initializing repository");
            Directory.SetCurrentDirectory(repositoryPath);
            string output;
            int returnCode = Tools.ExecuteCommand(hgCommand, "init", out output);
            Console.WriteLine(output);
            return returnCode;
        }

        public bool IsRepository()
        {
            return Directory.Exists(Path.Combine(repositoryPath, ".hg"));
        }
    }
}