##// END OF EJS Templates
dirstate-item: use the properties in fakedirstatewritetime...
marmoute -
r48332:20b65f34 default
parent child Browse files
Show More
@@ -1,107 +1,109
1 # extension to emulate invoking 'dirstate.write()' at the time
1 # extension to emulate invoking 'dirstate.write()' at the time
2 # specified by '[fakedirstatewritetime] fakenow', only when
2 # specified by '[fakedirstatewritetime] fakenow', only when
3 # 'dirstate.write()' is invoked via functions below:
3 # 'dirstate.write()' is invoked via functions below:
4 #
4 #
5 # - 'workingctx._poststatusfixup()' (= 'repo.status()')
5 # - 'workingctx._poststatusfixup()' (= 'repo.status()')
6 # - 'committablectx.markcommitted()'
6 # - 'committablectx.markcommitted()'
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from mercurial import (
10 from mercurial import (
11 context,
11 context,
12 dirstate,
12 dirstate,
13 dirstatemap as dirstatemapmod,
13 dirstatemap as dirstatemapmod,
14 extensions,
14 extensions,
15 policy,
15 policy,
16 registrar,
16 registrar,
17 )
17 )
18 from mercurial.utils import dateutil
18 from mercurial.utils import dateutil
19
19
20 try:
20 try:
21 from mercurial import rustext
21 from mercurial import rustext
22
22
23 rustext.__name__ # force actual import (see hgdemandimport)
23 rustext.__name__ # force actual import (see hgdemandimport)
24 except ImportError:
24 except ImportError:
25 rustext = None
25 rustext = None
26
26
27 configtable = {}
27 configtable = {}
28 configitem = registrar.configitem(configtable)
28 configitem = registrar.configitem(configtable)
29
29
30 configitem(
30 configitem(
31 b'fakedirstatewritetime',
31 b'fakedirstatewritetime',
32 b'fakenow',
32 b'fakenow',
33 default=None,
33 default=None,
34 )
34 )
35
35
36 parsers = policy.importmod('parsers')
36 parsers = policy.importmod('parsers')
37 rustmod = policy.importrust('parsers')
37 rustmod = policy.importrust('parsers')
38
38
39
39
40 def pack_dirstate(fakenow, orig, dmap, copymap, pl, now):
40 def pack_dirstate(fakenow, orig, dmap, copymap, pl, now):
41 # execute what original parsers.pack_dirstate should do actually
41 # execute what original parsers.pack_dirstate should do actually
42 # for consistency
42 # for consistency
43 actualnow = int(now)
43 actualnow = int(now)
44 for f, e in dmap.items():
44 for f, e in dmap.items():
45 if e[0] == 'n' and e[3] == actualnow:
45 if e.need_delay(actualnow):
46 e = parsers.DirstateItem(e[0], e[1], e[2], -1)
46 e = parsers.DirstateItem(
47 e.state, e.mode, e.size, dirstatemapmod.AMBIGUOUS_TIME
48 )
47 dmap[f] = e
49 dmap[f] = e
48
50
49 return orig(dmap, copymap, pl, fakenow)
51 return orig(dmap, copymap, pl, fakenow)
50
52
51
53
52 def fakewrite(ui, func):
54 def fakewrite(ui, func):
53 # fake "now" of 'pack_dirstate' only if it is invoked while 'func'
55 # fake "now" of 'pack_dirstate' only if it is invoked while 'func'
54
56
55 fakenow = ui.config(b'fakedirstatewritetime', b'fakenow')
57 fakenow = ui.config(b'fakedirstatewritetime', b'fakenow')
56 if not fakenow:
58 if not fakenow:
57 # Execute original one, if fakenow isn't configured. This is
59 # Execute original one, if fakenow isn't configured. This is
58 # useful to prevent subrepos from executing replaced one,
60 # useful to prevent subrepos from executing replaced one,
59 # because replacing 'parsers.pack_dirstate' is also effective
61 # because replacing 'parsers.pack_dirstate' is also effective
60 # in subrepos.
62 # in subrepos.
61 return func()
63 return func()
62
64
63 # parsing 'fakenow' in YYYYmmddHHMM format makes comparison between
65 # parsing 'fakenow' in YYYYmmddHHMM format makes comparison between
64 # 'fakenow' value and 'touch -t YYYYmmddHHMM' argument easy
66 # 'fakenow' value and 'touch -t YYYYmmddHHMM' argument easy
65 fakenow = dateutil.parsedate(fakenow, [b'%Y%m%d%H%M'])[0]
67 fakenow = dateutil.parsedate(fakenow, [b'%Y%m%d%H%M'])[0]
66
68
67 if rustmod is not None:
69 if rustmod is not None:
68 # The Rust implementation does not use public parse/pack dirstate
70 # The Rust implementation does not use public parse/pack dirstate
69 # to prevent conversion round-trips
71 # to prevent conversion round-trips
70 orig_dirstatemap_write = dirstatemapmod.dirstatemap.write
72 orig_dirstatemap_write = dirstatemapmod.dirstatemap.write
71 wrapper = lambda self, st, now: orig_dirstatemap_write(
73 wrapper = lambda self, st, now: orig_dirstatemap_write(
72 self, st, fakenow
74 self, st, fakenow
73 )
75 )
74 dirstatemapmod.dirstatemap.write = wrapper
76 dirstatemapmod.dirstatemap.write = wrapper
75
77
76 orig_dirstate_getfsnow = dirstate._getfsnow
78 orig_dirstate_getfsnow = dirstate._getfsnow
77 wrapper = lambda *args: pack_dirstate(fakenow, orig_pack_dirstate, *args)
79 wrapper = lambda *args: pack_dirstate(fakenow, orig_pack_dirstate, *args)
78
80
79 orig_module = parsers
81 orig_module = parsers
80 orig_pack_dirstate = parsers.pack_dirstate
82 orig_pack_dirstate = parsers.pack_dirstate
81
83
82 orig_module.pack_dirstate = wrapper
84 orig_module.pack_dirstate = wrapper
83 dirstate._getfsnow = lambda *args: fakenow
85 dirstate._getfsnow = lambda *args: fakenow
84 try:
86 try:
85 return func()
87 return func()
86 finally:
88 finally:
87 orig_module.pack_dirstate = orig_pack_dirstate
89 orig_module.pack_dirstate = orig_pack_dirstate
88 dirstate._getfsnow = orig_dirstate_getfsnow
90 dirstate._getfsnow = orig_dirstate_getfsnow
89 if rustmod is not None:
91 if rustmod is not None:
90 dirstatemapmod.dirstatemap.write = orig_dirstatemap_write
92 dirstatemapmod.dirstatemap.write = orig_dirstatemap_write
91
93
92
94
93 def _poststatusfixup(orig, workingctx, status, fixup):
95 def _poststatusfixup(orig, workingctx, status, fixup):
94 ui = workingctx.repo().ui
96 ui = workingctx.repo().ui
95 return fakewrite(ui, lambda: orig(workingctx, status, fixup))
97 return fakewrite(ui, lambda: orig(workingctx, status, fixup))
96
98
97
99
98 def markcommitted(orig, committablectx, node):
100 def markcommitted(orig, committablectx, node):
99 ui = committablectx.repo().ui
101 ui = committablectx.repo().ui
100 return fakewrite(ui, lambda: orig(committablectx, node))
102 return fakewrite(ui, lambda: orig(committablectx, node))
101
103
102
104
103 def extsetup(ui):
105 def extsetup(ui):
104 extensions.wrapfunction(
106 extensions.wrapfunction(
105 context.workingctx, '_poststatusfixup', _poststatusfixup
107 context.workingctx, '_poststatusfixup', _poststatusfixup
106 )
108 )
107 extensions.wrapfunction(context.workingctx, 'markcommitted', markcommitted)
109 extensions.wrapfunction(context.workingctx, 'markcommitted', markcommitted)
General Comments 0
You need to be logged in to leave comments. Login now