annotate tests/fakedirstatewritetime.py @ 26631:e077ce385609

localrepo: restore dirstate to one before rollbacking if not parent-gone 'localrepository.rollback()' explicilty restores dirstate, only if at least one of current parents of the working directory is removed at rollbacking (a.k.a "parent-gone"). After DirstateTransactionPlan, 'dirstate.write()' will cause marking '.hg/dirstate' as a file to be restored at rollbacking. https://mercurial.selenic.com/wiki/DirstateTransactionPlan Then, 'transaction.rollback()' restores '.hg/dirstate' regardless of parents of the working directory at that time, and this causes unexpected dirstate changes if not "parent-gone" (e.g. "hg update" to another branch after "hg commit" or so, then "hg rollback"). To avoid such situation, this patch restores dirstate to one before rollbacking if not "parent-gone". before: b1. restore dirstate explicitly, if "parent-gone" after: a1. save dirstate before actual rollbacking via dirstateguard a2. restore dirstate via 'transaction.rollback()' a3. if "parent-gone" - discard backup (a1) - restore dirstate from 'undo.dirstate' a4. otherwise, restore dirstate from backup (a1) Even though restoring dirstate at (a3) after (a2) seems redundant, this patch keeps this existing code path, because: - it isn't ensured that 'dirstate.write()' was invoked at least once while transaction running If not, '.hg/dirstate' isn't restored at (a2). In addition to it, rude 3rd party extension invoking 'dirstate.write()' without 'repo' while transaction running (see subsequent patches for detail) may break consistency of a file backup-ed by transaction. - this patch mainly focuses on changes for DirstateTransactionPlan Restoring dirstate at (a3) itself should be cheaper enough than rollbacking itself. Redundancy will be removed in next step. Newly added test is almost meaningless at this point. It will be used to detect regression while implementing delayed dirstate write out.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Tue, 13 Oct 2015 12:25:43 -0700
parents 3111b45a2bbf
children 09bb1ee7e73e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
25752
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
1 # extension to emulate invoking 'dirstate.write()' at the time
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
2 # specified by '[fakedirstatewritetime] fakenow', only when
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
3 # 'dirstate.write()' is invoked via functions below:
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
4 #
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
5 # - 'workingctx._checklookup()' (= 'repo.status()')
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
6 # - 'committablectx.markcommitted()'
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
7
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
8 from mercurial import context, extensions, parsers, util
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
9
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
10 def pack_dirstate(fakenow, orig, dmap, copymap, pl, now):
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
11 # execute what original parsers.pack_dirstate should do actually
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
12 # for consistency
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
13 actualnow = int(now)
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
14 for f, e in dmap.iteritems():
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
15 if e[0] == 'n' and e[3] == actualnow:
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
16 e = parsers.dirstatetuple(e[0], e[1], e[2], -1)
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
17 dmap[f] = e
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
18
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
19 return orig(dmap, copymap, pl, fakenow)
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
20
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
21 def fakewrite(ui, func):
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
22 # fake "now" of 'pack_dirstate' only if it is invoked while 'func'
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
23
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
24 fakenow = ui.config('fakedirstatewritetime', 'fakenow')
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
25 if not fakenow:
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
26 # Execute original one, if fakenow isn't configured. This is
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
27 # useful to prevent subrepos from executing replaced one,
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
28 # because replacing 'parsers.pack_dirstate' is also effective
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
29 # in subrepos.
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
30 return func()
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
31
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
32 # parsing 'fakenow' in YYYYmmddHHMM format makes comparison between
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
33 # 'fakenow' value and 'touch -t YYYYmmddHHMM' argument easy
26630
3111b45a2bbf parsers: make pack_dirstate take now in integer for consistency
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25752
diff changeset
34 fakenow = util.parsedate(fakenow, ['%Y%m%d%H%M'])[0]
25752
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
35
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
36 orig_pack_dirstate = parsers.pack_dirstate
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
37 wrapper = lambda *args: pack_dirstate(fakenow, orig_pack_dirstate, *args)
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
38
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
39 parsers.pack_dirstate = wrapper
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
40 try:
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
41 return func()
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
42 finally:
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
43 parsers.pack_dirstate = orig_pack_dirstate
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
44
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
45 def _checklookup(orig, workingctx, files):
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
46 ui = workingctx.repo().ui
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
47 return fakewrite(ui, lambda : orig(workingctx, files))
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
48
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
49 def markcommitted(orig, committablectx, node):
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
50 ui = committablectx.repo().ui
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
51 return fakewrite(ui, lambda : orig(committablectx, node))
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
52
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
53 def extsetup(ui):
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
54 extensions.wrapfunction(context.workingctx, '_checklookup',
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
55 _checklookup)
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
56 extensions.wrapfunction(context.committablectx, 'markcommitted',
815df73abf12 tests: add extension to emulate invoking dirstate.write at the specific time
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
diff changeset
57 markcommitted)