Mercurial > jhg
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. | 
