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