Mercurial > hg4j
diff cmdline/org/tmatesoft/hg/console/Outgoing.java @ 181:cd3371670f0b
Refactor incoming and outgoing code to be shared with RepositoryComparator. Placeholders for in/out commands. Refactor common remote lookup code
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 12 Apr 2011 19:10:38 +0200 |
parents | 62665d8f0686 |
children | c6fa4dbfc458 |
line wrap: on
line diff
--- a/cmdline/org/tmatesoft/hg/console/Outgoing.java Wed Apr 06 03:08:05 2011 +0200 +++ b/cmdline/org/tmatesoft/hg/console/Outgoing.java Tue Apr 12 19:10:38 2011 +0200 @@ -16,23 +16,15 @@ */ package org.tmatesoft.hg.console; -import static org.tmatesoft.hg.core.Nodeid.NULL; - -import java.io.File; -import java.net.URL; import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; import java.util.List; import org.tmatesoft.hg.core.HgException; import org.tmatesoft.hg.core.Nodeid; -import org.tmatesoft.hg.internal.ConfigFile; -import org.tmatesoft.hg.internal.Internals; +import org.tmatesoft.hg.internal.RepositoryComparator; import org.tmatesoft.hg.repo.HgChangelog; import org.tmatesoft.hg.repo.HgLookup; import org.tmatesoft.hg.repo.HgRemoteRepository; -import org.tmatesoft.hg.repo.HgRemoteRepository.RemoteBranch; import org.tmatesoft.hg.repo.HgRepository; @@ -52,19 +44,18 @@ System.err.printf("Can't find repository in: %s\n", hgRepo.getLocation()); return; } - String key = "hg4j-gc"; - ConfigFile cfg = new Internals().newConfigFile(); - cfg.addLocation(new File(System.getProperty("user.home"), ".hgrc")); - String server = cfg.getSection("paths").get(key); - if (server == null) { - throw new HgException(String.format("Can't find server %s specification in the config", key)); + HgRemoteRepository hgRemote = new HgLookup().detectRemote("hg4j-gc", hgRepo); + if (hgRemote.isInvalid()) { + System.err.printf("Remote repository %s is not valid", hgRemote.getLocation()); + return; } - HgRemoteRepository hgRemote = new HgLookup().detect(new URL(server)); HgChangelog.ParentWalker pw = hgRepo.getChangelog().new ParentWalker(); pw.init(); - List<Nodeid> commonKnown = findCommonWithRemote(pw, hgRemote); + RepositoryComparator repoCompare = new RepositoryComparator(pw, hgRemote); + repoCompare.compare(null); + List<Nodeid> commonKnown = repoCompare.getCommon(); dump("Nodes known to be both locally and at remote server", commonKnown); // sanity check for (Nodeid n : commonKnown) { @@ -77,86 +68,6 @@ dump("Result", result); } - private static List<Nodeid> findCommonWithRemote(HgChangelog.ParentWalker pwLocal, HgRemoteRepository hgRemote) throws HgException { - List<Nodeid> remoteHeads = hgRemote.heads(); - LinkedList<Nodeid> common = new LinkedList<Nodeid>(); // these remotes are known in local - LinkedList<Nodeid> toQuery = new LinkedList<Nodeid>(); // these need further queries to find common - for (Nodeid rh : remoteHeads) { - if (pwLocal.knownNode(rh)) { - common.add(rh); - } else { - toQuery.add(rh); - } - } - if (toQuery.isEmpty()) { - return common; - } - LinkedList<RemoteBranch> checkUp2Head = new LinkedList<RemoteBranch>(); // branch.root and branch.head are of interest only. - // these are branches with unknown head but known root, which might not be the last common known, - // i.e. there might be children changeset that are also available at remote, [..?..common-head..remote-head] - need to - // scroll up to common head. - while (!toQuery.isEmpty()) { - List<RemoteBranch> remoteBranches = hgRemote.branches(toQuery); //head, root, first parent, second parent - toQuery.clear(); - while(!remoteBranches.isEmpty()) { - RemoteBranch rb = remoteBranches.remove(0); - // I assume branches remote call gives branches with head equal to what I pass there, i.e. - // that I don't need to check whether rb.head is unknown. - if (pwLocal.knownNode(rb.root)) { - // we known branch start, common head is somewhere in its descendants line - checkUp2Head.add(rb); - } else { - // dig deeper in the history, if necessary - if (!NULL.equals(rb.p1) && !pwLocal.knownNode(rb.p1)) { - toQuery.add(rb.p1); - } - if (!NULL.equals(rb.p2) && !pwLocal.knownNode(rb.p2)) { - toQuery.add(rb.p2); - } - } - } - } - // can't check nodes between checkUp2Head element and local heads, remote might have distinct descendants sequence - for (RemoteBranch rb : checkUp2Head) { - // rb.root is known locally - List<Nodeid> remoteRevisions = hgRemote.between(rb.head, rb.root); - if (remoteRevisions.isEmpty()) { - // head is immediate child - common.add(rb.root); - } else { - // between gives result from head to root, I'd like to go in reverse direction - Collections.reverse(remoteRevisions); - Nodeid root = rb.root; - while(!remoteRevisions.isEmpty()) { - Nodeid n = remoteRevisions.remove(0); - if (pwLocal.knownNode(n)) { - if (remoteRevisions.isEmpty()) { - // this is the last known node before an unknown - common.add(n); - break; - } - if (remoteRevisions.size() == 1) { - // there's only one left between known n and unknown head - // this check is to save extra between query, not really essential - Nodeid last = remoteRevisions.remove(0); - common.add(pwLocal.knownNode(last) ? last : n); - break; - } - // might get handy for next between query, to narrow search down - root = n; - } else { - remoteRevisions = hgRemote.between(n, root); - Collections.reverse(remoteRevisions); - if (remoteRevisions.isEmpty()) { - common.add(root); - } - } - } - } - } - // TODO ensure unique elements in the list - return common; - } private static void dump(String s, Collection<Nodeid> c) { System.out.println(s);