Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgDirstate.java @ 290:8faad08c709b
Expose dirstate to allow pre-configuration of FileIterators for status collection in particular
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Wed, 14 Sep 2011 01:52:41 +0200 |
| parents | 7232b94f2ae3 |
| children | 1483e57541ef |
comparison
equal
deleted
inserted
replaced
| 289:086a326f181f | 290:8faad08c709b |
|---|---|
| 40 * @see http://mercurial.selenic.com/wiki/FileFormats#dirstate | 40 * @see http://mercurial.selenic.com/wiki/FileFormats#dirstate |
| 41 * | 41 * |
| 42 * @author Artem Tikhomirov | 42 * @author Artem Tikhomirov |
| 43 * @author TMate Software Ltd. | 43 * @author TMate Software Ltd. |
| 44 */ | 44 */ |
| 45 class HgDirstate /* XXX RepoChangeListener */{ | 45 public final class HgDirstate /* XXX RepoChangeListener */{ |
| 46 | |
| 47 public enum EntryKind { | |
| 48 Normal, Added, Removed, Merged, // order is being used in code of this class, don't change unless any use is checked | |
| 49 } | |
| 46 | 50 |
| 47 private final HgRepository repo; | 51 private final HgRepository repo; |
| 48 private final File dirstateFile; | 52 private final File dirstateFile; |
| 49 private final PathPool pathPool; | 53 private final PathPool pathPool; |
| 50 private Map<Path, Record> normal; | 54 private Map<Path, Record> normal; |
| 52 private Map<Path, Record> removed; | 56 private Map<Path, Record> removed; |
| 53 private Map<Path, Record> merged; | 57 private Map<Path, Record> merged; |
| 54 private Pair<Nodeid, Nodeid> parents; | 58 private Pair<Nodeid, Nodeid> parents; |
| 55 private String currentBranch; | 59 private String currentBranch; |
| 56 | 60 |
| 57 public HgDirstate(HgRepository hgRepo, File dirstate, PathPool pathPool) { | 61 /*package-local*/ HgDirstate(HgRepository hgRepo, File dirstate, PathPool pathPool) { |
| 58 repo = hgRepo; | 62 repo = hgRepo; |
| 59 dirstateFile = dirstate; // XXX decide whether file names shall be kept local to reader (see #branches()) or passed from outside | 63 dirstateFile = dirstate; // XXX decide whether file names shall be kept local to reader (see #branches()) or passed from outside |
| 60 this.pathPool = pathPool; | 64 this.pathPool = pathPool; |
| 61 } | 65 } |
| 62 | 66 |
| 124 parents = null; | 128 parents = null; |
| 125 return new Pair<Nodeid, Nodeid>(n1, n2); | 129 return new Pair<Nodeid, Nodeid>(n1, n2); |
| 126 } | 130 } |
| 127 | 131 |
| 128 /** | 132 /** |
| 129 * @return array of length 2 with working copy parents, non null. | 133 * @return pair of working copy parents, with {@link Nodeid#NULL} for missing values. |
| 130 */ | 134 */ |
| 131 public Pair<Nodeid,Nodeid> parents() { | 135 public Pair<Nodeid,Nodeid> parents() { |
| 132 if (parents == null) { | 136 if (parents == null) { |
| 133 parents = readParents(repo, dirstateFile); | 137 parents = readParents(repo, dirstateFile); |
| 134 } | 138 } |
| 136 } | 140 } |
| 137 | 141 |
| 138 /** | 142 /** |
| 139 * @return pair of parents, both {@link Nodeid#NULL} if dirstate is not available | 143 * @return pair of parents, both {@link Nodeid#NULL} if dirstate is not available |
| 140 */ | 144 */ |
| 141 public static Pair<Nodeid, Nodeid> readParents(HgRepository repo, File dirstateFile) { | 145 /*package-local*/ static Pair<Nodeid, Nodeid> readParents(HgRepository repo, File dirstateFile) { |
| 142 // do not read whole dirstate if all we need is WC parent information | 146 // do not read whole dirstate if all we need is WC parent information |
| 143 if (dirstateFile == null || !dirstateFile.exists()) { | 147 if (dirstateFile == null || !dirstateFile.exists()) { |
| 144 return new Pair<Nodeid,Nodeid>(NULL, NULL); | 148 return new Pair<Nodeid,Nodeid>(NULL, NULL); |
| 145 } | 149 } |
| 146 DataAccess da = repo.getDataAccess().create(dirstateFile); | 150 DataAccess da = repo.getDataAccess().create(dirstateFile); |
| 155 da.done(); | 159 da.done(); |
| 156 } | 160 } |
| 157 } | 161 } |
| 158 | 162 |
| 159 /** | 163 /** |
| 160 * XXX is it really proper place for the method? | |
| 161 * @return branch associated with the working directory | 164 * @return branch associated with the working directory |
| 162 */ | 165 */ |
| 163 public String branch() { | 166 public String branch() { |
| 167 // XXX is it really proper place for the method? | |
| 164 if (currentBranch == null) { | 168 if (currentBranch == null) { |
| 165 currentBranch = readBranch(repo); | 169 currentBranch = readBranch(repo); |
| 166 } | 170 } |
| 167 return currentBranch; | 171 return currentBranch; |
| 168 } | 172 } |
| 169 | 173 |
| 170 /** | 174 /** |
| 171 * XXX is it really proper place for the method? | 175 * XXX is it really proper place for the method? |
| 172 * @return branch associated with the working directory | 176 * @return branch associated with the working directory |
| 173 */ | 177 */ |
| 174 public static String readBranch(HgRepository repo) { | 178 /*package-local*/ static String readBranch(HgRepository repo) { |
| 175 String branch = HgRepository.DEFAULT_BRANCH_NAME; | 179 String branch = HgRepository.DEFAULT_BRANCH_NAME; |
| 176 File branchFile = new File(repo.getRepositoryRoot(), "branch"); | 180 File branchFile = new File(repo.getRepositoryRoot(), "branch"); |
| 177 if (branchFile.exists()) { | 181 if (branchFile.exists()) { |
| 178 try { | 182 try { |
| 179 BufferedReader r = new BufferedReader(new FileReader(branchFile)); | 183 BufferedReader r = new BufferedReader(new FileReader(branchFile)); |
| 191 return branch; | 195 return branch; |
| 192 } | 196 } |
| 193 | 197 |
| 194 // new, modifiable collection | 198 // new, modifiable collection |
| 195 /*package-local*/ TreeSet<Path> all() { | 199 /*package-local*/ TreeSet<Path> all() { |
| 196 read(); | 200 if (normal == null) { |
| 201 read(); | |
| 202 } | |
| 197 TreeSet<Path> rv = new TreeSet<Path>(); | 203 TreeSet<Path> rv = new TreeSet<Path>(); |
| 198 @SuppressWarnings("unchecked") | 204 @SuppressWarnings("unchecked") |
| 199 Map<Path, Record>[] all = new Map[] { normal, added, removed, merged }; | 205 Map<Path, Record>[] all = new Map[] { normal, added, removed, merged }; |
| 200 for (int i = 0; i < all.length; i++) { | 206 for (int i = 0; i < all.length; i++) { |
| 201 for (Record r : all[i].values()) { | 207 for (Record r : all[i].values()) { |
| 237 } | 243 } |
| 238 System.out.println(); | 244 System.out.println(); |
| 239 } | 245 } |
| 240 } | 246 } |
| 241 | 247 |
| 242 /*package-local*/ static class Record { | 248 public void walk(Inspector inspector) { |
| 243 final int mode; | 249 if (normal == null) { |
| 244 // it seems Dirstate keeps local file size (i.e. that with any filters already applied). | 250 read(); |
| 251 } | |
| 252 @SuppressWarnings("unchecked") | |
| 253 Map<Path, Record>[] all = new Map[] { normal, added, removed, merged }; | |
| 254 for (int i = 0; i < all.length; i++) { | |
| 255 EntryKind k = EntryKind.values()[i]; | |
| 256 for (Record r : all[i].values()) { | |
| 257 if (!inspector.next(k, r)) { | |
| 258 return; | |
| 259 } | |
| 260 } | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 public interface Inspector { | |
| 265 boolean next(EntryKind kind, Record entry); | |
| 266 } | |
| 267 | |
| 268 public static final class Record { | |
| 269 private final int mode, size, time; | |
| 270 // Dirstate keeps local file size (i.e. that with any filters already applied). | |
| 245 // Thus, can't compare directly to HgDataFile.length() | 271 // Thus, can't compare directly to HgDataFile.length() |
| 246 final int size; | 272 private final Path name1, name2; |
| 247 final int time; | 273 |
| 248 final Path name1; | 274 /*package-local*/ Record(int fmode, int fsize, int ftime, Path name1, Path name2) { |
| 249 final Path name2; | |
| 250 | |
| 251 public Record(int fmode, int fsize, int ftime, Path name1, Path name2) { | |
| 252 mode = fmode; | 275 mode = fmode; |
| 253 size = fsize; | 276 size = fsize; |
| 254 time = ftime; | 277 time = ftime; |
| 255 this.name1 = name1; | 278 this.name1 = name1; |
| 256 this.name2 = name2; | 279 this.name2 = name2; |
| 257 | 280 |
| 258 } | 281 } |
| 282 | |
| 283 public Path name() { | |
| 284 return name1; | |
| 285 } | |
| 286 | |
| 287 /** | |
| 288 * @return non-<code>null</code> for copy/move | |
| 289 */ | |
| 290 public Path copySource() { | |
| 291 return name2; | |
| 292 } | |
| 293 | |
| 294 public int modificationTime() { | |
| 295 return time; | |
| 296 } | |
| 297 | |
| 298 public int size() { | |
| 299 return size; | |
| 300 } | |
| 259 } | 301 } |
| 260 } | 302 } |
