/// <summary> /// Pulls versions /// </summary> /// <param name="git2vaultRepoPath">Key=git, Value=vault</param> /// <param name="limitCount"></param> /// <param name="restartLimitCount"></param> /// <returns></returns> public bool Pull(IEnumerable<KeyValuePair<string, string>> git2vaultRepoPath, long limitCount, long restartLimitCount) { int ticks = 0; //get git current branch name ticks += this.gitCurrentBranch(out OriginalGitBranch); Console.WriteLine("Starting git branch is {0}", OriginalGitBranch); //reorder target branches to start from current branch, so don't need to do checkout for first branch var targetList = git2vaultRepoPath.OrderByDescending(p => p.Key.Equals(OriginalGitBranch, StringComparison.CurrentCultureIgnoreCase)); ticks += vaultLogin(); if (!IsSetRootVaultWorkingFolder()) { Environment.Exit(1); } try { foreach (var pair in targetList) { var gitBranch = pair.Key; var vaultRepoPath = pair.Value; Console.WriteLine("\nProcessing git branch {0}", gitBranch); long currentGitVaultVersion = 0; //reset ticks ticks = 0; if (restartLimitCount > 0) { //get current version ticks += gitVaultVersion(gitBranch, restartLimitCount, ref currentGitVaultVersion); } else { currentGitVaultVersion = 0; } //get vaultVersions IDictionary<long, VaultVersionInfo> vaultVersions = new SortedList<long, VaultVersionInfo>(); ticks += this.vaultPopulateInfo(vaultRepoPath, vaultVersions); var versionsToProcess = vaultVersions.Where(p => p.Key > currentGitVaultVersion); //do init only if there is something to work on if (versionsToProcess.Count() > 0) ticks += Init(vaultRepoPath, gitBranch); //report init if (null != Progress) if (Progress(ProgressSpecialVersionInit, ticks)) return true; var counter = 0; foreach (var version in versionsToProcess) { ticks = Environment.TickCount; // Obtain just the ChangeSet for this Version of the repo TxInfo txnInfo = null; try { if (ForceFullFolderGet) { throw new FileNotFoundException( "Forcing full folder get"); } // Get a list of the changed files txnInfo = ServerOperations.ProcessCommandTxDetail(version.Value.TrxId); foreach (VaultTxDetailHistoryItem txdetailitem in txnInfo.items) { // Do deletions, renames and moves ourselves if (txdetailitem.RequestType == VaultRequestType.Delete) { // Convert the Vault path to a file system path String ItemPath1 = String.Copy( txdetailitem.ItemPath1 ); // Ensure the file is within the folder we are working with. if (ItemPath1.StartsWith(vaultRepoPath, true, System.Globalization.CultureInfo.CurrentCulture)) { ItemPath1 = ItemPath1.Replace(vaultRepoPath, WorkingFolder, StringComparison.CurrentCultureIgnoreCase); ItemPath1 = ItemPath1.Replace('/', '\\'); if (File.Exists(ItemPath1)) { File.Delete(ItemPath1); } if (Directory.Exists(ItemPath1)) { Directory.Delete(ItemPath1, true); } } continue; } else if (txdetailitem.RequestType == VaultRequestType.Move || txdetailitem.RequestType == VaultRequestType.Rename) { ProcessFileItem(vaultRepoPath, WorkingFolder, txdetailitem, true); continue; } else if (txdetailitem.RequestType == VaultRequestType.Share) { ProcessFileItem(vaultRepoPath, WorkingFolder, txdetailitem, false); continue; } else if (txdetailitem.RequestType == VaultRequestType.AddFolder) { // Git doesn't add empty folders continue; } else if (txdetailitem.RequestType == VaultRequestType.CopyBranch) { // Nothing in a CopyBranch to do. Its just a place marker continue; } // Shared file changes may be checked in as a file that's in a different vault tree, // so throw an exception to cause whole tree to be refreshed. if (txdetailitem.ItemPath1.StartsWith(vaultRepoPath, true, System.Globalization.CultureInfo.CurrentCulture)) { // Apply the changes from vault of the correct version for this file vaultGetFile(vaultRepoPath, txdetailitem); } else { if (Verbose) Console.WriteLine("{0} is outside current branch; getting whole folder", txdetailitem.ItemPath1); throw new FileNotFoundException( "Source file is outside the current branch: " + txdetailitem.ItemPath1); } if (File.Exists(vaultRepoPath)) { // // Remove Source Code Control // //change all sln files if (txdetailitem.ItemPath1.EndsWith("sln", true, System.Globalization.CultureInfo.CurrentCulture)) { removeSCCFromSln(txdetailitem.ItemPath1); } //change all csproj files if (txdetailitem.ItemPath1.EndsWith("csproj", true, System.Globalization.CultureInfo.CurrentCulture)) { removeSCCFromCSProj(txdetailitem.ItemPath1); } //change all vdproj files if (txdetailitem.ItemPath1.EndsWith("vdproj", true, System.Globalization.CultureInfo.CurrentCulture)) { removeSCCFromVDProj(txdetailitem.ItemPath1); } } } } catch (Exception e) { // If an exception is thrown, presume its because a file has been requested which no longer exists in the tip of the repository. // That is, the file has been moved, renamed or deleted. // It may be accurate to search the txn details in above loop for request types of moved, renamed or deleted and // if one is found, execute this code rather than waiting for the exception. Just not sure that it will find everything. But // I know this code works, though it is much slower for repositories with a large number of files in each Version. Also, all the // files that have been retrieved from the Server will still be in the client-side cache so the GetFile above is not wasted. // If we did not need this code then we would not need to use the Working Directory which would be a cleaner solution. try { vaultGetFolder(vaultRepoPath, version.Key, version.Value.TrxId); //change all sln files Directory.GetFiles( WorkingFolder, "*.sln", SearchOption.AllDirectories) //remove temp files created by vault .Where(f => !f.Contains("~")) .ToList() .ForEach(f => ticks += removeSCCFromSln(f)); //change all csproj files Directory.GetFiles( WorkingFolder, "*.csproj", SearchOption.AllDirectories) //remove temp files created by vault .Where(f => !f.Contains("~")) .ToList() .ForEach(f => ticks += removeSCCFromCSProj(f)); //change all vdproj files Directory.GetFiles( WorkingFolder, "*.vdproj", SearchOption.AllDirectories) //remove temp files created by vault .Where(f => !f.Contains("~")) .ToList() .ForEach(f => ticks += removeSCCFromVDProj(f)); } catch (System.Exception) { string errorStr = "Could not get txn details. Got exception: " + e.Message; throw new Exception("Cannot get transaction details for " + version.Value.TrxId); } } ticks = Environment.TickCount - ticks; //get vault version info var info = vaultVersions[version.Key]; if (Pause) { Console.WriteLine("Pause before commit. Enter to continue."); Console.ReadLine(); } //commit ticks += gitCommit(info.Login, info.TrxId, this.GitDomainName, buildCommitMessage(vaultRepoPath, version.Key, info), info.TimeStamp); if (null != Progress) if (Progress(version.Key, ticks)) return true; counter++; //call gc if (0 == counter%GitGCInterval) { ticks = gitGC(); if (null != Progress) if (Progress(ProgressSpecialVersionGc, ticks)) return true; } //check if limit is reached if (counter >= limitCount) break; } if (versionsToProcess.Count() > 0) { ticks = vaultFinalize(vaultRepoPath); } } } finally { Console.WriteLine("\n"); //complete ticks += vaultLogout(); //finalize git (update server info for dumb clients) ticks += gitFinalize(); if (null != Progress) Progress(ProgressSpecialVersionFinalize, ticks); } return false; }
/// <summary> /// Pulls versions /// </summary> /// <param name="git2vaultRepoPath">Key=git, Value=vault</param> /// <param name="limitCount"></param> /// <returns></returns> public bool Pull(IEnumerable<KeyValuePair<string,string>> git2vaultRepoPath, long limitCount) { int ticks = 0; //get git current branch string gitCurrentBranch; ticks += this.gitCurrentBranch(out gitCurrentBranch); //reorder target branches to start from current (to avoid checkouts) var targetList = git2vaultRepoPath.OrderByDescending(p => p.Key.Equals(gitCurrentBranch, StringComparison.CurrentCultureIgnoreCase)); ticks += vaultLogin(); try { foreach (var pair in targetList) { var gitBranch = pair.Key; var vaultRepoPath = pair.Value; long currentGitVaultVersion = 0; //reset ticks ticks = 0; //get current version ticks += gitVaultVersion(gitBranch, ref currentGitVaultVersion); //get vaultVersions IDictionary<long, VaultVersionInfo> vaultVersions = new SortedList<long, VaultVersionInfo>(); ticks += this.vaultPopulateInfo(vaultRepoPath, vaultVersions); var versionsToProcess = vaultVersions.Where(p => p.Key > currentGitVaultVersion); //do init only if there is something to work on if (versionsToProcess.Count() > 0) ticks += Init(vaultRepoPath, gitBranch); //report init if (null != Progress) if (Progress(ProgressSpecialVersionInit, ticks)) return true; var counter = 0; foreach (var version in versionsToProcess) { //get vault version ticks = vaultGet(vaultRepoPath, version.Key, version.Value.TrxId); //change all sln files Directory.GetFiles( WorkingFolder, "*.sln", SearchOption.AllDirectories) //remove temp files created by vault .Where(f => !f.Contains("~")) .ToList() .ForEach(f => ticks += removeSCCFromSln(f)); //change all csproj files Directory.GetFiles( WorkingFolder, "*.csproj", SearchOption.AllDirectories) //remove temp files created by vault .Where(f => !f.Contains("~")) .ToList() .ForEach(f => ticks += removeSCCFromCSProj(f)); //change all vdproj files Directory.GetFiles( WorkingFolder, "*.vdproj", SearchOption.AllDirectories) //remove temp files created by vault .Where(f => !f.Contains("~")) .ToList() .ForEach(f => ticks += removeSCCFromVDProj(f)); //get vault version info var info = vaultVersions[version.Key]; //commit ticks += gitCommit(info.Login, info.TrxId, this.GitDomainName, buildCommitMessage(vaultRepoPath, version.Key, info), info.TimeStamp); if (null != Progress) if (Progress(version.Key, ticks)) return true; counter++; //call gc if (0 == counter%GitGCInterval) { ticks = gitGC(); if (null != Progress) if (Progress(ProgressSpecialVersionGc, ticks)) return true; } //check if limit is reached if (counter >= limitCount) break; } ticks = vaultFinalize(vaultRepoPath); } } finally { //complete ticks += vaultLogout(); //finalize git (update server info for dumb clients) ticks += gitFinalize(); if (null != Progress) Progress(ProgressSpecialVersionFinalize, ticks); } return false; }
/// <summary> /// Pulls versions /// </summary> /// <param name="git2VaultRepoPath">Key=git, Value=vault</param> /// <param name="limitCount"></param> /// <returns></returns> public bool Pull(IEnumerable<KeyValuePair<string, string>> git2VaultRepoPath, long limitCount) { int ticks = 0; //get git current branch string gitCurrentBranch; ticks += _gitProcessor.GitCurrentBranch(GitCmd, WorkingFolder, out gitCurrentBranch); //reorder target branches to start from current (to avoid checkouts) var targetList = git2VaultRepoPath.OrderByDescending(p => p.Key.Equals(gitCurrentBranch, StringComparison.CurrentCultureIgnoreCase)); ticks += VaultLogin(); try { foreach (var pair in targetList) { _logger.Debug(String.Format("...handling ... {0} and {1}", pair.Key, pair.Value)); var gitBranch = pair.Key; var vaultRepoPath = pair.Value; long currentGitVaultVersion; //reset ticks ticks = 0; //get current version ticks += GitVaultVersion(gitBranch, out currentGitVaultVersion); //get vaultVersions IDictionary<long, VaultVersionInfo> vaultVersions = new SortedList<long, VaultVersionInfo>(); ticks += VaultPopulateInfo(vaultRepoPath, vaultVersions); var versionsToProcess = vaultVersions.Where(p => p.Key > currentGitVaultVersion).ToList(); //do init only if there is something to work on if (versionsToProcess.Any()) { ticks += Init(vaultRepoPath, gitBranch); } //report init if (null != Progress) if (Progress(PROGRESS_SPECIAL_VERSION_INIT, ticks)) return true; var counter = 0; foreach (var version in versionsToProcess) { _logger.Info(string.Format("performing actions for version: {0}", version.Key)); //get vault version ticks = VaultGet(vaultRepoPath, version.Key, version.Value.TrxId); _logger.Trace(string.Format("modifying all sln files for version: {0}", version.Key)); //change all sln files Directory.GetFiles( WorkingFolder, "*.sln", SearchOption.AllDirectories) //remove temp files created by vault .Where(f => !f.Contains("~")) .ToList() .ForEach(f => ticks += RemoveSccFromSln(f)); _logger.Trace(string.Format("modifying all CSPROJ files for version: {0}", version.Key)); //change all csproj files Directory.GetFiles( WorkingFolder, "*.csproj", SearchOption.AllDirectories) //remove temp files created by vault .Where(f => !f.Contains("~")) .ToList() .ForEach(f => ticks += RemoveSccFromCsProj(f)); _logger.Trace(string.Format("modifying all VDPROJ files for version: {0}", version)); //change all vdproj files Directory.GetFiles( WorkingFolder, "*.vdproj", SearchOption.AllDirectories) //remove temp files created by vault .Where(f => !f.Contains("~")) .ToList() .ForEach(f => ticks += RemoveSccFromVdProj(f)); //get vault version info var info = vaultVersions[version.Key]; //commit _logger.Trace("committing to git version: " + version.Key); ticks += GitCommit(info.Login, info.TrxId, GitDomainName, BuildCommitMessage(vaultRepoPath, version.Key, info), info.TimeStamp); if (null != Progress) if (Progress(version.Key, ticks)) return true; counter++; //call gc if (0 == counter%GitGarbageCollectionInterval) { _logger.Debug(String.Format("interval {0} reached. calling garbage collector", GitGarbageCollectionInterval)); ticks = _gitProcessor.GitTriggerGarbageCollection(GitCmd, WorkingFolder); if (null != Progress) if (Progress(PROGRESS_SPECIAL_VERSION_GC, ticks)) return true; } //check if limit is reached if (counter >= limitCount) { _logger.Info("limit reached. exiting..."); break; } } ticks = VaultFinalize(vaultRepoPath); } } finally { //complete ticks += VaultLogout(); //finalize git (update server info for dumb clients) ticks += _gitProcessor.GitFinalize(GitCmd, WorkingFolder); if (null != Progress) Progress(PROGRESS_SPECIAL_VERSION_FINALIZE, ticks); } return false; }