Mercurial > jhg
annotate src/org/tmatesoft/hg/repo/HgDataFile.java @ 319:fa4aea41746e
Dump exception to console
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> | 
|---|---|
| date | Thu, 29 Sep 2011 04:37:52 +0200 | 
| parents | 09628675bcee | 
| children | d68dcb3b5f49 | 
| 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: 
5diff
changeset | 1 /* | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 2 * Copyright (c) 2010-2011 TMate Software Ltd | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 3 * | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
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: 
56diff
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: 
56diff
changeset | 6 * the Free Software Foundation; version 2 of the License. | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 7 * | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
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: 
56diff
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: 
56diff
changeset | 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 11 * GNU General Public License for more details. | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 12 * | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 13 * For information on how to redistribute this software under | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
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: 
88diff
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: 
56diff
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 | 
| 148 
1a7a9a20e1f9
Exceptions, javadoc. Initial cancel and progress support
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
135diff
changeset | 19 import static org.tmatesoft.hg.repo.HgInternals.wrongLocalRevision; | 
| 
1a7a9a20e1f9
Exceptions, javadoc. Initial cancel and progress support
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
135diff
changeset | 20 import static org.tmatesoft.hg.repo.HgRepository.*; | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
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>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: 
233diff
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: 
233diff
changeset | 24 import java.io.FileInputStream; | 
| 148 
1a7a9a20e1f9
Exceptions, javadoc. Initial cancel and progress support
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
135diff
changeset | 25 import java.io.IOException; | 
| 115 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
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: 
233diff
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: 
77diff
changeset | 28 import java.util.ArrayList; | 
| 240 
29231022fec8
Do not expect file history to be ordered
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
237diff
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: 
77diff
changeset | 30 import java.util.Collection; | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 31 import java.util.Collections; | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
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: 
77diff
changeset | 33 | 
| 148 
1a7a9a20e1f9
Exceptions, javadoc. Initial cancel and progress support
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
135diff
changeset | 34 import org.tmatesoft.hg.core.HgDataStreamException; | 
| 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>diff
changeset | 35 import org.tmatesoft.hg.core.HgException; | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 36 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>diff
changeset | 37 import org.tmatesoft.hg.internal.DataAccess; | 
| 121 
b1d6208fb517
Conditionally apply filters to file content
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
115diff
changeset | 38 import org.tmatesoft.hg.internal.FilterByteChannel; | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 39 import org.tmatesoft.hg.internal.FilterDataAccess; | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 40 import org.tmatesoft.hg.internal.IntMap; | 
| 77 
c677e1593919
Moved RevlogStream implementation into .internal
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
74diff
changeset | 41 import org.tmatesoft.hg.internal.RevlogStream; | 
| 115 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 42 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: 
233diff
changeset | 43 import org.tmatesoft.hg.util.CancelSupport; | 
| 148 
1a7a9a20e1f9
Exceptions, javadoc. Initial cancel and progress support
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
135diff
changeset | 44 import org.tmatesoft.hg.util.CancelledException; | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 45 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: 
129diff
changeset | 46 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: 
233diff
changeset | 47 import org.tmatesoft.hg.util.ProgressSupport; | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 48 | 
| 5 
fc265ddeab26
File content and non-effective, although working, patch application
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
3diff
changeset | 49 | 
| 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: 
5diff
changeset | 50 | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 51 /** | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 52 * ? name:HgFileNode? | 
| 74 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 53 * | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 54 * @author Artem Tikhomirov | 
| 
6f1b88693d48
Complete refactoring to org.tmatesoft
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
56diff
changeset | 55 * @author TMate Software Ltd. | 
| 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 public class HgDataFile extends Revlog { | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 58 | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 59 // absolute from repo root? | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 60 // slashes, unix-style? | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 61 // 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: 
56diff
changeset | 62 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: 
133diff
changeset | 63 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 | 64 | 
| 115 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 65 /*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: 
17diff
changeset | 66 super(hgRepo, content); | 
| 115 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 67 path = filePath; | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 68 } | 
| 115 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 69 | 
| 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 70 /*package-local*/HgDataFile(HgRepository hgRepo, Path filePath) { | 
| 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 71 super(hgRepo); | 
| 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 72 path = filePath; | 
| 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 73 } | 
| 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 74 | 
| 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 75 // 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: 
102diff
changeset | 76 // 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: 
2diff
changeset | 77 public boolean exists() { | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 78 return content != null; // XXX need better impl | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 79 } | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 80 | 
| 77 
c677e1593919
Moved RevlogStream implementation into .internal
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
74diff
changeset | 81 // 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: 
56diff
changeset | 82 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>diff
changeset | 83 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 | 84 } | 
| 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 85 | 
| 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: 
245diff
changeset | 86 /** | 
| 
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: 
245diff
changeset | 87 * @return size of the file content at the given revision | 
| 
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: 
245diff
changeset | 88 */ | 
| 
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: 
245diff
changeset | 89 public int length(Nodeid nodeid) throws HgDataStreamException { | 
| 
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: 
245diff
changeset | 90 return length(getLocalRevision(nodeid)); | 
| 
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: 
245diff
changeset | 91 | 
| 
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: 
245diff
changeset | 92 } | 
| 
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: 
245diff
changeset | 93 | 
| 
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: 
245diff
changeset | 94 /** | 
| 
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: 
245diff
changeset | 95 * @return size of the file content at the revision identified by local revision number. | 
| 
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: 
245diff
changeset | 96 */ | 
| 
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: 
245diff
changeset | 97 public int length(int localRev) throws HgDataStreamException { | 
| 
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: 
245diff
changeset | 98 if (metadata == null || !metadata.checked(localRev)) { | 
| 
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: 
245diff
changeset | 99 checkAndRecordMetadata(localRev); | 
| 
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: 
245diff
changeset | 100 } | 
| 
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: 
245diff
changeset | 101 final int dataLen = content.dataLength(localRev); | 
| 
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: 
245diff
changeset | 102 if (metadata.known(localRev)) { | 
| 
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: 
245diff
changeset | 103 return dataLen - metadata.dataOffset(localRev); | 
| 
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: 
245diff
changeset | 104 } | 
| 
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: 
245diff
changeset | 105 return dataLen; | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
21diff
changeset | 106 } | 
| 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
21diff
changeset | 107 | 
| 237 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 108 /** | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 109 * 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: 
233diff
changeset | 110 * any filters is supplied through the sink. If file does not exist in the working dir, this method provides content of a file | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 111 * as if it would be refreshed in the working copy, i.e. its corresponding revision | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 112 * (XXX according to dirstate? file tip?) is read from the repository, and filters repo -> working copy get applied. | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 113 * | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 114 * @param sink where to pipe content to | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 115 * @throws HgDataStreamException to indicate troubles reading repository file | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 116 * @throws CancelledException if operation was cancelled | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 117 */ | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 118 public void workingCopy(ByteChannel sink) throws HgDataStreamException, CancelledException { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 119 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: 
233diff
changeset | 120 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: 
233diff
changeset | 121 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: 
233diff
changeset | 122 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: 
233diff
changeset | 123 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: 
233diff
changeset | 124 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: 
233diff
changeset | 125 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: 
233diff
changeset | 126 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: 
233diff
changeset | 127 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: 
233diff
changeset | 128 try { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 129 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: 
233diff
changeset | 130 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: 
233diff
changeset | 131 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: 
233diff
changeset | 132 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: 
233diff
changeset | 133 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: 
233diff
changeset | 134 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: 
233diff
changeset | 135 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: 
233diff
changeset | 136 } | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 137 } catch (IOException ex) { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 138 throw new HgDataStreamException(getPath(), ex); | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 139 } finally { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 140 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: 
233diff
changeset | 141 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: 
233diff
changeset | 142 try { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 143 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: 
233diff
changeset | 144 } catch (IOException ex) { | 
| 295 
981f9f50bb6c
Issue 11: Error log facility. SessionContext to share common facilities
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
277diff
changeset | 145 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: 
233diff
changeset | 146 } | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 147 } | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 148 } | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 149 } else { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 150 contentWithFilters(TIP, sink); | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 151 } | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 152 } | 
| 115 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 153 | 
| 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>diff
changeset | 154 // public void content(int revision, ByteChannel sink, boolean applyFilters) throws HgDataStreamException, IOException, CancelledException { | 
| 
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>diff
changeset | 155 // byte[] content = content(revision); | 
| 
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>diff
changeset | 156 // final CancelSupport cancelSupport = CancelSupport.Factory.get(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>diff
changeset | 157 // final ProgressSupport progressSupport = ProgressSupport.Factory.get(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>diff
changeset | 158 // ByteBuffer buf = ByteBuffer.allocate(512); | 
| 
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>diff
changeset | 159 // int left = content.length; | 
| 
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>diff
changeset | 160 // progressSupport.start(left); | 
| 
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>diff
changeset | 161 // int offset = 0; | 
| 
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>diff
changeset | 162 // cancelSupport.checkCancelled(); | 
| 
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>diff
changeset | 163 // ByteChannel _sink = applyFilters ? new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath())) : 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>diff
changeset | 164 // do { | 
| 
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>diff
changeset | 165 // buf.put(content, offset, Math.min(left, buf.remaining())); | 
| 
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>diff
changeset | 166 // buf.flip(); | 
| 
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>diff
changeset | 167 // cancelSupport.checkCancelled(); | 
| 
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>diff
changeset | 168 // // XXX I may not rely on returned number of bytes but track change in buf position instead. | 
| 
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>diff
changeset | 169 // int consumed = _sink.write(buf); | 
| 
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>diff
changeset | 170 // buf.compact(); | 
| 
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>diff
changeset | 171 // offset += consumed; | 
| 
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>diff
changeset | 172 // left -= consumed; | 
| 
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>diff
changeset | 173 // progressSupport.worked(consumed); | 
| 
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>diff
changeset | 174 // } while (left > 0); | 
| 
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>diff
changeset | 175 // progressSupport.done(); // XXX shall specify whether #done() is invoked always or only if completed successfully. | 
| 
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>diff
changeset | 176 // } | 
| 
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>diff
changeset | 177 | 
| 
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>diff
changeset | 178 /*XXX not sure distinct method contentWithFilters() is the best way to do, perhaps, callers shall add filters themselves?*/ | 
| 237 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 179 public void contentWithFilters(int revision, ByteChannel sink) throws HgDataStreamException, CancelledException { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 180 if (revision == WORKING_COPY) { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 181 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: 
233diff
changeset | 182 } else { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 183 content(revision, new FilterByteChannel(sink, getRepo().getFiltersFromRepoToWorkingDir(getPath()))); | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 184 } | 
| 115 
c0cc2535462c
Introduced channels to pipeline (and easily filter) data streams
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
102diff
changeset | 185 } | 
| 22 
603806cd2dc6
Status of local working dir against non-tip base revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
21diff
changeset | 186 | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 187 // for data files need to check heading of the file content for possible metadata | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 188 // @see http://mercurial.selenic.com/wiki/FileFormats#data.2BAC8- | 
| 237 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 189 public void content(int revision, ByteChannel sink) throws HgDataStreamException, CancelledException { | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 190 if (revision == TIP) { | 
| 135 
3959bffb14e9
explicit op name instead math op to get last rev number
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
134diff
changeset | 191 revision = getLastRevision(); | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 192 } | 
| 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>diff
changeset | 193 if (revision == 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: 
233diff
changeset | 194 // 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: 
233diff
changeset | 195 // 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>diff
changeset | 196 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>diff
changeset | 197 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>diff
changeset | 198 } | 
| 
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>diff
changeset | 199 if (wrongLocalRevision(revision) || revision == BAD_REVISION) { | 
| 148 
1a7a9a20e1f9
Exceptions, javadoc. Initial cancel and progress support
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
135diff
changeset | 200 throw new IllegalArgumentException(String.valueOf(revision)); | 
| 
1a7a9a20e1f9
Exceptions, javadoc. Initial cancel and progress support
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
135diff
changeset | 201 } | 
| 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>diff
changeset | 202 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>diff
changeset | 203 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>diff
changeset | 204 } | 
| 134 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 205 if (metadata == null) { | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 206 metadata = new Metadata(); | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 207 } | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 208 ErrorHandlingInspector insp; | 
| 134 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 209 if (metadata.none(revision)) { | 
| 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>diff
changeset | 210 insp = new ContentPipe(sink, 0); | 
| 
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>diff
changeset | 211 } else if (metadata.known(revision)) { | 
| 
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>diff
changeset | 212 insp = new ContentPipe(sink, metadata.dataOffset(revision)); | 
| 
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>diff
changeset | 213 } 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>diff
changeset | 214 // do not know if there's metadata | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 215 insp = new MetadataInspector(metadata, getPath(), new ContentPipe(sink, 0)); | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 216 } | 
| 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>diff
changeset | 217 insp.checkCancelled(); | 
| 
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>diff
changeset | 218 super.content.iterate(revision, revision, true, insp); | 
| 
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>diff
changeset | 219 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: 
233diff
changeset | 220 insp.checkFailed(); // XXX is there real need to throw IOException from ContentPipe? | 
| 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>diff
changeset | 221 } catch (HgDataStreamException 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>diff
changeset | 222 throw ex; | 
| 237 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 223 } catch (IOException ex) { | 
| 
6e1373b54e9b
Allow access to working copy content through HgDataFile. Give access to repository's working dir
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
233diff
changeset | 224 throw new HgDataStreamException(getPath(), ex); | 
| 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>diff
changeset | 225 } 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>diff
changeset | 226 // shall not happen, unless we changed ContentPipe or its subclass | 
| 215 
41a778e3fd31
Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
163diff
changeset | 227 throw new HgDataStreamException(getPath(), ex.getClass().getName(), ex); | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 228 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 229 } | 
| 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>diff
changeset | 230 | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 231 private static class HistoryNode { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 232 int changeset; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 233 Nodeid cset; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 234 HistoryNode parent1, parent2; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 235 List<HistoryNode> children; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 236 | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 237 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: 
306diff
changeset | 238 changeset = cs; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 239 parent1 = p1; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 240 parent2 = p2; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 241 if (p1 != null) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 242 p1.addChild(this); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 243 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 244 if (p2 != null) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 245 p2.addChild(this); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 246 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 247 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 248 | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 249 Nodeid changesetRevision() { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 250 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: 
306diff
changeset | 251 return cset; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 252 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 253 | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 254 void addChild(HistoryNode child) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 255 if (children == null) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 256 children = new ArrayList<HistoryNode>(2); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 257 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 258 children.add(child); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 259 } | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 260 } | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 261 | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 262 public void history(HgChangelog.TreeInspector inspector) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 263 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: 
306diff
changeset | 264 try { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 265 final boolean[] needsSorting = { false }; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 266 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: 
306diff
changeset | 267 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: 
306diff
changeset | 268 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: 
306diff
changeset | 269 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: 
306diff
changeset | 270 if (revisionNumber > 0) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 271 if (commitRevisions[revisionNumber-1] > linkRevision) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 272 needsSorting[0] = true; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 273 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 274 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 275 commitRevisions[revisionNumber] = linkRevision; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 276 HistoryNode p1 = null, p2 = null; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 277 if (parent1Revision != -1) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 278 p1 = completeHistory[parent1Revision]; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 279 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 280 if (parent2Revision != -1) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 281 p2 = completeHistory[parent2Revision]; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 282 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 283 completeHistory[revisionNumber] = new HistoryNode(linkRevision, p1, p2); | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 284 } | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 285 }; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 286 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: 
306diff
changeset | 287 cancelSupport.checkCancelled(); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 288 if (needsSorting[0]) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 289 Arrays.sort(commitRevisions); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 290 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 291 // 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: 
306diff
changeset | 292 // 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: 
306diff
changeset | 293 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: 
306diff
changeset | 294 getRepo().getChangelog().getRevisionsInternal(changesetRevisions, commitRevisions); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 295 cancelSupport.checkCancelled(); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 296 // assign them to corresponding HistoryNodes | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 297 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: 
306diff
changeset | 298 final HistoryNode n = completeHistory[i]; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 299 if (needsSorting[0]) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 300 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: 
306diff
changeset | 301 assert x >= 0; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 302 n.cset = changesetRevisions.get(x); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 303 } else { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 304 // 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: 
306diff
changeset | 305 n.cset = changesetRevisions.get(i); | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 306 } | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 307 } | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 308 cancelSupport.checkCancelled(); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 309 // 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: 
306diff
changeset | 310 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: 
306diff
changeset | 311 final HistoryNode n = completeHistory[i]; | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 312 HistoryNode p; | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 313 Nodeid p1, p2; | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 314 if ((p = n.parent1) != null) { | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 315 p1 = p.changesetRevision(); | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 316 } else { | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 317 p1 = Nodeid.NULL; | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 318 } | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 319 if ((p= n.parent2) != null) { | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 320 p2 = p.changesetRevision(); | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 321 } else { | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 322 p2 = Nodeid.NULL; | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 323 } | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 324 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: 
306diff
changeset | 325 final List<Nodeid> childChangesets; | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 326 if (n.children == null) { | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 327 childChangesets = Collections.emptyList(); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 328 } else { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 329 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: 
306diff
changeset | 330 int j = 0; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 331 for (HistoryNode hn : n.children) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 332 revisions[j++] = hn.changesetRevision(); | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 333 } | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 334 childChangesets = Arrays.asList(revisions); | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 335 } | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 336 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: 
306diff
changeset | 337 cancelSupport.checkCancelled(); | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 338 } | 
| 317 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 339 } catch (CancelledException ex) { | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 340 return; | 
| 
09628675bcee
Rework file history build approach to match rest of the API
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
306diff
changeset | 341 } | 
| 305 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 342 } | 
| 
ae8d116f4ee2
Experimental code to build file history
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
300diff
changeset | 343 | 
| 129 
645829962785
core.Cset renamed to HgChangeset; repo.Changeset moved into HgChangelog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
121diff
changeset | 344 public void history(HgChangelog.Inspector inspector) { | 
| 135 
3959bffb14e9
explicit op name instead math op to get last rev number
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
134diff
changeset | 345 history(0, getLastRevision(), inspector); | 
| 48 
e34f90b9ded1
Limit option for history/log
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
37diff
changeset | 346 } | 
| 
e34f90b9ded1
Limit option for history/log
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
37diff
changeset | 347 | 
| 129 
645829962785
core.Cset renamed to HgChangeset; repo.Changeset moved into HgChangelog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
121diff
changeset | 348 public void history(int start, int end, HgChangelog.Inspector inspector) { | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 349 if (!exists()) { | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 350 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: 
2diff
changeset | 351 } | 
| 135 
3959bffb14e9
explicit op name instead math op to get last rev number
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
134diff
changeset | 352 final int last = getLastRevision(); | 
| 77 
c677e1593919
Moved RevlogStream implementation into .internal
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
74diff
changeset | 353 if (end == TIP) { | 
| 
c677e1593919
Moved RevlogStream implementation into .internal
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
74diff
changeset | 354 end = last; | 
| 
c677e1593919
Moved RevlogStream implementation into .internal
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
74diff
changeset | 355 } | 
| 300 
650b45d290b1
Share range check code
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
295diff
changeset | 356 if (start == TIP) { | 
| 
650b45d290b1
Share range check code
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
295diff
changeset | 357 start = last; | 
| 
650b45d290b1
Share range check code
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
295diff
changeset | 358 } | 
| 
650b45d290b1
Share range check code
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
295diff
changeset | 359 HgInternals.checkRevlogRange(start, end, last); | 
| 
650b45d290b1
Share range check code
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
295diff
changeset | 360 | 
| 48 
e34f90b9ded1
Limit option for history/log
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
37diff
changeset | 361 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: 
240diff
changeset | 362 final boolean[] needsSorting = { false }; | 
| 77 
c677e1593919
Moved RevlogStream implementation into .internal
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
74diff
changeset | 363 RevlogStream.Inspector insp = new RevlogStream.Inspector() { | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 364 int count = 0; | 
| 51 
9429c7bd1920
Try DataAccess to reach revision data instead of plain byte arrays
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
49diff
changeset | 365 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: 
240diff
changeset | 366 if (count > 0) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
240diff
changeset | 367 if (commitRevisions[count -1] > linkRevision) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
240diff
changeset | 368 needsSorting[0] = true; | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
240diff
changeset | 369 } | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
240diff
changeset | 370 } | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 371 commitRevisions[count++] = linkRevision; | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 372 } | 
| 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 373 }; | 
| 48 
e34f90b9ded1
Limit option for history/log
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
37diff
changeset | 374 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: 
215diff
changeset | 375 final HgChangelog changelog = getRepo().getChangelog(); | 
| 242 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
240diff
changeset | 376 if (needsSorting[0]) { | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
240diff
changeset | 377 // automatic tools (svnmerge?) produce unnatural file history | 
| 
ad6a046943be
Improved reading of sparse revisions from a revlog
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
240diff
changeset | 378 // (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: 
240diff
changeset | 379 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: 
215diff
changeset | 380 } | 
| 245 
2fb439375ddc
Avoid sorting revision range twice
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
242diff
changeset | 381 changelog.rangeInternal(inspector, commitRevisions); | 
| 3 
24bb4f365164
Rudimentary log functionality with basic infrastructure is in place
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
2diff
changeset | 382 } | 
| 88 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 383 | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 384 // for a given local revision of the file, find out local revision in the changelog | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 385 public int getChangesetLocalRevision(int revision) { | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 386 return content.linkRevision(revision); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 387 } | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 388 | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 389 public Nodeid getChangesetRevision(Nodeid nid) { | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 390 int changelogRevision = getChangesetLocalRevision(getLocalRevision(nid)); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 391 return getRepo().getChangelog().getRevision(changelogRevision); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 392 } | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 393 | 
| 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>diff
changeset | 394 public boolean isCopy() throws HgDataStreamException { | 
| 134 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 395 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: 
245diff
changeset | 396 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: 
77diff
changeset | 397 } | 
| 134 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 398 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: 
77diff
changeset | 399 return false; | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 400 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 401 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: 
77diff
changeset | 402 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 403 | 
| 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>diff
changeset | 404 public Path getCopySourceName() throws HgDataStreamException { | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 405 if (isCopy()) { | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 406 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: 
77diff
changeset | 407 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 408 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: 
77diff
changeset | 409 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 410 | 
| 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>diff
changeset | 411 public Nodeid getCopySourceRevision() throws HgDataStreamException { | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 412 if (isCopy()) { | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 413 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: 
77diff
changeset | 414 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 415 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: 
77diff
changeset | 416 } | 
| 88 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 417 | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 418 @Override | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 419 public String toString() { | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 420 StringBuilder sb = new StringBuilder(getClass().getSimpleName()); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 421 sb.append('('); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 422 sb.append(getPath()); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 423 sb.append(')'); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 424 return sb.toString(); | 
| 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 425 } | 
| 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: 
245diff
changeset | 426 | 
| 
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: 
245diff
changeset | 427 private void checkAndRecordMetadata(int localRev) throws HgDataStreamException { | 
| 
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: 
245diff
changeset | 428 // content() always initializes metadata. | 
| 
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: 
245diff
changeset | 429 // FIXME this is expensive way to find out metadata, distinct RevlogStream.Iterator would be better. | 
| 
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: 
245diff
changeset | 430 // 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: 
245diff
changeset | 431 // 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: 
245diff
changeset | 432 // 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: 
245diff
changeset | 433 // (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: 
245diff
changeset | 434 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: 
245diff
changeset | 435 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: 
245diff
changeset | 436 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: 
245diff
changeset | 437 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: 
245diff
changeset | 438 } | 
| 
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: 
245diff
changeset | 439 }); | 
| 
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: 
245diff
changeset | 440 } 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: 
245diff
changeset | 441 // it's ok, we did that | 
| 
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: 
245diff
changeset | 442 } catch (Exception 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: 
245diff
changeset | 443 throw new HgDataStreamException(getPath(), "Can't initialize metadata", ex).setRevisionNumber(localRev); | 
| 
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: 
245diff
changeset | 444 } | 
| 
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: 
245diff
changeset | 445 } | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 446 | 
| 88 
61eedab3eb3e
Status between two revisions to recognize copy/rename
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
79diff
changeset | 447 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: 
77diff
changeset | 448 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: 
77diff
changeset | 449 private final int valueStart; | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 450 /*package-local*/MetadataEntry(String key, String value) { | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 451 entry = key + value; | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 452 valueStart = key.length(); | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 453 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 454 /*package-local*/boolean matchKey(String key) { | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 455 return key.length() == valueStart && entry.startsWith(key); | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 456 } | 
| 134 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 457 // 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: 
133diff
changeset | 458 // public String key() { | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 459 // 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: 
133diff
changeset | 460 // } | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 461 public String value() { | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 462 return entry.substring(valueStart); | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 463 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 464 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 465 | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 466 private static class Metadata { | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 467 private static class Record { | 
| 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 468 public final int offset; | 
| 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 469 public final MetadataEntry[] entries; | 
| 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 470 | 
| 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 471 public Record(int off, MetadataEntry[] entr) { | 
| 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 472 offset = off; | 
| 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 473 entries = entr; | 
| 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 474 } | 
| 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 475 } | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 476 // XXX sparse array needed | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 477 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: 
133diff
changeset | 478 | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 479 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: 
133diff
changeset | 480 | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 481 // 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: 
77diff
changeset | 482 boolean known(int revision) { | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 483 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: 
133diff
changeset | 484 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: 
133diff
changeset | 485 } | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 486 | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 487 // 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: 
133diff
changeset | 488 public boolean checked(int revision) { | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 489 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: 
77diff
changeset | 490 } | 
| 134 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 491 | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 492 // 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: 
133diff
changeset | 493 boolean none(int revision) { | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 494 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: 
133diff
changeset | 495 return i == NONE; | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 496 } | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 497 | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 498 // 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: 
133diff
changeset | 499 void recordNone(int revision) { | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 500 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: 
133diff
changeset | 501 if (i == NONE) { | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 502 return; // already there | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 503 } | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 504 if (i != null) { | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 505 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: 
133diff
changeset | 506 } | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 507 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: 
133diff
changeset | 508 } | 
| 
afac8ddc5dd2
Keep record if we tried and found no metadata for a given revision
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
133diff
changeset | 509 | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 510 // 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: 
77diff
changeset | 511 int dataOffset(int revision) { | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 512 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: 
77diff
changeset | 513 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 514 void add(int revision, int dataOffset, Collection<MetadataEntry> e) { | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 515 assert !entries.containsKey(revision); | 
| 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 516 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: 
77diff
changeset | 517 } | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 518 | 
| 78 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 519 String find(int revision, String key) { | 
| 276 
6355ecda1f08
Tailored Map implementation with int keys
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
275diff
changeset | 520 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: 
77diff
changeset | 521 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: 
77diff
changeset | 522 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: 
77diff
changeset | 523 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 524 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 525 return null; | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 526 } | 
| 
c25c5c348d1b
Skip metadata in the beginning of a file content. Parse metadata, recognize copies/renames
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
77diff
changeset | 527 } | 
| 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>diff
changeset | 528 | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 529 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>diff
changeset | 530 private final Metadata metadata; | 
| 215 
41a778e3fd31
Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
163diff
changeset | 531 private final Path fname; // need this only for error reporting | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 532 private final RevlogStream.Inspector delegate; | 
| 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>diff
changeset | 533 | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 534 public MetadataInspector(Metadata _metadata, Path file, 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>diff
changeset | 535 metadata = _metadata; | 
| 215 
41a778e3fd31
Issue 5: Facilities for progress and cancellation. More specific exceptions. Exceptions from callbacks as RuntimeException
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
163diff
changeset | 536 fname = file; | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 537 delegate = chain; | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 538 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>diff
changeset | 539 } | 
| 
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>diff
changeset | 540 | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 541 public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 542 try { | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 543 final int daLength = data.length(); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 544 if (daLength < 4 || data.readByte() != 1 || data.readByte() != 10) { | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 545 metadata.recordNone(revisionNumber); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 546 data.reset(); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 547 } else { | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 548 ArrayList<MetadataEntry> _metadata = new ArrayList<MetadataEntry>(); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 549 int offset = parseMetadata(data, daLength, _metadata); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 550 metadata.add(revisionNumber, offset, _metadata); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 551 // 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: 
276diff
changeset | 552 // 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: 
276diff
changeset | 553 // and we need to ensure predictable result. | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 554 data.reset(); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 555 data = new FilterDataAccess(data, offset, daLength - offset); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 556 } | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 557 if (delegate != null) { | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 558 delegate.next(revisionNumber, actualLen, baseRevision, linkRevision, parent1Revision, parent2Revision, nodeid, data); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 559 } | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 560 } catch (IOException ex) { | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 561 recordFailure(ex); | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 562 } catch (HgDataStreamException ex) { | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 563 recordFailure(ex.setRevisionNumber(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>diff
changeset | 564 } | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 565 } | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 566 | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 567 private int parseMetadata(DataAccess data, final int daLength, ArrayList<MetadataEntry> _metadata) throws IOException, HgDataStreamException { | 
| 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>diff
changeset | 568 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>diff
changeset | 569 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>diff
changeset | 570 // 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>diff
changeset | 571 // 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>diff
changeset | 572 // (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>diff
changeset | 573 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>diff
changeset | 574 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>diff
changeset | 575 boolean byteOne = false; | 
| 
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>diff
changeset | 576 for (int i = 2; i < daLength; i++) { | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 577 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>diff
changeset | 578 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>diff
changeset | 579 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>diff
changeset | 580 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>diff
changeset | 581 // XXX is it possible to have here incomplete key/value (i.e. if last pair didn't end with \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>diff
changeset | 582 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>diff
changeset | 583 } | 
| 
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>diff
changeset | 584 if (key == null || lastColon == -1 || i <= lastColon) { | 
| 
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>diff
changeset | 585 throw new IllegalStateException(); // FIXME log instead and record null key in the metadata. Ex just to fail fast during dev | 
| 
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>diff
changeset | 586 } | 
| 
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>diff
changeset | 587 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>diff
changeset | 588 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>diff
changeset | 589 _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>diff
changeset | 590 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>diff
changeset | 591 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>diff
changeset | 592 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>diff
changeset | 593 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>diff
changeset | 594 } | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 595 // 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>diff
changeset | 596 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>diff
changeset | 597 // 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>diff
changeset | 598 bos.write(1); | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 599 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>diff
changeset | 600 // 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>diff
changeset | 601 } | 
| 
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>diff
changeset | 602 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>diff
changeset | 603 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>diff
changeset | 604 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>diff
changeset | 605 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>diff
changeset | 606 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>diff
changeset | 607 } 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>diff
changeset | 608 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>diff
changeset | 609 } 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>diff
changeset | 610 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>diff
changeset | 611 } | 
| 
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>diff
changeset | 612 } | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 613 if (data.isEmpty() || !byteOne) { | 
| 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 614 throw new HgDataStreamException(fname, "Metadata is not closed properly", 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>diff
changeset | 615 } | 
| 277 
74e7493a042a
Favor delegation over generalization
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: 
276diff
changeset | 616 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: 
5diff
changeset | 617 } | 
| 
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: 
5diff
changeset | 618 } | 
| 2 
08db726a0fb7
Shaping out low-level Hg structures
 Artem Tikhomirov <tikhomirov.artem@gmail.com> parents: diff
changeset | 619 } | 
