/// <summary> /// Return DiffPosition if match succeeded and throw if match failed /// Throws ArgumentException in case of bad arguments. /// Throws MatchingException. /// </summary> public void Match(DiffRefs refs, string leftPath, string rightPath, int lineNumber, bool isLeftSideLine, out string leftLineNumber, out string rightLineNumber) { int?oppositeLine; try { oppositeLine = getOppositeLine(refs, isLeftSideLine, leftPath, rightPath, lineNumber); } catch (BadPosition) { throw new ArgumentException( String.Format("Bad position: Line Number {0} ({1})", lineNumber, isLeftSideLine ? "Left" : "Right")); } catch (FullContextDiffProviderException ex) { throw new MatchingException("Cannot match lines", ex); } string currentLineAsString = lineNumber.ToString(); string oppositeLineAsString = oppositeLine?.ToString(); leftLineNumber = isLeftSideLine ? currentLineAsString : oppositeLineAsString; rightLineNumber = isLeftSideLine ? oppositeLineAsString : currentLineAsString; }
private MatchResult match(DiffRefs diffRefs, DiffToolInfo difftoolInfo) { FullContextDiffProvider provider = new FullContextDiffProvider(_gitRepository); FullContextDiff context = provider.GetFullContextDiff(diffRefs.LeftSHA, diffRefs.RightSHA, difftoolInfo.Left?.FileName ?? null, difftoolInfo.Right?.FileName ?? null); Debug.Assert(context.Left.Count == context.Right.Count); bool isCurrentSideLeft = difftoolInfo.IsLeftSideCurrent; DiffToolInfo.Side currentSide = isCurrentSideLeft ? difftoolInfo.Left.Value : difftoolInfo.Right.Value; SparsedList <string> firstList = isCurrentSideLeft ? context.Left : context.Right; SparsedList <string> secondList = isCurrentSideLeft ? context.Right : context.Left; SparsedListIterator <string> itFirst = SparsedListUtils.FindNth(firstList.Begin(), currentSide.LineNumber - 1); SparsedListIterator <string> itSecond = SparsedListUtils.Advance(secondList.Begin(), itFirst.Position); return(new MatchResult { LeftLineNumber = isCurrentSideLeft ? currentSide.LineNumber : itSecond.LineNumber + 1, RightLineNumber = isCurrentSideLeft ? itSecond.LineNumber + 1 : currentSide.LineNumber }); }
public DiffPosition(string leftPath, string rightPath, string leftLine, string rightLine, DiffRefs refs) { LeftPath = leftPath; RightPath = rightPath; LeftLine = leftLine; RightLine = rightLine; Refs = refs; }
private void trace(string action, bool isLeftSide, DiffRefs refs, string sourceCurrentName, string sourceOppositeName, string fixedOppositeName) { Trace.TraceInformation(String.Format( "[FileNameMatcher] {0}. Repo: {1}. DiffRefs: {2}\n" + "sourceCurrentName: {3}\nsourceOppositeName: {4}\nfixedOppositeName: {5}\nIsLeftSide: {6}", action, _git.ToString(), refs.ToString(), sourceCurrentName, sourceOppositeName, fixedOppositeName, isLeftSide)); }
/// <summary> /// Throws MatchingException. /// </summary> public bool Match(DiffRefs refs, string originalLeftFileName, string originalRightFileName, bool isLeftSideLine, out string leftFileName, out string rightFileName) { string currentName = isLeftSideLine ? originalLeftFileName : originalRightFileName; string oppositeName = isLeftSideLine ? originalRightFileName : originalLeftFileName; oppositeName = getOppositeName(refs, isLeftSideLine, currentName, oppositeName); leftFileName = isLeftSideLine ? currentName : oppositeName; rightFileName = isLeftSideLine ? oppositeName : currentName; return(oppositeName != null); }
/// <summary> /// Return DiffPosition if match succeeded and throw if match failed /// Throws ArgumentException in case of bad arguments. /// Throws GitOperationException in case of problems with git. /// </summary> public DiffPosition Match(DiffRefs diffRefs, DiffToolInfo difftoolInfo) { if (!difftoolInfo.IsValid()) { throw new ArgumentException( String.Format("Bad diff tool info: {0}", difftoolInfo.ToString())); } MatchResult matchResult = match(diffRefs, difftoolInfo); return(createPosition(matchResult, diffRefs, difftoolInfo)); }
private void getOppositeNameInternal(DiffRefs refs, bool isLeftSide, string sourceCurrentName, out string anotherName, out bool moved) { try { anotherName = _git.RenameDetector.IsRenamed(refs.LeftSHA, refs.RightSHA, sourceCurrentName, isLeftSide, out moved); } catch (FileRenameDetectorException ex) { throw new MatchingException("Cannot detect if a file was renamed", ex); } }
private int?getOppositeLine(DiffRefs refs, bool isLeftSide, string leftFileName, string rightFileName, int lineNumber) { FullContextDiff context = _git.FullContextDiffProvider.GetFullContextDiff( refs.LeftSHA, refs.RightSHA, leftFileName, rightFileName); Debug.Assert(context.Left.Count == context.Right.Count); SparsedList <string> currentList = isLeftSide ? context.Left : context.Right; SparsedList <string> oppositeList = isLeftSide ? context.Right : context.Left; SparsedListIterator <string> itCurrentList = SparsedListUtils.FindNth(currentList.Begin(), lineNumber - 1); SparsedListIterator <string> itOppositeList = SparsedListUtils.Advance(oppositeList.Begin(), itCurrentList.Position); return(itOppositeList.GetLineNumber() == null ? new int?() : itOppositeList.GetLineNumber().Value + 1); }
private DiffPosition createPosition(MatchResult matchResult, DiffRefs diffRefs, DiffToolInfo difftoolInfo) { string leftPath = String.Empty; string rightPath = String.Empty; getPositionPaths(ref difftoolInfo, ref leftPath, ref rightPath); string leftLine = String.Empty; string rightLine = String.Empty; getPositionLines(matchResult, ref leftLine, ref rightLine); DiffPosition position = new DiffPosition { Refs = diffRefs, LeftPath = leftPath, LeftLine = leftLine, RightPath = rightPath, RightLine = rightLine }; return(position); }
/// <summary> /// Throws MatchingException. /// </summary> private string getOppositeName(DiffRefs refs, bool isLeftSide, string sourceCurrentName, string sourceOppositeName) { Debug.Assert(sourceCurrentName != String.Empty); getOppositeNameInternal(refs, isLeftSide, sourceCurrentName, out string anotherName, out bool moved); if (moved) { _onFileMove(sourceCurrentName, anotherName); trace("move", isLeftSide, refs, sourceCurrentName, sourceOppositeName, String.Empty); return(null); } Debug.Assert(anotherName != String.Empty); if (sourceOppositeName == String.Empty) { // nothing at the opposite side if (anotherName != sourceCurrentName) { // wrong match, propose to re-match or consider new/deleted if (_onFileRename(sourceCurrentName, anotherName, isLeftSide ? "deleted" : "new")) { // discard rename. fix up the opposite name to deceive GitLab. trace("rename (continue)", isLeftSide, refs, sourceCurrentName, sourceOppositeName, anotherName); return(anotherName); } else { // user will re-match trace("rename (cancel)", isLeftSide, refs, sourceCurrentName, sourceOppositeName, String.Empty); return(null); } } else { // no rename detected // GitLab expects a non-empty name in this case return(sourceCurrentName); } } else { // opposite side is not empty if (anotherName != sourceCurrentName) { // rename detected if (anotherName == sourceOppositeName) { // manually matched files, perfect match return(sourceOppositeName); } else { // wrong match, propose to re-match if (_onFileRename(sourceCurrentName, anotherName, "modified")) { // discard rename. fix up the opposite name to deceive GitLab. trace("rename (continue)", isLeftSide, refs, sourceCurrentName, sourceOppositeName, anotherName); return(anotherName); } else { // user will re-match trace("rename (cancel)", isLeftSide, refs, sourceCurrentName, sourceOppositeName, String.Empty); return(null); } } } else { // no rename detected if (sourceCurrentName != sourceOppositeName) { // wrong match, propose to re-match if (_onWrongMatch(sourceCurrentName)) { trace("wrong match (continue)", isLeftSide, refs, sourceCurrentName, sourceOppositeName, sourceCurrentName); return(sourceCurrentName); } else { trace("wrong match (cancel)", isLeftSide, refs, sourceCurrentName, sourceOppositeName, String.Empty); return(null); } } else { // it is not a rename but really modified file detected return(sourceOppositeName); } } } }