# HG changeset patch # User Artem Tikhomirov # Date 1294963625 -3600 # Node ID 4e9b66b07a2831722cd5aabe99a9460f9b3cfcbf # Parent 50dfc69c108e5139bc22fb2034c1eca4313fea55 Check changelog group starts with proper (known) base diff -r 50dfc69c108e -r 4e9b66b07a28 src/com/tmate/hgkit/ll/HgBundle.java --- a/src/com/tmate/hgkit/ll/HgBundle.java Fri Jan 14 00:52:19 2011 +0100 +++ b/src/com/tmate/hgkit/ll/HgBundle.java Fri Jan 14 01:07:05 2011 +0100 @@ -30,13 +30,20 @@ DataAccess da = accessProvider.create(bundleFile); try { List changelogGroup = readGroup(da); - byte[] baseRevContent = null; + if (changelogGroup.isEmpty()) { + throw new IllegalStateException("No changelog group in the bundle"); // XXX perhaps, just be silent and/or log? + } + // XXX in fact, bundle not necessarily starts with the first revision missing in hgRepo + // need to 'scroll' till the last one common. + final Nodeid base = changelogGroup.get(0).firstParent(); + if (!hgRepo.getChangelog().isKnown(base)) { + throw new IllegalArgumentException("unknown parent"); + } + // BundleFormat wiki says: + // Each Changelog entry patches the result of all previous patches + // (the previous, or parent patch of a given patch p is the patch that has a node equal to p's p1 field) + byte[] baseRevContent = hgRepo.getChangelog().content(base); for (GroupElement ge : changelogGroup) { - if (baseRevContent == null) { - // first parent is base revision, see bundlerepo.py - // if not prev: prev = p1 in bundlerevlog cons - baseRevContent = hgRepo.getChangelog().content(ge.firstParent()); - } int resultLen = 10000; // XXX calculate based on baseRevContent.length and ge.patches byte[] csetContent = RevlogStream.apply(baseRevContent, resultLen, ge.patches); Changeset cs = Changeset.parse(csetContent, 0, csetContent.length); diff -r 50dfc69c108e -r 4e9b66b07a28 src/com/tmate/hgkit/ll/Revlog.java --- a/src/com/tmate/hgkit/ll/Revlog.java Fri Jan 14 00:52:19 2011 +0100 +++ b/src/com/tmate/hgkit/ll/Revlog.java Fri Jan 14 01:07:05 2011 +0100 @@ -35,6 +35,16 @@ return content.revisionCount(); } + // Till now, i follow approach that NULL nodeid is never part of revlog + public boolean isKnown(Nodeid nodeid) { + try { + int revision = content.findLocalRevisionNumber(nodeid); + return revision >= 0 && revision < getRevisionCount(); + } catch (IllegalArgumentException ex) { + // FIXME bad way to figure out if nodeid is from this revlog + return false; + } + } /** * Access to revision data as is (decompressed, but otherwise unprocessed, i.e. not parsed for e.g. changeset or manifest entries) * @param nodeid