annotate src/org/tmatesoft/hg/repo/HgDataFile.java @ 416:d30083c80d52

Better names - non-confusing and aligned with the rest of API
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 22 Mar 2012 19:11:33 +0100
parents ee8264d80747
children ccd7d25e5aea
rev   line source
17
571e1b2cc3f7 Query file for its parents. Demo of recently added ignore and digest support from within cat cmd
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 5
diff changeset
1 /*
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
2 * Copyright (c) 2010-2012 TMate Software Ltd
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
3 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
4 * This program is free software; you can redistribute it and/or modify
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
5 * it under the terms of the GNU General Public License as published by
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
6 * the Free Software Foundation; version 2 of the License.
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
7 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
8 * This program is distributed in the hope that it will be useful,
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
11 * GNU General Public License for more details.
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
12 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
13 * For information on how to redistribute this software under
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
14 * the terms of a license other than GNU General Public License
102
a3a2e5deb320 Updated contact address to support@hg4j.com
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 88
diff changeset
15 * contact TMate Software at support@hg4j.com
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
16 */
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
17 package org.tmatesoft.hg.repo;
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
18
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
19 import static org.tmatesoft.hg.repo.HgInternals.wrongRevisionIndex;
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
20 import static org.tmatesoft.hg.repo.HgRepository.*;
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
21
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
22 import java.io.ByteArrayOutputStream;
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
23 import java.io.File;
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
24 import java.io.FileInputStream;
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
25 import java.io.IOException;
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
26 import java.nio.ByteBuffer;
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
27 import java.nio.channels.FileChannel;
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
28 import java.util.ArrayList;
240
29231022fec8 Do not expect file history to be ordered
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 237
diff changeset
29 import java.util.Arrays;
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
30 import java.util.Collection;
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
31 import java.util.Collections;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
32 import java.util.List;
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
33
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
34 import org.tmatesoft.hg.core.HgException;
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
35 import org.tmatesoft.hg.core.HgInvalidControlFileException;
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
36 import org.tmatesoft.hg.core.HgInvalidFileException;
347
8da7ade36c57 Add specific IAE subclass to handle wrong (e.g. outdated after rollback) revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 328
diff changeset
37 import org.tmatesoft.hg.core.HgInvalidRevisionException;
328
a674b8590362 Move file tree history to upper API level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 323
diff changeset
38 import org.tmatesoft.hg.core.HgLogCommand;
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
39 import org.tmatesoft.hg.core.Nodeid;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
40 import org.tmatesoft.hg.internal.DataAccess;
121
b1d6208fb517 Conditionally apply filters to file content
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 115
diff changeset
41 import org.tmatesoft.hg.internal.FilterByteChannel;
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
42 import org.tmatesoft.hg.internal.FilterDataAccess;
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
43 import org.tmatesoft.hg.internal.IntMap;
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
44 import org.tmatesoft.hg.internal.RevlogStream;
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
45 import org.tmatesoft.hg.util.ByteChannel;
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
46 import org.tmatesoft.hg.util.CancelSupport;
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
47 import org.tmatesoft.hg.util.CancelledException;
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
48 import org.tmatesoft.hg.util.LogFacility;
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
49 import org.tmatesoft.hg.util.Pair;
133
4a948ec83980 core.Path to util.Path as it's not Hg repo dependant
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 129
diff changeset
50 import org.tmatesoft.hg.util.Path;
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
51 import org.tmatesoft.hg.util.ProgressSupport;
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
52
5
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 3
diff changeset
53
17
571e1b2cc3f7 Query file for its parents. Demo of recently added ignore and digest support from within cat cmd
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 5
diff changeset
54
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
55 /**
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
56 * ? name:HgFileNode?
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
57 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
58 * @author Artem Tikhomirov
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
59 * @author TMate Software Ltd.
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
60 */
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
61 public class HgDataFile extends Revlog {
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
62
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
63 // absolute from repo root?
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
64 // slashes, unix-style?
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
65 // repo location agnostic, just to give info to user, not to access real storage
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
66 private final Path path;
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
67 private Metadata metadata; // get initialized on first access to file content.
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
68
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
69 /*package-local*/HgDataFile(HgRepository hgRepo, Path filePath, RevlogStream content) {
21
e929cecae4e1 Refactor to move revlog content to base class
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 17
diff changeset
70 super(hgRepo, content);
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
71 path = filePath;
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
72 }
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
73
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
74 /*package-local*/HgDataFile(HgRepository hgRepo, Path filePath) {
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
75 super(hgRepo);
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
76 path = filePath;
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
77 }
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
78
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
79 // exists is not the best name possible. now it means no file with such name was ever known to the repo.
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
80 // it might be confused with files existed before but lately removed.
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
81 public boolean exists() {
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
82 return content != null; // XXX need better impl
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
83 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
84
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
85 // human-readable (i.e. "COPYING", not "store/data/_c_o_p_y_i_n_g.i")
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
86 public Path getPath() {
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
87 return path; // hgRepo.backresolve(this) -> name? In this case, what about hashed long names?
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
88 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
89
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
90 /**
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
91 * Handy shorthand for {@link #getLength(int) length(getRevisionIndex(nodeid))}
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
92 *
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
93 * @param nodeid revision of the file
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
94 *
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
95 * @return size of the file content at the given revision
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
96 * @throws HgInvalidRevisionException if supplied nodeid doesn't identify any revision from this revlog (<em>runtime exception</em>)
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
97 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
98 */
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
99 public int getLength(Nodeid nodeid) throws HgInvalidControlFileException, HgInvalidRevisionException {
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
100 try {
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
101 return getLength(getRevisionIndex(nodeid));
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
102 } catch (HgInvalidControlFileException ex) {
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
103 throw ex.isRevisionSet() ? ex : ex.setRevision(nodeid);
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
104 } catch (HgInvalidRevisionException ex) {
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
105 throw ex.isRevisionSet() ? ex : ex.setRevision(nodeid);
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
106 }
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
107 }
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
108
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
109 /**
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
110 * @deprecated Use {@link #getLength(Nodeid)} instead
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
111 */
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
112 @Deprecated
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
113 public int length(Nodeid nodeid) throws HgInvalidControlFileException, HgInvalidRevisionException {
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
114 return getLength(nodeid);
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
115 }
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
116
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
117 /**
368
8107b95f4280 Update Javadoc with 'revision index'
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
118 * @param fileRevisionIndex - revision local index, non-negative. From predefined constants, only {@link HgRepository#TIP} makes sense.
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
119 * @return size of the file content at the revision identified by local revision number.
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
120 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog (<em>runtime exception</em>)
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
121 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
122 */
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
123 public int getLength(int fileRevisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException {
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
124 if (wrongRevisionIndex(fileRevisionIndex) || fileRevisionIndex == BAD_REVISION) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
125 throw new HgInvalidRevisionException(fileRevisionIndex);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
126 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
127 if (fileRevisionIndex == TIP) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
128 fileRevisionIndex = getLastRevision();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
129 } else if (fileRevisionIndex == WORKING_COPY) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
130 File f = getRepo().getFile(this);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
131 if (f.exists()) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
132 return (int) /*FIXME long!*/ f.length();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
133 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
134 Nodeid fileRev = getWorkingCopyRevision();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
135 if (fileRev == null) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
136 throw new HgInvalidRevisionException(String.format("File %s is not part of working copy", getPath()), null, fileRevisionIndex);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
137 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
138 fileRevisionIndex = getRevisionIndex(fileRev);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
139 }
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
140 if (metadata == null || !metadata.checked(fileRevisionIndex)) {
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
141 checkAndRecordMetadata(fileRevisionIndex);
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
142 }
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
143 final int dataLen = content.dataLength(fileRevisionIndex);
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
144 if (metadata.known(fileRevisionIndex)) {
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
145 return dataLen - metadata.dataOffset(fileRevisionIndex);
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
146 }
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
147 return dataLen;
22
603806cd2dc6 Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 21
diff changeset
148 }
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
149
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
150 /**
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
151 * @deprecated Use {@link #getLength(int)} instead
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
152 */
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
153 @Deprecated
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
154 public int length(int fileRevisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException {
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
155 return getLength(fileRevisionIndex);
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
156 }
22
603806cd2dc6 Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 21
diff changeset
157
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
158 /**
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
159 * Reads content of the file from working directory. If file present in the working directory, its actual content without
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
160 * any filters is supplied through the sink. If file does not exist in the working dir, this method provides content of a file
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
161 * as if it would be refreshed in the working copy, i.e. its corresponding revision (according to dirstate) is read from the
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
162 * repository, and filters repo -> working copy get applied.
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
163 *
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
164 * NOTE, if file is missing from the working directory and is not part of the dirstate (but otherwise legal repository file,
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
165 * e.g. from another branch), no content would be supplied.
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
166 *
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
167 * @param sink content consumer
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
168 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
169 * @throws HgInvalidFileException if access to file in working directory failed
380
9517df1ef7ec Comments/javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 368
diff changeset
170 * @throws CancelledException if execution of the operation was cancelled
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
171 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
172 public void workingCopy(ByteChannel sink) throws HgException, CancelledException {
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
173 File f = getRepo().getFile(this);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
174 if (f.exists()) {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
175 final CancelSupport cs = CancelSupport.Factory.get(sink);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
176 final ProgressSupport progress = ProgressSupport.Factory.get(sink);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
177 final long flength = f.length();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
178 final int bsize = (int) Math.min(flength, 32*1024);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
179 progress.start((int) (flength > Integer.MAX_VALUE ? flength >>> 15 /*32 kb buf size*/ : flength));
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
180 ByteBuffer buf = ByteBuffer.allocate(bsize);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
181 FileChannel fc = null;
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
182 try {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
183 fc = new FileInputStream(f).getChannel();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
184 while (fc.read(buf) != -1) {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
185 cs.checkCancelled();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
186 buf.flip();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
187 int consumed = sink.write(buf);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
188 progress.worked(flength > Integer.MAX_VALUE ? 1 : consumed);
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
189 buf.compact();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
190 }
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
191 } catch (IOException ex) {
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
192 throw new HgInvalidFileException("Working copy read failed", ex, f);
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
193 } finally {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
194 progress.done();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
195 if (fc != null) {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
196 try {
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
197 fc.close();
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
198 } catch (IOException ex) {
295
981f9f50bb6c Issue 11: Error log facility. SessionContext to share common facilities
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 277
diff changeset
199 getRepo().getContext().getLog().info(getClass(), ex, null);
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
200 }
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
201 }
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
202 }
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
203 } else {
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
204 Nodeid fileRev = getWorkingCopyRevision();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
205 if (fileRev == null) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
206 // no content for this data file in the working copy - it is not part of the actual working state.
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
207 // XXX perhaps, shall report this to caller somehow, not silently pass no data?
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
208 return;
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
209 }
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
210 final int fileRevIndex = getRevisionIndex(fileRev);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
211 contentWithFilters(fileRevIndex, sink);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
212 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
213 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
214
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
215 /**
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
216 * @return file revision as recorded in repository manifest for dirstate parent, or <code>null</code> if no file revision can be found
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
217 */
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
218 private Nodeid getWorkingCopyRevision() throws HgInvalidControlFileException {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
219 final Pair<Nodeid, Nodeid> wcParents = getRepo().getWorkingCopyParents();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
220 Nodeid p = wcParents.first().isNull() ? wcParents.second() : wcParents.first();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
221 final HgChangelog clog = getRepo().getChangelog();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
222 final int csetRevIndex;
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
223 if (p.isNull()) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
224 // no dirstate parents
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
225 getRepo().getContext().getLog().info(getClass(), "No dirstate parents, resort to TIP", getPath());
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
226 // if it's a repository with no dirstate, use TIP then
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
227 csetRevIndex = clog.getLastRevision();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
228 if (csetRevIndex == -1) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
229 // shall not happen provided there's .i for this data file (hence at least one cset)
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
230 // and perhaps exception is better here. However, null as "can't find" indication seems reasonable.
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
231 return null;
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
232 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
233 } else {
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
234 // common case to avoid searching complete changelog for nodeid match
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
235 final Nodeid tipRev = clog.getRevision(TIP);
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
236 if (tipRev.equals(p)) {
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
237 csetRevIndex = clog.getLastRevision();
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
238 } else {
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
239 // bad luck, need to search honestly
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
240 csetRevIndex = getRepo().getChangelog().getRevisionIndex(p);
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
241 }
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
242 }
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
243 Nodeid fileRev = getRepo().getManifest().getFileRevision(csetRevIndex, getPath());
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
244 // it's possible for a file to be in working dir and have store/.i but to belong e.g. to a different
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
245 // branch than the one from dirstate. Thus it's possible to get null fileRev
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
246 // which would serve as an indication this data file is not part of working copy
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
247 return fileRev;
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
248 }
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
249
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
250 /**
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
251 * Access content of a file revision
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
252 * XXX not sure distinct method contentWithFilters() is the best way to do, perhaps, callers shall add filters themselves?
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
253 *
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
254 * @param fileRevisionIndex - revision local index, non-negative. From predefined constants, {@link HgRepository#TIP} and {@link HgRepository#WORKING_COPY} make sense.
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
255 * @param sink content consumer
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
256 *
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
257 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
258 * @throws HgInvalidFileException if access to file in working directory failed
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
259 * @throws CancelledException if execution of the operation was cancelled
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
260 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog (<em>runtime exception</em>)
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
261 */
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
262 public void contentWithFilters(int fileRevisionIndex, ByteChannel sink) throws HgException, CancelledException, HgInvalidRevisionException {
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
263 if (fileRevisionIndex == WORKING_COPY) {
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
264 workingCopy(sink); // pass un-mangled sink
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
265 } else {
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
266 content(fileRevisionIndex, new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath())));
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
267 }
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
268 }
22
603806cd2dc6 Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 21
diff changeset
269
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
270 /**
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
271 * Retrieve content of specific revision. Content is provided as is, without any filters (e.g. keywords, eol, etc.) applied.
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
272 * For filtered content, use {@link #contentWithFilters(int, ByteChannel)}.
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
273 *
368
8107b95f4280 Update Javadoc with 'revision index'
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
274 * @param fileRevisionIndex - revision local index, non-negative. From predefined constants, {@link HgRepository#TIP} and {@link HgRepository#WORKING_COPY} make sense.
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
275 * @param sink content consumer
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
276 *
380
9517df1ef7ec Comments/javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 368
diff changeset
277 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
278 * @throws HgInvalidFileException if access to file in working directory failed
380
9517df1ef7ec Comments/javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 368
diff changeset
279 * @throws CancelledException if execution of the operation was cancelled
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
280 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog (<em>runtime exception</em>)
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
281 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
282 public void content(int fileRevisionIndex, ByteChannel sink) throws HgException, CancelledException, HgInvalidRevisionException {
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
283 // for data files need to check heading of the file content for possible metadata
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
284 // @see http://mercurial.selenic.com/wiki/FileFormats#data.2BAC8-
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
285 if (fileRevisionIndex == TIP) {
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
286 fileRevisionIndex = getLastRevision();
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
287 }
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
288 if (fileRevisionIndex == WORKING_COPY) {
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
289 // sink is supposed to come into workingCopy without filters
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
290 // thus we shall not get here (into #content) from #contentWithFilters(WC)
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
291 workingCopy(sink);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
292 return;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
293 }
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
294 if (wrongRevisionIndex(fileRevisionIndex) || fileRevisionIndex == BAD_REVISION) {
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
295 throw new HgInvalidRevisionException(fileRevisionIndex);
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
296 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
297 if (sink == null) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
298 throw new IllegalArgumentException();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
299 }
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
300 if (metadata == null) {
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
301 metadata = new Metadata();
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
302 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
303 ErrorHandlingInspector insp;
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
304 final LogFacility lf = getRepo().getContext().getLog();
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
305 if (metadata.none(fileRevisionIndex)) {
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
306 insp = new ContentPipe(sink, 0, lf);
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
307 } else if (metadata.known(fileRevisionIndex)) {
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
308 insp = new ContentPipe(sink, metadata.dataOffset(fileRevisionIndex), lf);
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
309 } else {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
310 // do not know if there's metadata
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
311 insp = new MetadataInspector(metadata, lf, new ContentPipe(sink, 0, lf));
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
312 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
313 insp.checkCancelled();
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
314 super.content.iterate(fileRevisionIndex, fileRevisionIndex, true, insp);
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
315 try {
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
316 insp.checkFailed(); // XXX is there real need to throw IOException from ContentPipe?
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
317 } catch (HgInvalidControlFileException ex) {
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
318 ex = ex.setFileName(getPath());
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
319 throw ex.isRevisionIndexSet() ? ex : ex.setRevisionIndex(fileRevisionIndex);
237
6e1373b54e9b Allow access to working copy content through HgDataFile. Give access to repository's working dir
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 233
diff changeset
320 } catch (IOException ex) {
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
321 HgInvalidControlFileException e = new HgInvalidControlFileException("Revision content access failed", ex, null);
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
322 throw content.initWithIndexFile(e).setFileName(getPath()).setRevisionIndex(fileRevisionIndex);
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
323 } catch (HgException ex) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
324 // shall not happen, unless we changed ContentPipe or its subclass
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
325 HgInvalidControlFileException e = new HgInvalidControlFileException("Revision content access failed", ex, null);
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
326 throw content.initWithIndexFile(e).setFileName(getPath()).setRevisionIndex(fileRevisionIndex);
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
327 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
328 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
329
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
330 private static class HistoryNode {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
331 int changeset;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
332 Nodeid cset;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
333 HistoryNode parent1, parent2;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
334 List<HistoryNode> children;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
335
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
336 HistoryNode(int cs, HistoryNode p1, HistoryNode p2) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
337 changeset = cs;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
338 parent1 = p1;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
339 parent2 = p2;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
340 if (p1 != null) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
341 p1.addChild(this);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
342 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
343 if (p2 != null) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
344 p2.addChild(this);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
345 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
346 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
347
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
348 Nodeid changesetRevision() {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
349 assert cset != null : "we initialize all csets prior to use";
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
350 return cset;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
351 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
352
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
353 void addChild(HistoryNode child) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
354 if (children == null) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
355 children = new ArrayList<HistoryNode>(2);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
356 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
357 children.add(child);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
358 }
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
359 }
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
360
328
a674b8590362 Move file tree history to upper API level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 323
diff changeset
361 /**
a674b8590362 Move file tree history to upper API level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 323
diff changeset
362 * @deprecated use {@link HgLogCommand#execute(org.tmatesoft.hg.core.HgChangesetTreeHandler)} instead
a674b8590362 Move file tree history to upper API level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 323
diff changeset
363 */
a674b8590362 Move file tree history to upper API level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 323
diff changeset
364 @Deprecated
366
189dc6dc1c3e Use exceptions to expose errors reading mercurial data
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 355
diff changeset
365 public void history(HgChangelog.TreeInspector inspector) throws HgInvalidControlFileException{
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
366 final CancelSupport cancelSupport = CancelSupport.Factory.get(inspector);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
367 try {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
368 final boolean[] needsSorting = { false };
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
369 final HistoryNode[] completeHistory = new HistoryNode[getRevisionCount()];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
370 final int[] commitRevisions = new int[completeHistory.length];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
371 RevlogStream.Inspector insp = new RevlogStream.Inspector() {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
372 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
373 if (revisionNumber > 0) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
374 if (commitRevisions[revisionNumber-1] > linkRevision) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
375 needsSorting[0] = true;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
376 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
377 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
378 commitRevisions[revisionNumber] = linkRevision;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
379 HistoryNode p1 = null, p2 = null;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
380 if (parent1Revision != -1) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
381 p1 = completeHistory[parent1Revision];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
382 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
383 if (parent2Revision != -1) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
384 p2 = completeHistory[parent2Revision];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
385 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
386 completeHistory[revisionNumber] = new HistoryNode(linkRevision, p1, p2);
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
387 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
388 };
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
389 content.iterate(0, getLastRevision(), false, insp);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
390 cancelSupport.checkCancelled();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
391 if (needsSorting[0]) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
392 Arrays.sort(commitRevisions);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
393 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
394 // read changeset revisions at once (to avoid numerous changelog.getRevision reads)
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
395 // but just nodeids, not RawChangeset (changelog.iterate(data=false)
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
396 ArrayList<Nodeid> changesetRevisions = new ArrayList<Nodeid>(commitRevisions.length);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
397 getRepo().getChangelog().getRevisionsInternal(changesetRevisions, commitRevisions);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
398 cancelSupport.checkCancelled();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
399 // assign them to corresponding HistoryNodes
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
400 for (int i = 0; i < completeHistory.length; i++ ) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
401 final HistoryNode n = completeHistory[i];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
402 if (needsSorting[0]) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
403 int x = Arrays.binarySearch(commitRevisions, n.changeset);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
404 assert x >= 0;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
405 n.cset = changesetRevisions.get(x);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
406 } else {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
407 // commit revisions were not sorted, may use original index directly
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
408 n.cset = changesetRevisions.get(i);
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
409 }
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
410 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
411 cancelSupport.checkCancelled();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
412 // XXX shall sort completeHistory according to changeset numbers?
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
413 for (int i = 0; i < completeHistory.length; i++ ) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
414 final HistoryNode n = completeHistory[i];
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
415 HistoryNode p;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
416 Nodeid p1, p2;
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
417 if ((p = n.parent1) != null) {
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
418 p1 = p.changesetRevision();
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
419 } else {
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
420 p1 = Nodeid.NULL;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
421 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
422 if ((p= n.parent2) != null) {
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
423 p2 = p.changesetRevision();
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
424 } else {
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
425 p2 = Nodeid.NULL;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
426 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
427 final Pair<Nodeid, Nodeid> parentChangesets = new Pair<Nodeid, Nodeid>(p1, p2);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
428 final List<Nodeid> childChangesets;
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
429 if (n.children == null) {
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
430 childChangesets = Collections.emptyList();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
431 } else {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
432 Nodeid[] revisions = new Nodeid[n.children.size()];
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
433 int j = 0;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
434 for (HistoryNode hn : n.children) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
435 revisions[j++] = hn.changesetRevision();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
436 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
437 childChangesets = Arrays.asList(revisions);
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
438 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
439 inspector.next(n.changesetRevision(), parentChangesets, childChangesets);
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
440 cancelSupport.checkCancelled();
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
441 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
442 } catch (CancelledException ex) {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
443 return;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
444 }
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
445 }
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
446
366
189dc6dc1c3e Use exceptions to expose errors reading mercurial data
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 355
diff changeset
447 public void history(HgChangelog.Inspector inspector) throws HgInvalidControlFileException {
135
3959bffb14e9 explicit op name instead math op to get last rev number
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 134
diff changeset
448 history(0, getLastRevision(), inspector);
48
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
449 }
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
450
366
189dc6dc1c3e Use exceptions to expose errors reading mercurial data
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 355
diff changeset
451 public void history(int start, int end, HgChangelog.Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException {
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
452 if (!exists()) {
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
453 throw new IllegalStateException("Can't get history of invalid repository file node");
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
454 }
135
3959bffb14e9 explicit op name instead math op to get last rev number
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 134
diff changeset
455 final int last = getLastRevision();
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
456 if (end == TIP) {
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
457 end = last;
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
458 }
300
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
459 if (start == TIP) {
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
460 start = last;
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
461 }
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
462 HgInternals.checkRevlogRange(start, end, last);
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
463
48
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
464 final int[] commitRevisions = new int[end - start + 1];
242
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
465 final boolean[] needsSorting = { false };
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
466 RevlogStream.Inspector insp = new RevlogStream.Inspector() {
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
467 int count = 0;
51
9429c7bd1920 Try DataAccess to reach revision data instead of plain byte arrays
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 49
diff changeset
468 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) {
242
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
469 if (count > 0) {
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
470 if (commitRevisions[count -1] > linkRevision) {
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
471 needsSorting[0] = true;
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
472 }
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
473 }
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
474 commitRevisions[count++] = linkRevision;
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
475 }
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
476 };
48
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
477 content.iterate(start, end, false, insp);
233
1d389c0cb0a5 Optimize file history walk not to iterat over whole changelog for sparse and distant revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 215
diff changeset
478 final HgChangelog changelog = getRepo().getChangelog();
242
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
479 if (needsSorting[0]) {
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
480 // automatic tools (svnmerge?) produce unnatural file history
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
481 // (e.g. cpython/Lib/doctest.py, revision 164 points to cset 63509, 165 - to 38453)
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
482 Arrays.sort(commitRevisions);
233
1d389c0cb0a5 Optimize file history walk not to iterat over whole changelog for sparse and distant revisions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 215
diff changeset
483 }
245
2fb439375ddc Avoid sorting revision range twice
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 242
diff changeset
484 changelog.rangeInternal(inspector, commitRevisions);
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
485 }
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
486
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
487 /**
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
488 * For a given revision of the file (identified with revision index), find out index of the corresponding changeset.
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
489 *
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
490 * @return changeset revision index
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
491 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
492 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
493 */
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
494 public int getChangesetRevisionIndex(int revision) throws HgInvalidControlFileException, HgInvalidRevisionException {
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
495 return content.linkRevision(revision);
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
496 }
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
497 /**
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
498 * @deprecated use {@link #getChangesetRevisionIndex(int)} instead
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
499 */
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
500 @Deprecated
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
501 public int getChangesetLocalRevision(int revision) throws HgInvalidControlFileException, HgInvalidRevisionException {
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
502 return getChangesetRevisionIndex(revision);
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
503 }
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
504
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
505 /**
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
506 * Complements {@link #getChangesetRevisionIndex(int)} to get changeset revision that corresponds to supplied file revision
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
507 *
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
508 * @param nid revision of the file
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
509 * @return changeset revision
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
510 * @throws HgInvalidRevisionException if supplied argument doesn't represent revision index in this revlog
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
511 * @throws HgInvalidControlFileException if access to revlog index/data entry failed
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
512 */
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
513 public Nodeid getChangesetRevision(Nodeid nid) throws HgInvalidControlFileException, HgInvalidRevisionException {
367
2fadf8695f8a Use 'revision index' instead of the vague 'local revision number' concept in the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 366
diff changeset
514 int changelogRevision = getChangesetRevisionIndex(getRevisionIndex(nid));
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
515 return getRepo().getChangelog().getRevision(changelogRevision);
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
516 }
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
517
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
518 /**
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
519 * Tells whether this file originates from another repository file
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
520 * @return <code>true</code> if this file is a copy of another from the repository
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
521 * @throws HgInvalidControlFileException if access to revlog or file metadata failed
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
522 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
523 public boolean isCopy() throws HgInvalidControlFileException {
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
524 if (metadata == null || !metadata.checked(0)) {
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
525 checkAndRecordMetadata(0);
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
526 }
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
527 if (!metadata.known(0)) {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
528 return false;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
529 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
530 return metadata.find(0, "copy") != null;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
531 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
532
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
533 /**
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
534 * Get name of the file this one was copied from.
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
535 *
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
536 * @return name of the file origin
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
537 * @throws HgInvalidControlFileException if access to revlog or file metadata failed
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
538 * @throws UnsupportedOperationException if this file doesn't represent a copy ({@link #isCopy()} was false)
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
539 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
540 public Path getCopySourceName() throws HgInvalidControlFileException {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
541 if (isCopy()) {
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
542 return Path.create(metadata.find(0, "copy"));
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
543 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
544 throw new UnsupportedOperationException(); // XXX REVISIT, think over if Exception is good (clients would check isCopy() anyway, perhaps null is sufficient?)
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
545 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
546
415
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
547 /**
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
548 *
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
549 * @return revision this file was copied from
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
550 * @throws HgInvalidControlFileException if access to revlog or file metadata failed
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
551 * @throws UnsupportedOperationException if this file doesn't represent a copy ({@link #isCopy()} was false)
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
552 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
553 public Nodeid getCopySourceRevision() throws HgInvalidControlFileException {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
554 if (isCopy()) {
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
555 return Nodeid.fromAscii(metadata.find(0, "copyrev")); // XXX reuse/cache Nodeid
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
556 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
557 throw new UnsupportedOperationException();
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
558 }
415
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
559 /* FIXME
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
560 public Nodeid getRevisionAtChangeset(int changesetRevision) {
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
561 }
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
562
415
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
563 public HgManifest.Flags getFlagsAtChangeset(int changesetRevisionIndex) {
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
564 }
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
565 */
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
566
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
567 /**
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
568 *
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
569 * @param fileRevisionIndex - revision local index, non-negative, or {@link HgRepository#TIP}.
415
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
570 * FIXME EXCEPTIONS
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
571 * @throws HgInvalidControlFileException
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
572 * @throws HgInvalidRevisionException
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
573 */
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
574 public HgManifest.Flags getFlags(int fileRevisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException {
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
575 int changesetRevIndex = getChangesetRevisionIndex(fileRevisionIndex);
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
576 return getRepo().getManifest().extractFlags(changesetRevIndex, getPath());
ee8264d80747 Explicit constant for regular file flags, access to flags for a given file revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 401
diff changeset
577 }
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
578
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
579 @Override
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
580 public String toString() {
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
581 StringBuilder sb = new StringBuilder(getClass().getSimpleName());
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
582 sb.append('(');
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
583 sb.append(getPath());
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
584 sb.append(')');
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
585 return sb.toString();
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
586 }
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
587
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
588 private void checkAndRecordMetadata(int localRev) throws HgInvalidControlFileException {
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
589 // content() always initializes metadata.
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
590 // TODO [post-1.0] this is expensive way to find out metadata, distinct RevlogStream.Iterator would be better.
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
591 // Alternatively, may parameterize MetadataContentPipe to do prepare only.
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
592 // For reference, when throwing CancelledException, hg status -A --rev 3:80 takes 70 ms
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
593 // however, if we just consume buffer instead (buffer.position(buffer.limit()), same command takes ~320ms
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
594 // (compared to command-line counterpart of 190ms)
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
595 try {
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
596 content(localRev, new ByteChannel() { // No-op channel
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
597 public int write(ByteBuffer buffer) throws IOException, CancelledException {
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
598 throw new CancelledException();
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
599 }
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
600 });
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
601 } catch (CancelledException ex) {
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
602 // it's ok, we did that
366
189dc6dc1c3e Use exceptions to expose errors reading mercurial data
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 355
diff changeset
603 } catch (HgInvalidControlFileException ex) {
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
604 throw ex.isRevisionIndexSet() ? ex : ex.setRevisionIndex(localRev);
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
605 } catch (HgException ex) {
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
606 // metadata comes from the content, hence initWithDataFile
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
607 throw content.initWithDataFile(new HgInvalidControlFileException(null, ex, null));
275
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
608 }
6d1804fe0ed7 Issue 10: Report file content length with respect of metadata. Respect dirstate parents for WC's status. Exceptions to keep useful attributes of the location
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 245
diff changeset
609 }
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
610
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
611 private static final class MetadataEntry {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
612 private final String entry;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
613 private final int valueStart;
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
614
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
615 // key may be null
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
616 /*package-local*/MetadataEntry(String key, String value) {
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
617 if (key == null) {
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
618 entry = value;
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
619 valueStart = -1; // not 0 to tell between key == null and key == ""
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
620 } else {
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
621 entry = key + value;
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
622 valueStart = key.length();
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
623 }
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
624 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
625 /*package-local*/boolean matchKey(String key) {
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
626 return key == null ? valueStart == -1 : key.length() == valueStart && entry.startsWith(key);
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
627 }
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
628 // uncomment once/if needed
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
629 // public String key() {
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
630 // return entry.substring(0, valueStart);
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
631 // }
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
632 public String value() {
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
633 return valueStart == -1 ? entry : entry.substring(valueStart);
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
634 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
635 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
636
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
637 private static class Metadata {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
638 private static class Record {
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
639 public final int offset;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
640 public final MetadataEntry[] entries;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
641
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
642 public Record(int off, MetadataEntry[] entr) {
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
643 offset = off;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
644 entries = entr;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
645 }
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
646 }
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
647 // XXX sparse array needed
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
648 private final IntMap<Record> entries = new IntMap<Record>(5);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
649
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
650 private final Record NONE = new Record(-1, null); // don't want statics
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
651
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
652 // true when there's metadata for given revision
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
653 boolean known(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
654 Record i = entries.get(revision);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
655 return i != null && NONE != i;
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
656 }
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
657
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
658 // true when revision has been checked for metadata presence.
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
659 public boolean checked(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
660 return entries.containsKey(revision);
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
661 }
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
662
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
663 // true when revision has been checked and found not having any metadata
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
664 boolean none(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
665 Record i = entries.get(revision);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
666 return i == NONE;
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
667 }
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
668
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
669 // mark revision as having no metadata.
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
670 void recordNone(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
671 Record i = entries.get(revision);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
672 if (i == NONE) {
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
673 return; // already there
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
674 }
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
675 if (i != null) {
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
676 throw new IllegalStateException(String.format("Trying to override Metadata state for revision %d (known offset: %d)", revision, i));
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
677 }
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
678 entries.put(revision, NONE);
134
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
679 }
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
680
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
681 // since this is internal class, callers are supposed to ensure arg correctness (i.e. ask known() before)
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
682 int dataOffset(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
683 return entries.get(revision).offset;
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
684 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
685 void add(int revision, int dataOffset, Collection<MetadataEntry> e) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
686 assert !entries.containsKey(revision);
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
687 entries.put(revision, new Record(dataOffset, e.toArray(new MetadataEntry[e.size()])));
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
688 }
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
689
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
690 String find(int revision, String key) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
691 for (MetadataEntry me : entries.get(revision).entries) {
78
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
692 if (me.matchKey(key)) {
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
693 return me.value();
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
694 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
695 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
696 return null;
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
697 }
c25c5c348d1b Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 77
diff changeset
698 }
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
699
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
700 private static class MetadataInspector extends ErrorHandlingInspector implements RevlogStream.Inspector {
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
701 private final Metadata metadata;
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
702 private final RevlogStream.Inspector delegate;
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
703 private final LogFacility log;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
704
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
705 public MetadataInspector(Metadata _metadata, LogFacility logFacility, RevlogStream.Inspector chain) {
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
706 metadata = _metadata;
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
707 log = logFacility;
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
708 delegate = chain;
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
709 setCancelSupport(CancelSupport.Factory.get(chain));
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
710 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
711
366
189dc6dc1c3e Use exceptions to expose errors reading mercurial data
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 355
diff changeset
712 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) throws HgException {
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
713 try {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
714 final int daLength = data.length();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
715 if (daLength < 4 || data.readByte() != 1 || data.readByte() != 10) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
716 metadata.recordNone(revisionNumber);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
717 data.reset();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
718 } else {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
719 ArrayList<MetadataEntry> _metadata = new ArrayList<MetadataEntry>();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
720 int offset = parseMetadata(data, daLength, _metadata);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
721 metadata.add(revisionNumber, offset, _metadata);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
722 // da is in prepared state (i.e. we consumed all bytes up to metadata end).
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
723 // However, it's not safe to assume delegate won't call da.reset() for some reason,
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
724 // and we need to ensure predictable result.
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
725 data.reset();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
726 data = new FilterDataAccess(data, offset, daLength - offset);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
727 }
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
728 if (delegate != null) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
729 delegate.next(revisionNumber, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeid, data);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
730 }
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
731 } catch (IOException ex) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
732 recordFailure(ex);
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
733 } catch (HgInvalidControlFileException ex) {
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
734 recordFailure(ex.isRevisionIndexSet() ? ex : ex.setRevisionIndex(revisionNumber));
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
735 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
736 }
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
737
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
738 private int parseMetadata(DataAccess data, final int daLength, ArrayList<MetadataEntry> _metadata) throws IOException, HgInvalidControlFileException {
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
739 int lastEntryStart = 2;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
740 int lastColon = -1;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
741 // XXX in fact, need smth like ByteArrayBuilder, similar to StringBuilder,
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
742 // which can't be used here because we can't convert bytes to chars as we read them
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
743 // (there might be multi-byte encoding), and we need to collect all bytes before converting to string
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
744 ByteArrayOutputStream bos = new ByteArrayOutputStream();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
745 String key = null, value = null;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
746 boolean byteOne = false;
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
747 boolean metadataIsComplete = false;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
748 for (int i = 2; i < daLength; i++) {
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
749 byte b = data.readByte();
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
750 if (b == '\n') {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
751 if (byteOne) { // i.e. \n follows 1
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
752 lastEntryStart = i+1;
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
753 metadataIsComplete = true;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
754 // XXX is it possible to have here incomplete key/value (i.e. if last pair didn't end with \n)
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
755 // if yes, need to set metadataIsComplete to true in that case as well
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
756 break;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
757 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
758 if (key == null || lastColon == -1 || i <= lastColon) {
388
b015f3918120 Work on FIXME: correct HgDataFile#workingCopy with tests; BasicSessionContext with property override; platform-specific options to internals
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 383
diff changeset
759 log.error(getClass(), "Missing key in file revision metadata at index %d", i);
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
760 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
761 value = new String(bos.toByteArray()).trim();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
762 bos.reset();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
763 _metadata.add(new MetadataEntry(key, value));
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
764 key = value = null;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
765 lastColon = -1;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
766 lastEntryStart = i+1;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
767 continue;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
768 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
769 // byteOne has to be consumed up to this line, if not yet, consume it
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
770 if (byteOne) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
771 // insert 1 we've read on previous step into the byte builder
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
772 bos.write(1);
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
773 byteOne = false;
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
774 // fall-through to consume current byte
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
775 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
776 if (b == (int) ':') {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
777 assert value == null;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
778 key = new String(bos.toByteArray());
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
779 bos.reset();
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
780 lastColon = i;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
781 } else if (b == 1) {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
782 byteOne = true;
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
783 } else {
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
784 bos.write(b);
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
785 }
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
786 }
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
787 // data.isEmpty is not reliable, renamed files of size==0 keep only metadata
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
788 if (!metadataIsComplete) {
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
789 // XXX perhaps, worth a testcase (empty file, renamed, read or ask ifCopy
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
790 throw new HgInvalidControlFileException("Metadata is not closed properly", null, null);
157
d5268ca7715b Merged branch wrap-data-access into default for resource-friendly data access. Updated API to promote that friendliness to clients (channels, not byte[]). More exceptions
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 51 148
diff changeset
791 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
792 return lastEntryStart;
17
571e1b2cc3f7 Query file for its parents. Demo of recently added ignore and digest support from within cat cmd
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 5
diff changeset
793 }
322
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
794
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
795 @Override
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
796 public void checkFailed() throws HgException, IOException, CancelledException {
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
797 super.checkFailed();
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
798 if (delegate instanceof ErrorHandlingInspector) {
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
799 // XXX need to add ErrorDestination and pass it around (much like CancelSupport get passed)
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
800 // so that delegate would be able report its failures directly to caller without this hack
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
801 ((ErrorHandlingInspector) delegate).checkFailed();
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
802 }
d68dcb3b5f49 Propagate command's CancelSupport to low-level API. CancelSupport from context got priority over one from command
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 317
diff changeset
803 }
17
571e1b2cc3f7 Query file for its parents. Demo of recently added ignore and digest support from within cat cmd
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 5
diff changeset
804 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
805 }