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