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