annotate src/org/tmatesoft/hg/repo/HgDataFile.java @ 420:6c22bdc0bdfd

Respect long offsets in revlogs
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 22 Mar 2012 22:56:01 +0100
parents ccd7d25e5aea
children 9c9c442b5f2e
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;
420
6c22bdc0bdfd Respect long offsets in revlogs
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 417
diff changeset
44 import org.tmatesoft.hg.internal.Internals;
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
45 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
46 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
47 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
48 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
49 import org.tmatesoft.hg.util.LogFacility;
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
50 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
51 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
52 import org.tmatesoft.hg.util.ProgressSupport;
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
53
5
fc265ddeab26 File content and non-effective, although working, patch application
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 3
diff changeset
54
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
55
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
56 /**
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
57 * ? name:HgFileNode?
74
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
58 *
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
59 * @author Artem Tikhomirov
6f1b88693d48 Complete refactoring to org.tmatesoft
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 56
diff changeset
60 * @author TMate Software Ltd.
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
61 */
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
62 public class HgDataFile extends Revlog {
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
63
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
64 // absolute from repo root?
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
65 // slashes, unix-style?
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
66 // 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
67 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
68 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
69
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
70 /*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
71 super(hgRepo, content);
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
72 path = filePath;
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
73 }
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
74
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
75 /*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
76 super(hgRepo);
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
77 path = filePath;
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
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
80 // 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
81 // 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
82 public boolean exists() {
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
83 return content != null; // XXX need better impl
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
84 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
85
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
86 // 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
87 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
88 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
89 }
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
90
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
91 /**
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
92 * 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
93 *
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
94 * @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
95 *
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
96 * @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
97 * @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
98 * @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
99 */
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
100 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
101 try {
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
102 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
103 } 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
104 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
105 } 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
106 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
107 }
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
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
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
110 /**
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
111 * @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
112 */
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
113 @Deprecated
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
114 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
115 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
116 }
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
117
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
118 /**
368
8107b95f4280 Update Javadoc with 'revision index'
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
119 * @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
120 * @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
121 * @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
122 * @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
123 */
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
124 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
125 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
126 throw new HgInvalidRevisionException(fileRevisionIndex);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
127 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
128 if (fileRevisionIndex == TIP) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
129 fileRevisionIndex = getLastRevision();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
130 } else if (fileRevisionIndex == WORKING_COPY) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
131 File f = getRepo().getFile(this);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
132 if (f.exists()) {
420
6c22bdc0bdfd Respect long offsets in revlogs
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 417
diff changeset
133 // single revision can't be greater than 2^32, shall be safe to cast to int
6c22bdc0bdfd Respect long offsets in revlogs
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 417
diff changeset
134 return Internals.ltoi(f.length());
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
135 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
136 Nodeid fileRev = getWorkingCopyRevision();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
137 if (fileRev == null) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
138 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
139 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
140 fileRevisionIndex = getRevisionIndex(fileRev);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
141 }
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
142 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
143 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
144 }
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
145 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
146 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
147 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
148 }
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
149 return dataLen;
22
603806cd2dc6 Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 21
diff changeset
150 }
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
151
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 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
154 */
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
155 @Deprecated
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
156 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
157 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
158 }
22
603806cd2dc6 Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 21
diff changeset
159
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
160 /**
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
161 * 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
162 * 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
163 * 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
164 * 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
165 *
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
166 * 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
167 * 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
168 *
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
169 * @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
170 * @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
171 * @throws HgInvalidFileException if access to file in working directory failed
380
9517df1ef7ec Comments/javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 368
diff changeset
172 * @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
173 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
174 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
175 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
176 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
177 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
178 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
179 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
180 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
181 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
182 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
183 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
184 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
185 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
186 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
187 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
188 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
189 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
190 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
191 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
192 }
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 } 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
194 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
195 } 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
196 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
197 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
198 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
199 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
200 } 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
201 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
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 }
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
204 }
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
205 } else {
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
206 Nodeid fileRev = getWorkingCopyRevision();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
207 if (fileRev == null) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
208 // 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
209 // 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
210 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
211 }
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
212 final int fileRevIndex = getRevisionIndex(fileRev);
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
213 contentWithFilters(fileRevIndex, sink);
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
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 * @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
219 */
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
220 private Nodeid getWorkingCopyRevision() throws HgInvalidControlFileException {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
221 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
222 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
223 final HgChangelog clog = getRepo().getChangelog();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
224 final int csetRevIndex;
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
225 if (p.isNull()) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
226 // no dirstate parents
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
227 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
228 // 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
229 csetRevIndex = clog.getLastRevision();
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
230 if (csetRevIndex == -1) {
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
231 // 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
232 // 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
233 return null;
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
234 }
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
235 } 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
236 // 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
237 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
238 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
239 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
240 } 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
241 // 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
242 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
243 }
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
244 }
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
245 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
246 // 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
247 // 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
248 // 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
249 return fileRev;
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
250 }
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
251
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
252 /**
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
253 * 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
254 * 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
255 *
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
256 * @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
257 * @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
258 *
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 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
260 * @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
261 * @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
262 * @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
263 */
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
264 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
265 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
266 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
267 } 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
268 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
269 }
115
c0cc2535462c Introduced channels to pipeline (and easily filter) data streams
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 102
diff changeset
270 }
22
603806cd2dc6 Status of local working dir against non-tip base revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 21
diff changeset
271
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
272 /**
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
273 * 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
274 * 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
275 *
368
8107b95f4280 Update Javadoc with 'revision index'
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 367
diff changeset
276 * @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
277 * @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
278 *
380
9517df1ef7ec Comments/javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 368
diff changeset
279 * @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
280 * @throws HgInvalidFileException if access to file in working directory failed
380
9517df1ef7ec Comments/javadoc
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 368
diff changeset
281 * @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
282 * @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
283 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
284 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
285 // 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
286 // @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
287 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
288 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
289 }
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
290 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
291 // 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
292 // 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
293 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
294 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
295 }
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
296 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
297 throw new HgInvalidRevisionException(fileRevisionIndex);
148
1a7a9a20e1f9 Exceptions, javadoc. Initial cancel and progress support
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 135
diff changeset
298 }
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
299 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
300 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
301 }
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
302 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
303 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
304 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
305 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
306 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
307 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
308 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
309 } 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
310 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
311 } 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
312 // 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
313 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
314 }
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 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
316 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
317 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
318 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
319 } 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
320 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
321 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
322 } 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
323 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
324 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
325 } 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
326 // 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
327 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
328 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
329 }
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
330 }
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
331
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
332 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
333 int changeset;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
334 Nodeid cset;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
335 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
336 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
337
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
338 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
339 changeset = cs;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
340 parent1 = p1;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
341 parent2 = p2;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
342 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
343 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
344 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
345 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
346 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
347 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
348 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
349
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
350 Nodeid changesetRevision() {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
351 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
352 return cset;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
353 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
354
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
355 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
356 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
357 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
358 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
359 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
360 }
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
361 }
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
362
328
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 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
365 */
a674b8590362 Move file tree history to upper API level
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 323
diff changeset
366 @Deprecated
366
189dc6dc1c3e Use exceptions to expose errors reading mercurial data
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 355
diff changeset
367 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
368 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
369 try {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
370 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
371 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
372 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
373 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
374 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
375 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
376 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
377 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
378 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
379 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
380 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
381 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
382 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
383 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
384 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
385 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
386 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
387 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
388 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
389 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
390 };
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
391 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
392 cancelSupport.checkCancelled();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
393 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
394 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
395 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
396 // 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
397 // 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
398 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
399 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
400 cancelSupport.checkCancelled();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
401 // 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
402 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
403 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
404 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
405 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
406 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
407 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
408 } else {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
409 // 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
410 n.cset = changesetRevisions.get(i);
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
411 }
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
412 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
413 cancelSupport.checkCancelled();
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
414 // 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
415 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
416 final HistoryNode n = completeHistory[i];
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
417 HistoryNode p;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
418 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
419 if ((p = n.parent1) != null) {
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
420 p1 = p.changesetRevision();
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
421 } else {
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
422 p1 = Nodeid.NULL;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
423 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
424 if ((p= n.parent2) != null) {
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
425 p2 = p.changesetRevision();
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
426 } else {
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
427 p2 = Nodeid.NULL;
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
428 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
429 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
430 final List<Nodeid> childChangesets;
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
431 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
432 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
433 } else {
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
434 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
435 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
436 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
437 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
438 }
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
439 childChangesets = Arrays.asList(revisions);
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
440 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
441 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
442 cancelSupport.checkCancelled();
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
443 }
317
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
444 } 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
445 return;
09628675bcee Rework file history build approach to match rest of the API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 306
diff changeset
446 }
305
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
447 }
ae8d116f4ee2 Experimental code to build file history
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 300
diff changeset
448
366
189dc6dc1c3e Use exceptions to expose errors reading mercurial data
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 355
diff changeset
449 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
450 history(0, getLastRevision(), inspector);
48
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
451 }
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
452
417
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
453 /**
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
454 *
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
455 * @param start local revision index
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
456 * @param end local revision index
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
457 * @param inspector
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
458 * FIXME EXCEPTIONS
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
459 * @throws HgInvalidRevisionException
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
460 * @throws HgInvalidControlFileException
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
461 */
366
189dc6dc1c3e Use exceptions to expose errors reading mercurial data
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 355
diff changeset
462 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
463 if (!exists()) {
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
464 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
465 }
135
3959bffb14e9 explicit op name instead math op to get last rev number
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 134
diff changeset
466 final int last = getLastRevision();
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
467 if (end == TIP) {
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
468 end = last;
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
469 }
300
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
470 if (start == TIP) {
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
471 start = last;
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
472 }
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
473 HgInternals.checkRevlogRange(start, end, last);
650b45d290b1 Share range check code
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 295
diff changeset
474
48
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
475 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
476 final boolean[] needsSorting = { false };
77
c677e1593919 Moved RevlogStream implementation into .internal
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 74
diff changeset
477 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
478 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
479 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
480 if (count > 0) {
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
481 if (commitRevisions[count -1] > linkRevision) {
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
482 needsSorting[0] = true;
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
483 }
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
484 }
3
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
485 commitRevisions[count++] = linkRevision;
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
486 }
24bb4f365164 Rudimentary log functionality with basic infrastructure is in place
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 2
diff changeset
487 };
48
e34f90b9ded1 Limit option for history/log
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 37
diff changeset
488 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
489 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
490 if (needsSorting[0]) {
ad6a046943be Improved reading of sparse revisions from a revlog
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 240
diff changeset
491 // 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
492 // (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
493 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
494 }
245
2fb439375ddc Avoid sorting revision range twice
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 242
diff changeset
495 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
496 }
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
497
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
498 /**
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
499 * 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
500 *
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
501 * @return changeset revision index
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
502 * @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
503 * @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
504 */
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
505 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
506 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
507 }
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
508 /**
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
509 * @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
510 */
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
511 @Deprecated
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
512 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
513 return getChangesetRevisionIndex(revision);
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
514 }
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
515
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
516 /**
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
517 * 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
518 *
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
519 * @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
520 * @return changeset revision
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
521 * @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
522 * @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
523 */
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
524 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
525 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
526 return getRepo().getChangelog().getRevision(changelogRevision);
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
527 }
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
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
529 /**
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
530 * 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
531 * @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
532 * @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
533 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
534 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
535 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
536 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
537 }
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
538 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
539 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
540 }
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 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
542 }
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
354
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
544 /**
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
545 * 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
546 *
5f9073eabf06 Propagate errors with exceptions up to a end client
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 347
diff changeset
547 * @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
548 * @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
549 * @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
550 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
551 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
552 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
553 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
554 }
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 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
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
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
558 /**
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 *
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 * @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
561 * @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
562 * @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
563 */
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
564 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
565 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
566 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
567 }
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
568 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
569 }
417
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
570
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
571 /**
417
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
572 * Get file flags recorded in the manifest
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
573 * @param fileRevisionIndex - revision local index, non-negative, or {@link HgRepository#TIP}.
417
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
574 * @see HgManifest#getFileFlags(int, Path)
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
575 * FIXME EXCEPTIONS
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
576 * @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
577 * @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
578 */
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
579 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
580 int changesetRevIndex = getChangesetRevisionIndex(fileRevisionIndex);
417
ccd7d25e5aea New and better name for HgFileInformer - HgChangesetFileSneaker. Explain (comments) ties between HgManifest, HgDataFile, HgChangesetFileSneaker and reasons for method placement
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 416
diff changeset
581 return getRepo().getManifest().getFileFlags(changesetRevIndex, getPath());
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
582 }
416
d30083c80d52 Better names - non-confusing and aligned with the rest of API
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 415
diff changeset
583
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
584 @Override
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
585 public String toString() {
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
586 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
587 sb.append('(');
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
588 sb.append(getPath());
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
589 sb.append(')');
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
590 return sb.toString();
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
591 }
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
592
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
593 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
594 // content() always initializes metadata.
401
a57a21aa4190 Support WORKING_COPY constant for dataFile.length() operation
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 396
diff changeset
595 // 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
596 // 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
597 // 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
598 // 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
599 // (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
600 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
601 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
602 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
603 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
604 }
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
605 });
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
606 } 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
607 // 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
608 } 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
609 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
610 } 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
611 // 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
612 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
613 }
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
614 }
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
615
88
61eedab3eb3e Status between two revisions to recognize copy/rename
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 79
diff changeset
616 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
617 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
618 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
619
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 // 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
621 /*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
622 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
623 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
624 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
625 } 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
626 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
627 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
628 }
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
629 }
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
630 /*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
631 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
632 }
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
633 // 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
634 // 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
635 // 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
636 // }
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
637 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
638 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
639 }
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
640 }
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
641
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
642 private static class Metadata {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
643 private static class Record {
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
644 public final int offset;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
645 public final MetadataEntry[] entries;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
646
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
647 public Record(int off, MetadataEntry[] entr) {
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
648 offset = off;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
649 entries = entr;
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
650 }
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
651 }
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
652 // XXX sparse array needed
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
653 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
654
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
655 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
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 // 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
658 boolean known(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
659 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
660 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
661 }
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 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
664 public boolean checked(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
665 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
666 }
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
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 // 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
669 boolean none(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
670 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
671 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
672 }
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
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 // 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
675 void recordNone(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
676 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
677 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
678 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
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 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
681 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
682 }
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
683 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
684 }
afac8ddc5dd2 Keep record if we tried and found no metadata for a given revision
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 133
diff changeset
685
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
686 // 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
687 int dataOffset(int revision) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
688 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
689 }
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 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
691 assert !entries.containsKey(revision);
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
692 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
693 }
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
694
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
695 String find(int revision, String key) {
276
6355ecda1f08 Tailored Map implementation with int keys
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 275
diff changeset
696 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
697 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
698 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
699 }
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
700 }
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
701 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
702 }
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
703 }
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
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
705 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
706 private final Metadata metadata;
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
707 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
708 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
709
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
710 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
711 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
712 log = logFacility;
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
713 delegate = chain;
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
714 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
715 }
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
716
366
189dc6dc1c3e Use exceptions to expose errors reading mercurial data
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 355
diff changeset
717 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
718 try {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
719 final int daLength = data.length();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
720 if (daLength < 4 || data.readByte() != 1 || data.readByte() != 10) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
721 metadata.recordNone(revisionNumber);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
722 data.reset();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
723 } else {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
724 ArrayList<MetadataEntry> _metadata = new ArrayList<MetadataEntry>();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
725 int offset = parseMetadata(data, daLength, _metadata);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
726 metadata.add(revisionNumber, offset, _metadata);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
727 // 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
728 // 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
729 // and we need to ensure predictable result.
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
730 data.reset();
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
731 data = new FilterDataAccess(data, offset, daLength - offset);
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
732 }
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
733 if (delegate != null) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
734 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
735 }
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
736 } catch (IOException ex) {
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
737 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
738 } 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
739 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
740 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
741 }
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
742
396
0ae53c32ecef Straighten out exceptions thrown when file access failed - three is too much
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 388
diff changeset
743 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
744 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
745 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
746 // 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
747 // 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
748 // (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
749 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
750 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
751 boolean byteOne = false;
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
752 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
753 for (int i = 2; i < daLength; i++) {
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
754 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
755 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
756 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
757 lastEntryStart = i+1;
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
758 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
759 // 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
760 // 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
761 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
762 }
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 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
764 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
765 }
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 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
767 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
768 _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
769 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
770 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
771 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
772 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
773 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
774 // 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
775 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
776 // 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
777 bos.write(1);
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
778 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
779 // 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
780 }
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 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
782 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
783 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
784 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
785 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
786 } 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
787 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
788 } 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
789 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
790 }
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 }
323
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
792 // 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
793 if (!metadataIsComplete) {
4c7e3ba67213 Exception when analyzing metadata of an empty renamed file
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 322
diff changeset
794 // 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
795 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
796 }
277
74e7493a042a Favor delegation over generalization
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents: 276
diff changeset
797 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
798 }
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
799
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 @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
801 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
802 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
803 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
804 // 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
805 // 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
806 ((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
807 }
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
808 }
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
809 }
2
08db726a0fb7 Shaping out low-level Hg structures
Artem Tikhomirov <tikhomirov.artem@gmail.com>
parents:
diff changeset
810 }