Mercurial > hg4j
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); |