# HG changeset patch # User Artem Tikhomirov # Date 1297915567 -3600 # Node ID 37a34044e6bd56e6efb7ce3f1bdaa745dce9260b # Parent 8248aae33f7db63c109eca393e583be95242c96a More reasonable use of path normalizer and path.source diff -r 8248aae33f7d -r 37a34044e6bd cmdline/org/tmatesoft/hg/console/Log.java --- a/cmdline/org/tmatesoft/hg/console/Log.java Thu Feb 17 04:08:34 2011 +0100 +++ b/cmdline/org/tmatesoft/hg/console/Log.java Thu Feb 17 05:06:07 2011 +0100 @@ -24,7 +24,6 @@ import org.tmatesoft.hg.core.HgLogCommand; import org.tmatesoft.hg.core.HgLogCommand.FileRevision; import org.tmatesoft.hg.core.Nodeid; -import org.tmatesoft.hg.repo.HgChangelog; import org.tmatesoft.hg.repo.HgDataFile; import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.util.Path; @@ -82,16 +81,15 @@ for (String fname : cmdLineOpts.files) { HgDataFile f1 = hgRepo.getFileNode(fname); System.out.println("History of the file: " + f1.getPath()); - String normalizesName = hgRepo.getPathHelper().rewrite(fname); if (cmdLineOpts.limit == -1) { - cmd.file(Path.create(normalizesName), true).execute(dump); + cmd.file(f1.getPath(), true).execute(dump); } else { int[] r = new int[] { 0, f1.getRevisionCount() }; if (fixRange(r, dump.reverseOrder, cmdLineOpts.limit) == 0) { System.out.println("No changes"); continue; } - cmd.range(r[0], r[1]).file(Path.create(normalizesName), true).execute(dump); + cmd.range(r[0], r[1]).file(f1.getPath(), true).execute(dump); } dump.complete(); } @@ -123,12 +121,12 @@ // own private LinkedList l = new LinkedList(); private final HgRepository repo; - private HgChangelog.ParentWalker changelogWalker; +// private HgChangelog.ParentWalker changelogWalker; private final int tip ; public Dump(HgRepository hgRepo) { repo = hgRepo; - tip = hgRepo.getChangelog().getRevisionCount() - 1; + tip = hgRepo.getChangelog().getLastRevision(); } public void copy(FileRevision from, FileRevision to) { @@ -155,7 +153,7 @@ System.out.print(s); } l.clear(); - changelogWalker = null; +// changelogWalker = null; } private String print(HgChangeset cset) { diff -r 8248aae33f7d -r 37a34044e6bd src/org/tmatesoft/hg/core/HgChangeset.java --- a/src/org/tmatesoft/hg/core/HgChangeset.java Thu Feb 17 04:08:34 2011 +0100 +++ b/src/org/tmatesoft/hg/core/HgChangeset.java Thu Feb 17 05:06:07 2011 +0100 @@ -25,7 +25,6 @@ import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.repo.HgStatusCollector; import org.tmatesoft.hg.util.Path; -import org.tmatesoft.hg.util.PathPool; /** @@ -38,7 +37,7 @@ */ public class HgChangeset implements Cloneable { private final HgStatusCollector statusHelper; - private final PathPool pathHelper; + private final Path.Source pathHelper; // private Changeset changeset; @@ -51,9 +50,9 @@ // XXX consider CommandContext with StatusCollector, PathPool etc. Commands optionally get CC through a cons or create new // and pass it around - /*package-local*/HgChangeset(HgStatusCollector statusCollector, PathPool pathPool) { + /*package-local*/HgChangeset(HgStatusCollector statusCollector, Path.Source pathFactory) { statusHelper = statusCollector; - pathHelper = pathPool; + pathHelper = pathFactory; } /*package-local*/ diff -r 8248aae33f7d -r 37a34044e6bd src/org/tmatesoft/hg/core/HgLogCommand.java --- a/src/org/tmatesoft/hg/core/HgLogCommand.java Thu Feb 17 04:08:34 2011 +0100 +++ b/src/org/tmatesoft/hg/core/HgLogCommand.java Thu Feb 17 05:06:07 2011 +0100 @@ -33,6 +33,7 @@ import org.tmatesoft.hg.repo.HgStatusCollector; import org.tmatesoft.hg.util.Path; import org.tmatesoft.hg.util.PathPool; +import org.tmatesoft.hg.util.PathRewrite; /** @@ -148,6 +149,13 @@ followHistory = followCopyRename; return this; } + + /** + * Handy analog of {@link #file(Path, boolean)} when clients' paths come from filesystem and need conversion to repository's + */ + public HgLogCommand file(String file, boolean followCopyRename) { + return file(Path.create(repo.getToRepoPathHelper().rewrite(file)), followCopyRename); + } /** * Similar to {@link #execute(org.tmatesoft.hg.repo.Changeset.Inspector)}, collects and return result as a list. @@ -174,7 +182,12 @@ try { delegate = handler; count = 0; - changeset = new HgChangeset(new HgStatusCollector(repo), new PathPool(repo.getPathHelper())); + HgStatusCollector statusCollector = new HgStatusCollector(repo); + // files listed in a changeset don't need their names to be rewritten (they are normalized already) + PathPool pp = new PathPool(new PathRewrite.Empty()); + // #file(String, boolean) above may utilize PathPool as well. CommandContext? + statusCollector.setPathPool(pp); + changeset = new HgChangeset(statusCollector, pp); if (file == null) { repo.getChangelog().range(startRev, endRev, this); } else { diff -r 8248aae33f7d -r 37a34044e6bd src/org/tmatesoft/hg/core/HgManifestCommand.java --- a/src/org/tmatesoft/hg/core/HgManifestCommand.java Thu Feb 17 04:08:34 2011 +0100 +++ b/src/org/tmatesoft/hg/core/HgManifestCommand.java Thu Feb 17 05:06:07 2011 +0100 @@ -28,6 +28,7 @@ import org.tmatesoft.hg.repo.HgRepository; import org.tmatesoft.hg.util.Path; import org.tmatesoft.hg.util.PathPool; +import org.tmatesoft.hg.util.PathRewrite; /** @@ -106,12 +107,16 @@ // I'd rather let HgManifestCommand implement HgManifest.Inspector directly, but this pollutes API alot private class Mediator implements HgManifest.Inspector { + // file names are likely to repeat in each revision, hence caching of Paths. + // However, once HgManifest.Inspector switches to Path objects, perhaps global Path pool + // might be more effective? private PathPool pathPool; private List manifestContent; private Nodeid manifestNodeid; public void start() { - pathPool = new PathPool(repo.getPathHelper()); + // Manifest keeps normalized paths + pathPool = new PathPool(new PathRewrite.Empty()); } public void done() { diff -r 8248aae33f7d -r 37a34044e6bd src/org/tmatesoft/hg/repo/HgInternals.java --- a/src/org/tmatesoft/hg/repo/HgInternals.java Thu Feb 17 04:08:34 2011 +0100 +++ b/src/org/tmatesoft/hg/repo/HgInternals.java Thu Feb 17 05:06:07 2011 +0100 @@ -21,6 +21,7 @@ import java.net.UnknownHostException; import org.tmatesoft.hg.internal.ConfigFile; +import org.tmatesoft.hg.util.Path; /** @@ -48,7 +49,7 @@ HgIgnore ignore = repo.getIgnore(); boolean[] rv = new boolean[toCheck.length]; for (int i = 0; i < toCheck.length; i++) { - rv[i] = ignore.isIgnored(toCheck[i]); + rv[i] = ignore.isIgnored(Path.create(toCheck[i])); } return rv; } diff -r 8248aae33f7d -r 37a34044e6bd src/org/tmatesoft/hg/repo/HgRepository.java --- a/src/org/tmatesoft/hg/repo/HgRepository.java Thu Feb 17 04:08:34 2011 +0100 +++ b/src/org/tmatesoft/hg/repo/HgRepository.java Thu Feb 17 05:06:07 2011 +0100 @@ -57,17 +57,7 @@ private final File repoDir; // .hg folder private final String repoLocation; private final DataAccessProvider dataAccess; - private final PathRewrite normalizePath = new PathRewrite() { - - public String rewrite(String path) { - // TODO handle . and .. (although unlikely to face them from GUI client) - path = path.replace('\\', '/').replace("//", "/"); - if (path.startsWith("/")) { - path = path.substring(1); - } - return path; - } - }; + private final PathRewrite normalizePath; private final PathRewrite dataPathHelper; private final PathRewrite repoPathHelper; @@ -86,6 +76,7 @@ repoLocation = repositoryPath; dataAccess = null; dataPathHelper = repoPathHelper = null; + normalizePath = null; } HgRepository(File repositoryRoot) throws IOException { @@ -93,6 +84,22 @@ repoDir = repositoryRoot; repoLocation = repositoryRoot.getParentFile().getCanonicalPath(); dataAccess = new DataAccessProvider(); + final boolean runningOnWindows = System.getProperty("os.name").indexOf("Windows") != -1; + if (runningOnWindows) { + normalizePath = new PathRewrite() { + + public String rewrite(String path) { + // TODO handle . and .. (although unlikely to face them from GUI client) + path = path.replace('\\', '/').replace("//", "/"); + if (path.startsWith("/")) { + path = path.substring(1); + } + return path; + } + }; + } else { + normalizePath = new PathRewrite.Empty(); // or strip leading slash, perhaps? + } parseRequires(); dataPathHelper = impl.buildDataFilesHelper(); repoPathHelper = impl.buildRepositoryFilesHelper(); @@ -158,7 +165,8 @@ return new HgDataFile(this, path, content); } - public PathRewrite getPathHelper() { // Really need to be public? + /* clients need to rewrite path from their FS to a repository-friendly paths, and, perhaps, vice versa*/ + public PathRewrite getToRepoPathHelper() { return normalizePath; } @@ -194,7 +202,7 @@ // FIXME not sure repository shall create walkers /*package-local*/ FileIterator createWorkingDirWalker() { File repoRoot = repoDir.getParentFile(); - Path.Source pathSrc = new Path.SimpleSource(new PathRewrite.Composite(new RelativePathRewrite(repoRoot), getPathHelper())); + Path.Source pathSrc = new Path.SimpleSource(new PathRewrite.Composite(new RelativePathRewrite(repoRoot), getToRepoPathHelper())); // Impl note: simple source is enough as files in the working dir are all unique // even if they might get reused (i.e. after FileIterator#reset() and walking once again), // path caching is better to be done in the code which knows that path are being reused diff -r 8248aae33f7d -r 37a34044e6bd src/org/tmatesoft/hg/repo/HgStatusCollector.java --- a/src/org/tmatesoft/hg/repo/HgStatusCollector.java Thu Feb 17 04:08:34 2011 +0100 +++ b/src/org/tmatesoft/hg/repo/HgStatusCollector.java Thu Feb 17 05:06:07 2011 +0100 @@ -79,6 +79,9 @@ return pathPool; } + /** + * Allows sharing of a common path cache + */ public void setPathPool(PathPool pathPool) { this.pathPool = pathPool; } diff -r 8248aae33f7d -r 37a34044e6bd src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java --- a/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Thu Feb 17 04:08:34 2011 +0100 +++ b/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java Thu Feb 17 05:06:07 2011 +0100 @@ -130,7 +130,7 @@ // modified, added, removed, clean if (collect != null) { // need to check against base revision, not FS file checkLocalStatusAgainstBaseRevision(baseRevFiles, collect, baseRevision, fname, f, inspector); - baseRevFiles.remove(fname); + baseRevFiles.remove(fname.toString()); } else { checkLocalStatusAgainstFile(fname, f, inspector); } diff -r 8248aae33f7d -r 37a34044e6bd src/org/tmatesoft/hg/util/PathRewrite.java --- a/src/org/tmatesoft/hg/util/PathRewrite.java Thu Feb 17 04:08:34 2011 +0100 +++ b/src/org/tmatesoft/hg/util/PathRewrite.java Thu Feb 17 05:06:07 2011 +0100 @@ -20,7 +20,8 @@ import java.util.List; /** - * + * File names often need transformations, like Windows-style path to Unix or human-readable data file name to storage location. + * * @author Artem Tikhomirov * @author TMate Software Ltd. */ @@ -40,8 +41,8 @@ public Composite(PathRewrite... e) { LinkedList r = new LinkedList(); - for (int i = (e == null ? -1 : e.length); i >=0; i--) { - r.addFirst(e[i]); + for (int i = 0; e != null && i < e.length; i++) { + r.addLast(e[i]); } chain = r; }