localrepo: add optional validation (defaults to off) for incoming changes
This verifies that all manifests are present for incoming changes,
and all files for those manifests are also present. This is a simple
first-pass, and could be better, but seems like a valuable thing to
have, as I've seen pushes in the past that propagated revlog corruption.
--- a/mercurial/localrepo.py Thu Feb 11 21:11:59 2010 +0100
+++ b/mercurial/localrepo.py Thu Feb 11 16:37:43 2010 -0600
@@ -2005,6 +2005,16 @@
# be empty during the pull
self.manifest.addgroup(chunkiter, revmap, trp)
+ needfiles = {}
+ if self.ui.configbool('server', 'validate', default=False):
+ # validate incoming csets have their manifests
+ for cset in xrange(clstart, clend):
+ mfest = self.changelog.read(self.changelog.node(cset))[0]
+ mfest = self.manifest.readdelta(mfest)
+ # store file nodes we must see
+ for f, n in mfest.iteritems():
+ needfiles.setdefault(f, set()).add(n)
+
# process the files
self.ui.status(_("adding file changes\n"))
while 1:
@@ -2019,6 +2029,24 @@
raise util.Abort(_("received file revlog group is empty"))
revisions += len(fl) - o
files += 1
+ if f in needfiles:
+ needs = needfiles[f]
+ for new in xrange(o, len(fl)):
+ n = fl.node(new)
+ if n in needs:
+ needs.remove(n)
+ if not needs:
+ del needfiles[f]
+
+ for f, needs in needfiles.iteritems():
+ fl = self.file(f)
+ for n in needs:
+ try:
+ fl.rev(n)
+ except error.LookupError:
+ raise util.Abort(
+ _('missing file data for %s:%s - run hg verify') %
+ (f, hex(n)))
newheads = len(cl.heads())
heads = ""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-push-validation Thu Feb 11 16:37:43 2010 -0600
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+STRIP=`pwd`
+
+hg init test
+cd test
+cat > .hg/hgrc <<EOF
+[server]
+validate=1
+EOF
+echo alpha > alpha
+echo beta > beta
+hg addr
+hg ci -m 1
+
+cd ..
+hg clone test test-clone
+
+cd test-clone
+cp .hg/store/data/beta.i tmp
+echo blah >> beta
+hg ci -m '2 (corrupt)'
+mv tmp .hg/store/data/beta.i
+hg push 2>&1 | sed "s%$STRIP%test-root%"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-push-validation.out Thu Feb 11 16:37:43 2010 -0600
@@ -0,0 +1,12 @@
+adding alpha
+adding beta
+updating to branch default
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+pushing to test-root/test
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+transaction abort!
+rollback completed
+abort: missing file data for beta:dddc47b3ba30e54484720ce0f4f768a0f4b6efb9 - run hg verify