Mercurial > jhg
comparison src/org/tmatesoft/hg/core/HgDiffCommand.java @ 632:54e16ab771ec v1.1rc2
Progress/cancel for HgDiffCommand. Renamed execute method
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 30 May 2013 16:13:43 +0200 |
parents | 72c979555cb8 |
children | a20121a2bba6 |
comparison
equal
deleted
inserted
replaced
631:8a5cdcb27b8f | 632:54e16ab771ec |
---|---|
19 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; | 19 import static org.tmatesoft.hg.repo.HgRepository.NO_REVISION; |
20 import static org.tmatesoft.hg.repo.HgRepository.TIP; | 20 import static org.tmatesoft.hg.repo.HgRepository.TIP; |
21 | 21 |
22 import org.tmatesoft.hg.internal.BlameHelper; | 22 import org.tmatesoft.hg.internal.BlameHelper; |
23 import org.tmatesoft.hg.internal.CsetParamKeeper; | 23 import org.tmatesoft.hg.internal.CsetParamKeeper; |
24 import org.tmatesoft.hg.internal.Experimental; | |
25 import org.tmatesoft.hg.internal.FileHistory; | 24 import org.tmatesoft.hg.internal.FileHistory; |
26 import org.tmatesoft.hg.internal.FileRevisionHistoryChunk; | 25 import org.tmatesoft.hg.internal.FileRevisionHistoryChunk; |
27 import org.tmatesoft.hg.repo.HgDataFile; | 26 import org.tmatesoft.hg.repo.HgDataFile; |
28 import org.tmatesoft.hg.repo.HgRepository; | 27 import org.tmatesoft.hg.repo.HgRepository; |
29 import org.tmatesoft.hg.repo.HgRuntimeException; | 28 import org.tmatesoft.hg.repo.HgRuntimeException; |
29 import org.tmatesoft.hg.util.CancelSupport; | |
30 import org.tmatesoft.hg.util.CancelledException; | 30 import org.tmatesoft.hg.util.CancelledException; |
31 import org.tmatesoft.hg.util.Path; | 31 import org.tmatesoft.hg.util.Path; |
32 import org.tmatesoft.hg.util.ProgressSupport; | |
32 | 33 |
33 /** | 34 /** |
34 * 'hg diff' counterpart, with similar, diff-based, functionality | 35 * 'hg diff' counterpart, with similar, although not identical, functionality. |
36 * Despite both 'hg diff' and this command are diff-based, implementation | |
37 * peculiarities may lead to slightly different diff results. Either is valid | |
38 * as there's no strict diff specification. | |
39 * | |
40 * <p> | |
41 * <strong>Note</strong>, at the moment this command annotates single file only. Diff over | |
42 * complete repository (all the file changed in a given changeset) might | |
43 * be added later. | |
35 * | 44 * |
36 * @since 1.1 | 45 * @since 1.1 |
37 * @author Artem Tikhomirov | 46 * @author Artem Tikhomirov |
38 * @author TMate Software Ltd. | 47 * @author TMate Software Ltd. |
39 */ | 48 */ |
40 @Experimental(reason="#execute* methods might get renamed") | |
41 public class HgDiffCommand extends HgAbstractCommand<HgDiffCommand> { | 49 public class HgDiffCommand extends HgAbstractCommand<HgDiffCommand> { |
42 | 50 |
43 private final HgRepository repo; | 51 private final HgRepository repo; |
44 private HgDataFile df; | 52 private HgDataFile df; |
45 private final CsetParamKeeper clogRevIndexStart, clogRevIndexEnd; | 53 private final CsetParamKeeper clogRevIndexStart, clogRevIndexEnd; |
84 clogRevIndexEnd.set(changelogRevIndexEnd); | 92 clogRevIndexEnd.set(changelogRevIndexEnd); |
85 return this; | 93 return this; |
86 } | 94 } |
87 | 95 |
88 /** | 96 /** |
89 * Selects revision for {@link #executeAnnotateSingleRevision(HgBlameInspector)}, the one | 97 * Selects revision for {@link #executeParentsAnnotate(HgBlameInspector)}, the one |
90 * to diff against its parents. | 98 * to diff against its parents. |
91 * | 99 * |
92 * Besides, it is handy when range of interest spans up to the very beginning of the file history | 100 * Besides, it is handy when range of interest spans up to the very beginning of the file history |
93 * (and thus is equivalent to <code>range(0, changelogRevIndex)</code>) | 101 * (and thus is equivalent to <code>range(0, changelogRevIndex)</code>) |
94 * | 102 * |
105 /** | 113 /** |
106 * Revision differences are reported in selected order when | 114 * Revision differences are reported in selected order when |
107 * annotating {@link #range(int, int) range} of changesets with | 115 * annotating {@link #range(int, int) range} of changesets with |
108 * {@link #executeAnnotate(HgBlameInspector)}. | 116 * {@link #executeAnnotate(HgBlameInspector)}. |
109 * <p> | 117 * <p> |
110 * This method doesn't affect {@link #executeAnnotateSingleRevision(HgBlameInspector)} and | 118 * This method doesn't affect {@link #executeParentsAnnotate(HgBlameInspector)} and |
111 * {@link #executeDiff(HgBlameInspector)} | 119 * {@link #executeDiff(HgBlameInspector)} |
112 * | 120 * |
113 * @param order desired iteration order | 121 * @param order desired iteration order |
114 * @return <code>this</code> for convenience | 122 * @return <code>this</code> for convenience |
115 */ | 123 */ |
116 public HgDiffCommand order(HgIterateDirection order) { | 124 public HgDiffCommand order(HgIterateDirection order) { |
117 iterateDirection = order; | 125 iterateDirection = order; |
118 return this; | 126 return this; |
119 } | 127 } |
120 | |
121 // FIXME progress and cancellation | |
122 | 128 |
123 /** | 129 /** |
124 * Diff two revisions selected with {@link #range(int, int)} against each other. | 130 * Diff two revisions selected with {@link #range(int, int)} against each other. |
125 * <p>mimics 'hg diff -r clogRevIndex1 -r clogRevIndex2' | 131 * <p>mimics 'hg diff -r clogRevIndex1 -r clogRevIndex2' |
126 * | 132 * |
128 * @throws CancelledException if execution of the command was cancelled | 134 * @throws CancelledException if execution of the command was cancelled |
129 * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state | 135 * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state |
130 */ | 136 */ |
131 public void executeDiff(HgBlameInspector insp) throws HgCallbackTargetException, CancelledException, HgException { | 137 public void executeDiff(HgBlameInspector insp) throws HgCallbackTargetException, CancelledException, HgException { |
132 checkFile(); | 138 checkFile(); |
139 final ProgressSupport progress = getProgressSupport(insp); | |
140 progress.start(2); | |
133 try { | 141 try { |
142 final CancelSupport cancel = getCancelSupport(insp, true); | |
134 int fileRevIndex1 = fileRevIndex(df, clogRevIndexStart.get()); | 143 int fileRevIndex1 = fileRevIndex(df, clogRevIndexStart.get()); |
135 int fileRevIndex2 = fileRevIndex(df, clogRevIndexEnd.get()); | 144 int fileRevIndex2 = fileRevIndex(df, clogRevIndexEnd.get()); |
136 BlameHelper bh = new BlameHelper(insp); | 145 BlameHelper bh = new BlameHelper(insp); |
137 bh.prepare(df, clogRevIndexStart.get(), clogRevIndexEnd.get()); | 146 bh.prepare(df, clogRevIndexStart.get(), clogRevIndexEnd.get()); |
147 progress.worked(1); | |
148 cancel.checkCancelled(); | |
138 bh.diff(fileRevIndex1, clogRevIndexStart.get(), fileRevIndex2, clogRevIndexEnd.get()); | 149 bh.diff(fileRevIndex1, clogRevIndexStart.get(), fileRevIndex2, clogRevIndexEnd.get()); |
150 progress.worked(1); | |
151 cancel.checkCancelled(); | |
139 } catch (HgRuntimeException ex) { | 152 } catch (HgRuntimeException ex) { |
140 throw new HgLibraryFailureException(ex); | 153 throw new HgLibraryFailureException(ex); |
154 } finally { | |
155 progress.done(); | |
141 } | 156 } |
142 } | 157 } |
143 | 158 |
144 /** | 159 /** |
145 * Walk file history {@link #range(int, int) range} and report changes (diff) for each revision | 160 * Walk file history {@link #range(int, int) range} and report changes (diff) for each revision |
148 * @throws CancelledException if execution of the command was cancelled | 163 * @throws CancelledException if execution of the command was cancelled |
149 * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state | 164 * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state |
150 */ | 165 */ |
151 public void executeAnnotate(HgBlameInspector insp) throws HgCallbackTargetException, CancelledException, HgException { | 166 public void executeAnnotate(HgBlameInspector insp) throws HgCallbackTargetException, CancelledException, HgException { |
152 checkFile(); | 167 checkFile(); |
168 ProgressSupport progress = null; | |
153 try { | 169 try { |
154 if (!df.exists()) { | 170 if (!df.exists()) { |
155 return; | 171 return; |
156 } | 172 } |
173 final CancelSupport cancel = getCancelSupport(insp, true); | |
157 BlameHelper bh = new BlameHelper(insp); | 174 BlameHelper bh = new BlameHelper(insp); |
158 FileHistory fileHistory = bh.prepare(df, clogRevIndexStart.get(), clogRevIndexEnd.get()); | 175 FileHistory fileHistory = bh.prepare(df, clogRevIndexStart.get(), clogRevIndexEnd.get()); |
159 | 176 // |
177 cancel.checkCancelled(); | |
178 int totalWork = 0; | |
179 for (FileRevisionHistoryChunk fhc : fileHistory.iterate(iterateDirection)) { | |
180 totalWork += fhc.revisionCount(); | |
181 } | |
182 progress = getProgressSupport(insp); | |
183 progress.start(totalWork + 1); | |
184 progress.worked(1); // BlameHelper.prepare | |
185 // | |
160 int[] fileClogParentRevs = new int[2]; | 186 int[] fileClogParentRevs = new int[2]; |
161 int[] fileParentRevs = new int[2]; | 187 int[] fileParentRevs = new int[2]; |
162 for (FileRevisionHistoryChunk fhc : fileHistory.iterate(iterateDirection)) { | 188 for (FileRevisionHistoryChunk fhc : fileHistory.iterate(iterateDirection)) { |
163 for (int fri : fhc.fileRevisions(iterateDirection)) { | 189 for (int fri : fhc.fileRevisions(iterateDirection)) { |
164 int clogRevIndex = fhc.changeset(fri); | 190 int clogRevIndex = fhc.changeset(fri); |
166 assert clogRevIndex >= clogRevIndexStart.get(); | 192 assert clogRevIndex >= clogRevIndexStart.get(); |
167 assert clogRevIndex <= clogRevIndexEnd.get(); | 193 assert clogRevIndex <= clogRevIndexEnd.get(); |
168 fhc.fillFileParents(fri, fileParentRevs); | 194 fhc.fillFileParents(fri, fileParentRevs); |
169 fhc.fillCsetParents(fri, fileClogParentRevs); | 195 fhc.fillCsetParents(fri, fileClogParentRevs); |
170 bh.annotateChange(fri, clogRevIndex, fileParentRevs, fileClogParentRevs); | 196 bh.annotateChange(fri, clogRevIndex, fileParentRevs, fileClogParentRevs); |
197 progress.worked(1); | |
198 cancel.checkCancelled(); | |
171 } | 199 } |
172 } | 200 } |
173 } catch (HgRuntimeException ex) { | 201 } catch (HgRuntimeException ex) { |
174 throw new HgLibraryFailureException(ex); | 202 throw new HgLibraryFailureException(ex); |
203 } finally { | |
204 if (progress != null) { | |
205 progress.done(); | |
206 } | |
175 } | 207 } |
176 } | 208 } |
177 | 209 |
178 /** | 210 /** |
179 * Annotates changes of the file against its parent(s). | 211 * Annotates changes of the file against its parent(s). |
182 * | 214 * |
183 * @throws HgCallbackTargetException propagated exception from the handler | 215 * @throws HgCallbackTargetException propagated exception from the handler |
184 * @throws CancelledException if execution of the command was cancelled | 216 * @throws CancelledException if execution of the command was cancelled |
185 * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state | 217 * @throws HgException subclass thereof to indicate specific issue with the command arguments or repository state |
186 */ | 218 */ |
187 public void executeAnnotateSingleRevision(HgBlameInspector insp) throws HgCallbackTargetException, CancelledException, HgException { | 219 public void executeParentsAnnotate(HgBlameInspector insp) throws HgCallbackTargetException, CancelledException, HgException { |
188 checkFile(); | 220 checkFile(); |
221 final ProgressSupport progress = getProgressSupport(insp); | |
222 progress.start(2); | |
189 try { | 223 try { |
224 final CancelSupport cancel = getCancelSupport(insp, true); | |
190 int changelogRevisionIndex = clogRevIndexEnd.get(); | 225 int changelogRevisionIndex = clogRevIndexEnd.get(); |
191 // TODO detect if file is text/binary (e.g. looking for chars < ' ' and not \t\r\n\f | 226 // TODO detect if file is text/binary (e.g. looking for chars < ' ' and not \t\r\n\f |
192 int fileRevIndex = fileRevIndex(df, changelogRevisionIndex); | 227 int fileRevIndex = fileRevIndex(df, changelogRevisionIndex); |
193 int[] fileRevParents = new int[2]; | 228 int[] fileRevParents = new int[2]; |
194 df.parents(fileRevIndex, fileRevParents, null, null); | 229 df.parents(fileRevIndex, fileRevParents, null, null); |
199 fileClogParentRevs[0] = fileRevParents[0] == NO_REVISION ? NO_REVISION : df.getChangesetRevisionIndex(fileRevParents[0]); | 234 fileClogParentRevs[0] = fileRevParents[0] == NO_REVISION ? NO_REVISION : df.getChangesetRevisionIndex(fileRevParents[0]); |
200 fileClogParentRevs[1] = fileRevParents[1] == NO_REVISION ? NO_REVISION : df.getChangesetRevisionIndex(fileRevParents[1]); | 235 fileClogParentRevs[1] = fileRevParents[1] == NO_REVISION ? NO_REVISION : df.getChangesetRevisionIndex(fileRevParents[1]); |
201 BlameHelper bh = new BlameHelper(insp); | 236 BlameHelper bh = new BlameHelper(insp); |
202 int clogIndexStart = fileClogParentRevs[0] == NO_REVISION ? (fileClogParentRevs[1] == NO_REVISION ? 0 : fileClogParentRevs[1]) : fileClogParentRevs[0]; | 237 int clogIndexStart = fileClogParentRevs[0] == NO_REVISION ? (fileClogParentRevs[1] == NO_REVISION ? 0 : fileClogParentRevs[1]) : fileClogParentRevs[0]; |
203 bh.prepare(df, clogIndexStart, changelogRevisionIndex); | 238 bh.prepare(df, clogIndexStart, changelogRevisionIndex); |
239 progress.worked(1); | |
240 cancel.checkCancelled(); | |
204 bh.annotateChange(fileRevIndex, changelogRevisionIndex, fileRevParents, fileClogParentRevs); | 241 bh.annotateChange(fileRevIndex, changelogRevisionIndex, fileRevParents, fileClogParentRevs); |
242 progress.worked(1); | |
243 cancel.checkCancelled(); | |
205 } catch (HgRuntimeException ex) { | 244 } catch (HgRuntimeException ex) { |
206 throw new HgLibraryFailureException(ex); | 245 throw new HgLibraryFailureException(ex); |
246 } finally { | |
247 progress.done(); | |
207 } | 248 } |
208 } | 249 } |
209 | 250 |
210 private void checkFile() { | 251 private void checkFile() { |
211 if (df == null) { | 252 if (df == null) { |