private void createDummyPlaceHoldersForGitDiff(GitDiffArguments arguments, Comparison comparison, out bool dummyOld, out bool dummyNew) { dummyOld = false; dummyNew = false; foreach (DiffStruct diff in comparison.Diffs) { if (diff.Old_Path == arguments.CommonArgs.Filename1 && diff.New_Path == arguments.CommonArgs.Filename2) { Debug.Assert(!String.IsNullOrEmpty(diff.Old_Path) && !String.IsNullOrEmpty(diff.New_Path)); if (diff.New_File) { dummyOld = createDummyRevision(arguments.CommonArgs.Sha1, diff.Old_Path); dummyNew = false; } else if (diff.Deleted_File) { dummyOld = false; dummyNew = createDummyRevision(arguments.CommonArgs.Sha2, diff.New_Path); } return; } } }
public Task FetchAsync(GitDiffArguments arguments) { try { return(runCommandAndCacheResultAsync(arguments, _cachedDiffs)); } catch (GitCommandServiceInternalException ex) { ExceptionHandlers.Handle(ex.Message, ex); throw new FetchFailedException(ex); } }
public IEnumerable <string> ShowDiff(GitDiffArguments arguments) { try { return(runCommandAndCacheResult(arguments, _cachedDiffs)); } catch (GitCommandServiceInternalException ex) { ExceptionHandlers.Handle(ex.Message, ex); throw new GitNotAvailableDataException(ex); } }
protected override object runCommand(GitDiffArguments arguments) { try { ConvertedArguments converted = _argumentConverter.Convert(arguments); return(startExternalProcess(converted.App, converted.Arguments, _path, true, new int[] { 0, 1 }) .StdOut.Where(x => !String.IsNullOrEmpty(x))); } catch (ArgumentConversionException ex) { throw new GitCommandServiceInternalException(ex); } }
async protected override Task <object> runCommandAsync(GitDiffArguments arguments) { try { ConvertedArguments converted = _argumentConverter.Convert(arguments); IEnumerable <string> result = (await startExternalProcessAsync(converted.App, converted.Arguments, _path, new int[] { 0, 1 })).StdOut; return(result.Where(x => !String.IsNullOrEmpty(x))); } catch (ArgumentConversionException ex) { throw new GitCommandServiceInternalException(ex); } }
public ConvertedArguments Convert(GitDiffArguments arguments) { string baseSha = arguments.CommonArgs.Sha1; string headSha = arguments.CommonArgs.Sha2; throwOnEmptySha(new[] { baseSha, headSha }); throwOnBadFilenamePair(arguments.CommonArgs.Filename1, arguments.CommonArgs.Filename2); Comparison comparison = getComparison(baseSha, headSha); createDummyPlaceHoldersForGitDiff(arguments, comparison, out bool dummyOld, out bool dummyNew); string filename1; string filename2; switch (arguments.Mode) { case GitDiffArguments.DiffMode.Context: filename1 = getFilePath(baseSha, arguments.CommonArgs.Filename1, dummyOld); filename2 = getFilePath(headSha, arguments.CommonArgs.Filename2, dummyNew); break; case GitDiffArguments.DiffMode.ShortStat: filename1 = getPath(baseSha); filename2 = getPath(headSha); break; case GitDiffArguments.DiffMode.NumStat: // Not tested. // NumStat Mode is used to detect renames in GitRepositoryRenameDetector. // FileStorageRenameDetector does not use it. default: throw new NotImplementedException(); } GitDiffArguments modifiedArguments = new GitDiffArguments(arguments.Mode, new GitDiffArguments.CommonArguments(string.Empty, string.Empty, filename1, filename2, arguments.CommonArgs.Filter), arguments.SpecialArgs); return(new ConvertedArguments("git", modifiedArguments.ToString())); }
abstract protected Task <object> runCommandAsync(GitDiffArguments arguments);
abstract protected object runCommand(GitDiffArguments arguments);
async protected override Task <object> runCommandAsync(GitDiffArguments arguments) { return((await startExternalProcessAsync("git", arguments.ToString(), _path, null)).StdOut); }
protected override object runCommand(GitDiffArguments arguments) { return(startExternalProcess("git", arguments.ToString(), _path, true, null).StdOut); }
/// <summary> /// Returns a name of file at the opposite side. /// Throws MatchingException. /// </summary> public string IsRenamed(string leftcommit, string rightcommit, string filename, bool leftsidename, out bool moved) { GitDiffArguments arguments = new GitDiffArguments( GitDiffArguments.DiffMode.NumStat, new GitDiffArguments.CommonArguments(leftcommit, rightcommit, null, null, "R"), null); IEnumerable <string> renames; try { renames = _git?.ShowDiff(arguments); } catch (GitNotAvailableDataException ex) { throw new FileRenameDetectorException("Cannot obtain list of renamed files", ex); } if (renames == null) { throw new FileRenameDetectorException("Cannot obtain list of renamed files", null); } moved = false; foreach (string line in renames) { Match m = diffRenameRe.Match(line); if (!m.Success || m.Groups.Count < 4) { continue; } if (!m.Groups["left_name"].Success || !m.Groups["right_name"].Success) { continue; } Debug.Assert(m.Groups["added"].Success); Debug.Assert(m.Groups["deleted"].Success); int added = int.Parse(m.Groups["added"].Value); int deleted = int.Parse(m.Groups["deleted"].Value); string leftName = m.Groups["left_name"].Value; string rightName = m.Groups["right_name"].Value; if (leftName.Contains('{')) { Debug.Assert(rightName.Contains('}')); int leftPathIdx = leftName.IndexOf('{'); string commonPrefix = leftName.Substring(0, leftPathIdx); string leftPart = leftName.Substring(leftPathIdx + 1, leftName.Length - leftPathIdx - 1); int rightPathIdx = rightName.IndexOf('}'); string commonSuffix = rightName.Substring(rightPathIdx + 1, rightName.Length - rightPathIdx - 1); string rightPart = rightName.Substring(0, rightPathIdx); leftName = commonPrefix + leftPart + commonSuffix; rightName = commonPrefix + rightPart + commonSuffix; } if (leftsidename && leftName == filename) { moved = (added + deleted == 0); return(rightName); } else if (!leftsidename && rightName == filename) { moved = (added + deleted == 0); return(leftName); } } return(filename); }
/// <summary> /// Throws GitDiffAnalyzerException. /// </summary> private IEnumerable <GitDiffSection> getDiffSections(string sha1, string sha2, string filename1, string filename2) { CacheKey key = new CacheKey(sha1, sha2, filename1, filename2); if (_cachedSections.TryGetValue(key, out IEnumerable <GitDiffSection> cachedSections)) { return(cachedSections); } List <GitDiffSection> sections = new List <GitDiffSection>(); GitDiffArguments arguments = new GitDiffArguments( GitDiffArguments.DiffMode.Context, new GitDiffArguments.CommonArguments(sha1, sha2, filename1, filename2, null), new GitDiffArguments.DiffContextArguments(0)); IEnumerable <string> diff; try { diff = _git?.ShowDiff(arguments); } catch (GitNotAvailableDataException ex) { throw new GitDiffAnalyzerException("Cannot obtain git diff", ex); } if (diff == null) { throw new GitDiffAnalyzerException("Cannot obtain git diff", null); } foreach (string line in diff) { Match m = diffSectionRe.Match(line); if (!m.Success || m.Groups.Count < 3) { continue; } if (!m.Groups["left_start"].Success || !m.Groups["right_start"].Success) { continue; } // @@ -1 +1 @@ is essentially the same as @@ -1,1 +1,1 @@ int leftSectionStart = int.Parse(m.Groups["left_start"].Value); int leftSectionLength = m.Groups["left_len"].Success ? int.Parse(m.Groups["left_len"].Value) : 1; int rightSectionStart = int.Parse(m.Groups["right_start"].Value); int rightSectionLength = m.Groups["right_len"].Success ? int.Parse(m.Groups["right_len"].Value) : 1; GitDiffSection section = new GitDiffSection( leftSectionStart, leftSectionStart + leftSectionLength, rightSectionStart, rightSectionStart + rightSectionLength); sections.Add(section); } _cachedSections.Add(key, sections); return(sections); }
/// <summary> /// Throws FullContextDiffProviderException. /// </summary> public FullContextDiff GetFullContextDiff(string leftSHA, string rightSHA, string leftFileName, string rightFileName) { CacheKey key = new CacheKey(leftSHA, rightSHA, leftFileName, rightFileName); if (_cachedContexts.TryGetValue(key, out FullContextDiff context)) { return(context); } FullContextDiff fullContextDiff = new FullContextDiff(new SparsedList <string>(), new SparsedList <string>()); GitDiffArguments arguments = new GitDiffArguments( GitDiffArguments.DiffMode.Context, new GitDiffArguments.CommonArguments(leftSHA, rightSHA, leftFileName, rightFileName, null), new GitDiffArguments.DiffContextArguments(Constants.FullContextSize)); IEnumerable <string> fullDiff; try { fullDiff = _git?.ShowDiff(arguments); } catch (GitNotAvailableDataException ex) { throw new FullContextDiffProviderException("Cannot obtain git diff", ex); } if (fullDiff == null) { throw new FullContextDiffProviderException("Cannot obtain git diff", null); } if (fullDiff.Count() == 0) { Trace.TraceWarning(String.Format( "[FullContextDiffProvider] Context size is zero. LeftSHA: {0}, Right SHA: {1}, Left file: {2}, Right file: {3}", leftSHA, rightSHA, leftFileName, rightFileName)); } bool skip = true; foreach (string line in fullDiff) { char sign = line[0]; if (skip) { // skip meta information about diff if (sign == '@') { // next lines should not be skipped because they contain a diff itself skip = false; } continue; } string lineOrig = line.Substring(1, line.Length - 1); switch (sign) { case '-': fullContextDiff.Left.Add(lineOrig); fullContextDiff.Right.Add(null); break; case '+': fullContextDiff.Left.Add(null); fullContextDiff.Right.Add(lineOrig); break; case ' ': fullContextDiff.Left.Add(lineOrig); fullContextDiff.Right.Add(lineOrig); break; } } _cachedContexts.Add(key, fullContextDiff); return(fullContextDiff); }