changeset 184:ec1820f64d2b

Complete incoming cmdline client, with both lite (revisions) and complete (full changeset) information dump
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 13 Apr 2011 19:09:10 +0200
parents 9807bf8f3a9c
children c6fa4dbfc458
files cmdline/org/tmatesoft/hg/console/Incoming.java src/org/tmatesoft/hg/internal/RepositoryComparator.java src/org/tmatesoft/hg/repo/HgRemoteRepository.java
diffstat 3 files changed, 44 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/cmdline/org/tmatesoft/hg/console/Incoming.java	Wed Apr 13 14:15:13 2011 +0200
+++ b/cmdline/org/tmatesoft/hg/console/Incoming.java	Wed Apr 13 19:09:10 2011 +0200
@@ -23,19 +23,23 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map.Entry;
 
+import org.tmatesoft.hg.core.HgBadStateException;
 import org.tmatesoft.hg.core.HgException;
 import org.tmatesoft.hg.core.Nodeid;
 import org.tmatesoft.hg.internal.RepositoryComparator;
 import org.tmatesoft.hg.internal.RepositoryComparator.BranchChain;
+import org.tmatesoft.hg.repo.HgBundle;
 import org.tmatesoft.hg.repo.HgChangelog;
 import org.tmatesoft.hg.repo.HgLookup;
 import org.tmatesoft.hg.repo.HgRemoteRepository;
 import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
 
 
 /**
@@ -53,12 +57,12 @@
 			return;
 		}
 		Options cmdLineOpts = Options.parse(args);
-		HgRepository hgRepo = cmdLineOpts.findRepository();
+		final HgRepository hgRepo = cmdLineOpts.findRepository();
 		if (hgRepo.isInvalid()) {
 			System.err.printf("Can't find repository in: %s\n", hgRepo.getLocation());
 			return;
 		}
-		HgRemoteRepository hgRemote = new HgLookup().detectRemote("svnkit", hgRepo);
+		HgRemoteRepository hgRemote = new HgLookup().detectRemote(cmdLineOpts.getSingle(""), hgRepo);
 		if (hgRemote.isInvalid()) {
 			System.err.printf("Remote repository %s is not valid", hgRemote.getLocation());
 			return;
@@ -72,11 +76,17 @@
 		RepositoryComparator repoCompare = new RepositoryComparator(pw, hgRemote);
 		repoCompare.compare(null);
 		List<BranchChain> missingBranches0 = repoCompare.calculateMissingBranches();
+		final LinkedHashSet<Nodeid> common = new LinkedHashSet<Nodeid>();
+		// XXX common can be obtained from repoCompare, but at the moment it would almost duplicate work of calculateMissingBranches
+		// once I refactor latter, common shall be taken from repoCompare.
 		for (BranchChain bc : missingBranches0) {
 			bc.dump();
-			
+			common.add(bc.branchRoot); // common known node
 			List<Nodeid> missing = visitBranches(repoCompare, bc);
-			// Collections.reverse(missing); // useful to test output, from newer to older
+			assert bc.branchRoot.equals(missing.get(0)); 
+			missing.remove(0);
+			Collections.reverse(missing); // useful to test output, from newer to older
+			System.out.println("Nodes to fetch in this branch:");
 			for (Nodeid n : missing) {
 				if (pw.knownNode(n)) {
 					System.out.println("Erroneous to fetch:" + n);
@@ -86,10 +96,31 @@
 			}
 			System.out.println("Branch done");
 		}
-		
+		//
+		// Complete
+		HgBundle changegroup = hgRemote.getChanges(new LinkedList<Nodeid>(common));
+		changegroup.changes(hgRepo, new HgChangelog.Inspector() {
+			private int localIndex;
+			
+			public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
+				if (pw.knownNode(nodeid)) {
+					if (!common.contains(nodeid)) {
+						throw new HgBadStateException("Bundle shall not report known nodes other than roots we've supplied");
+					}
+					localIndex = hgRepo.getChangelog().getLocalRevision(nodeid);
+					return;
+				}
+				System.out.printf("changeset:  %d:%s\n", ++localIndex, nodeid.toString());
+				System.out.printf("user:       %s\n", cset.user());
+				System.out.printf("date:       %s\n", cset.dateString());
+				System.out.printf("comment:    %s\n\n", cset.comment());
+				
+			}
+		});
 	}
 	
-	
+	// returns in order from branch root to head
+	// for a non-empty BranchChain, shall return modifiable list
 	private static List<Nodeid> visitBranches(RepositoryComparator repoCompare, BranchChain bc) throws HgException {
 		if (bc == null) {
 			return Collections.emptyList();
--- a/src/org/tmatesoft/hg/internal/RepositoryComparator.java	Wed Apr 13 14:15:13 2011 +0200
+++ b/src/org/tmatesoft/hg/internal/RepositoryComparator.java	Wed Apr 13 19:09:10 2011 +0200
@@ -181,6 +181,8 @@
 					chainElement = new BranchChain(rb.head);
 					// record this unknown branch to download later
 					branches2load.add(chainElement);
+					// the only chance we'll need chainElement in the head2chain is when we know this branch's root 
+					head2chain.put(rb.head, chainElement);
 				}
 				if (localRepo.knownNode(rb.root)) {
 					// we known branch start, common head is somewhere in its descendants line  
@@ -203,8 +205,9 @@
 			Nodeid h = rb.head;
 			Nodeid r = rb.root;
 			int watchdog = 1000;
+			assert head2chain.containsKey(h);
 			BranchChain bc = head2chain.get(h);
-			assert bc != null;
+			assert bc != null : h.toString();
 			// if we know branch root locally, there could be no parent branch chain elements.
 			assert bc.p1 == null;
 			assert bc.p2 == null;
--- a/src/org/tmatesoft/hg/repo/HgRemoteRepository.java	Wed Apr 13 14:15:13 2011 +0200
+++ b/src/org/tmatesoft/hg/repo/HgRemoteRepository.java	Wed Apr 13 19:09:10 2011 +0200
@@ -301,7 +301,8 @@
 		}
 	}
 
-	// WireProtocol wiki: roots = a list of the latest nodes on every service side changeset branch that both the client and server know about. 
+	// WireProtocol wiki: roots = a list of the latest nodes on every service side changeset branch that both the client and server know about.
+	// perhaps, shall be named 'changegroup'
 	public HgBundle getChanges(List<Nodeid> roots) throws HgException {
 		StringBuilder sb = new StringBuilder(20 + roots.size() * 41);
 		sb.append("roots=");
@@ -385,6 +386,7 @@
 			end = to;
 		}
 	}
+
 	public static final class RemoteBranch {
 		public final Nodeid head, root, p1, p2;