Mercurial > hg4j
comparison src/org/tmatesoft/hg/repo/HgDataFile.java @ 628:6526d8adbc0f
Explicit HgRuntimeException to facilitate easy switch from runtime to checked exceptions
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Wed, 22 May 2013 15:52:31 +0200 |
parents | b4948b159ab1 |
children | 5f52074707b2 |
comparison
equal
deleted
inserted
replaced
627:5153eb73b18d | 628:6526d8adbc0f |
---|---|
192 } | 192 } |
193 } | 193 } |
194 | 194 |
195 /** | 195 /** |
196 * @return file revision as recorded in repository manifest for dirstate parent, or <code>null</code> if no file revision can be found | 196 * @return file revision as recorded in repository manifest for dirstate parent, or <code>null</code> if no file revision can be found |
197 */ | 197 * @throws HgInvalidControlFileException if failed to access revlog index/data entry. <em>Runtime exception</em> |
198 private Nodeid getWorkingCopyRevision() throws HgInvalidControlFileException { | 198 * @throws HgRuntimeException subclass thereof to indicate other issues with the library. <em>Runtime exception</em> |
199 */ | |
200 private Nodeid getWorkingCopyRevision() throws HgRuntimeException { | |
199 final Pair<Nodeid, Nodeid> wcParents = getRepo().getWorkingCopyParents(); | 201 final Pair<Nodeid, Nodeid> wcParents = getRepo().getWorkingCopyParents(); |
200 Nodeid p = wcParents.first().isNull() ? wcParents.second() : wcParents.first(); | 202 Nodeid p = wcParents.first().isNull() ? wcParents.second() : wcParents.first(); |
201 final HgChangelog clog = getRepo().getChangelog(); | 203 final HgChangelog clog = getRepo().getChangelog(); |
202 final int csetRevIndex; | 204 final int csetRevIndex; |
203 if (p.isNull()) { | 205 if (p.isNull()) { |
215 final Nodeid tipRev = clog.getRevision(TIP); | 217 final Nodeid tipRev = clog.getRevision(TIP); |
216 if (tipRev.equals(p)) { | 218 if (tipRev.equals(p)) { |
217 csetRevIndex = clog.getLastRevision(); | 219 csetRevIndex = clog.getLastRevision(); |
218 } else { | 220 } else { |
219 // bad luck, need to search honestly | 221 // bad luck, need to search honestly |
220 csetRevIndex = getRepo().getChangelog().getRevisionIndex(p); | 222 csetRevIndex = clog.getRevisionIndex(p); |
221 } | 223 } |
222 } | 224 } |
223 Nodeid fileRev = getRepo().getManifest().getFileRevision(csetRevIndex, getPath()); | 225 Nodeid fileRev = getRepo().getManifest().getFileRevision(csetRevIndex, getPath()); |
224 // it's possible for a file to be in working dir and have store/.i but to belong e.g. to a different | 226 // it's possible for a file to be in working dir and have store/.i but to belong e.g. to a different |
225 // branch than the one from dirstate. Thus it's possible to get null fileRev | 227 // branch than the one from dirstate. Thus it's possible to get null fileRev |
426 } | 428 } |
427 | 429 |
428 /** | 430 /** |
429 * mimic 'hg diff -r clogRevIndex1 -r clogRevIndex2' | 431 * mimic 'hg diff -r clogRevIndex1 -r clogRevIndex2' |
430 */ | 432 */ |
431 public void diff(int clogRevIndex1, int clogRevIndex2, HgBlameInspector insp) throws HgCallbackTargetException { | 433 public void diff(int clogRevIndex1, int clogRevIndex2, HgBlameInspector insp) throws HgRuntimeException, HgCallbackTargetException { |
432 int fileRevIndex1 = fileRevIndex(this, clogRevIndex1); | 434 int fileRevIndex1 = fileRevIndex(this, clogRevIndex1); |
433 int fileRevIndex2 = fileRevIndex(this, clogRevIndex2); | 435 int fileRevIndex2 = fileRevIndex(this, clogRevIndex2); |
434 BlameHelper bh = new BlameHelper(insp); | 436 BlameHelper bh = new BlameHelper(insp); |
435 bh.prepare(this, clogRevIndex1, clogRevIndex2); | 437 bh.prepare(this, clogRevIndex1, clogRevIndex2); |
436 bh.diff(fileRevIndex1, clogRevIndex1, fileRevIndex2, clogRevIndex2); | 438 bh.diff(fileRevIndex1, clogRevIndex1, fileRevIndex2, clogRevIndex2); |
437 } | 439 } |
438 | 440 |
439 /** | 441 /** |
440 * Walk file history up/down to revision at given changeset and report changes for each revision | 442 * Walk file history up/down to revision at given changeset and report changes for each revision |
441 */ | 443 */ |
442 public void annotate(int changelogRevisionIndex, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgCallbackTargetException { | 444 public void annotate(int changelogRevisionIndex, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgRuntimeException, HgCallbackTargetException { |
443 annotate(0, changelogRevisionIndex, insp, iterateOrder); | 445 annotate(0, changelogRevisionIndex, insp, iterateOrder); |
444 } | 446 } |
445 | 447 |
446 /** | 448 /** |
447 * Walk file history range and report changes for each revision | 449 * Walk file history range and report changes for each revision |
448 */ | 450 */ |
449 public void annotate(int changelogRevIndexStart, int changelogRevIndexEnd, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgCallbackTargetException { | 451 public void annotate(int changelogRevIndexStart, int changelogRevIndexEnd, HgBlameInspector insp, HgIterateDirection iterateOrder) throws HgRuntimeException, HgCallbackTargetException { |
450 if (wrongRevisionIndex(changelogRevIndexStart) || wrongRevisionIndex(changelogRevIndexEnd)) { | 452 if (wrongRevisionIndex(changelogRevIndexStart) || wrongRevisionIndex(changelogRevIndexEnd)) { |
451 throw new IllegalArgumentException(); | 453 throw new IllegalArgumentException(); |
452 } | 454 } |
453 // Note, changelogRevIndexEnd may be TIP, while the code below doesn't tolerate constants | 455 // Note, changelogRevIndexEnd may be TIP, while the code below doesn't tolerate constants |
454 // | 456 // |
481 /** | 483 /** |
482 * Annotates changes of the file against its parent(s). | 484 * Annotates changes of the file against its parent(s). |
483 * Unlike {@link #annotate(HgDataFile, int, Inspector, HgIterateDirection)}, doesn't | 485 * Unlike {@link #annotate(HgDataFile, int, Inspector, HgIterateDirection)}, doesn't |
484 * walk file history, looks at the specified revision only. Handles both parents (if merge revision). | 486 * walk file history, looks at the specified revision only. Handles both parents (if merge revision). |
485 */ | 487 */ |
486 public void annotateSingleRevision(int changelogRevisionIndex, HgBlameInspector insp) throws HgCallbackTargetException { | 488 public void annotateSingleRevision(int changelogRevisionIndex, HgBlameInspector insp) throws HgRuntimeException, HgCallbackTargetException { |
487 // TODO detect if file is text/binary (e.g. looking for chars < ' ' and not \t\r\n\f | 489 // TODO detect if file is text/binary (e.g. looking for chars < ' ' and not \t\r\n\f |
488 int fileRevIndex = fileRevIndex(this, changelogRevisionIndex); | 490 int fileRevIndex = fileRevIndex(this, changelogRevisionIndex); |
489 int[] fileRevParents = new int[2]; | 491 int[] fileRevParents = new int[2]; |
490 parents(fileRevIndex, fileRevParents, null, null); | 492 parents(fileRevIndex, fileRevParents, null, null); |
491 if (changelogRevisionIndex == TIP) { | 493 if (changelogRevisionIndex == TIP) { |
507 sb.append(getPath()); | 509 sb.append(getPath()); |
508 sb.append(')'); | 510 sb.append(')'); |
509 return sb.toString(); | 511 return sb.toString(); |
510 } | 512 } |
511 | 513 |
512 private void checkAndRecordMetadata(int localRev) throws HgInvalidControlFileException { | 514 private void checkAndRecordMetadata(int localRev) throws HgRuntimeException { |
513 if (metadata == null) { | 515 if (metadata == null) { |
514 metadata = new Metadata(getRepo()); | 516 metadata = new Metadata(getRepo()); |
515 } | 517 } |
516 // use MetadataInspector without delegate to process metadata only | 518 // use MetadataInspector without delegate to process metadata only |
517 RevlogStream.Inspector insp = new MetadataInspector(metadata, null); | 519 RevlogStream.Inspector insp = new MetadataInspector(metadata, null); |
518 super.content.iterate(localRev, localRev, true, insp); | 520 super.content.iterate(localRev, localRev, true, insp); |
519 } | 521 } |
520 | 522 |
521 | 523 |
522 private static int fileRevIndex(HgDataFile df, int csetRevIndex) { | 524 private static int fileRevIndex(HgDataFile df, int csetRevIndex) throws HgRuntimeException { |
523 Nodeid fileRev = df.getRepo().getManifest().getFileRevision(csetRevIndex, df.getPath()); | 525 Nodeid fileRev = df.getRepo().getManifest().getFileRevision(csetRevIndex, df.getPath()); |
524 return df.getRevisionIndex(fileRev); | 526 return df.getRevisionIndex(fileRev); |
525 } | 527 } |
526 | 528 |
527 | 529 |
537 metadata = _metadata; | 539 metadata = _metadata; |
538 delegate = chain; | 540 delegate = chain; |
539 setCancelSupport(CancelSupport.Factory.get(chain)); | 541 setCancelSupport(CancelSupport.Factory.get(chain)); |
540 } | 542 } |
541 | 543 |
542 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { | 544 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgRuntimeException { |
543 try { | 545 try { |
544 if (metadata.tryRead(revisionNumber, data)) { | 546 if (metadata.tryRead(revisionNumber, data)) { |
545 // da is in prepared state (i.e. we consumed all bytes up to metadata end). | 547 // da is in prepared state (i.e. we consumed all bytes up to metadata end). |
546 // However, it's not safe to assume delegate won't call da.reset() for some reason, | 548 // However, it's not safe to assume delegate won't call da.reset() for some reason, |
547 // and we need to ensure predictable result. | 549 // and we need to ensure predictable result. |