[PATCH] localrepo: add optional validation (defaults to off) for incoming changes
Augie Fackler
durin42 at gmail.com
Tue Feb 9 23:58:08 UTC 2010
# HG changeset patch
# User Augie Fackler <durin42 at gmail.com>
# Date 1265758800 21600
# Node ID e24ff7e571d125a5c2517959b8e30321b32c587f
# Parent 2d30d66a89ad29f471aa6918fc46121a4bc3fbe8
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.
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -2005,6 +2005,16 @@
# be empty during the pull
self.manifest.addgroup(chunkiter, revmap, trp)
+ needfiles = {}
+ if self.ui.configbool('repo', '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.read(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 = ""
diff --git a/tests/test-push-validation b/tests/test-push-validation
new file mode 100755
--- /dev/null
+++ b/tests/test-push-validation
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+hg init test
+cd test
+cat > .hg/hgrc <<EOF
+[repo]
+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
diff --git a/tests/test-push-validation.out b/tests/test-push-validation.out
new file mode 100644
--- /dev/null
+++ b/tests/test-push-validation.out
@@ -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 /Volumes/RAMDisk/hgtests.CsBogz/test-push-validation/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
More information about the Mercurial-devel
mailing list