private string GetMapping(VaultVersionInfo info) { string key = info.Branch + ":"; if (info.TxId != 0) { key += info.TxId; } if (_txidMappings == null || _txidMappings.Count == 0) //Reload from file { _txidMappings = Tools.ReadFromXml(MappingSaveLocation)?.ToDictionary(kp => kp.Key, kp => kp.Value) ?? new Dictionary <string, string>(); } if (!_txidMappings.ContainsKey(key)) { // Rebuild mapping from git Console.WriteLine($"Missing an entry for key {key}, trying to rebuild mapping from git repository..."); _txidMappings = RebuildMapping(); if (!_txidMappings.ContainsKey(key)) { if (!(info.TxId == 0) | !(_txidMappings.Where(k => k.Key.StartsWith(key)).Any())) { // can't find it - the branch was probably deleted in vault // default to branch off of current state of master key = "master:"; } key = _txidMappings.Where(k => k.Key.StartsWith(key)).FirstOrDefault().Key; } } return(_txidMappings[key]); }
private VaultVersionInfo getVaultVersionFromGitLogMessage(string[] msg, ref VaultVersionInfo info) { //get last string var stringToParse = msg.Last(); //search for version tag var versionString = stringToParse.Split(new string[] { VaultTag }, StringSplitOptions.None).LastOrDefault(); if (null == versionString) { return(info); } //parse path reporepoPath@branch/TxId/version var version = versionString.Split('@'); var versionTrxTag = version.LastOrDefault(); if (null == versionTrxTag) { return(info); } //get version string[] tag = versionTrxTag.Split('/'); if (tag.Count() > 2) { info.Branch = tag[0]; long.TryParse(tag[1], out info.Version); long.TryParse(tag[2], out info.TxId); } return(info); }
private int gitCreateBranch(VaultVersionInfo info, out string currentBranch) { /* get vault items (itempath1/itempath2) * filter by itempath2 = branchpath * get source branch from end of itempath1 * get hash of latest commit in the identified branch * use the hash as the source of the branch */ TxInfo txDetail = ServerOperations.ProcessCommandTxDetail(info.TxId); string sourceBranch; var items = txDetail.items.Where(i => (i.ItemPath2 == info.Path || info.Path.StartsWith(i.ItemPath2 + "/"))); if (items.Count() > 0) { sourceBranch = items.FirstOrDefault().ItemPath1.Split('/').LastOrDefault(); } else { sourceBranch = "master:"; } string gitStartPoint = GetMapping(new VaultVersionInfo { Branch = Tools.GetBranchMapping(sourceBranch), TxId = 0 }); string[] msgs; int ticks = runGitCommand(string.Format(_gitCreateBranch, info.Branch, gitStartPoint), string.Empty, out msgs); currentBranch = info.Branch; return(ticks); }
private string buildCommitMessage(string repoPath, long version, VaultVersionInfo info) { //parse path repo$RepoPath@version/trx var r = new StringBuilder(info.Comment); r.AppendLine(); r.AppendFormat("{4} {0}{1}@{2}/{3}", this.VaultRepository, repoPath, version, info.TrxId, VaultTag); r.AppendLine(); return(r.ToString()); }
private string buildCommitMessage(VaultVersionInfo info) { //parse path repo$RepoPath@branch/version/trx var r = new StringBuilder(info.Comment); r.AppendLine(); r.AppendFormat("{4} {0}{1}@{5}/{2}/{3}", this.VaultRepository, info.Path, info.Version, info.TxId, VaultTag, info.Branch); r.AppendLine(); return(r.ToString()); }
private int gitVaultVersion(ref VaultVersionInfo currentVersion) { string[] msgs; //get info var ticks = gitLog(out msgs); //get vault version getVaultVersionFromGitLogMessage(msgs, ref currentVersion); return(ticks); }
private int vaultGet(VaultVersionInfo info) { var ticks = Environment.TickCount; //apply version to the repo folder GetOperations.ProcessCommandGetVersion( info.Path, Convert.ToInt32(info.Version), new GetOptions() { MakeWritable = MakeWritableType.MakeAllFilesWritable, Merge = MergeType.OverwriteWorkingCopy, OverrideEOL = VaultEOL.None, //remove working copy does not work -- bug http://support.sourcegear.com/viewtopic.php?f=5&t=11145 PerformDeletions = PerformDeletionsType.RemoveWorkingCopy, SetFileTime = SetFileTimeType.Modification, Recursive = true }); //now process deletions, moves, and renames (due to vault bug) var allowedRequests = new int[] { 9, //delete 12, //move 15 //rename }; foreach (var item in ServerOperations.ProcessCommandTxDetail(info.TxId).items .Where(i => allowedRequests.Contains(i.RequestType))) { //delete file //check if it is within current branch, but ignore if it equals the branch if (item.ItemPath1.StartsWith(info.Path, StringComparison.CurrentCultureIgnoreCase) && !item.ItemPath1.Equals(info.Path, StringComparison.CurrentCultureIgnoreCase)) { var pathToDelete = Path.Combine(this.WorkingFolder, item.ItemPath1.Substring(info.Path.Length + 1)); //Console.WriteLine("delete {0} => {1}", item.ItemPath1, pathToDelete); if (File.Exists(pathToDelete)) { File.Delete(pathToDelete); } if (Directory.Exists(pathToDelete)) { Directory.Delete(pathToDelete, true); } } } return(Environment.TickCount - ticks); }
private void AddMapping(VaultVersionInfo info, string git) { string key = info.Branch + ":" + info.TxId; if (_txidMappings == null || _txidMappings.Count == 0) //Reload from file { _txidMappings = Tools.ReadFromXml(MappingSaveLocation)?.ToDictionary(kp => kp.Key, kp => kp.Value) ?? new Dictionary <string, string>(); } if (_txidMappings.ContainsKey(key)) { var formerValue = _txidMappings[key]; _txidMappings[key] = git; Console.WriteLine($"Updated value for existing key {key} from {formerValue} to {git}."); } _txidMappings.Add(new KeyValuePair <string, string>(key, git)); Tools.SaveMapping(_txidMappings, MappingSaveLocation); }
private int Init(VaultVersionInfo info, ref string gitCurrentBranch) { //set vault working folder int ticks = setVaultWorkingFolder(info.Path); bool branchExists = false; //verify git branch exists - create if needed ticks += gitVerifyBranchExists(info.Branch, out branchExists); if (branchExists) { if (!gitCurrentBranch.Equals(info.Branch, StringComparison.OrdinalIgnoreCase)) { ticks += this.gitCheckoutBranch(info.Branch, out gitCurrentBranch); } } else { ticks += gitCreateBranch(info, out gitCurrentBranch); } return(ticks); }
private int gitCreateRepo() { string[] msgs; int ticks = runGitCommand(_gitInitCmd, string.Empty, out msgs); if (!msgs[0].StartsWith("Initialized empty Git repository")) { throw new InvalidOperationException("The local git repository doesn't exist and can't be created."); } //add .gitignore and .gitattributes Tools.CopyFile("Resources\\.gitignore", WorkingFolder + ".gitignore"); Tools.CopyFile("Resources\\.gitattributes", WorkingFolder + ".gitattributes"); ticks += runGitCommand(_gitAddCmd, string.Empty, out msgs); Dictionary <string, string> env = new Dictionary <string, string>(); env.Add("GIT_COMMITTER_DATE", DateTime.Parse(RevisionStartDate).ToString("yyyy-MM-ddTHH:mm:ss.fff")); ticks += runGitCommand(string.Format(_gitInitInitalCommitCmd, DateTime.Parse(RevisionStartDate).ToString("yyyy-MM-ddTHH:mm:ss.fff"), VaultTag), string.Empty, out msgs, env); if (msgs.Any()) { string gitCommitId = msgs[0].Split(' ')[2]; gitCommitId = gitCommitId.Substring(0, gitCommitId.Length - 1); VaultVersionInfo info = new VaultVersionInfo { Branch = "Master", TxId = 0 }; AddMapping(info, gitCommitId); } return(ticks); }
private int gitCommit(VaultVersionInfo info, string gitDomainName, string vaultCommitMessage) { string gitCurrentBranch; string gitName; string gitEmail; string gitAuthor; string commitTimeStamp; this.gitCurrentBranch(out gitCurrentBranch); string[] msgs; var ticks = runGitCommand(_gitAddCmd, string.Empty, out msgs); if (SkipEmptyCommits) { //checking status ticks += runGitCommand( _gitStatusCmd, string.Empty, out msgs ); if (!msgs.Any()) { return(ticks); } } gitAuthor = Tools.GetGitAuthor(info.Login); if (gitAuthor != null) { gitName = gitAuthor.Split(':')[0]; gitEmail = gitAuthor.Split(':')[1]; } else { gitName = info.Login; gitEmail = info.Login + '@' + gitDomainName; } commitTimeStamp = info.TimeStamp.GetDateTime().ToString("yyyy-MM-ddTHH:mm:ss"); Dictionary <string, string> env = new Dictionary <string, string>(); env.Add("GIT_COMMITTER_DATE", commitTimeStamp); env.Add("GIT_COMMITTER_NAME", gitName); env.Add("GIT_COMMITTER_EMAIL", gitEmail); ticks += runGitCommand( string.Format(_gitCommitCmd, gitName, gitEmail, string.Format("{0:s}", commitTimeStamp)), vaultCommitMessage, out msgs, env ); // Mapping Vault Transaction ID to Git Commit SHA-1 Hash if (msgs[0].StartsWith("[" + gitCurrentBranch)) { string gitCommitId = msgs[0].Split(' ')[1]; gitCommitId = gitCommitId.Substring(0, gitCommitId.Length - 1); AddMapping(info, gitCommitId); } return(ticks); }
/// <summary> /// Pulls versions /// </summary> /// <param name="git2vaultRepoPath">Key=git, Value=vault</param> /// <param name="limitCount"></param> /// <returns></returns> public bool Pull(List <string> git2vaultRepoPath, long limitCount) { var completedStepCount = 0; var versionProcessingTime = new Stopwatch(); var overallProcessingTime = new Stopwatch(); int ticks = 0; //load git authors Tools.ParseMapFile(AuthorMapPath); //create git repo if doesn't exist, otherwise, rebuild vault to git mappings from log if (!File.Exists(WorkingFolder + ".git/config")) { ticks += gitCreateRepo(); } else { RebuildMapping(); } //get git current branch string gitCurrentBranch; ticks += this.gitCurrentBranch(out gitCurrentBranch); ticks += vaultLogin(); try { //reset ticks ticks = 0; List <string> vaultRepoPaths = git2vaultRepoPath; VaultVersionInfo currentGitVaultVersion = new VaultVersionInfo { Branch = string.Empty, Comment = string.Empty, Login = string.Empty, Path = string.Empty, TimeStamp = VaultLib.VaultDateTime.MinValue, TxId = 0, Version = 0 }; //get current version ticks += gitVaultVersion(ref currentGitVaultVersion); //get vaultVersions Console.Write($"Fetching history from vault from {RevisionStartDate} to {RevisionEndDate}... "); IDictionary <string, VaultVersionInfo> vaultVersions = new SortedList <string, VaultVersionInfo>(); foreach (string rp in vaultRepoPaths) { ticks += vaultPopulateInfo(rp, vaultVersions); } var gitProgress = vaultVersions.Where(p => (p.Value.Branch == currentGitVaultVersion.Branch && p.Value.TxId == currentGitVaultVersion.TxId)); var versionsToProcess = gitProgress.Any() ? vaultVersions.Where(p => (p.Key.CompareTo(gitProgress.FirstOrDefault().Value.TimeStamp.GetDateTime().ToString("yyyy-MM-ddTHH:mm:ss.fff") + ":" + gitProgress.FirstOrDefault().Value.Branch) > 0)) : vaultVersions; var keyValuePairs = versionsToProcess.ToList(); Console.WriteLine($"done! Fetched {keyValuePairs.Count} versions for processing."); //report init if (null != Progress) { if (Progress(ProgressSpecialVersionInit, 0L, ticks)) { return(true); } } var counter = 0; overallProcessingTime.Restart(); foreach (var version in keyValuePairs) { versionProcessingTime.Restart(); ticks = 0; ticks = Init(version.Value, ref gitCurrentBranch); //check to see if we are in the correct branch if (!gitCurrentBranch.Equals(version.Value.Branch, StringComparison.OrdinalIgnoreCase)) { ticks += this.gitCheckoutBranch(version.Value.Branch, out gitCurrentBranch); } //get vault version Console.Write($"Starting get version {version.Key} from Vault..."); ticks += vaultGet(version.Value); Console.WriteLine($" done!"); //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 VaultVersionInfo info = vaultVersions[version.Key]; //commit Console.Write($"Starting git commit..."); ticks += gitCommit(info, GitDomainName, buildCommitMessage(info)); Console.WriteLine($" done!"); if (null != Progress) { if (Progress(info.Version, keyValuePairs.Count, ticks)) { return(true); } } counter++; //call gc if (0 == counter % GitGCInterval) { ticks = gitGC(); if (null != Progress) { if (Progress(ProgressSpecialVersionGc, keyValuePairs.Count, ticks)) { return(true); } } } //check if limit is reached if (counter >= limitCount) { break; } completedStepCount++; versionProcessingTime.Stop(); Tools.WriteProgressInfo(string.Empty, versionProcessingTime.Elapsed, completedStepCount, keyValuePairs.Count, overallProcessingTime.Elapsed); } ticks = vaultFinalize(vaultRepoPaths); } finally { //complete //ticks += vaultLogout(); // Drops log-out as it kills the Native allocations //finalize git (update server info for dumb clients) ticks += gitFinalize(); if (null != Progress) { Progress(ProgressSpecialVersionFinalize, 0L, ticks); } } return(false); }