Mercurial > hg
changeset 10418:5fc090ba08a6
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.
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Thu, 11 Feb 2010 16:37:43 -0600 |
parents | 4cfd0d56be6d |
children | 992dc3d39357 |
files | mercurial/localrepo.py tests/test-push-validation tests/test-push-validation.out |
diffstat | 3 files changed, 64 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- 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