changeset 142:37a34044e6bd

More reasonable use of path normalizer and path.source
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Thu, 17 Feb 2011 05:06:07 +0100
parents 8248aae33f7d
children b9700740553a
files cmdline/org/tmatesoft/hg/console/Log.java src/org/tmatesoft/hg/core/HgChangeset.java src/org/tmatesoft/hg/core/HgLogCommand.java src/org/tmatesoft/hg/core/HgManifestCommand.java src/org/tmatesoft/hg/repo/HgInternals.java src/org/tmatesoft/hg/repo/HgRepository.java src/org/tmatesoft/hg/repo/HgStatusCollector.java src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java src/org/tmatesoft/hg/util/PathRewrite.java
diffstat 9 files changed, 59 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- 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<String> l = new LinkedList<String>();
 		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) {
--- 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*/
--- 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 {
--- 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<FileRevision> 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() {
--- 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;
 	}
--- 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 
--- 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;
 	}
--- 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);
 				}
--- 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<PathRewrite> r = new LinkedList<PathRewrite>();
-			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;
 		}