Show More
@@ -0,0 +1,57 b'' | |||
|
1 | # dirstatenonnormalcheck.py - extension to check the consistency of the | |
|
2 | # dirstate's non-normal map | |
|
3 | # | |
|
4 | # For most operations on dirstate, this extensions checks that the nonnormalset | |
|
5 | # contains the right entries. | |
|
6 | # It compares the nonnormal file to a nonnormalset built from the map of all | |
|
7 | # the files in the dirstate to check that they contain the same files. | |
|
8 | ||
|
9 | from __future__ import absolute_import | |
|
10 | ||
|
11 | from mercurial import ( | |
|
12 | dirstate, | |
|
13 | extensions, | |
|
14 | ) | |
|
15 | ||
|
16 | def nonnormalentries(dmap): | |
|
17 | """Compute nonnormal entries from dirstate's dmap""" | |
|
18 | res = set() | |
|
19 | for f, e in dmap.iteritems(): | |
|
20 | if e[0] != 'n' or e[3] == -1: | |
|
21 | res.add(f) | |
|
22 | return res | |
|
23 | ||
|
24 | def checkconsistency(ui, orig, dmap, _nonnormalset, label): | |
|
25 | """Compute nonnormalset from dmap, check that it matches _nonnormalset""" | |
|
26 | nonnormalcomputedmap = nonnormalentries(dmap) | |
|
27 | if _nonnormalset != nonnormalcomputedmap: | |
|
28 | ui.develwarn("%s call to %s\n" % (label, orig)) | |
|
29 | ui.develwarn("inconsistency in nonnormalset\n") | |
|
30 | ui.develwarn("[nonnormalset] %s\n" % _nonnormalset) | |
|
31 | ui.develwarn("[map] %s\n" % nonnormalcomputedmap) | |
|
32 | ||
|
33 | def _checkdirstate(orig, self, arg): | |
|
34 | """Check nonnormal set consistency before and after the call to orig""" | |
|
35 | checkconsistency(self._ui, orig, self._map, self._nonnormalset, "before") | |
|
36 | r = orig(self, arg) | |
|
37 | checkconsistency(self._ui, orig, self._map, self._nonnormalset, "after") | |
|
38 | return r | |
|
39 | ||
|
40 | def extsetup(ui): | |
|
41 | """Wrap functions modifying dirstate to check nonnormalset consistency""" | |
|
42 | dirstatecl = dirstate.dirstate | |
|
43 | devel = ui.configbool('devel', 'all-warnings') | |
|
44 | paranoid = ui.configbool('experimental', 'nonnormalparanoidcheck') | |
|
45 | if devel: | |
|
46 | extensions.wrapfunction(dirstatecl, '_writedirstate', _checkdirstate) | |
|
47 | if paranoid: | |
|
48 | # We don't do all these checks when paranoid is disable as it would | |
|
49 | # make the extension run very slowly on large repos | |
|
50 | extensions.wrapfunction(dirstatecl, 'normallookup', _checkdirstate) | |
|
51 | extensions.wrapfunction(dirstatecl, 'otherparent', _checkdirstate) | |
|
52 | extensions.wrapfunction(dirstatecl, 'normal', _checkdirstate) | |
|
53 | extensions.wrapfunction(dirstatecl, 'write', _checkdirstate) | |
|
54 | extensions.wrapfunction(dirstatecl, 'add', _checkdirstate) | |
|
55 | extensions.wrapfunction(dirstatecl, 'remove', _checkdirstate) | |
|
56 | extensions.wrapfunction(dirstatecl, 'merge', _checkdirstate) | |
|
57 | extensions.wrapfunction(dirstatecl, 'drop', _checkdirstate) |
@@ -0,0 +1,22 b'' | |||
|
1 | $ cat >> $HGRCPATH << EOF | |
|
2 | > [ui] | |
|
3 | > logtemplate="{rev}:{node|short} ({phase}) [{tags} {bookmarks}] {desc|firstline}\n" | |
|
4 | > [extensions] | |
|
5 | > dirstateparanoidcheck = $TESTDIR/../contrib/dirstatenonnormalcheck.py | |
|
6 | > [experimental] | |
|
7 | > nonnormalparanoidcheck = True | |
|
8 | > [devel] | |
|
9 | > all-warnings=True | |
|
10 | > EOF | |
|
11 | $ mkcommit() { | |
|
12 | > echo "$1" > "$1" | |
|
13 | > hg add "$1" | |
|
14 | > hg ci -m "add $1" | |
|
15 | > } | |
|
16 | ||
|
17 | $ hg init testrepo | |
|
18 | $ cd testrepo | |
|
19 | $ mkcommit a | |
|
20 | $ mkcommit b | |
|
21 | $ mkcommit c | |
|
22 | $ hg status |
General Comments 0
You need to be logged in to leave comments.
Login now