comparison src/org/tmatesoft/hg/repo/HgBlameFacility.java @ 557:b9e5ac26dd83

Annotate: Line annotation needs true line position from merged blocks; test-annotate repo updated to show elements from both parents in the merged revision
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Sun, 24 Feb 2013 00:11:40 +0100
parents e55f17a7a195
children 154718ae23ed
comparison
equal deleted inserted replaced
556:e55f17a7a195 557:b9e5ac26dd83
440 if (p2MergeCommon != null) { 440 if (p2MergeCommon != null) {
441 mergeRanges.clear(); 441 mergeRanges.clear();
442 p2MergeCommon.combineAndMarkRangesWithTarget(s2From, s2To - s2From, csetOrigin, csetMergeParent, mergeRanges); 442 p2MergeCommon.combineAndMarkRangesWithTarget(s2From, s2To - s2From, csetOrigin, csetMergeParent, mergeRanges);
443 443
444 /* 444 /*
445 * Usecases: 445 * Usecases, how it USED TO BE initially:
446 * 3 lines changed to 10 lines. range of 10 lines breaks down to 2 from p2, 3 from p1, and 5 from p2. 446 * 3 lines changed to 10 lines. range of 10 lines breaks down to 2 from p2, 3 from p1, and 5 from p2.
447 * We report: 2 lines changed to 2(p2), then 1 line changed with 3(p1) and 5 lines added from p2. 447 * We report: 2 lines changed to 2(p2), then 1 line changed with 3(p1) and 5 lines added from p2.
448 * 448 *
449 * 10 lines changed to 3 lines, range of 3 lines breaks down to 2 line from p1 and 1 line from p2. 449 * 10 lines changed to 3 lines, range of 3 lines breaks down to 2 line from p1 and 1 line from p2.
450 * We report: 2 lines changed to 2(p1) and 8 lines changed to 1(p2) 450 * We report: 2 lines changed to 2(p1) and 8 lines changed to 1(p2)
451 *
452 * NOW, lines from p2 are always reported as pure add (since we need their insertion point to be in p2, not in p1)
453 * and we try to consume p1 changes as soon as we see first p1's range
451 */ 454 */
452 int s1TotalLines = s1To - s1From, s1ConsumedLines = 0, s1Start = s1From; 455 int s1TotalLines = s1To - s1From, s1ConsumedLines = 0, s1Start = s1From;
453 456
454 for (int i = 0; i < mergeRanges.size(); i += 3) { 457 for (int i = 0; i < mergeRanges.size(); i += 3) {
455 final int rangeOrigin = mergeRanges.get(i); 458 final int rangeOrigin = mergeRanges.get(i);
456 final int rangeStart = mergeRanges.get(i+1); 459 final int rangeStart = mergeRanges.get(i+1);
457 final int rangeLen = mergeRanges.get(i+2); 460 final int rangeLen = mergeRanges.get(i+2);
458 final boolean lastRange = i+3 >= mergeRanges.size(); 461 final boolean lastRange = i+3 >= mergeRanges.size();
459 final int s1LinesLeft = s1TotalLines - s1ConsumedLines; 462 final int s1LinesLeft = s1TotalLines - s1ConsumedLines;
460 // how many lines we may reported as changed (don't use more than in range unless it's the very last range) 463 // how many lines we may report as changed (don't use more than in range unless it's the very last range)
461 final int s1LinesToBorrow = lastRange ? s1LinesLeft : Math.min(s1LinesLeft, rangeLen); 464 final int s1LinesToBorrow = lastRange ? s1LinesLeft : Math.min(s1LinesLeft, rangeLen);
462 if (s1LinesToBorrow > 0) { 465 if (rangeOrigin != csetMergeParent && s1LinesToBorrow > 0) {
463 ChangeBlockImpl block = getChangeBlock(s1Start, s1LinesToBorrow, rangeStart, rangeLen); 466 ChangeBlockImpl block = getChangeBlock(s1Start, s1LinesToBorrow, rangeStart, rangeLen);
464 block.setOriginAndTarget(rangeOrigin, csetTarget); 467 block.setOriginAndTarget(rangeOrigin, csetTarget);
465 insp.changed(block); 468 insp.changed(block);
466 s1ConsumedLines += s1LinesToBorrow; 469 s1ConsumedLines += s1LinesToBorrow;
467 s1Start += s1LinesToBorrow; 470 s1Start += s1LinesToBorrow;
468 } else { 471 } else {
469 ChangeBlockImpl block = getAddBlock(rangeStart, rangeLen, s1Start); 472 int blockInsPoint = rangeOrigin != csetMergeParent ? s1Start : p2MergeCommon.reverseMapLine(rangeStart);
473 ChangeBlockImpl block = getAddBlock(rangeStart, rangeLen, blockInsPoint);
470 block.setOriginAndTarget(rangeOrigin, csetTarget); 474 block.setOriginAndTarget(rangeOrigin, csetTarget);
471 insp.added(block); 475 insp.added(block);
472 } 476 }
473 } 477 }
474 if (s1ConsumedLines != s1TotalLines) { 478 if (s1ConsumedLines != s1TotalLines) {
475 throw new HgInvalidStateException(String.format("Expected to process %d lines, but actually was %d", s1TotalLines, s1ConsumedLines)); 479 assert s1ConsumedLines < s1TotalLines : String.format("Expected to process %d lines, but actually was %d", s1TotalLines, s1ConsumedLines);
480 // either there were no ranges from p1, whole s2From..s2To range came from p2, shall report as deleted
481 // or the ranges found were not enough to consume whole s2From..s2To
482 // The "deletion point" is shifted to the end of last csetOrigin->csetTarget change
483 int s2DeletePoint = s2From + s1ConsumedLines;
484 ChangeBlockImpl block = new ChangeBlockImpl(annotatedRevision.origin, null, s1Start, s1To - s1Start, -1, -1, -1, s2DeletePoint);
485 block.setOriginAndTarget(csetOrigin, csetTarget);
486 insp.deleted(block);
476 } 487 }
477 } else { 488 } else {
478 ChangeBlockImpl block = getChangeBlock(s1From, s1To - s1From, s2From, s2To - s2From); 489 ChangeBlockImpl block = getChangeBlock(s1From, s1To - s1From, s2From, s2To - s2From);
479 block.setOriginAndTarget(csetOrigin, csetTarget); 490 block.setOriginAndTarget(csetOrigin, csetTarget);
480 insp.changed(block); 491 insp.changed(block);
728 } 739 }
729 } 740 }
730 741
731 742
732 static class EqualBlocksCollector implements DiffHelper.MatchInspector<LineSequence> { 743 static class EqualBlocksCollector implements DiffHelper.MatchInspector<LineSequence> {
744 // FIXME replace with RangeSeq
733 private final IntVector matches = new IntVector(10*3, 2*3); 745 private final IntVector matches = new IntVector(10*3, 2*3);
734 746
735 public void begin(LineSequence s1, LineSequence s2) { 747 public void begin(LineSequence s1, LineSequence s2) {
736 } 748 }
737 749
769 result.add(s); 781 result.add(s);
770 result.add((start + length) - s); 782 result.add((start + length) - s);
771 } 783 }
772 } 784 }
773 785
786 /**
787 * find out line index in origin that matches specifid target line
788 */
789 public int reverseMapLine(int targetLine) {
790 for (int i = 0; i < matches.size(); i +=3) {
791 int os = matches.get(i);
792 int ts = matches.get(i + 1);
793 int l = matches.get(i + 2);
794 if (ts > targetLine) {
795 return -1;
796 }
797 if (ts + l > targetLine) {
798 return os + (targetLine - ts);
799 }
800 }
801 return -1;
802 }
803
804
774 /* 805 /*
775 * intersects [start..start+length) with ranges of target lines, and based on the intersection 806 * intersects [start..start+length) with ranges of target lines, and based on the intersection
776 * breaks initial range into smaller ranges and records them into result, with marker to indicate 807 * breaks initial range into smaller ranges and records them into result, with marker to indicate
777 * whether the range is from initial range (markerSource) or is a result of the intersection with target 808 * whether the range is from initial range (markerSource) or is a result of the intersection with target
778 * (markerTarget) 809 * (markerTarget)
875 } 906 }
876 907
877 public int fileRevisionIndex() { 908 public int fileRevisionIndex() {
878 return fileRevIndex; 909 return fileRevIndex;
879 } 910 }
911 @Override
912 public String toString() {
913 if (isMerge()) {
914 return String.format("[%d,%d->%d]", originCset, mergeCset, targetCset);
915 }
916 return String.format("[%d->%d]", originCset, targetCset);
917 }
880 } 918 }
881 919
882 public static void main(String[] args) { 920 public static void main(String[] args) {
883 EqualBlocksCollector bc = new EqualBlocksCollector(); 921 EqualBlocksCollector bc = new EqualBlocksCollector();
884 bc.match(-1, 5, 3); 922 bc.match(-1, 5, 3);