Mercurial > hg4j
comparison src/org/tmatesoft/hg/core/HgAnnotateCommand.java @ 676:3219cfadda49
Switch to alternative annotate producer (walks from parents to children). Refactor FileAnnotation to match updated annotate approach
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Thu, 18 Jul 2013 18:03:51 +0200 |
| parents | 5f52074707b2 |
| children | 1c49c0cee540 |
comparison
equal
deleted
inserted
replaced
| 675:a20121a2bba6 | 676:3219cfadda49 |
|---|---|
| 14 * the terms of a license other than GNU General Public License | 14 * the terms of a license other than GNU General Public License |
| 15 * contact TMate Software at support@hg4j.com | 15 * contact TMate Software at support@hg4j.com |
| 16 */ | 16 */ |
| 17 package org.tmatesoft.hg.core; | 17 package org.tmatesoft.hg.core; |
| 18 | 18 |
| 19 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; | |
| 20 | |
| 21 import java.util.Arrays; | |
| 22 | |
| 23 import org.tmatesoft.hg.core.HgBlameInspector.BlockData; | |
| 24 import org.tmatesoft.hg.internal.Callback; | 19 import org.tmatesoft.hg.internal.Callback; |
| 25 import org.tmatesoft.hg.internal.CsetParamKeeper; | 20 import org.tmatesoft.hg.internal.CsetParamKeeper; |
| 26 import org.tmatesoft.hg.internal.FileAnnotation; | 21 import org.tmatesoft.hg.internal.ForwardAnnotateInspector; |
| 27 import org.tmatesoft.hg.internal.FileAnnotation.LineDescriptor; | |
| 28 import org.tmatesoft.hg.internal.FileAnnotation.LineInspector; | |
| 29 import org.tmatesoft.hg.repo.HgDataFile; | 22 import org.tmatesoft.hg.repo.HgDataFile; |
| 30 import org.tmatesoft.hg.repo.HgRepository; | 23 import org.tmatesoft.hg.repo.HgRepository; |
| 31 import org.tmatesoft.hg.repo.HgRuntimeException; | 24 import org.tmatesoft.hg.repo.HgRuntimeException; |
| 32 import org.tmatesoft.hg.util.CancelSupport; | 25 import org.tmatesoft.hg.util.CancelSupport; |
| 33 import org.tmatesoft.hg.util.CancelledException; | 26 import org.tmatesoft.hg.util.CancelledException; |
| 86 followRename = followCopyRename; | 79 followRename = followCopyRename; |
| 87 return this; | 80 return this; |
| 88 } | 81 } |
| 89 | 82 |
| 90 // TODO [post-1.1] set encoding and provide String line content from LineInfo | 83 // TODO [post-1.1] set encoding and provide String line content from LineInfo |
| 84 // TODO FWIW: diff algorithms: http://bramcohen.livejournal.com/73318.html | |
| 91 | 85 |
| 92 /** | 86 /** |
| 93 * Annotate selected file | 87 * Annotate selected file |
| 94 * | 88 * |
| 95 * @param inspector | 89 * @param inspector |
| 105 throw new HgBadArgumentException("Command needs file argument", null); | 99 throw new HgBadArgumentException("Command needs file argument", null); |
| 106 } | 100 } |
| 107 final ProgressSupport progress = getProgressSupport(inspector); | 101 final ProgressSupport progress = getProgressSupport(inspector); |
| 108 final CancelSupport cancellation = getCancelSupport(inspector, true); | 102 final CancelSupport cancellation = getCancelSupport(inspector, true); |
| 109 cancellation.checkCancelled(); | 103 cancellation.checkCancelled(); |
| 110 progress.start(2); | 104 progress.start(200); |
| 111 try { | 105 try { |
| 112 HgDataFile df = repo.getFileNode(file); | 106 HgDataFile df = repo.getFileNode(file); |
| 113 if (!df.exists()) { | 107 if (!df.exists()) { |
| 114 return; | 108 return; |
| 115 } | 109 } |
| 116 final int changesetStart = followRename ? 0 : df.getChangesetRevisionIndex(0); | 110 final int changesetStart = followRename ? 0 : df.getChangesetRevisionIndex(0); |
| 117 Collector c = new Collector(cancellation); | 111 final int annotateRevIndex = annotateRevision.get(); |
| 118 FileAnnotation fa = new FileAnnotation(c); | 112 HgDiffCommand cmd = new HgDiffCommand(repo).file(df); |
| 119 HgDiffCommand cmd = new HgDiffCommand(repo); | 113 cmd.range(changesetStart, annotateRevIndex); |
| 120 cmd.file(df).order(HgIterateDirection.NewToOld); | 114 cmd.set(cancellation); |
| 121 cmd.range(changesetStart, annotateRevision.get()); | 115 cmd.set(new ProgressSupport.Sub(progress, 100)); |
| 122 cmd.executeAnnotate(fa); | 116 // |
| 123 progress.worked(1); | 117 // ReverseAnnotateInspector ai = new ReverseAnnotateInspector(); |
| 124 c.throwIfCancelled(); | 118 ForwardAnnotateInspector ai = new ForwardAnnotateInspector(); |
| 119 cmd.order(ai.iterateDirection()); | |
| 120 // | |
| 121 cmd.executeAnnotate(ai); | |
| 125 cancellation.checkCancelled(); | 122 cancellation.checkCancelled(); |
| 126 ProgressSupport.Sub subProgress = new ProgressSupport.Sub(progress, 1); | 123 ai.report(annotateRevIndex, inspector, new ProgressSupport.Sub(progress, 100), cancellation); |
| 127 subProgress.start(c.lineRevisions.length); | |
| 128 LineImpl li = new LineImpl(); | |
| 129 for (int i = 0; i < c.lineRevisions.length; i++) { | |
| 130 li.init(i+1, c.lineRevisions[i], c.line(i)); | |
| 131 inspector.next(li); | |
| 132 subProgress.worked(1); | |
| 133 cancellation.checkCancelled(); | |
| 134 } | |
| 135 subProgress.done(); | |
| 136 } catch (HgRuntimeException ex) { | 124 } catch (HgRuntimeException ex) { |
| 137 throw new HgLibraryFailureException(ex); | 125 throw new HgLibraryFailureException(ex); |
| 138 } | 126 } |
| 139 progress.done(); | 127 progress.done(); |
| 140 } | 128 } |
| 157 public interface LineInfo { | 145 public interface LineInfo { |
| 158 int getLineNumber(); | 146 int getLineNumber(); |
| 159 int getChangesetIndex(); | 147 int getChangesetIndex(); |
| 160 byte[] getContent(); | 148 byte[] getContent(); |
| 161 } | 149 } |
| 162 | |
| 163 // TODO [post-1.1] there's no need in FileAnnotation.LineInspector, merge it here | |
| 164 // ok for 1.1 as this LineInspector is internal class | |
| 165 private static class Collector implements LineInspector { | |
| 166 private int[] lineRevisions; | |
| 167 private byte[][] lines; | |
| 168 private final CancelSupport cancelSupport; | |
| 169 private CancelledException cancelEx; | |
| 170 | |
| 171 Collector(CancelSupport cancellation) { | |
| 172 cancelSupport = cancellation; | |
| 173 } | |
| 174 | |
| 175 public void line(int lineNumber, int changesetRevIndex, BlockData lineContent, LineDescriptor ld) { | |
| 176 if (cancelEx != null) { | |
| 177 return; | |
| 178 } | |
| 179 if (lineRevisions == null) { | |
| 180 lineRevisions = new int [ld.totalLines()]; | |
| 181 Arrays.fill(lineRevisions, NO_REVISION); | |
| 182 lines = new byte[ld.totalLines()][]; | |
| 183 } | |
| 184 lineRevisions[lineNumber] = changesetRevIndex; | |
| 185 lines[lineNumber] = lineContent.asArray(); | |
| 186 try { | |
| 187 cancelSupport.checkCancelled(); | |
| 188 } catch (CancelledException ex) { | |
| 189 cancelEx = ex; | |
| 190 } | |
| 191 } | |
| 192 | |
| 193 public byte[] line(int i) { | |
| 194 return lines[i]; | |
| 195 } | |
| 196 | |
| 197 public void throwIfCancelled() throws CancelledException { | |
| 198 if (cancelEx != null) { | |
| 199 throw cancelEx; | |
| 200 } | |
| 201 } | |
| 202 } | |
| 203 | |
| 204 | |
| 205 private static class LineImpl implements LineInfo { | |
| 206 private int ln; | |
| 207 private int rev; | |
| 208 private byte[] content; | |
| 209 | |
| 210 void init(int line, int csetRev, byte[] cnt) { | |
| 211 ln = line; | |
| 212 rev = csetRev; | |
| 213 content = cnt; | |
| 214 } | |
| 215 | |
| 216 public int getLineNumber() { | |
| 217 return ln; | |
| 218 } | |
| 219 | |
| 220 public int getChangesetIndex() { | |
| 221 return rev; | |
| 222 } | |
| 223 | |
| 224 public byte[] getContent() { | |
| 225 return content; | |
| 226 } | |
| 227 } | |
| 228 } | 150 } |
