Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 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 | 2d30d66a89ad |
children | 1c50a954a524 |
comparison
equal
deleted
inserted
replaced
10416:4cfd0d56be6d | 10418:5fc090ba08a6 |
---|---|
2003 # if the result of the merge of 1 and 2 is the same in 3 and 4, | 2003 # if the result of the merge of 1 and 2 is the same in 3 and 4, |
2004 # no new manifest will be created and the manifest group will | 2004 # no new manifest will be created and the manifest group will |
2005 # be empty during the pull | 2005 # be empty during the pull |
2006 self.manifest.addgroup(chunkiter, revmap, trp) | 2006 self.manifest.addgroup(chunkiter, revmap, trp) |
2007 | 2007 |
2008 needfiles = {} | |
2009 if self.ui.configbool('server', 'validate', default=False): | |
2010 # validate incoming csets have their manifests | |
2011 for cset in xrange(clstart, clend): | |
2012 mfest = self.changelog.read(self.changelog.node(cset))[0] | |
2013 mfest = self.manifest.readdelta(mfest) | |
2014 # store file nodes we must see | |
2015 for f, n in mfest.iteritems(): | |
2016 needfiles.setdefault(f, set()).add(n) | |
2017 | |
2008 # process the files | 2018 # process the files |
2009 self.ui.status(_("adding file changes\n")) | 2019 self.ui.status(_("adding file changes\n")) |
2010 while 1: | 2020 while 1: |
2011 f = changegroup.getchunk(source) | 2021 f = changegroup.getchunk(source) |
2012 if not f: | 2022 if not f: |
2017 chunkiter = changegroup.chunkiter(source) | 2027 chunkiter = changegroup.chunkiter(source) |
2018 if fl.addgroup(chunkiter, revmap, trp) is None: | 2028 if fl.addgroup(chunkiter, revmap, trp) is None: |
2019 raise util.Abort(_("received file revlog group is empty")) | 2029 raise util.Abort(_("received file revlog group is empty")) |
2020 revisions += len(fl) - o | 2030 revisions += len(fl) - o |
2021 files += 1 | 2031 files += 1 |
2032 if f in needfiles: | |
2033 needs = needfiles[f] | |
2034 for new in xrange(o, len(fl)): | |
2035 n = fl.node(new) | |
2036 if n in needs: | |
2037 needs.remove(n) | |
2038 if not needs: | |
2039 del needfiles[f] | |
2040 | |
2041 for f, needs in needfiles.iteritems(): | |
2042 fl = self.file(f) | |
2043 for n in needs: | |
2044 try: | |
2045 fl.rev(n) | |
2046 except error.LookupError: | |
2047 raise util.Abort( | |
2048 _('missing file data for %s:%s - run hg verify') % | |
2049 (f, hex(n))) | |
2022 | 2050 |
2023 newheads = len(cl.heads()) | 2051 newheads = len(cl.heads()) |
2024 heads = "" | 2052 heads = "" |
2025 if oldheads and newheads != oldheads: | 2053 if oldheads and newheads != oldheads: |
2026 heads = _(" (%+d heads)") % (newheads - oldheads) | 2054 heads = _(" (%+d heads)") % (newheads - oldheads) |