annotate contrib/dirstatenonnormalcheck.py @ 43913:4b7d5d10c45d

exchange: ensure all outgoing subrepo references are present before pushing We've run into occasional problems with people committing a repo, and then amending or rebasing in the subrepo. That makes it so that the revision in the parent can't be checked out, and the problem gets propagated on push. Mercurial already tries to defend against this sort of dangling reference by pushing *all* subrepo revisions first. This reuses the checks that trigger warnings in `hg verify` to bail on the push unless using `--force`. I thought about putting this on the server side, but at that point, all of the data has been transferred, only to bail out. Additionally, SCM Manager hosts subrepos in a location that isn't nested in the parent, so normal subrepo code would complain that the subrepo is missing when run on the server. Because the push command pushes subrepos before calling this exchange code, a subrepo will be pushed before the parent is verified. Not great, but no dangling references are exchanged, so it solves the problem. This code isn't in the loop that pushes the subrepos because: 1) the list of outgoing revisions is needed to limit the scope of the check 2) the loop only accesses the current revision, and therefore can miss subrepos that were dropped in previous commits 3) this code is called when pushing a subrepo, so the protection is recursive I'm not sure if there's a cheap check for the list of files in the outgoing bundle. If there is, that would provide a fast path to bypass this check for people not using subrepos (or if no subrepo changes were made). There's probably also room for verifying other references like tags. But since that doesn't break checkouts, it's much less of a problem. Differential Revision: https://phab.mercurial-scm.org/D7616
author Matt Harbison <matt_harbison@yahoo.com>
date Thu, 12 Dec 2019 12:30:15 -0500
parents 2372284d9457
children 35295f5a5b9f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
27591
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
1 # dirstatenonnormalcheck.py - extension to check the consistency of the
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
2 # dirstate's non-normal map
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
3 #
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
4 # For most operations on dirstate, this extensions checks that the nonnormalset
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
5 # contains the right entries.
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
6 # It compares the nonnormal file to a nonnormalset built from the map of all
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
7 # the files in the dirstate to check that they contain the same files.
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
8
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
9 from __future__ import absolute_import
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
10
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
11 from mercurial import (
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
12 dirstate,
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
13 extensions,
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
14 )
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
15
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
16
27591
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
17 def nonnormalentries(dmap):
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
18 """Compute nonnormal entries from dirstate's dmap"""
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
19 res = set()
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
20 for f, e in dmap.iteritems():
35878
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 34674
diff changeset
21 if e[0] != b'n' or e[3] == -1:
27591
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
22 res.add(f)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
23 return res
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
24
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
25
27591
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
26 def checkconsistency(ui, orig, dmap, _nonnormalset, label):
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
27 """Compute nonnormalset from dmap, check that it matches _nonnormalset"""
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
28 nonnormalcomputedmap = nonnormalentries(dmap)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
29 if _nonnormalset != nonnormalcomputedmap:
35878
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 34674
diff changeset
30 ui.develwarn(b"%s call to %s\n" % (label, orig), config=b'dirstate')
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 34674
diff changeset
31 ui.develwarn(b"inconsistency in nonnormalset\n", config=b'dirstate')
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 34674
diff changeset
32 ui.develwarn(b"[nonnormalset] %s\n" % _nonnormalset, config=b'dirstate')
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 34674
diff changeset
33 ui.develwarn(b"[map] %s\n" % nonnormalcomputedmap, config=b'dirstate')
27591
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
34
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
35
27591
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
36 def _checkdirstate(orig, self, arg):
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
37 """Check nonnormal set consistency before and after the call to orig"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
38 checkconsistency(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
39 self._ui, orig, self._map, self._map.nonnormalset, b"before"
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
40 )
27637
b502138f5faa cleanup: remove superfluous space after space after equals (python)
timeless <timeless@mozdev.org>
parents: 27591
diff changeset
41 r = orig(self, arg)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
42 checkconsistency(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
43 self._ui, orig, self._map, self._map.nonnormalset, b"after"
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
44 )
27591
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
45 return r
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
46
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 35878
diff changeset
47
27591
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
48 def extsetup(ui):
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
49 """Wrap functions modifying dirstate to check nonnormalset consistency"""
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
50 dirstatecl = dirstate.dirstate
35878
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 34674
diff changeset
51 devel = ui.configbool(b'devel', b'all-warnings')
6e7fae8f1c6c contrib: fix dirstatenonnormalcheck to work in Python 3
Augie Fackler <augie@google.com>
parents: 34674
diff changeset
52 paranoid = ui.configbool(b'experimental', b'nonnormalparanoidcheck')
27591
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
53 if devel:
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
54 extensions.wrapfunction(dirstatecl, '_writedirstate', _checkdirstate)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
55 if paranoid:
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
56 # We don't do all these checks when paranoid is disable as it would
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
57 # make the extension run very slowly on large repos
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
58 extensions.wrapfunction(dirstatecl, 'normallookup', _checkdirstate)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
59 extensions.wrapfunction(dirstatecl, 'otherparent', _checkdirstate)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
60 extensions.wrapfunction(dirstatecl, 'normal', _checkdirstate)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
61 extensions.wrapfunction(dirstatecl, 'write', _checkdirstate)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
62 extensions.wrapfunction(dirstatecl, 'add', _checkdirstate)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
63 extensions.wrapfunction(dirstatecl, 'remove', _checkdirstate)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
64 extensions.wrapfunction(dirstatecl, 'merge', _checkdirstate)
127cc7f78475 dirstate: add test for non-normal set consistency
Laurent Charignon <lcharignon@fb.com>
parents:
diff changeset
65 extensions.wrapfunction(dirstatecl, 'drop', _checkdirstate)