Mercurial > jhg
comparison 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 |
comparison
equal
deleted
inserted
replaced
231:1792b37650f2 | 232:b7347daa50e3 |
---|---|
39 | 39 |
40 private final HgRepository repo; | 40 private final HgRepository repo; |
41 private Path file; | 41 private Path file; |
42 private int localRevision = TIP; | 42 private int localRevision = TIP; |
43 private Nodeid revision; | 43 private Nodeid revision; |
44 private Nodeid cset; | |
44 | 45 |
45 public HgCatCommand(HgRepository hgRepo) { | 46 public HgCatCommand(HgRepository hgRepo) { |
46 repo = hgRepo; | 47 repo = hgRepo; |
47 } | 48 } |
48 | 49 |
59 file = fname; | 60 file = fname; |
60 return this; | 61 return this; |
61 } | 62 } |
62 | 63 |
63 /** | 64 /** |
65 * Select specific local revision of the file to cat. Note, revision numbering is of particular file, not that of | |
66 * repository (i.e. revision 0 means initial content of the file, irrespective of changeset revision at the time of commit) | |
67 * | |
64 * Invocation of this method clears revision set with {@link #revision(Nodeid)} or {@link #revision(int)} earlier. | 68 * Invocation of this method clears revision set with {@link #revision(Nodeid)} or {@link #revision(int)} earlier. |
69 * | |
65 * XXX rev can't be WORKING_COPY (if allowed, need to implement in #execute()) | 70 * XXX rev can't be WORKING_COPY (if allowed, need to implement in #execute()) |
66 * @param rev local revision number, non-negative, or one of predefined constants. Note, use of {@link HgRepository#BAD_REVISION}, | 71 * @param rev local revision number, non-negative, or one of predefined constants. Note, use of {@link HgRepository#BAD_REVISION}, |
67 * although possible, makes little sense (command would fail if executed). | 72 * although possible, makes little sense (command would fail if executed). |
68 * @return <code>this</code> for convenience | 73 * @return <code>this</code> for convenience |
69 */ | 74 */ |
71 if (wrongLocalRevision(rev)) { | 76 if (wrongLocalRevision(rev)) { |
72 throw new IllegalArgumentException(String.valueOf(rev)); | 77 throw new IllegalArgumentException(String.valueOf(rev)); |
73 } | 78 } |
74 localRevision = rev; | 79 localRevision = rev; |
75 revision = null; | 80 revision = null; |
81 cset = null; | |
76 return this; | 82 return this; |
77 } | 83 } |
78 | 84 |
79 /** | 85 /** |
80 * Select revision to read. Invocation of this method clears revision set with {@link #revision(int)} or {@link #revision(Nodeid)} earlier. | 86 * Select revision to read. Note, this revision is file revision (i.e. the one from manifest), not the changeset revision. |
87 * | |
88 * Invocation of this method clears revision set with {@link #revision(int)} or {@link #revision(Nodeid)} earlier. | |
81 * | 89 * |
82 * @param nodeid - unique revision identifier, Note, use of <code>null</code> or {@link Nodeid#NULL} is senseless | 90 * @param nodeid - unique file revision identifier, Note, use of <code>null</code> or {@link Nodeid#NULL} is senseless |
83 * @return <code>this</code> for convenience | 91 * @return <code>this</code> for convenience |
84 */ | 92 */ |
85 public HgCatCommand revision(Nodeid nodeid) { | 93 public HgCatCommand revision(Nodeid nodeid) { |
86 if (nodeid != null && nodeid.isNull()) { | 94 if (nodeid != null && nodeid.isNull()) { |
87 nodeid = null; | 95 nodeid = null; |
88 } | 96 } |
89 revision = nodeid; | 97 revision = nodeid; |
90 localRevision = BAD_REVISION; | 98 localRevision = BAD_REVISION; |
99 cset = null; | |
100 return this; | |
101 } | |
102 | |
103 /** | |
104 * 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 | |
105 * operates in terms of repository global revisions (aka changesets). | |
106 * | |
107 * Invocation of this method clears local file revisions selection. | |
108 * | |
109 * @param nodeid changeset revision | |
110 * @return <code>this</code> for convenience | |
111 */ | |
112 public HgCatCommand changeset(Nodeid nodeid) { | |
113 localRevision = BAD_REVISION; | |
114 revision = null; | |
115 cset = nodeid; | |
91 return this; | 116 return this; |
92 } | 117 } |
93 | 118 |
94 /** | 119 /** |
95 * Runs the command with current set of parameters and pipes data to provided sink. | 120 * Runs the command with current set of parameters and pipes data to provided sink. |
97 * @param sink output channel to write data to. | 122 * @param sink output channel to write data to. |
98 * @throws HgDataStreamException | 123 * @throws HgDataStreamException |
99 * @throws IllegalArgumentException when command arguments are incomplete or wrong | 124 * @throws IllegalArgumentException when command arguments are incomplete or wrong |
100 */ | 125 */ |
101 public void execute(ByteChannel sink) throws HgDataStreamException, IOException, CancelledException { | 126 public void execute(ByteChannel sink) throws HgDataStreamException, IOException, CancelledException { |
102 if (localRevision == BAD_REVISION && revision == null) { | 127 if (localRevision == BAD_REVISION && revision == null && cset == null) { |
103 throw new IllegalArgumentException("Either local file revision number or nodeid shall be specified"); | 128 throw new IllegalArgumentException("File revision, corresponing local number, or a changset nodeid shall be specified"); |
104 } | 129 } |
105 if (file == null) { | 130 if (file == null) { |
106 throw new IllegalArgumentException("Name of the file is missing"); | 131 throw new IllegalArgumentException("Name of the file is missing"); |
107 } | 132 } |
108 if (sink == null) { | 133 if (sink == null) { |
111 HgDataFile dataFile = repo.getFileNode(file); | 136 HgDataFile dataFile = repo.getFileNode(file); |
112 if (!dataFile.exists()) { | 137 if (!dataFile.exists()) { |
113 throw new HgDataStreamException(file, new FileNotFoundException(file.toString())); | 138 throw new HgDataStreamException(file, new FileNotFoundException(file.toString())); |
114 } | 139 } |
115 int revToExtract; | 140 int revToExtract; |
116 if (revision != null) { | 141 if (cset != null) { |
142 int csetRev = repo.getChangelog().getLocalRevision(cset); | |
143 Nodeid toExtract = null; | |
144 do { | |
145 toExtract = repo.getManifest().getFileRevision(csetRev, file); | |
146 if (toExtract == null) { | |
147 if (dataFile.isCopy()) { | |
148 file = dataFile.getCopySourceName(); | |
149 dataFile = repo.getFileNode(file); | |
150 } else { | |
151 break; | |
152 } | |
153 } | |
154 } while (toExtract == null); | |
155 if (toExtract == null) { | |
156 throw new HgBadStateException(String.format("File %s not its origins were not known at repository %s revision", file, cset.shortNotation())); | |
157 } | |
158 revToExtract = dataFile.getLocalRevision(toExtract); | |
159 } else if (revision != null) { | |
117 revToExtract = dataFile.getLocalRevision(revision); | 160 revToExtract = dataFile.getLocalRevision(revision); |
118 } else { | 161 } else { |
119 revToExtract = localRevision; | 162 revToExtract = localRevision; |
120 } | 163 } |
121 dataFile.contentWithFilters(revToExtract, sink); | 164 dataFile.contentWithFilters(revToExtract, sink); |