Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgDataFile.java @ 689:5050ee565bd1
Issue 44: Renames/copies other than for the very first revision of a file are not recognized
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Sat, 27 Jul 2013 22:06:14 +0200 |
| parents | 12a4f60ea972 |
| children | 7efabe0cddcf |
comparison
equal
deleted
inserted
replaced
| 688:1499139a600a | 689:5050ee565bd1 |
|---|---|
| 26 import java.nio.ByteBuffer; | 26 import java.nio.ByteBuffer; |
| 27 import java.nio.channels.FileChannel; | 27 import java.nio.channels.FileChannel; |
| 28 import java.util.Arrays; | 28 import java.util.Arrays; |
| 29 | 29 |
| 30 import org.tmatesoft.hg.core.HgChangesetFileSneaker; | 30 import org.tmatesoft.hg.core.HgChangesetFileSneaker; |
| 31 import org.tmatesoft.hg.core.HgFileRevision; | |
| 31 import org.tmatesoft.hg.core.Nodeid; | 32 import org.tmatesoft.hg.core.Nodeid; |
| 32 import org.tmatesoft.hg.internal.DataAccess; | 33 import org.tmatesoft.hg.internal.DataAccess; |
| 33 import org.tmatesoft.hg.internal.FileUtils; | 34 import org.tmatesoft.hg.internal.FileUtils; |
| 34 import org.tmatesoft.hg.internal.FilterByteChannel; | 35 import org.tmatesoft.hg.internal.FilterByteChannel; |
| 35 import org.tmatesoft.hg.internal.FilterDataAccess; | 36 import org.tmatesoft.hg.internal.FilterDataAccess; |
| 369 int changelogRevision = getChangesetRevisionIndex(getRevisionIndex(nid)); | 370 int changelogRevision = getChangesetRevisionIndex(getRevisionIndex(nid)); |
| 370 return getRepo().getChangelog().getRevision(changelogRevision); | 371 return getRepo().getChangelog().getRevision(changelogRevision); |
| 371 } | 372 } |
| 372 | 373 |
| 373 /** | 374 /** |
| 374 * Tells whether this file originates from another repository file | 375 * Tells whether first revision of this file originates from another repository file. |
| 375 * @return <code>true</code> if this file is a copy of another from the repository | 376 * This method is shorthand for {@link #isCopy(int) isCopy(0)} and it's advised to use {@link #isCopy(int)} instead. |
| 377 * | |
| 378 * @return <code>true</code> if first revision of this file is a copy of some other from the repository | |
| 376 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 379 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> |
| 377 */ | 380 */ |
| 378 public boolean isCopy() throws HgRuntimeException { | 381 public boolean isCopy() throws HgRuntimeException { |
| 379 if (metadata == null || !metadata.checked(0)) { | 382 return isCopy(0); |
| 380 checkAndRecordMetadata(0); | 383 } |
| 381 } | 384 |
| 382 if (!metadata.known(0)) { | 385 /** |
| 383 return false; | 386 * Get name of the file first revision of this one was copied from. |
| 384 } | 387 * Note, it's better to use {@link #getCopySource(int)} instead. |
| 385 return metadata.find(0, "copy") != null; | |
| 386 } | |
| 387 | |
| 388 /** | |
| 389 * Get name of the file this one was copied from. | |
| 390 * | 388 * |
| 391 * @return name of the file origin | 389 * @return name of the file origin |
| 392 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 390 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> |
| 393 */ | 391 */ |
| 394 public Path getCopySourceName() throws HgRuntimeException { | 392 public Path getCopySourceName() throws HgRuntimeException { |
| 398 } | 396 } |
| 399 throw new UnsupportedOperationException(); // XXX REVISIT, think over if Exception is good (clients would check isCopy() anyway, perhaps null is sufficient?) | 397 throw new UnsupportedOperationException(); // XXX REVISIT, think over if Exception is good (clients would check isCopy() anyway, perhaps null is sufficient?) |
| 400 } | 398 } |
| 401 | 399 |
| 402 /** | 400 /** |
| 403 * | 401 * Use {@link #getCopySource(int)} instead |
| 404 * @return revision this file was copied from | 402 * @return revision this file was copied from |
| 405 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | 403 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> |
| 406 */ | 404 */ |
| 407 public Nodeid getCopySourceRevision() throws HgRuntimeException { | 405 public Nodeid getCopySourceRevision() throws HgRuntimeException { |
| 408 if (isCopy()) { | 406 if (isCopy()) { |
| 409 return Nodeid.fromAscii(metadata.find(0, "copyrev")); // XXX reuse/cache Nodeid | 407 return Nodeid.fromAscii(metadata.find(0, "copyrev")); // XXX reuse/cache Nodeid |
| 410 } | 408 } |
| 411 throw new UnsupportedOperationException(); | 409 throw new UnsupportedOperationException(); |
| 410 } | |
| 411 | |
| 412 /** | |
| 413 * Tell if specified file revision was created by copying or renaming another file | |
| 414 * | |
| 415 * @param fileRevisionIndex index of file revision to check | |
| 416 * @return <code>true</code> if this revision originates (as a result of copy/rename) from another file | |
| 417 * @throws HgRuntimeException subclass thereof to indicate issues with the library. <em>Runtime exception</em> | |
| 418 * @since 1.2 | |
| 419 */ | |
| 420 public boolean isCopy(int fileRevisionIndex) throws HgRuntimeException { | |
| 421 if (fileRevisionIndex == TIP) { | |
| 422 fileRevisionIndex = getLastRevision(); | |
| 423 } | |
| 424 if (wrongRevisionIndex(fileRevisionIndex) || fileRevisionIndex == BAD_REVISION || fileRevisionIndex == WORKING_COPY || fileRevisionIndex == NO_REVISION) { | |
| 425 throw new HgInvalidRevisionException(fileRevisionIndex); | |
| 426 } | |
| 427 | |
| 428 if (metadata == null || !metadata.checked(fileRevisionIndex)) { | |
| 429 checkAndRecordMetadata(fileRevisionIndex); | |
| 430 } | |
| 431 if (!metadata.known(fileRevisionIndex)) { | |
| 432 return false; | |
| 433 } | |
| 434 return metadata.find(fileRevisionIndex, "copy") != null; | |
| 435 } | |
| 436 | |
| 437 /** | |
| 438 * Find out which file and which revision of that file given revision originates from | |
| 439 * | |
| 440 * @param fileRevisionIndex file revision index of interest, it's assumed {@link #isCopy(int)} for the same revision is <code>true</code> | |
| 441 * @return origin revision descriptor | |
| 442 * @throws HgRuntimeException | |
| 443 * @throws UnsupportedOperationException if specified revision is not a {@link #isCopy(int) copy} revision | |
| 444 * @since 1.2 | |
| 445 */ | |
| 446 public HgFileRevision getCopySource(int fileRevisionIndex) throws HgRuntimeException { | |
| 447 if (fileRevisionIndex == TIP) { | |
| 448 fileRevisionIndex = getLastRevision(); | |
| 449 } | |
| 450 if (!isCopy(fileRevisionIndex)) { | |
| 451 throw new UnsupportedOperationException(); | |
| 452 } | |
| 453 Path.Source ps = getRepo().getSessionContext().getPathFactory(); | |
| 454 Path origin = ps.path(metadata.find(fileRevisionIndex, "copy")); | |
| 455 Nodeid originRev = Nodeid.fromAscii(metadata.find(fileRevisionIndex, "copyrev")); // XXX reuse/cache Nodeid | |
| 456 return new HgFileRevision(getRepo(), originRev, null, origin); | |
| 412 } | 457 } |
| 413 | 458 |
| 414 /** | 459 /** |
| 415 * Get file flags recorded in the manifest | 460 * Get file flags recorded in the manifest |
| 416 * @param fileRevisionIndex - revision local index, non-negative, or {@link HgRepository#TIP}. | 461 * @param fileRevisionIndex - revision local index, non-negative, or {@link HgRepository#TIP}. |
