Mercurial > hg4j
diff src/org/tmatesoft/hg/internal/RepositoryComparator.java @ 202:706bcc7cfee4
Basic test for HgIncomingCommand. Fix RepositoryComparator for cases when whole repository is unknown. Respect freshly initialized (empty) repositories in general.
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 26 Apr 2011 02:50:06 +0200 |
parents | e5407b5a586a |
children | 66fd2c73c56f |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/RepositoryComparator.java Thu Apr 21 19:16:45 2011 +0200 +++ b/src/org/tmatesoft/hg/internal/RepositoryComparator.java Tue Apr 26 02:50:06 2011 +0200 @@ -27,6 +27,7 @@ import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import org.tmatesoft.hg.core.HgBadStateException; import org.tmatesoft.hg.core.HgException; @@ -237,14 +238,23 @@ } else { chainElement.branchRoot = rb.root; // dig deeper in the history, if necessary - if (!NULL.equals(rb.p1) && !localRepo.knownNode(rb.p1)) { + boolean hasP1 = !NULL.equals(rb.p1), hasP2 = !NULL.equals(rb.p2); + if (hasP1 && !localRepo.knownNode(rb.p1)) { toQuery.add(rb.p1); head2chain.put(rb.p1, chainElement.p1 = new BranchChain(rb.p1)); } - if (!NULL.equals(rb.p2) && !localRepo.knownNode(rb.p2)) { + if (hasP2 && !localRepo.knownNode(rb.p2)) { toQuery.add(rb.p2); head2chain.put(rb.p2, chainElement.p2 = new BranchChain(rb.p2)); } + if (!hasP1 && !hasP2) { + // special case, when we do incoming against blank repository, chainElement.branchRoot + // is first unknown element (revision 0). We need to add another fake BranchChain + // to fill the promise that terminal BranchChain has branchRoot that is known both locally and remotely + BranchChain fake = new BranchChain(NULL); + fake.branchRoot = NULL; + chainElement.p1 = chainElement.p2 = fake; + } } } } @@ -291,6 +301,11 @@ return branches2load; } + // root and head (and all between) are unknown for each chain element but last (terminal), which has known root (revision + // known to be locally and at remote server + // alternative would be to keep only unknown elements (so that promise of calculateMissingBranches would be 100% true), but that + // seems to complicate the method, while being useful only for the case when we ask incoming for an empty repository (i.e. + // where branch chain return all nodes, -1..tip. public static final class BranchChain { // when we construct a chain, we know head which is missing locally, hence init it right away. // as for root (branch unknown start), we might happen to have one locally, and need further digging to find out right branch start @@ -307,9 +322,15 @@ branchHead = head; } public boolean isTerminal() { - return p1 == null || p2 == null; + return p1 == null && p2 == null; // either can be null, see comment above. Terminal is only when no way to descent } + // true when this BranchChain is a branch that spans up to very start of the repository + // Thus, the only common revision is NULL, recorded in a fake BranchChain object shared between p1 and p2 + /*package-local*/ boolean isRepoStart() { + return p1 == p2 && p1 != null && p1.branchHead == p1.branchRoot && NULL.equals(p1.branchHead); + } + @Override public String toString() { return String.format("BranchChain [%s, %s]", branchRoot, branchHead); @@ -460,7 +481,7 @@ return Collections.emptyList(); } List<Nodeid> mine = completeBranch(bc.branchRoot, bc.branchHead); - if (bc.isTerminal()) { + if (bc.isTerminal() || bc.isRepoStart()) { return mine; } List<Nodeid> parentBranch1 = visitBranches(bc.p1); @@ -495,4 +516,18 @@ return rv; } + public void collectKnownRoots(BranchChain bc, Set<Nodeid> result) { + if (bc == null) { + return; + } + if (bc.isTerminal()) { + result.add(bc.branchRoot); + return; + } + if (bc.isRepoStart()) { + return; + } + collectKnownRoots(bc.p1, result); + collectKnownRoots(bc.p2, result); + } }