public void ExportToGit(string repoPath) { workQueue.AddLast(delegate(object work) { var stopwatch = Stopwatch.StartNew(); logger.WriteSectionSeparator(); LogStatus(work, "Initializing Git repository"); // create repository directory if it does not exist if (!Directory.Exists(repoPath)) { Directory.CreateDirectory(repoPath); } var git = new GitWrapper(repoPath, logger); git.CommitEncoding = commitEncoding; while (!git.FindExecutable()) { var button = MessageBox.Show("Git not found in PATH. " + "If you need to modify your PATH variable, please " + "restart the program for the changes to take effect.", "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); if (button == DialogResult.Cancel) { workQueue.Abort(); return; } } if (!RetryCancel(delegate { git.Init(); })) { return; } if (commitEncoding.WebName != "utf-8") { AbortRetryIgnore(delegate { git.SetConfig("i18n.commitencoding", commitEncoding.WebName); }); } var pathMapper = new VssPathMapper(); // create mappings for root projects foreach (var rootProject in revisionAnalyzer.RootProjects) { var rootPath = VssPathMapper.GetWorkingPath(repoPath, rootProject.Path); pathMapper.SetProjectPath(rootProject.PhysicalName, rootPath, rootProject.Path); } // replay each changeset var changesetId = 1; var changesets = changesetBuilder.Changesets; var commitCount = 0; var tagCount = 0; var replayStopwatch = new Stopwatch(); var labels = new LinkedList <Revision>(); tagsUsed.Clear(); foreach (var changeset in changesets) { var changesetDesc = string.Format(CultureInfo.InvariantCulture, "changeset {0} from {1}", changesetId, changeset.DateTime); // replay each revision in changeset LogStatus(work, "Replaying " + changesetDesc); labels.Clear(); replayStopwatch.Start(); bool needCommit; try { needCommit = ReplayChangeset(pathMapper, changeset, git, labels); } finally { replayStopwatch.Stop(); } if (workQueue.IsAborting) { return; } // commit changes if (needCommit) { LogStatus(work, "Committing " + changesetDesc); if (CommitChangeset(git, changeset)) { ++commitCount; } } if (workQueue.IsAborting) { return; } // create tags for any labels in the changeset if (labels.Count > 0) { foreach (Revision label in labels) { var labelName = ((VssLabelAction)label.Action).Label; if (string.IsNullOrEmpty(labelName)) { logger.WriteLine("NOTE: Ignoring empty label"); } else if (commitCount == 0) { logger.WriteLine("NOTE: Ignoring label '{0}' before initial commit", labelName); } else { var tagName = GetTagFromLabel(labelName); var tagMessage = "Creating tag " + tagName; if (tagName != labelName) { tagMessage += " for label '" + labelName + "'"; } LogStatus(work, tagMessage); // annotated tags require (and are implied by) a tag message; // tools like Mercurial's git converter only import annotated tags var tagComment = label.Comment; if (string.IsNullOrEmpty(tagComment) && forceAnnotatedTags) { // use the original VSS label as the tag message if none was provided tagComment = labelName; } if (AbortRetryIgnore( delegate { git.Tag(tagName, label.User, GetEmail(label.User), tagComment, label.DateTime); })) { ++tagCount; } } } } ++changesetId; } stopwatch.Stop(); logger.WriteSectionSeparator(); logger.WriteLine("Git export complete in {0:HH:mm:ss}", new DateTime(stopwatch.ElapsedTicks)); logger.WriteLine("Replay time: {0:HH:mm:ss}", new DateTime(replayStopwatch.ElapsedTicks)); logger.WriteLine("Git time: {0:HH:mm:ss}", new DateTime(git.ElapsedTime.Ticks)); logger.WriteLine("Git commits: {0}", commitCount); logger.WriteLine("Git tags: {0}", tagCount); }); }
public void ExportToGit(string repoPath) { workQueue.AddLast(delegate(object work) { var stopwatch = Stopwatch.StartNew(); logger.WriteSectionSeparator(); LogStatus(work, "Initializing Git repository"); // create repository directory if it does not exist if (!Directory.Exists(repoPath)) { Directory.CreateDirectory(repoPath); } var git = new GitWrapper(repoPath, logger); git.CommitEncoding = commitEncoding; while (!git.FindExecutable()) { var button = MessageBox.Show("Git not found in PATH. " + "If you need to modify your PATH variable, please " + "restart the program for the changes to take effect.", "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error); if (button == DialogResult.Cancel) { workQueue.Abort(); return; } } if (!RetryCancel(delegate { git.Init(); })) { return; } if (commitEncoding.WebName != "utf-8") { AbortRetryIgnore(delegate { git.SetConfig("i18n.commitencoding", commitEncoding.WebName); }); } var pathMapper = new VssPathMapper(); // create mappings for root projects foreach (var rootProject in revisionAnalyzer.RootProjects) { var rootPath = VssPathMapper.GetWorkingPath(repoPath, rootProject.Path); pathMapper.SetProjectPath(rootProject.PhysicalName, rootPath, rootProject.Path); } // replay each changeset var changesetId = 1; var changesets = changesetBuilder.Changesets; var commitCount = 0; var tagCount = 0; var replayStopwatch = new Stopwatch(); var labels = new LinkedList<Revision>(); tagsUsed.Clear(); foreach (var changeset in changesets) { var changesetDesc = string.Format(CultureInfo.InvariantCulture, "changeset {0} from {1}", changesetId, changeset.DateTime); // replay each revision in changeset LogStatus(work, "Replaying " + changesetDesc); labels.Clear(); replayStopwatch.Start(); bool needCommit; try { needCommit = ReplayChangeset(pathMapper, changeset, git, labels); } finally { replayStopwatch.Stop(); } if (workQueue.IsAborting) { return; } // commit changes if (needCommit) { LogStatus(work, "Committing " + changesetDesc); if (CommitChangeset(git, changeset)) { ++commitCount; } } if (workQueue.IsAborting) { return; } // create tags for any labels in the changeset if (labels.Count > 0) { foreach (Revision label in labels) { var labelName = ((VssLabelAction)label.Action).Label; if (string.IsNullOrEmpty(labelName)) { logger.WriteLine("NOTE: Ignoring empty label"); } else if (commitCount == 0) { logger.WriteLine("NOTE: Ignoring label '{0}' before initial commit", labelName); } else { var tagName = GetTagFromLabel(labelName); var tagMessage = "Creating tag " + tagName; if (tagName != labelName) { tagMessage += " for label '" + labelName + "'"; } LogStatus(work, tagMessage); // annotated tags require (and are implied by) a tag message; // tools like Mercurial's git converter only import annotated tags var tagComment = label.Comment; if (string.IsNullOrEmpty(tagComment) && forceAnnotatedTags) { // use the original VSS label as the tag message if none was provided tagComment = labelName; } if (AbortRetryIgnore( delegate { git.Tag(tagName, label.User, GetEmail(label.User), tagComment, label.DateTime); })) { ++tagCount; } } } } ++changesetId; } stopwatch.Stop(); logger.WriteSectionSeparator(); logger.WriteLine("Git export complete in {0:HH:mm:ss}", new DateTime(stopwatch.ElapsedTicks)); logger.WriteLine("Replay time: {0:HH:mm:ss}", new DateTime(replayStopwatch.ElapsedTicks)); logger.WriteLine("Git time: {0:HH:mm:ss}", new DateTime(git.ElapsedTime.Ticks)); logger.WriteLine("Git commits: {0}", commitCount); logger.WriteLine("Git tags: {0}", tagCount); }); }