changeset 39:4e9b66b07a28

Check changelog group starts with proper (known) base
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 14 Jan 2011 01:07:05 +0100
parents 50dfc69c108e
children 21e26da142fa
files src/com/tmate/hgkit/ll/HgBundle.java src/com/tmate/hgkit/ll/Revlog.java
diffstat 2 files changed, 23 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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<GroupElement> 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);
--- 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