# HG changeset patch # User Artem Tikhomirov # Date 1295305695 -3600 # Node ID b771e94a4f7cc54e42f1ba5b621397e02ff50701 # Parent 4cfc47bc14cc6f9960eb32e8efb33b5c1f5286dd Introduce Internals to keep LocalHgRepo casts and alike in a single place. WCSC optionally to reuse SC data diff -r 4cfc47bc14cc -r b771e94a4f7c src/com/tmate/hgkit/console/Cat.java --- a/src/com/tmate/hgkit/console/Cat.java Mon Jan 17 23:01:19 2011 +0100 +++ b/src/com/tmate/hgkit/console/Cat.java Tue Jan 18 00:08:15 2011 +0100 @@ -6,9 +6,8 @@ import com.tmate.hgkit.fs.RepositoryLookup; import com.tmate.hgkit.ll.DigestHelper; import com.tmate.hgkit.ll.HgDataFile; -import com.tmate.hgkit.ll.HgIgnore; import com.tmate.hgkit.ll.HgRepository; -import com.tmate.hgkit.ll.LocalHgRepo; +import com.tmate.hgkit.ll.Internals; /** * @author artem @@ -24,9 +23,11 @@ System.err.printf("Can't find repository in: %s\n", hgRepo.getLocation()); return; } - HgIgnore ignore = ((LocalHgRepo) hgRepo).loadIgnore(); - for (String s : new String[] {"design.txt", "src/com/tmate/hgkit/ll/Changelog.java", "src/Extras.java", "bin/com/tmate/hgkit/ll/Changelog.class"} ) { - System.out.println("Ignored " + s + ": " + ignore.isIgnored(s)); + Internals debug = new Internals(hgRepo); + String[] toCheck = new String[] {"design.txt", "src/com/tmate/hgkit/ll/Changelog.java", "src/Extras.java", "bin/com/tmate/hgkit/ll/Changelog.class"}; + boolean[] checkResult = debug.checkIgnored(toCheck); + for (int i = 0; i < toCheck.length; i++) { + System.out.println("Ignored " + toCheck[i] + ": " + checkResult[i]); } DigestHelper dh = new DigestHelper(); for (String fname : cmdLineOpts.files) { diff -r 4cfc47bc14cc -r b771e94a4f7c src/com/tmate/hgkit/console/Status.java --- a/src/com/tmate/hgkit/console/Status.java Mon Jan 17 23:01:19 2011 +0100 +++ b/src/com/tmate/hgkit/console/Status.java Tue Jan 18 00:08:15 2011 +0100 @@ -12,6 +12,7 @@ import com.tmate.hgkit.fs.RepositoryLookup; import com.tmate.hgkit.ll.HgDataFile; import com.tmate.hgkit.ll.HgRepository; +import com.tmate.hgkit.ll.Internals; import com.tmate.hgkit.ll.LocalHgRepo; import com.tmate.hgkit.ll.Nodeid; import com.tmate.hgkit.ll.StatusCollector; @@ -32,7 +33,8 @@ return; } System.out.println(hgRepo.getLocation()); - ((LocalHgRepo) hgRepo).loadDirstate().dump(); + Internals debug = new Internals(hgRepo); + debug.dumpDirstate(); final StatusDump dump = new StatusDump(); dump.showIgnored = false; dump.showClean = false; diff -r 4cfc47bc14cc -r b771e94a4f7c src/com/tmate/hgkit/ll/HgDirstate.java --- a/src/com/tmate/hgkit/ll/HgDirstate.java Mon Jan 17 23:01:19 2011 +0100 +++ b/src/com/tmate/hgkit/ll/HgDirstate.java Tue Jan 18 00:08:15 2011 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Artem Tikhomirov + * Copyright (c) 2010, 2011 Artem Tikhomirov */ package com.tmate.hgkit.ll; @@ -20,25 +20,30 @@ */ public class HgDirstate { - private final LocalHgRepo repo; + private final DataAccessProvider accessProvider; private final File dirstateFile; private Map normal; private Map added; private Map removed; private Map merged; - public HgDirstate(LocalHgRepo hgRepo, File dirstate) { - this.repo = hgRepo; - this.dirstateFile = dirstate; + /*package-local*/ HgDirstate() { + // empty instance + accessProvider = null; + dirstateFile = null; + } + + public HgDirstate(DataAccessProvider dap, File dirstate) { + accessProvider = dap; + dirstateFile = dirstate; } private void read() { normal = added = removed = merged = Collections.emptyMap(); - if (!dirstateFile.exists()) { + if (dirstateFile == null || !dirstateFile.exists()) { return; } - DataAccessProvider dap = repo.getDataAccess(); - DataAccess da = dap.create(dirstateFile); + DataAccess da = accessProvider.create(dirstateFile); if (da.isEmpty()) { return; } diff -r 4cfc47bc14cc -r b771e94a4f7c src/com/tmate/hgkit/ll/Internals.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/tmate/hgkit/ll/Internals.java Tue Jan 18 00:08:15 2011 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 Artem Tikhomirov + */ +package com.tmate.hgkit.ll; + +/** + * DO NOT USE THIS CLASS, INTENDED FOR TESTING PURPOSES. + * + * Debug helper, to access otherwise restricted (package-local) methods + * + * @author artem + */ +public class Internals { + + private final HgRepository repo; + + public Internals(HgRepository hgRepo) { + this.repo = hgRepo; + } + + public void dumpDirstate() { + if (repo instanceof LocalHgRepo) { + ((LocalHgRepo) repo).loadDirstate().dump(); + } + } + + public boolean[] checkIgnored(String... toCheck) { + if (repo instanceof LocalHgRepo) { + HgIgnore ignore = ((LocalHgRepo) repo).loadIgnore(); + boolean[] rv = new boolean[toCheck.length]; + for (int i = 0; i < toCheck.length; i++) { + rv[i] = ignore.isIgnored(toCheck[i]); + } + return rv; + } + return new boolean[0]; + } +} diff -r 4cfc47bc14cc -r b771e94a4f7c src/com/tmate/hgkit/ll/LocalHgRepo.java --- a/src/com/tmate/hgkit/ll/LocalHgRepo.java Mon Jan 17 23:01:19 2011 +0100 +++ b/src/com/tmate/hgkit/ll/LocalHgRepo.java Tue Jan 18 00:08:15 2011 +0100 @@ -3,20 +3,14 @@ */ package com.tmate.hgkit.ll; -import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; -import java.io.FileFilter; import java.io.FileInputStream; -import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; import java.lang.ref.SoftReference; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; -import java.util.LinkedList; -import java.util.Set; import java.util.TreeSet; import com.tmate.hgkit.fs.DataAccessProvider; @@ -56,9 +50,8 @@ } // XXX package-local, unless there are cases when required from outside (guess, working dir/revision walkers may hide dirstate access and no public visibility needed) - public final HgDirstate loadDirstate() { - // XXX may cache in SoftReference if creation is expensive - return new HgDirstate(this, new File(repoDir, "dirstate")); + final HgDirstate loadDirstate() { + return new HgDirstate(getDataAccess(), new File(repoDir, "dirstate")); } // package-local, see comment for loadDirstate diff -r 4cfc47bc14cc -r b771e94a4f7c src/com/tmate/hgkit/ll/StatusCollector.java --- a/src/com/tmate/hgkit/ll/StatusCollector.java Mon Jan 17 23:01:19 2011 +0100 +++ b/src/com/tmate/hgkit/ll/StatusCollector.java Tue Jan 18 00:08:15 2011 +0100 @@ -40,6 +40,10 @@ return i; } + /*package-local*/ ManifestRevisionInspector raw(int rev) { + return get(rev); + } + // hg status --change public void change(int rev, Inspector inspector) { int[] parents = new int[2]; diff -r 4cfc47bc14cc -r b771e94a4f7c src/com/tmate/hgkit/ll/WorkingCopyStatusCollector.java --- a/src/com/tmate/hgkit/ll/WorkingCopyStatusCollector.java Mon Jan 17 23:01:19 2011 +0100 +++ b/src/com/tmate/hgkit/ll/WorkingCopyStatusCollector.java Tue Jan 18 00:08:15 2011 +0100 @@ -23,22 +23,47 @@ private final HgRepository repo; private final FileWalker repoWalker; + private HgDirstate dirstate; + private StatusCollector baseRevisionCollector; public WorkingCopyStatusCollector(HgRepository hgRepo, FileWalker hgRepoWalker) { this.repo = hgRepo; this.repoWalker = hgRepoWalker; } + + /** + * Optionally, supply a collector instance that may cache (or have already cached) base revision + * @param sc may be null + */ + public void setBseRevisionCollector(StatusCollector sc) { + baseRevisionCollector = sc; + } + + private HgDirstate getDirstate() { + if (dirstate == null) { + if (repo instanceof LocalHgRepo) { + dirstate = ((LocalHgRepo) repo).loadDirstate(); + } else { + dirstate = new HgDirstate(); + } + } + return dirstate; + } + // may be invoked few times public void walk(int baseRevision, StatusCollector.Inspector inspector) { final HgIgnore hgIgnore = ((LocalHgRepo) repo).loadIgnore(); // FIXME hack - final HgDirstate dirstate = ((LocalHgRepo) repo).loadDirstate(); // FIXME hack - TreeSet knownEntries = dirstate.all(); + TreeSet knownEntries = getDirstate().all(); final boolean isTipBase = baseRevision == TIP || baseRevision == repo.getManifest().getRevisionCount(); StatusCollector.ManifestRevisionInspector collect = null; Set baseRevFiles = Collections.emptySet(); if (!isTipBase) { - collect = new StatusCollector.ManifestRevisionInspector(baseRevision, baseRevision); - repo.getManifest().walk(baseRevision, baseRevision, collect); + if (baseRevisionCollector != null) { + collect = baseRevisionCollector.raw(baseRevision); + } else { + collect = new StatusCollector.ManifestRevisionInspector(baseRevision, baseRevision); + repo.getManifest().walk(baseRevision, baseRevision, collect); + } baseRevFiles = new TreeSet(collect.files(baseRevision)); } repoWalker.reset(); @@ -53,10 +78,10 @@ if (collect != null) { // need to check against base revision, not FS file Nodeid nid1 = collect.nodeid(baseRevision, fname); String flags = collect.flags(baseRevision, fname); - checkLocalStatusAgainstBaseRevision(baseRevFiles, nid1, flags, fname, f, dirstate, inspector); + checkLocalStatusAgainstBaseRevision(baseRevFiles, nid1, flags, fname, f, inspector); baseRevFiles.remove(fname); } else { - checkLocalStatusAgainstFile(fname, f, dirstate, inspector); + checkLocalStatusAgainstFile(fname, f, inspector); } } else { inspector.unknown(fname); @@ -69,7 +94,7 @@ } for (String m : knownEntries) { // removed from the repository and missing from working dir shall not be reported as 'deleted' - if (dirstate.checkRemoved(m) == null) { + if (getDirstate().checkRemoved(m) == null) { inspector.missing(m); } } @@ -84,9 +109,9 @@ //******************************************** - private static void checkLocalStatusAgainstFile(String fname, File f, HgDirstate dirstate, StatusCollector.Inspector inspector) { + private void checkLocalStatusAgainstFile(String fname, File f, StatusCollector.Inspector inspector) { HgDirstate.Record r; - if ((r = dirstate.checkNormal(fname)) != null) { + if ((r = getDirstate().checkNormal(fname)) != null) { // either clean or modified if (f.lastModified() / 1000 == r.time && r.size == f.length()) { inspector.clean(fname); @@ -94,35 +119,35 @@ // FIXME check actual content to avoid false modified files inspector.modified(fname); } - } else if ((r = dirstate.checkAdded(fname)) != null) { + } else if ((r = getDirstate().checkAdded(fname)) != null) { if (r.name2 == null) { inspector.added(fname); } else { inspector.copied(fname, r.name2); } - } else if ((r = dirstate.checkRemoved(fname)) != null) { + } else if ((r = getDirstate().checkRemoved(fname)) != null) { inspector.removed(fname); - } else if ((r = dirstate.checkMerged(fname)) != null) { + } else if ((r = getDirstate().checkMerged(fname)) != null) { inspector.modified(fname); } } // XXX refactor checkLocalStatus methods in more OO way - private void checkLocalStatusAgainstBaseRevision(Set baseRevNames, Nodeid nid1, String flags, String fname, File f, HgDirstate dirstate, StatusCollector.Inspector inspector) { + private void checkLocalStatusAgainstBaseRevision(Set baseRevNames, Nodeid nid1, String flags, String fname, File f, StatusCollector.Inspector inspector) { // fname is in the dirstate, either Normal, Added, Removed or Merged HgDirstate.Record r; if (nid1 == null) { // normal: added? // added: not known at the time of baseRevision, shall report // merged: was not known, report as added? - if ((r = dirstate.checkAdded(fname)) != null) { + if ((r = getDirstate().checkAdded(fname)) != null) { if (r.name2 != null && baseRevNames.contains(r.name2)) { baseRevNames.remove(r.name2); inspector.copied(r.name2, fname); return; } // fall-through, report as added - } else if (dirstate.checkRemoved(fname) != null) { + } else if (getDirstate().checkRemoved(fname) != null) { // removed: removed file was not known at the time of baseRevision, and we should not report it as removed return; } @@ -130,7 +155,7 @@ } else { // was known; check whether clean or modified // when added - seems to be the case of a file added once again, hence need to check if content is different - if ((r = dirstate.checkNormal(fname)) != null || (r = dirstate.checkMerged(fname)) != null || (r = dirstate.checkAdded(fname)) != null) { + if ((r = getDirstate().checkNormal(fname)) != null || (r = getDirstate().checkMerged(fname)) != null || (r = getDirstate().checkAdded(fname)) != null) { // either clean or modified HgDataFile fileNode = repo.getFileNode(fname); final int lengthAtRevision = fileNode.length(nid1);