} // MigratePvcsArchiveSourcestoGit static bool MigratePvcsArchiveSourcestoGit(PvcsCompleteSystemArchiveDetail pvcsCompleteSystemArchiveDetail, string singlePromotionGroupName, string rootWorkingDirectory) { bool success = false; const CommandOperation.DebugProgress debugProgress = CommandOperation.DebugProgress.None; const int highLevelIndent = 0; PvcsPromotionGroupDetailCollection pvcsPromotionGroupDetailCollection = new PvcsPromotionGroupDetailCollection(); // ============================================================================================================ // For this to work, the Repository must have the branch from which this Promotion Group is to come checked out // ============================================================================================================ success = GitOperation.ImportBranchFromPvcs(pvcsCompleteSystemArchiveDetail, singlePromotionGroupName, true, pvcsPromotionGroupDetailCollection.PromotionGroupNetworkShareName(singlePromotionGroupName), pvcsPromotionGroupDetailCollection.GitBranchName(singlePromotionGroupName), rootWorkingDirectory, String.Format("Initial PVCS {0} commit to Git {1}", singlePromotionGroupName, pvcsPromotionGroupDetailCollection.GitBranchName(singlePromotionGroupName)), highLevelIndent, debugProgress); return(success); } // MigratePvcsArchiveSourcestoGit
} // Commit /// <summary> /// Import all the sources associated with a PVCS Promotion Group into a single git branch /// </summary> /// <param name="pvcsCompleteSystemArchiveDetail">Complete set of PVCS Archive Details with Promotion Group and revision details</param> /// <param name="promotionGroup">The particular Promotion Group to be imported</param> /// <param name="performImport">Whether or not to actually perform the import (true) or just create the branch (false)</param> /// <param name="promotionGroupSourceVolume">The location of the PVCS source revisions that correspond to the Promotion Group</param> /// <param name="branchName">The name of the Git Branch into which to perform the import</param> /// <param name="rootWorkingDirectory">The full path to the directory containing the Git Repository including working tree</param> /// <param name="commitMessage">The message to be placed on the Git Branch Commit</param> /// <param name="indent">The indent value of output</param> /// <param name="debugProgress">The progress debug output details</param> /// <returns></returns> public static bool ImportBranchFromPvcs(PvcsCompleteSystemArchiveDetail pvcsCompleteSystemArchiveDetail, string promotionGroup, bool performImport, string promotionGroupSourceVolume, string branchName, string rootWorkingDirectory, string commitMessage, int indent, CommandOperation.DebugProgress debugProgress) { bool success = false; Console.WriteLine(); Console.WriteLine("Importing PVCS \"{0}\" Source Revisions from \"{1}\" to Repository \"{2}\" branch \"{3}\"", promotionGroup, promotionGroupSourceVolume, rootWorkingDirectory, branchName); // Check that the working directory has/is a Git Repository success = GitOperation.GitStatus(rootWorkingDirectory, indent, debugProgress); if (success && (success = GitOperation.CreateAndSwitchToBranch(branchName, rootWorkingDirectory, indent, debugProgress)) ) { // On the appropriate Git Repository branch if (performImport) { Console.WriteLine(); Console.WriteLine("Adding Source Revisions for PVCS Promotion Group \"{0}\" to \"{1}\"", promotionGroup, branchName); if (pvcsCompleteSystemArchiveDetail.GitAdd(promotionGroup, indent, promotionGroupSourceVolume, rootWorkingDirectory) ) { success = GitOperation.Commit(commitMessage, rootWorkingDirectory, indent, debugProgress); if (success) { Console.WriteLine(); Console.WriteLine("Committed Source Revisions for PVCS Promotion Group \"{0}\" to \"{1}\"", promotionGroup, branchName); } } else { success = false; Console.WriteLine("*** Not all \"{0}\" Source Revisions were added to branch \"{1}\"", promotionGroup, branchName); } } else { Console.WriteLine(); Console.WriteLine("Skipping import of PVCS Promotion Group \"{0}\" to \"{1}\"", promotionGroup, branchName); } } // On the appropriate Git Repository branch return(success); } // ImportBranchFromPvcs
} // GitStatus // Perform a Git Status and return the standard output and standard error to the caller for subsequent perocessing public static bool GitStatus(string rootWorkingDirectory, int indent, CommandOperation.DebugProgress debugProgress, List <string> standardOutput, List <string> errorOutput) { bool success = false; string command = "git status"; success = CommandOperation.RunMonitoredCommand(rootWorkingDirectory, command, indent, debugProgress, CommandOperation.CommandOutputDisplayType.StandardOutputOnly, standardOutput, errorOutput); return(success); } // GitStatus
public static bool Init(string rootWorkingDirectory, int indent, CommandOperation.DebugProgress debugProgress) { bool success = false; string command; command = "git init"; success = CommandOperation.RunMonitoredCommand(rootWorkingDirectory, command, indent, debugProgress, CommandOperation.CommandOutputDisplayType.StandardOutputOnly, null, null); return(success); }
} // Add public static bool Commit(string description, string rootWorkingDirectory, int indent, CommandOperation.DebugProgress debugProgress) { bool success = false; List <string> standardOutput = new List <string>(); // Add the file to the Repo string command = "git commit -m \"" + description + "\""; success = CommandOperation.RunMonitoredCommand(rootWorkingDirectory, command, indent, debugProgress, CommandOperation.CommandOutputDisplayType.StandardOutputOnly, standardOutput, null); if (!success) { // Try to work out what went wrong if (standardOutput.Count >= 2) { if ((standardOutput[1].IndexOf("nothing to commit, working directory clean") > -1) || (standardOutput[1].IndexOf("nothing to commit, working tree clean") > -1) ) { Console.WriteLine("{0}The failure of the commit is not an error because there were no sources to commit", ConsoleDisplay.Indent(indent)); success = true; } } if (!success) { Console.WriteLine("Unexpected commit failure"); } } // Try to work out what went wrong return(success); } // Commit
} // MigratePvcsArchiveSourcestoGit static bool CreateRepositoryAndPerformInitialCommit(string rootWorkingDirectory, int indent, CommandOperation.DebugProgress debugProgress) { bool success = false; DirectoryInfo directoryInfo = new DirectoryInfo(rootWorkingDirectory); if (!directoryInfo.Exists) { Console.WriteLine(); Console.WriteLine("{0}Local Git Repository Directory \"{1}\" does not exist", ConsoleDisplay.Indent(indent), rootWorkingDirectory); success = false; } else { // Root working directory exists Console.WriteLine(); Console.WriteLine("{0}Local Git Repository Directory is \"{1}\"", ConsoleDisplay.Indent(indent), rootWorkingDirectory); // Create the Git Repository success = GitOperation.Init(rootWorkingDirectory, indent, debugProgress); if (success) { // Repository was initialised successfully const string readMeFilename = "readme.txt"; const string initialCommitMessage = "Initial commit to create Branch master"; string readMeFileFullPathAndFilename = Path.Combine(rootWorkingDirectory, readMeFilename); try { using (System.IO.StreamWriter readMeFile = new System.IO.StreamWriter(readMeFileFullPathAndFilename, true)) { string[] readMeLines = { "Heritage Source Git Repository", "Contains all the sources imported from the PVCS Change Control System" }; foreach (string readMeLine in readMeLines) { readMeFile.WriteLine(readMeLine); } DateTime datetimeNow = DateTime.Now; readMeFile.WriteLine("Git Repository created {0} {1}", datetimeNow.ToString("D"), datetimeNow.ToString("T")); } success = true; } catch (Exception eek) { success = false; Console.WriteLine("Exception writing file \"{0}\" = {1}", readMeFileFullPathAndFilename, eek.ToString()); } if (success) { // Add the file to the Repo success = GitOperation.Add(rootWorkingDirectory, readMeFilename, indent, debugProgress); if (success) { success = GitOperation.Commit(initialCommitMessage, rootWorkingDirectory, indent, debugProgress); if (success) { Console.WriteLine(); Console.WriteLine("Committed initial file \"{0}\"", readMeFileFullPathAndFilename); } } } } // Repository was initialised successfully } // Root working directory exists return(success); } // CreateRepositoryAndPerformInitialCommit
static bool MigratePvcsArchiveSourcestoGit(PvcsCompleteSystemArchiveDetail pvcsCompleteSystemArchiveDetail, SortedSet <string> sortedSetPromotionGroupExclude, string rootWorkingDirectory, bool useExistingGitRepository) { bool success = false; const CommandOperation.DebugProgress debugProgress = CommandOperation.DebugProgress.None; const int highLevelIndent = 0; PvcsPromotionGroupDetailCollection pvcsPromotionGroupDetailCollection = new PvcsPromotionGroupDetailCollection(); bool createRepositoryAndPerformInitialCommit = !useExistingGitRepository; // Assume that if using the existing Repository the user knows that the branch structure already exists bool importPvcsProduction = !sortedSetPromotionGroupExclude.Contains(PvcsPromotionGroupDetailCollection.ProductionPromotionGroupName); // It only makes sense to import this Promotion Group if all higher Promotion Groups have been imported // unless the existing Git Repository already contains those higher Promotion Groups bool importPvcsPreProduction = ((importPvcsProduction) || (useExistingGitRepository /* Higher Promotion Group must already be present */)) && (!sortedSetPromotionGroupExclude.Contains(PvcsPromotionGroupDetailCollection.PreProductionPromotionGroupName)); // It only makes sense to import this Promotion Group if all higher Promotion Groups have been imported // unless the existing Git Repository already contains those higher Promotion Groups bool importPvcsUserTest = ((importPvcsPreProduction) || (useExistingGitRepository /* Higher Promotion Group must already be present */)) && (!sortedSetPromotionGroupExclude.Contains(PvcsPromotionGroupDetailCollection.UserTestPromotionGroupName)); // It only makes sense to import this Promotion Group if all higher Promotion Groups have been imported // unless the existing Git Repository already contains those higher Promotion Groups bool importPvcsSystemTest = ((importPvcsUserTest) || (useExistingGitRepository /* Higher Promotion Group must already be present */)) && (!sortedSetPromotionGroupExclude.Contains(PvcsPromotionGroupDetailCollection.SystemTestPromotionGroupName)); Console.WriteLine(); ConsoleDisplay.WritelineWithUnderline("Importing PVCS Archive Revisions for PVCS Promotion Groups into a single Git Repository"); if (createRepositoryAndPerformInitialCommit) { success = CreateRepositoryAndPerformInitialCommit(rootWorkingDirectory, highLevelIndent, debugProgress); } else { // Indicate success so that subsequent steps execute success = true; } if (success) { string promotionGroupName = PvcsPromotionGroupDetailCollection.ProductionPromotionGroupName; bool importPromotionGroup = importPvcsProduction; success = GitOperation.ImportBranchFromPvcs( pvcsCompleteSystemArchiveDetail, promotionGroupName, importPromotionGroup, pvcsPromotionGroupDetailCollection.PromotionGroupNetworkShareName(promotionGroupName), pvcsPromotionGroupDetailCollection.GitBranchName(promotionGroupName), rootWorkingDirectory, String.Format("Initial PVCS {0} commit to Git {1}", promotionGroupName, pvcsPromotionGroupDetailCollection.GitBranchName(promotionGroupName)), highLevelIndent, debugProgress); } if (success) { string promotionGroupName = PvcsPromotionGroupDetailCollection.PreProductionPromotionGroupName; bool importPromotionGroup = importPvcsPreProduction; success = GitOperation.ImportBranchFromPvcs( pvcsCompleteSystemArchiveDetail, promotionGroupName, importPromotionGroup, pvcsPromotionGroupDetailCollection.PromotionGroupNetworkShareName(promotionGroupName), pvcsPromotionGroupDetailCollection.GitBranchName(promotionGroupName), rootWorkingDirectory, String.Format("Initial PVCS {0} commit to Git {1}", promotionGroupName, pvcsPromotionGroupDetailCollection.GitBranchName(promotionGroupName)), highLevelIndent, debugProgress); } if (success) { string promotionGroupName = PvcsPromotionGroupDetailCollection.UserTestPromotionGroupName; bool importPromotionGroup = importPvcsUserTest; success = GitOperation.ImportBranchFromPvcs( pvcsCompleteSystemArchiveDetail, promotionGroupName, importPromotionGroup, pvcsPromotionGroupDetailCollection.PromotionGroupNetworkShareName(promotionGroupName), pvcsPromotionGroupDetailCollection.GitBranchName(promotionGroupName), rootWorkingDirectory, String.Format("Initial PVCS {0} commit to Git {1}", promotionGroupName, pvcsPromotionGroupDetailCollection.GitBranchName(promotionGroupName)), highLevelIndent, debugProgress); } if (success) { string promotionGroupName = PvcsPromotionGroupDetailCollection.SystemTestPromotionGroupName; bool importPromotionGroup = importPvcsSystemTest; success = GitOperation.ImportBranchFromPvcs( pvcsCompleteSystemArchiveDetail, promotionGroupName, importPromotionGroup, pvcsPromotionGroupDetailCollection.PromotionGroupNetworkShareName(promotionGroupName), pvcsPromotionGroupDetailCollection.GitBranchName(promotionGroupName), rootWorkingDirectory, String.Format("Initial PVCS {0} commit to Git {1}", promotionGroupName, pvcsPromotionGroupDetailCollection.GitBranchName(promotionGroupName)), highLevelIndent, debugProgress); } if (success) { for (int pvcsSystemTestIndex = PvcsPromotionGroupDetailCollection.FirstLowerSystemTestNumber; (success) && (pvcsSystemTestIndex <= PvcsPromotionGroupDetailCollection.LastLowerSystemTestNumber); ++pvcsSystemTestIndex) { string pvcsBranchName = String.Format("{0}{1}", PvcsPromotionGroupDetailCollection.SystemTestPromotionGroupName, pvcsSystemTestIndex); string pvcsShareName = pvcsPromotionGroupDetailCollection.PromotionGroupNetworkShareName(pvcsBranchName); string gitBranchName = pvcsPromotionGroupDetailCollection.GitBranchName(pvcsBranchName); string gitBranchCommitComment = String.Format("Initial PVCS {0} commit to Git {1}", pvcsBranchName, gitBranchName); // Ensure that the new Git Branch comes off Git Integration Test if (!GitOperation.CheckedOutBranchIs(pvcsPromotionGroupDetailCollection.GitBranchName(PvcsPromotionGroupDetailCollection.SystemTestPromotionGroupName), rootWorkingDirectory) ) { // Switch (back) to the Integration Test Branch success = GitOperation.CheckOutBranch(pvcsPromotionGroupDetailCollection.GitBranchName(PvcsPromotionGroupDetailCollection.SystemTestPromotionGroupName), rootWorkingDirectory, highLevelIndent, debugProgress); } if (success) { // It only makes sense to import this Promotion Group if all higher Promotion Groups have been imported // unless the existing Git Repository already contains those higher Promotion Groups bool importPvcsLowerSystemTest = ((importPvcsSystemTest) || (useExistingGitRepository /* Higher Promotion Group must already be present */)) && (!sortedSetPromotionGroupExclude.Contains(pvcsBranchName)); success = GitOperation.ImportBranchFromPvcs(pvcsCompleteSystemArchiveDetail, pvcsBranchName, importPvcsLowerSystemTest, pvcsShareName, gitBranchName, rootWorkingDirectory, gitBranchCommitComment, highLevelIndent, debugProgress); } } // for pvcsSystemTestIndex } if (success) { // Switch to the Integration Test Branch when everything is done success = GitOperation.CheckOutBranch(pvcsPromotionGroupDetailCollection.GitBranchName(PvcsPromotionGroupDetailCollection.SystemTestPromotionGroupName), rootWorkingDirectory, highLevelIndent, debugProgress); } return(success); } // MigratePvcsArchiveSourcestoGit
public static bool CheckOutBranch(string branchName, string rootWorkingDirectory, int indent, CommandOperation.DebugProgress debugProgress) { bool success = false; string command = "git checkout " + branchName; success = CommandOperation.RunMonitoredCommand(rootWorkingDirectory, command, indent, debugProgress, CommandOperation.CommandOutputDisplayType.StandardOutputOnly); return(success); }
} // CreateAndSwitchToBranch public static bool Add(string rootWorkingDirectory, string sourceRelativePath, int indent, CommandOperation.DebugProgress debugProgress) { bool success = false; // Add the file to the Repo string command = "git add -f \"" + sourceRelativePath + "\""; success = CommandOperation.RunMonitoredCommand(rootWorkingDirectory, command, indent, debugProgress, CommandOperation.CommandOutputDisplayType.StandardOutputOnly); return(success); } // Add
public static bool CreateAndSwitchToBranch(string branchName, string rootWorkingDirectory, int indent, CommandOperation.DebugProgress debugProgress) { bool success = false; if (CheckedOutBranchIs(branchName, rootWorkingDirectory)) { // Already on the specified branch success = true; } else { // Create the branch List <string> standardOutput = new List <string>(); List <string> standardError = new List <string>(); string command = "git branch " + branchName; success = CommandOperation.RunMonitoredCommand(rootWorkingDirectory, command, indent, debugProgress, CommandOperation.CommandOutputDisplayType.StandardOutputAndStandardError, standardOutput, standardError); if (!success) { // Check that the error was a real error and not just that the branch already existed if (standardOutput.Count >= 1) { if (standardOutput[0].StartsWith("fatal: A branch named")) { Console.WriteLine("{0}The failure of the creation of branch \"{1}\" is not an error because a branch of that name already exists", ConsoleDisplay.Indent(indent), branchName); success = true; } } } if (success) { // Switch to the branch success = CheckOutBranch(branchName, rootWorkingDirectory, indent, debugProgress); } // Switch to the branch } // Create the branch if (success) { Console.WriteLine("{0}Staging to branch \"{1}\"", ConsoleDisplay.Indent(indent + 1), branchName); } else { Console.WriteLine("{0}*** Failed to switch to branch \"{1}\"", ConsoleDisplay.Indent(indent + 1), branchName); } return(success); } // CreateAndSwitchToBranch
public bool GitAdd(string sourceRootDirectory, string rootWorkingDirectory, int indent, CommandOperation.DebugProgress debugProgress) { bool success = false; // PVCS Archive Names start with the Archive Drive which ends at the first slash int firstSlashIndex = Name.IndexOf('\\'); if (firstSlashIndex >= 0) { // Found start of relative path string relativePathAndFilename = Name.Substring(firstSlashIndex + 1); string sourceFileFullPath = Path.Combine(sourceRootDirectory, relativePathAndFilename); if (!File.Exists(sourceFileFullPath)) { Console.WriteLine("{0}*** Source File \"{1}\" does not exist", ConsoleDisplay.Indent(indent), sourceFileFullPath); } else { // Source File exists string workfileFullPath = Path.Combine(rootWorkingDirectory, relativePathAndFilename); if (debugProgress == CommandOperation.DebugProgress.Enabled) { Console.WriteLine("{0}Archive Path \"{1}\" working path resolves to \"{2}\"", ConsoleDisplay.Indent(indent), Name, workfileFullPath); } // Find the last slash to pass to xcopy so that it works with a destination directory int lastSlashIndex = workfileFullPath.LastIndexOf('\\'); string workfileDirectory = workfileFullPath.Substring(0, lastSlashIndex + 1); string fullWorkfilePathAndFilename = Path.Combine(workfileDirectory, this.FileName); // Determine the length of the filename without the drive specifier firstSlashIndex = fullWorkfilePathAndFilename.IndexOf('\\'); string fullRootRelativeWorkfilePathAndFilename = fullWorkfilePathAndFilename.Substring(firstSlashIndex + 1); const int longPathAndFilenameLength = 240; if (fullRootRelativeWorkfilePathAndFilename.Length > longPathAndFilenameLength) { Console.WriteLine("{0}+++ Warning: \"{1}\" workfile name is {2} characters long which is longer than {3} characters", ConsoleDisplay.Indent(indent), fullWorkfilePathAndFilename, fullWorkfilePathAndFilename.Length, longPathAndFilenameLength); } string command = String.Format("xcopy \"{0}\" \"{1}\" /v/f/y", sourceFileFullPath, workfileDirectory); // Copy the file into the working directorBy which will cause the file to be "Staged" if (CommandOperation.RunCommand(rootWorkingDirectory, command, debugProgress, CommandOperation.CommandOutputDisplayType.None)) { DateTime dateTimeNow = DateTime.Now; Console.WriteLine("{0}{1} \"{2}\" -> \"{3}\"", ConsoleDisplay.Indent(indent), dateTimeNow.ToString("yyyy-MM-dd-HH:mm:ss"), sourceFileFullPath, workfileDirectory); // Add the file to the Repo success = GitOperation.Add(rootWorkingDirectory, WorkfileRelativePath(rootWorkingDirectory), indent, debugProgress); } else { DateTime dateTimeNow = DateTime.Now; Console.WriteLine("{0} *** {1} Failed \"{2}\" -> \"{3}\"", ConsoleDisplay.Indent(indent), dateTimeNow.ToString("yyyy-MM-dd-HH:mm:ss"), sourceFileFullPath, workfileDirectory); } } // Source File exists } // Found start of relative path return(success); } // GitAdd