Mercurial > jhg
diff src/org/tmatesoft/hg/core/HgCatCommand.java @ 232:b7347daa50e3
Allow to cat a file with changeset revision
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Thu, 02 Jun 2011 05:13:39 +0200 |
parents | 41a778e3fd31 |
children | 6e1373b54e9b |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/core/HgCatCommand.java Wed Jun 01 05:44:25 2011 +0200 +++ b/src/org/tmatesoft/hg/core/HgCatCommand.java Thu Jun 02 05:13:39 2011 +0200 @@ -41,6 +41,7 @@ private Path file; private int localRevision = TIP; private Nodeid revision; + private Nodeid cset; public HgCatCommand(HgRepository hgRepo) { repo = hgRepo; @@ -61,7 +62,11 @@ } /** + * Select specific local revision of the file to cat. Note, revision numbering is of particular file, not that of + * repository (i.e. revision 0 means initial content of the file, irrespective of changeset revision at the time of commit) + * * Invocation of this method clears revision set with {@link #revision(Nodeid)} or {@link #revision(int)} earlier. + * * XXX rev can't be WORKING_COPY (if allowed, need to implement in #execute()) * @param rev local revision number, non-negative, or one of predefined constants. Note, use of {@link HgRepository#BAD_REVISION}, * although possible, makes little sense (command would fail if executed). @@ -73,13 +78,16 @@ } localRevision = rev; revision = null; + cset = null; return this; } /** - * Select revision to read. Invocation of this method clears revision set with {@link #revision(int)} or {@link #revision(Nodeid)} earlier. + * Select revision to read. Note, this revision is file revision (i.e. the one from manifest), not the changeset revision. + * + * Invocation of this method clears revision set with {@link #revision(int)} or {@link #revision(Nodeid)} earlier. * - * @param nodeid - unique revision identifier, Note, use of <code>null</code> or {@link Nodeid#NULL} is senseless + * @param nodeid - unique file revision identifier, Note, use of <code>null</code> or {@link Nodeid#NULL} is senseless * @return <code>this</code> for convenience */ public HgCatCommand revision(Nodeid nodeid) { @@ -88,6 +96,23 @@ } revision = nodeid; localRevision = BAD_REVISION; + cset = null; + return this; + } + + /** + * Select whatever revision of the file that was actual at the time of the specified changeset. Unlike {@link #revision(int)} or {@link #revision(Nodeid)}, this method + * operates in terms of repository global revisions (aka changesets). + * + * Invocation of this method clears local file revisions selection. + * + * @param nodeid changeset revision + * @return <code>this</code> for convenience + */ + public HgCatCommand changeset(Nodeid nodeid) { + localRevision = BAD_REVISION; + revision = null; + cset = nodeid; return this; } @@ -99,8 +124,8 @@ * @throws IllegalArgumentException when command arguments are incomplete or wrong */ public void execute(ByteChannel sink) throws HgDataStreamException, IOException, CancelledException { - if (localRevision == BAD_REVISION && revision == null) { - throw new IllegalArgumentException("Either local file revision number or nodeid shall be specified"); + if (localRevision == BAD_REVISION && revision == null && cset == null) { + throw new IllegalArgumentException("File revision, corresponing local number, or a changset nodeid shall be specified"); } if (file == null) { throw new IllegalArgumentException("Name of the file is missing"); @@ -113,7 +138,25 @@ throw new HgDataStreamException(file, new FileNotFoundException(file.toString())); } int revToExtract; - if (revision != null) { + if (cset != null) { + int csetRev = repo.getChangelog().getLocalRevision(cset); + Nodeid toExtract = null; + do { + toExtract = repo.getManifest().getFileRevision(csetRev, file); + if (toExtract == null) { + if (dataFile.isCopy()) { + file = dataFile.getCopySourceName(); + dataFile = repo.getFileNode(file); + } else { + break; + } + } + } while (toExtract == null); + if (toExtract == null) { + throw new HgBadStateException(String.format("File %s not its origins were not known at repository %s revision", file, cset.shortNotation())); + } + revToExtract = dataFile.getLocalRevision(toExtract); + } else if (revision != null) { revToExtract = dataFile.getLocalRevision(revision); } else { revToExtract = localRevision;