annotate src/org/tmatesoft/hg/repo/HgBlameFacility.java @ 584:ed243b668502

Conditionally enable effective patch merge alternative for revlog reading
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 25 Apr 2013 16:08:17 +0200
parents e49f9d9513fa
children 43cfa08ff3fd
rev   line source
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
1 /*
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
2 * Copyright (c) 2013 TMate Software Ltd
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
3 *
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
4 * This program is free software; you can redistribute it and/or modify
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
6 * the Free Software Foundation; version 2 of the License.
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
7 *
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
8 * This program is distributed in the hope that it will be useful,
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
11 * GNU General Public License for more details.
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
12 *
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
13 * For information on how to redistribute this software under
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
14 * the terms of a license other than GNU General Public License
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
15 * contact TMate Software at support@hg4j.com
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
17 package org.tmatesoft.hg.repo;
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
19 import static org.tmatesoft.hg.core.HgIterateDirection.NewToOld;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
20 import static org.tmatesoft.hg.core.HgIterateDirection.OldToNew;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
21 import static org.tmatesoft.hg.repo.HgInternals.wrongRevisionIndex;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
22 import static org.tmatesoft.hg.repo.HgRepository.*;
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
23
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
24 import java.util.Arrays;
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
25 import java.util.BitSet;
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
26 import java.util.Collections;
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
27 import java.util.LinkedList;
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
28
562
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
29 import org.tmatesoft.hg.core.HgCallbackTargetException;
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
30 import org.tmatesoft.hg.core.HgIterateDirection;
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
31 import org.tmatesoft.hg.core.Nodeid;
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
32 import org.tmatesoft.hg.internal.BlameHelper;
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
33 import org.tmatesoft.hg.internal.Callback;
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
34 import org.tmatesoft.hg.internal.Experimental;
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
35 import org.tmatesoft.hg.internal.IntVector;
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
36 import org.tmatesoft.hg.util.Adaptable;
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
37
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
38 /**
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
39 * Facility with diff/annotate functionality.
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
40 *
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
41 * @author Artem Tikhomirov
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
42 * @author TMate Software Ltd.
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
43 */
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
44 @Experimental(reason="Unstable API")
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
45 public final class HgBlameFacility {
568
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
46 private final HgDataFile df;
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
47
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
48 public HgBlameFacility(HgDataFile file) {
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
49 if (file == null) {
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
50 throw new IllegalArgumentException();
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
51 }
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
52 df = file;
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
53 }
549
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
54
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
55 /**
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
56 * mimic 'hg diff -r clogRevIndex1 -r clogRevIndex2'
549
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
57 */
568
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
58 public void diff(int clogRevIndex1, int clogRevIndex2, Inspector insp) throws HgCallbackTargetException {
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
59 // FIXME clogRevIndex1 and clogRevIndex2 may point to different files, need to decide whether to throw an exception
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
60 // or to attempt to look up correct file node (tricky)
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
61 int fileRevIndex1 = fileRevIndex(df, clogRevIndex1);
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
62 int fileRevIndex2 = fileRevIndex(df, clogRevIndex2);
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
63 BlameHelper bh = new BlameHelper(insp, 5);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
64 bh.useFileUpTo(df, clogRevIndex2);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
65 bh.diff(fileRevIndex1, clogRevIndex1, fileRevIndex2, clogRevIndex2);
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
66 }
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
67
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
68 /**
568
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
69 * Walk file history up/down to revision at given changeset and report changes for each revision
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
70 */
568
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
71 public void annotate(int changelogRevisionIndex, Inspector insp, HgIterateDirection iterateOrder) throws HgCallbackTargetException {
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
72 annotate(0, changelogRevisionIndex, insp, iterateOrder);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
73 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
74
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
75 /**
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
76 * Walk file history range and report changes for each revision
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
77 */
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
78 public void annotate(int changelogRevIndexStart, int changelogRevIndexEnd, Inspector insp, HgIterateDirection iterateOrder) throws HgCallbackTargetException {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
79 if (wrongRevisionIndex(changelogRevIndexStart) || wrongRevisionIndex(changelogRevIndexEnd)) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
80 throw new IllegalArgumentException();
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
81 }
573
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
82 // Note, changelogRevIndexEnd may be TIP, while the code below doesn't tolerate constants
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
83 //
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
84 int lastRevision = df.getRepo().getChangelog().getLastRevision();
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
85 if (changelogRevIndexEnd == TIP) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
86 changelogRevIndexEnd = lastRevision;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
87 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
88 HgInternals.checkRevlogRange(changelogRevIndexStart, changelogRevIndexEnd, lastRevision);
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
89 if (!df.exists()) {
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
90 return;
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
91 }
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
92 BlameHelper bh = new BlameHelper(insp, 10);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
93 HgDataFile currentFile = df;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
94 int fileLastClogRevIndex = changelogRevIndexEnd;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
95 FileRevisionHistoryChunk nextChunk = null;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
96 LinkedList<FileRevisionHistoryChunk> fileCompleteHistory = new LinkedList<FileRevisionHistoryChunk>();
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
97 do {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
98 FileRevisionHistoryChunk fileHistory = new FileRevisionHistoryChunk(currentFile);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
99 fileHistory.init(fileLastClogRevIndex);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
100 fileHistory.linkTo(nextChunk);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
101 fileCompleteHistory.addFirst(fileHistory); // to get the list in old-to-new order
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
102 nextChunk = fileHistory;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
103 bh.useFileUpTo(currentFile, fileLastClogRevIndex);
573
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
104 if (fileHistory.changeset(0) > changelogRevIndexStart && currentFile.isCopy()) {
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
105 // fileHistory.changeset(0) is the earliest revision we know about so far,
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
106 // once we get to revisions earlier than the requested start, stop digging.
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
107 // The reason there's NO == (i.e. not >=) because:
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
108 // (easy): once it's equal, we've reached our intended start
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
109 // (hard): if changelogRevIndexStart happens to be exact start of one of renames in the
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
110 // chain of renames (test-annotate2 repository, file1->file1a->file1b, i.e. points
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
111 // to the very start of file1a or file1 history), presence of == would get us to the next
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
112 // chunk and hence changed parents of present chunk's first element. Our annotate alg
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
113 // relies on parents only (i.e. knows nothing about 'last iteration element') to find out
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
114 // what to compare, and hence won't report all lines of 'last iteration element' (which is the
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
115 // first revision of the renamed file) as "added in this revision", leaving gaps in annotate
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
116 HgRepository repo = currentFile.getRepo();
570
36853bb80a35 Tests for HgAnnotateCommand with follow/no-follow option
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 569
diff changeset
117 Nodeid originLastRev = currentFile.getCopySourceRevision();
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
118 currentFile = repo.getFileNode(currentFile.getCopySourceName());
570
36853bb80a35 Tests for HgAnnotateCommand with follow/no-follow option
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 569
diff changeset
119 fileLastClogRevIndex = currentFile.getChangesetRevisionIndex(currentFile.getRevisionIndex(originLastRev));
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
120 // XXX perhaps, shall fail with meaningful exception if new file doesn't exist (.i/.d not found for whatever reason)
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
121 // or source revision is missing?
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
122 } else {
573
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
123 fileHistory.chopAtChangeset(changelogRevIndexStart);
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
124 currentFile = null; // stop iterating
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
125 }
573
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
126 } while (currentFile != null && fileLastClogRevIndex > changelogRevIndexStart);
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
127 // fileCompleteHistory is in (origin, intermediate target, ultimate target) order
568
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
128
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
129 int[] fileClogParentRevs = new int[2];
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
130 int[] fileParentRevs = new int[2];
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
131 if (iterateOrder == NewToOld) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
132 Collections.reverse(fileCompleteHistory);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
133 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
134 boolean shallFilterStart = changelogRevIndexStart != 0; // no reason if complete history is walked
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
135 for (FileRevisionHistoryChunk fileHistory : fileCompleteHistory) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
136 for (int fri : fileHistory.fileRevisions(iterateOrder)) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
137 int clogRevIndex = fileHistory.changeset(fri);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
138 if (shallFilterStart) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
139 if (iterateOrder == NewToOld) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
140 // clogRevIndex decreases
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
141 if (clogRevIndex < changelogRevIndexStart) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
142 break;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
143 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
144 // fall-through, clogRevIndex is in the [start..end] range
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
145 } else { // old to new
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
146 // the way we built fileHistory ensures we won't walk past changelogRevIndexEnd
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
147 // here we ensure we start from the right one, the one indicated with changelogRevIndexStart
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
148 if (clogRevIndex < changelogRevIndexStart) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
149 continue;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
150 } else {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
151 shallFilterStart = false; // once boundary is crossed, no need to check
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
152 // fall-through
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
153 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
154 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
155 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
156 fileHistory.fillFileParents(fri, fileParentRevs);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
157 fileHistory.fillCsetParents(fri, fileClogParentRevs);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
158 bh.annotateChange(fri, clogRevIndex, fileParentRevs, fileClogParentRevs);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
159 }
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
160 }
549
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
161 }
548
ab21ac7dd833 Line-by-line annotation API and support code in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 546
diff changeset
162
ab21ac7dd833 Line-by-line annotation API and support code in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 546
diff changeset
163 /**
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
164 * Annotates changes of the file against its parent(s).
562
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
165 * Unlike {@link #annotate(HgDataFile, int, Inspector, HgIterateDirection)}, doesn't
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
166 * walk file history, looks at the specified revision only. Handles both parents (if merge revision).
548
ab21ac7dd833 Line-by-line annotation API and support code in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 546
diff changeset
167 */
568
8ed4f4f4f0a6 Blame facility refactored, get ready for follow/no-follow support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 562
diff changeset
168 public void annotateSingleRevision(int changelogRevisionIndex, Inspector insp) throws HgCallbackTargetException {
545
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
169 // TODO detect if file is text/binary (e.g. looking for chars < ' ' and not \t\r\n\f
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
170 int fileRevIndex = fileRevIndex(df, changelogRevisionIndex);
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
171 int[] fileRevParents = new int[2];
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
172 df.parents(fileRevIndex, fileRevParents, null, null);
552
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
173 if (changelogRevisionIndex == TIP) {
45751456b471 Annotate file changes through few revisions, walking either direction (old to new and vice versa)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 551
diff changeset
174 changelogRevisionIndex = df.getChangesetRevisionIndex(fileRevIndex);
548
ab21ac7dd833 Line-by-line annotation API and support code in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 546
diff changeset
175 }
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
176 BlameHelper bh = new BlameHelper(insp, 5);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
177 bh.useFileUpTo(df, changelogRevisionIndex);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
178 int[] fileClogParentRevs = new int[2];
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
179 fileClogParentRevs[0] = fileRevParents[0] == NO_REVISION ? NO_REVISION : df.getChangesetRevisionIndex(fileRevParents[0]);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
180 fileClogParentRevs[1] = fileRevParents[1] == NO_REVISION ? NO_REVISION : df.getChangesetRevisionIndex(fileRevParents[1]);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
181 bh.annotateChange(fileRevIndex, changelogRevisionIndex, fileRevParents, fileClogParentRevs);
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
182 }
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
183
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
184 /**
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
185 * Client's sink for revision differences.
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
186 *
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
187 * When implemented, clients shall not expect new {@link Block blocks} instances in each call.
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
188 *
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
189 * In case more information about annotated revision is needed, inspector instances may supply
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
190 * {@link RevisionDescriptor.Recipient} through {@link Adaptable}.
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
191 */
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
192 @Callback
562
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
193 public interface Inspector {
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
194 void same(EqualBlock block) throws HgCallbackTargetException;
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
195 void added(AddBlock block) throws HgCallbackTargetException;
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
196 void changed(ChangeBlock block) throws HgCallbackTargetException;
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
197 void deleted(DeleteBlock block) throws HgCallbackTargetException;
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
198 }
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
199
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
200 /**
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
201 * No need to keep "Block" prefix as long as there's only one {@link Inspector}
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
202 */
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
203 @Deprecated
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
204 public interface BlockInspector extends Inspector {
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
205 }
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
206
554
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
207 /**
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
208 * Represents content of a block, either as a sequence of bytes or a
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
209 * sequence of smaller blocks (lines), if appropriate (according to usage context).
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
210 *
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
211 * This approach allows line-by-line access to content data along with complete byte sequence for the whole block, i.e.
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
212 * <pre>
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
213 * BlockData bd = addBlock.addedLines()
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
214 * // bd describes data from the addition completely.
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
215 * // elements of the BlockData are lines
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
216 * bd.elementCount() == addBlock.totalAddedLines();
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
217 * // one cat obtain complete addition with
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
218 * byte[] everythingAdded = bd.asArray();
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
219 * // or iterate line by line
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
220 * for (int i = 0; i < bd.elementCount(); i++) {
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
221 * byte[] lineContent = bd.elementAt(i);
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
222 * String line = new String(lineContent, fileEncodingCharset);
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
223 * }
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
224 * where bd.elementAt(0) is the line at index addBlock.firstAddedLine()
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
225 * </pre>
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
226 *
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
227 * LineData or ChunkData?
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
228 */
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
229 public interface BlockData {
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
230 BlockData elementAt(int index);
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
231 int elementCount();
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
232 byte[] asArray();
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
233 }
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
234
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
235 /**
562
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
236 * {@link Inspector} may optionally request extra information about revisions
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
237 * being inspected, denoting itself as a {@link RevisionDescriptor.Recipient}. This class
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
238 * provides complete information about file revision under annotation now.
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
239 */
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
240 public interface RevisionDescriptor {
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
241 /**
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
242 * @return complete source of the diff origin, never <code>null</code>
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
243 */
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
244 BlockData origin();
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
245 /**
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
246 * @return complete source of the diff target, never <code>null</code>
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
247 */
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
248 BlockData target();
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
249 /**
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
250 * @return changeset revision index of original file, or {@link HgRepository#NO_REVISION} if it's the very first revision
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
251 */
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
252 int originChangesetIndex();
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
253 /**
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
254 * @return changeset revision index of the target file
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
255 */
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
256 int targetChangesetIndex();
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
257 /**
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
258 * @return <code>true</code> if this revision is merge
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
259 */
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
260 boolean isMerge();
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
261 /**
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
262 * @return changeset revision index of the second, merged parent
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
263 */
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
264 int mergeChangesetIndex();
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
265 /**
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
266 * @return revision index of the change in target file's revlog
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
267 */
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
268 int fileRevisionIndex();
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
269
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
270 /**
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
271 * @return file object under blame (target file)
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
272 */
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
273 HgDataFile file();
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
274
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
275 /**
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
276 * Implement to indicate interest in {@link RevisionDescriptor}.
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
277 *
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
278 * Note, instance of {@link RevisionDescriptor} is the same for
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
279 * {@link #start(RevisionDescriptor)} and {@link #done(RevisionDescriptor)}
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
280 * methods, and not necessarily a new one (i.e. <code>==</code>) for the next
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
281 * revision announced.
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
282 */
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
283 @Callback
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
284 public interface Recipient {
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
285 /**
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
286 * Comes prior to any change {@link Block blocks}
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
287 */
562
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
288 void start(RevisionDescriptor revisionDescription) throws HgCallbackTargetException;
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
289 /**
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
290 * Comes after all change {@link Block blocks} were dispatched
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
291 */
562
6fbca6506bb5 Allow HgBlameFacility.Inspector (former BlockInspector) to throw an exception
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 561
diff changeset
292 void done(RevisionDescriptor revisionDescription) throws HgCallbackTargetException;
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
293 }
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
294 }
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
295
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
296 /**
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
297 * Each change block comes from a single origin, blocks that are result of a merge
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
298 * have {@link #originChangesetIndex()} equal to {@link RevisionDescriptor#mergeChangesetIndex()}.
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
299 */
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
300 public interface Block {
545
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
301 int originChangesetIndex();
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
302 int targetChangesetIndex();
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
303 }
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
304
545
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
305 public interface EqualBlock extends Block {
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
306 int originStart();
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
307 int targetStart();
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
308 int length();
554
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
309 BlockData content();
545
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
310 }
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
311
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
312 public interface AddBlock extends Block {
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
313 /**
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
314 * @return line index in the origin where this block is inserted
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
315 */
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
316 int insertedAt();
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
317 /**
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
318 * @return line index of the first added line in the target revision
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
319 */
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
320 int firstAddedLine();
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
321 /**
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
322 * @return number of added lines in this block
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
323 */
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
324 int totalAddedLines();
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
325 /**
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
326 * @return content of added lines
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
327 */
554
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
328 BlockData addedLines();
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
329 }
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
330 public interface DeleteBlock extends Block {
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
331 /**
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
332 * @return line index in the target revision were this deleted block would be
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
333 */
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
334 int removedAt();
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
335 /**
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
336 * @return line index of the first removed line in the original revision
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
337 */
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
338 int firstRemovedLine();
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
339 /**
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
340 * @return number of deleted lines in this block
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
341 */
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
342 int totalRemovedLines();
556
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
343 /**
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
344 * @return content of deleted lines
e55f17a7a195 AnnotateFacility renamed to HgBlameFacility and exposed, API shapes out and got some javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 555
diff changeset
345 */
554
a5fd757d1b5d Access to content of annotated files through BlockData interface
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 553
diff changeset
346 BlockData removedLines();
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
347 }
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
348 public interface ChangeBlock extends AddBlock, DeleteBlock {
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
349 }
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
350
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
351
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
352 private static int fileRevIndex(HgDataFile df, int csetRevIndex) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
353 Nodeid fileRev = df.getRepo().getManifest().getFileRevision(csetRevIndex, df.getPath());
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
354 return df.getRevisionIndex(fileRev);
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
355 }
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
356
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
357 private static class FileRevisionHistoryChunk {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
358 private final HgDataFile df;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
359 // change ancestry, sequence of file revisions
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
360 private IntVector fileRevsToVisit;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
361 // parent pairs of complete file history
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
362 private IntVector fileParentRevs;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
363 // map file revision to changelog revision (sparse array, only file revisions to visit are set)
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
364 private int[] file2changelog;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
365 private int originChangelogRev = BAD_REVISION, originFileRev = BAD_REVISION;
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
366
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
367 public FileRevisionHistoryChunk(HgDataFile file) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
368 df = file;
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
369 }
545
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
370
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
371 public void init(int changelogRevisionIndex) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
372 // XXX df.indexWalk(0, fileRevIndex, ) might be more effective
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
373 int fileRevIndex = fileRevIndex(df, changelogRevisionIndex);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
374 int[] fileRevParents = new int[2];
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
375 fileParentRevs = new IntVector((fileRevIndex+1) * 2, 0);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
376 fileParentRevs.add(NO_REVISION, NO_REVISION); // parents of fileRevIndex == 0
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
377 for (int i = 1; i <= fileRevIndex; i++) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
378 df.parents(i, fileRevParents, null, null);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
379 fileParentRevs.add(fileRevParents[0], fileRevParents[1]);
545
15b406c7cd9d First round of annotate file is functional
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 544
diff changeset
380 }
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
381 // fileRevsToVisit keep file change ancestry from new to old
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
382 fileRevsToVisit = new IntVector(fileRevIndex + 1, 0);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
383 // keep map of file revision to changelog revision
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
384 file2changelog = new int[fileRevIndex+1];
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
385 // only elements worth visit would get mapped, so there would be unfilled areas in the file2changelog,
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
386 // prevent from error (make it explicit) by bad value
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
387 Arrays.fill(file2changelog, BAD_REVISION);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
388 LinkedList<Integer> queue = new LinkedList<Integer>();
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
389 BitSet seen = new BitSet(fileRevIndex + 1);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
390 queue.add(fileRevIndex);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
391 do {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
392 int x = queue.removeFirst();
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
393 if (seen.get(x)) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
394 continue;
549
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
395 }
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
396 seen.set(x);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
397 fileRevsToVisit.add(x);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
398 file2changelog[x] = df.getChangesetRevisionIndex(x);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
399 int p1 = fileParentRevs.get(2*x);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
400 int p2 = fileParentRevs.get(2*x + 1);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
401 if (p1 != NO_REVISION) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
402 queue.addLast(p1);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
403 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
404 if (p2 != NO_REVISION) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
405 queue.addLast(p2);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
406 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
407 } while (!queue.isEmpty());
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
408 // make sure no child is processed before we handled all (grand-)parents of the element
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
409 fileRevsToVisit.sort(false);
549
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
410 }
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
411
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
412 public void linkTo(FileRevisionHistoryChunk target) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
413 // assume that target.init() has been called already
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
414 if (target == null) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
415 return;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
416 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
417 target.originFileRev = fileRevsToVisit.get(0); // files to visit are new to old
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
418 target.originChangelogRev = changeset(target.originFileRev);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
419 }
573
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
420
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
421 /**
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
422 * Mark revision closest(ceil) to specified as the very first one (no parents)
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
423 */
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
424 public void chopAtChangeset(int firstChangelogRevOfInterest) {
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
425 if (firstChangelogRevOfInterest == 0) {
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
426 return; // nothing to do
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
427 }
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
428 int i = 0, x = fileRevsToVisit.size(), fileRev = BAD_REVISION;
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
429 // fileRevsToVisit is new to old, greater numbers to smaller
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
430 while (i < x && changeset(fileRev = fileRevsToVisit.get(i)) >= firstChangelogRevOfInterest) {
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
431 i++;
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
432 }
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
433 assert fileRev != BAD_REVISION; // there's at least 1 revision in fileRevsToVisit
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
434 if (i == x && changeset(fileRev) != firstChangelogRevOfInterest) {
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
435 assert false : "Requested changeset shall belong to the chunk";
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
436 return;
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
437 }
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
438 fileRevsToVisit.trimTo(i); // no need to iterate more
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
439 // pretend fileRev got no parents
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
440 fileParentRevs.set(fileRev * 2, NO_REVISION);
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
441 fileParentRevs.set(fileRev, NO_REVISION);
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
442 }
e49f9d9513fa Partial blame when start/end revisions are in the middle of a single filename history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 570
diff changeset
443
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
444 public int[] fileRevisions(HgIterateDirection iterateOrder) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
445 // fileRevsToVisit is { r10, r7, r6, r5, r0 }, new to old
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
446 int[] rv = fileRevsToVisit.toArray();
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
447 if (iterateOrder == OldToNew) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
448 // reverse return value
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
449 for (int a = 0, b = rv.length-1; a < b; a++, b--) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
450 int t = rv[b];
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
451 rv[b] = rv[a];
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
452 rv[a] = t;
549
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
453 }
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
454 }
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
455 return rv;
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
456 }
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
457
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
458 public int changeset(int fileRevIndex) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
459 return file2changelog[fileRevIndex];
555
e623aa2ca526 Annotate: RevisionDescriptor provides extra knowledge about inspected/annotated revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 554
diff changeset
460 }
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
461
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
462 public void fillFileParents(int fileRevIndex, int[] fileParents) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
463 if (fileRevIndex == 0 && originFileRev != BAD_REVISION) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
464 // this chunk continues another file
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
465 assert originFileRev != NO_REVISION;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
466 fileParents[0] = originFileRev;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
467 fileParents[1] = NO_REVISION;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
468 return;
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 556
diff changeset
469 }
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
470 fileParents[0] = fileParentRevs.get(fileRevIndex * 2);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
471 fileParents[1] = fileParentRevs.get(fileRevIndex * 2 + 1);
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
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 556
diff changeset
472 }
569
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
473
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
474 public void fillCsetParents(int fileRevIndex, int[] csetParents) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
475 if (fileRevIndex == 0 && originFileRev != BAD_REVISION) {
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
476 assert originFileRev != NO_REVISION;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
477 csetParents[0] = originChangelogRev;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
478 csetParents[1] = NO_REVISION; // I wonder if possible to start a copy with two parents?
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
479 return;
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
480 }
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
481 int fp1 = fileParentRevs.get(fileRevIndex * 2);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
482 int fp2 = fileParentRevs.get(fileRevIndex * 2 + 1);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
483 csetParents[0] = fp1 == NO_REVISION ? NO_REVISION : changeset(fp1);
c4fd1037bc6f Support for copy/rename follow/no-follow for annotate
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 568
diff changeset
484 csetParents[1] = fp2 == NO_REVISION ? NO_REVISION : changeset(fp2);
549
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
485 }
83afa680555d Annotate merge revision (combined diff against two parents without looking further)
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 548
diff changeset
486 }
542
a71a05ec11bc Towards annotate/blame support: general outline of the functionality
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
487 }