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