Mercurial > hg
annotate mercurial/transaction.py @ 28238:b57d45ec33b2
test: update test-bundle2-format.t comment
Now that bundle2 is used by default for all exchanges, this comment is obviously
out of date. Having deep testing of the API and expected behavior of the format
and its processing is still valuable, so the comment is updated.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Thu, 25 Feb 2016 10:34:31 +0100 |
parents | 24361fb68cba |
children | a5009789960c |
rev | line source |
---|---|
17424
e7cfe3587ea4
fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents:
16689
diff
changeset
|
1 # transaction.py - simple journaling scheme for mercurial |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
2 # |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
3 # This transaction scheme is intended to gracefully handle program |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
4 # errors and interruptions. More serious failures like system crashes |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
5 # can be recovered with an fsck-like tool. As the whole repository is |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
6 # effectively log-structured, this should amount to simply truncating |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
7 # anything that isn't referenced in the changelog. |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
8 # |
2859 | 9 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com> |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
10 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8071
diff
changeset
|
11 # This software may be used and distributed according to the terms of the |
10263 | 12 # GNU General Public License version 2 or any later version. |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
13 |
25986
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
14 from __future__ import absolute_import |
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
15 |
20886
203908968644
transaction: drop extra import caught by pyflakes
Matt Mackall <mpm@selenic.com>
parents:
20882
diff
changeset
|
16 import errno |
25986
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
17 |
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
18 from .i18n import _ |
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
19 from . import ( |
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
20 error, |
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
21 util, |
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
22 ) |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
23 |
23313
991098579940
transaction: set backupentries version to proper value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23312
diff
changeset
|
24 version = 2 |
23064
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
25 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
26 def active(func): |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
27 def _active(self, *args, **kwds): |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
28 if self.count == 0: |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
29 raise error.Abort(_( |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
30 'cannot use transaction when it is already committed/aborted')) |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
31 return func(self, *args, **kwds) |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
32 return _active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
33 |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
34 def _playback(journal, report, opener, vfsmap, entries, backupentries, |
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
35 unlink=True): |
22204
f8dc6599da5d
cleanup: name unused variables using convention of leading _
Mads Kiilerich <madski@unity3d.com>
parents:
22199
diff
changeset
|
36 for f, o, _ignore in entries: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
37 if o or not unlink: |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
38 try: |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
39 fp = opener(f, 'a') |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
40 fp.truncate(o) |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
41 fp.close() |
9686
ddf2adf88b89
transaction: more specific exceptions, os.unlink can raise OSError
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9220
diff
changeset
|
42 except IOError: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
43 report(_("failed to truncate %s\n") % f) |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
44 raise |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
45 else: |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
46 try: |
20084
a3378a1b0a05
transaction: unlink target file via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17424
diff
changeset
|
47 opener.unlink(f) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25658
diff
changeset
|
48 except (IOError, OSError) as inst: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
49 if inst.errno != errno.ENOENT: |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
50 raise |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
51 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
52 backupfiles = [] |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
53 for l, f, b, c in backupentries: |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
54 if l not in vfsmap and c: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
55 report("couldn't handle %s: unknown cache location %s\n" |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
56 % (b, l)) |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
57 vfs = vfsmap[l] |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
58 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
59 if f and b: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
60 filepath = vfs.join(f) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
61 backuppath = vfs.join(b) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
62 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
63 util.copyfile(backuppath, filepath) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
64 backupfiles.append(b) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
65 except IOError: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
66 report(_("failed to recover %s\n") % f) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
67 else: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
68 target = f or b |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
69 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
70 vfs.unlink(target) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25658
diff
changeset
|
71 except (IOError, OSError) as inst: |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
72 if inst.errno != errno.ENOENT: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
73 raise |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26576
diff
changeset
|
74 except (IOError, OSError, error.Abort) as inst: |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
75 if not c: |
23278
aa19432764d6
transaction: handle missing file in backupentries (instead of using entries)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23253
diff
changeset
|
76 raise |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
77 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
78 backuppath = "%s.backupfiles" % journal |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
79 if opener.exists(backuppath): |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
80 opener.unlink(backuppath) |
26753
96dd93de548c
transaction: reorder unlinking .hg/journal and .hg/journal.backupfiles
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
26587
diff
changeset
|
81 opener.unlink(journal) |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
82 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
83 for f in backupfiles: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
84 if opener.exists(f): |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
85 opener.unlink(f) |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26576
diff
changeset
|
86 except (IOError, OSError, error.Abort) as inst: |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
87 # only pure backup file remains, it is sage to ignore any error |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
88 pass |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
89 |
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1541
diff
changeset
|
90 class transaction(object): |
23903
426607be9c69
transaction: pass the name of the "undo" journal to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23901
diff
changeset
|
91 def __init__(self, report, opener, vfsmap, journalname, undoname=None, |
26576
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
92 after=None, createmode=None, validator=None, releasefn=None): |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
93 """Begin a new transaction |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
94 |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
95 Begins a new transaction that allows rolling back writes in the event of |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
96 an exception. |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
97 |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
98 * `after`: called after the transaction has been committed |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
99 * `createmode`: the mode of the journal file that will be created |
26576
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
100 * `releasefn`: called after releasing (with transaction and result) |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
101 """ |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
102 self.count = 1 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
103 self.usages = 1 |
582 | 104 self.report = report |
23310
5bd1f6572db0
transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23309
diff
changeset
|
105 # a vfs to the store content |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
106 self.opener = opener |
23310
5bd1f6572db0
transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23309
diff
changeset
|
107 # a map to access file in various {location -> vfs} |
5bd1f6572db0
transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23309
diff
changeset
|
108 vfsmap = vfsmap.copy() |
5bd1f6572db0
transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23309
diff
changeset
|
109 vfsmap[''] = opener # set default value |
5bd1f6572db0
transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23309
diff
changeset
|
110 self._vfsmap = vfsmap |
95 | 111 self.after = after |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
112 self.entries = [] |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
113 self.map = {} |
23901
13268fde4c4d
transaction: clarify the name of 'journal' argument for transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23900
diff
changeset
|
114 self.journal = journalname |
23903
426607be9c69
transaction: pass the name of the "undo" journal to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23901
diff
changeset
|
115 self.undoname = undoname |
23279
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
116 self._queue = [] |
24283
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
117 # A callback to validate transaction content before closing it. |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
118 # should raise exception is anything is wrong. |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
119 # target user is repository hooks. |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
120 if validator is None: |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
121 validator = lambda tr: None |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
122 self.validator = validator |
26576
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
123 # A callback to do something just after releasing transaction. |
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
124 if releasefn is None: |
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
125 releasefn = lambda tr, success: None |
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
126 self.releasefn = releasefn |
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
127 |
23279
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
128 # a dict of arguments to be passed to hooks |
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
129 self.hookargs = {} |
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
130 self.file = opener.open(self.journal, "w") |
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
131 |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
132 # a list of ('location', 'path', 'backuppath', cache) entries. |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
133 # - if 'backuppath' is empty, no file existed at backup time |
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
134 # - if 'path' is empty, this is a temporary transaction file |
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
135 # - if 'location' is not empty, the path is outside main opener reach. |
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
136 # use 'location' value as a key in a vfsmap to find the right 'vfs' |
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
137 # (cache is currently unused) |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
138 self._backupentries = [] |
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
139 self._backupmap = {} |
23901
13268fde4c4d
transaction: clarify the name of 'journal' argument for transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23900
diff
changeset
|
140 self._backupjournal = "%s.backupfiles" % self.journal |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
141 self._backupsfile = opener.open(self._backupjournal, 'w') |
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
142 self._backupsfile.write('%d\n' % version) |
23279
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
143 |
6065
53ed9b40cfc4
make the journal/undo files from transactions inherit the mode from .hg/store
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents:
5865
diff
changeset
|
144 if createmode is not None: |
25658
e93036747902
global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25302
diff
changeset
|
145 opener.chmod(self.journal, createmode & 0o666) |
e93036747902
global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25302
diff
changeset
|
146 opener.chmod(self._backupjournal, createmode & 0o666) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
147 |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
148 # hold file generations to be performed on commit |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
149 self._filegenerators = {} |
23543
4dd8a6a1240d
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
23513
diff
changeset
|
150 # hold callback to write pending data for hooks |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
151 self._pendingcallback = {} |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
152 # True is any pending data have been written ever |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
153 self._anypending = False |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
154 # holds callback to call when writing the transaction |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
155 self._finalizecallback = {} |
23543
4dd8a6a1240d
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
23513
diff
changeset
|
156 # hold callback for post transaction close |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
157 self._postclosecallback = {} |
23764
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
158 # holds callbacks to call during abort |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
159 self._abortcallback = {} |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
160 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
161 def __del__(self): |
558
0ceea19182a9
transaction: __del__ should do nothing if the journal already exists
mpm@selenic.com
parents:
515
diff
changeset
|
162 if self.journal: |
9693
c40a1ee20aa5
transaction: always remove empty journal on abort
Sune Foldager <cryo@cyanite.org>
parents:
9686
diff
changeset
|
163 self._abort() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
164 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
165 @active |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
166 def startgroup(self): |
23250
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
167 """delay registration of file entry |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
168 |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
169 This is used by strip to delay vision of strip offset. The transaction |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
170 sees either none or all of the strip actions to be done.""" |
23251
85c634ff395a
transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23250
diff
changeset
|
171 self._queue.append([]) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
172 |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
173 @active |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
174 def endgroup(self): |
23250
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
175 """apply delayed registration of file entry. |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
176 |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
177 This is used by strip to delay vision of strip offset. The transaction |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
178 sees either none or all of the strip actions to be done.""" |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
179 q = self._queue.pop() |
23253
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
180 for f, o, data in q: |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
181 self._addentry(f, o, data) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
182 |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
183 @active |
2084 | 184 def add(self, file, offset, data=None): |
23252
70809438c644
transaction: document `tr.add`
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23251
diff
changeset
|
185 """record the state of an append-only file before update""" |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
186 if file in self.map or file in self._backupmap: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10263
diff
changeset
|
187 return |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
188 if self._queue: |
23251
85c634ff395a
transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23250
diff
changeset
|
189 self._queue[-1].append((file, offset, data)) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
190 return |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
191 |
23253
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
192 self._addentry(file, offset, data) |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
193 |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
194 def _addentry(self, file, offset, data): |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
195 """add a append-only entry to memory and on-disk state""" |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
196 if file in self.map or file in self._backupmap: |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
197 return |
2084 | 198 self.entries.append((file, offset, data)) |
199 self.map[file] = len(self.entries) - 1 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
200 # add enough data to the journal to do the truncate |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
201 self.file.write("%s\0%d\n" % (file, offset)) |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
202 self.file.flush() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
203 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
204 @active |
23316
fc3670f41d3e
transaction: use 'location' instead of 'vfs' in the addbackup method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23315
diff
changeset
|
205 def addbackup(self, file, hardlink=True, location=''): |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
206 """Adds a backup of the file to the transaction |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
207 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
208 Calling addbackup() creates a hardlink backup of the specified file |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
209 that is used to recover the file in the event of the transaction |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
210 aborting. |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
211 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
212 * `file`: the file path, relative to .hg/store |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
213 * `hardlink`: use a hardlink to quickly create the backup |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
214 """ |
23251
85c634ff395a
transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23250
diff
changeset
|
215 if self._queue: |
85c634ff395a
transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23250
diff
changeset
|
216 msg = 'cannot use transaction.addbackup inside "group"' |
85c634ff395a
transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23250
diff
changeset
|
217 raise RuntimeError(msg) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
218 |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
219 if file in self.map or file in self._backupmap: |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
220 return |
23582
7559dc8c4238
vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23581
diff
changeset
|
221 vfs = self._vfsmap[location] |
7559dc8c4238
vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23581
diff
changeset
|
222 dirname, filename = vfs.split(file) |
23315
66275ecc73c1
addbackup: handle file in subdirectory
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23314
diff
changeset
|
223 backupfilename = "%s.backup.%s" % (self.journal, filename) |
23581
aed981c7bebf
vfs: add a 'reljoin' function for joining relative paths
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23543
diff
changeset
|
224 backupfile = vfs.reljoin(dirname, backupfilename) |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
225 if vfs.exists(file): |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
226 filepath = vfs.join(file) |
23314
43f66ae57a66
addbackup: use the vfs for the backup destination too
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23313
diff
changeset
|
227 backuppath = vfs.join(backupfile) |
23900
5eb3541f907e
transaction: use 'util.copyfile' for creating backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23764
diff
changeset
|
228 util.copyfile(filepath, backuppath, hardlink=hardlink) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
229 else: |
23278
aa19432764d6
transaction: handle missing file in backupentries (instead of using entries)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23253
diff
changeset
|
230 backupfile = '' |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
231 |
23316
fc3670f41d3e
transaction: use 'location' instead of 'vfs' in the addbackup method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23315
diff
changeset
|
232 self._addbackupentry((location, file, backupfile, False)) |
23283
b04263c38a92
transaction: extract backupentry registration in a dedicated function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23282
diff
changeset
|
233 |
b04263c38a92
transaction: extract backupentry registration in a dedicated function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23282
diff
changeset
|
234 def _addbackupentry(self, entry): |
b04263c38a92
transaction: extract backupentry registration in a dedicated function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23282
diff
changeset
|
235 """register a new backup entry and write it to disk""" |
b04263c38a92
transaction: extract backupentry registration in a dedicated function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23282
diff
changeset
|
236 self._backupentries.append(entry) |
25294
b1b89a0a606d
transaction: really fix _addbackupentry key usage (issue4684)
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
25263
diff
changeset
|
237 self._backupmap[entry[1]] = len(self._backupentries) - 1 |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
238 self._backupsfile.write("%s\0%s\0%s\0%d\n" % entry) |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
239 self._backupsfile.flush() |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
240 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
241 @active |
23354
918c77775df6
transaction: accept a 'location' argument for registertmp
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23318
diff
changeset
|
242 def registertmp(self, tmpfile, location=''): |
23291
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
243 """register a temporary transaction file |
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
244 |
23355
7faa55c20b0e
transaction: fix some docstring grammar
Matt Mackall <mpm@selenic.com>
parents:
23354
diff
changeset
|
245 Such files will be deleted when the transaction exits (on both |
7faa55c20b0e
transaction: fix some docstring grammar
Matt Mackall <mpm@selenic.com>
parents:
23354
diff
changeset
|
246 failure and success). |
23291
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
247 """ |
23354
918c77775df6
transaction: accept a 'location' argument for registertmp
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23318
diff
changeset
|
248 self._addbackupentry((location, '', tmpfile, False)) |
23291
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
249 |
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
250 @active |
23317
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
251 def addfilegenerator(self, genid, filenames, genfunc, order=0, |
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
252 location=''): |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
253 """add a function to generates some files at transaction commit |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
254 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
255 The `genfunc` argument is a function capable of generating proper |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
256 content of each entry in the `filename` tuple. |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
257 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
258 At transaction close time, `genfunc` will be called with one file |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
259 object argument per entries in `filenames`. |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
260 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
261 The transaction itself is responsible for the backup, creation and |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
262 final write of such file. |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
263 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
264 The `genid` argument is used to ensure the same set of file is only |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
265 generated once. Call to `addfilegenerator` for a `genid` already |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
266 present will overwrite the old entry. |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
267 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
268 The `order` argument may be used to control the order in which multiple |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
269 generator will be executed. |
23317
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
270 |
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
271 The `location` arguments may be used to indicate the files are located |
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
272 outside of the the standard directory for transaction. It should match |
23543
4dd8a6a1240d
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
23513
diff
changeset
|
273 one of the key of the `transaction.vfsmap` dictionary. |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
274 """ |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
275 # For now, we are unable to do proper backup and restore of custom vfs |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
276 # but for bookmarks that are handled outside this mechanism. |
23317
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
277 self._filegenerators[genid] = (order, filenames, genfunc, location) |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
278 |
23356
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
279 def _generatefiles(self, suffix=''): |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
280 # write files registered for generation |
23357
ba033f461f00
transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23356
diff
changeset
|
281 any = False |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
282 for entry in sorted(self._filegenerators.values()): |
23357
ba033f461f00
transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23356
diff
changeset
|
283 any = True |
23317
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
284 order, filenames, genfunc, location = entry |
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
285 vfs = self._vfsmap[location] |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
286 files = [] |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
287 try: |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
288 for name in filenames: |
23356
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
289 name += suffix |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
290 if suffix: |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
291 self.registertmp(name, location=location) |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
292 else: |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
293 self.addbackup(name, location=location) |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
294 files.append(vfs(name, 'w', atomictemp=True)) |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
295 genfunc(*files) |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
296 finally: |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
297 for f in files: |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
298 f.close() |
23357
ba033f461f00
transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23356
diff
changeset
|
299 return any |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
300 |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
301 @active |
2084 | 302 def find(self, file): |
303 if file in self.map: | |
304 return self.entries[self.map[file]] | |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
305 if file in self._backupmap: |
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
306 return self._backupentries[self._backupmap[file]] |
2084 | 307 return None |
308 | |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
309 @active |
2084 | 310 def replace(self, file, offset, data=None): |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
311 ''' |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
312 replace can only replace already committed entries |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
313 that are not pending in the queue |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
314 ''' |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
315 |
2084 | 316 if file not in self.map: |
317 raise KeyError(file) | |
318 index = self.map[file] | |
319 self.entries[index] = (file, offset, data) | |
320 self.file.write("%s\0%d\n" % (file, offset)) | |
321 self.file.flush() | |
322 | |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
323 @active |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
324 def nest(self): |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
325 self.count += 1 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
326 self.usages += 1 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
327 return self |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
328 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
329 def release(self): |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
330 if self.count > 0: |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
331 self.usages -= 1 |
11685 | 332 # if the transaction scopes are left without being closed, fail |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
333 if self.count > 0 and self.usages == 0: |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
334 self._abort() |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
335 |
27862
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
336 def __enter__(self): |
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
337 return self |
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
338 |
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
339 def __exit__(self, exc_type, exc_val, exc_tb): |
27924
24361fb68cba
transaction: abort transaction during hook exception
Durham Goode <durham@fb.com>
parents:
27862
diff
changeset
|
340 try: |
24361fb68cba
transaction: abort transaction during hook exception
Durham Goode <durham@fb.com>
parents:
27862
diff
changeset
|
341 if exc_type is None: |
24361fb68cba
transaction: abort transaction during hook exception
Durham Goode <durham@fb.com>
parents:
27862
diff
changeset
|
342 self.close() |
24361fb68cba
transaction: abort transaction during hook exception
Durham Goode <durham@fb.com>
parents:
27862
diff
changeset
|
343 finally: |
24361fb68cba
transaction: abort transaction during hook exception
Durham Goode <durham@fb.com>
parents:
27862
diff
changeset
|
344 self.release() |
27862
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
345 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
346 def running(self): |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
347 return self.count > 0 |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
348 |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
349 def addpending(self, category, callback): |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
350 """add a callback to be called when the transaction is pending |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
351 |
23280
b01c491af0cf
transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23279
diff
changeset
|
352 The transaction will be given as callback's first argument. |
b01c491af0cf
transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23279
diff
changeset
|
353 |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
354 Category is a unique identifier to allow overwriting an old callback |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
355 with a newer callback. |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
356 """ |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
357 self._pendingcallback[category] = callback |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
358 |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
359 @active |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
360 def writepending(self): |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
361 '''write pending file to temporary version |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
362 |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
363 This is used to allow hooks to view a transaction before commit''' |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
364 categories = sorted(self._pendingcallback) |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
365 for cat in categories: |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
366 # remove callback since the data will have been flushed |
23280
b01c491af0cf
transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23279
diff
changeset
|
367 any = self._pendingcallback.pop(cat)(self) |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
368 self._anypending = self._anypending or any |
23358
1b51d1b05482
transaction: write pending generated files
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23357
diff
changeset
|
369 self._anypending |= self._generatefiles(suffix='.pending') |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
370 return self._anypending |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
371 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
372 @active |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
373 def addfinalize(self, category, callback): |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
374 """add a callback to be called when the transaction is closed |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
375 |
23281
f60ed8cf4afc
transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23280
diff
changeset
|
376 The transaction will be given as callback's first argument. |
f60ed8cf4afc
transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23280
diff
changeset
|
377 |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
378 Category is a unique identifier to allow overwriting old callbacks with |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
379 newer callbacks. |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
380 """ |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
381 self._finalizecallback[category] = callback |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
382 |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
383 @active |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
384 def addpostclose(self, category, callback): |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
385 """add a callback to be called after the transaction is closed |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
386 |
23282
6c1351352b6c
transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23281
diff
changeset
|
387 The transaction will be given as callback's first argument. |
6c1351352b6c
transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23281
diff
changeset
|
388 |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
389 Category is a unique identifier to allow overwriting an old callback |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
390 with a newer callback. |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
391 """ |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
392 self._postclosecallback[category] = callback |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
393 |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
394 @active |
23764
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
395 def addabort(self, category, callback): |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
396 """add a callback to be called when the transaction is aborted. |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
397 |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
398 The transaction will be given as the first argument to the callback. |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
399 |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
400 Category is a unique identifier to allow overwriting an old callback |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
401 with a newer callback. |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
402 """ |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
403 self._abortcallback[category] = callback |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
404 |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
405 @active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
406 def close(self): |
9220
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
407 '''commit the transaction''' |
23290
59513ec76748
transaction: always generate file on close
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23283
diff
changeset
|
408 if self.count == 1: |
24283
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
409 self.validator(self) # will raise exception if needed |
23103
29bfa964d6d8
transaction: only generate file when we actually close the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23102
diff
changeset
|
410 self._generatefiles() |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
411 categories = sorted(self._finalizecallback) |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
412 for cat in categories: |
23281
f60ed8cf4afc
transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23280
diff
changeset
|
413 self._finalizecallback[cat](self) |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
414 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
415 self.count -= 1 |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
416 if self.count != 0: |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
417 return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
418 self.file.close() |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
419 self._backupsfile.close() |
23291
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
420 # cleanup temporary files |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
421 for l, f, b, c in self._backupentries: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
422 if l not in self._vfsmap and c: |
26754
e7e1528cf200
spelling: fix typo in transaction error messages
Matt Mackall <mpm@selenic.com>
parents:
26753
diff
changeset
|
423 self.report("couldn't remove %s: unknown cache location %s\n" |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
424 % (b, l)) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
425 continue |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
426 vfs = self._vfsmap[l] |
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
427 if not f and b and vfs.exists(b): |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
428 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
429 vfs.unlink(b) |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26576
diff
changeset
|
430 except (IOError, OSError, error.Abort) as inst: |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
431 if not c: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
432 raise |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
433 # Abort may be raise by read only opener |
26754
e7e1528cf200
spelling: fix typo in transaction error messages
Matt Mackall <mpm@selenic.com>
parents:
26753
diff
changeset
|
434 self.report("couldn't remove %s: %s\n" |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
435 % (vfs.join(b), inst)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
436 self.entries = [] |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
437 self._writeundo() |
95 | 438 if self.after: |
785 | 439 self.after() |
26753
96dd93de548c
transaction: reorder unlinking .hg/journal and .hg/journal.backupfiles
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
26587
diff
changeset
|
440 if self.opener.isfile(self._backupjournal): |
96dd93de548c
transaction: reorder unlinking .hg/journal and .hg/journal.backupfiles
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
26587
diff
changeset
|
441 self.opener.unlink(self._backupjournal) |
20087
cf3b8285af00
transaction: take journal file path relative to vfs to use file API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20084
diff
changeset
|
442 if self.opener.isfile(self.journal): |
cf3b8285af00
transaction: take journal file path relative to vfs to use file API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20084
diff
changeset
|
443 self.opener.unlink(self.journal) |
27662
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
444 for l, _f, b, c in self._backupentries: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
445 if l not in self._vfsmap and c: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
446 self.report("couldn't remove %s: unknown cache location" |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
447 "%s\n" % (b, l)) |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
448 continue |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
449 vfs = self._vfsmap[l] |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
450 if b and vfs.exists(b): |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
451 try: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
452 vfs.unlink(b) |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
453 except (IOError, OSError, error.Abort) as inst: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
454 if not c: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
455 raise |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
456 # Abort may be raise by read only opener |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
457 self.report("couldn't remove %s: %s\n" |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
458 % (vfs.join(b), inst)) |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
459 self._backupentries = [] |
573 | 460 self.journal = None |
26576
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
461 |
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
462 self.releasefn(self, True) # notify success of closing transaction |
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
463 |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
464 # run post close action |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
465 categories = sorted(self._postclosecallback) |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
466 for cat in categories: |
23282
6c1351352b6c
transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23281
diff
changeset
|
467 self._postclosecallback[cat](self) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
468 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
469 @active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
470 def abort(self): |
9220
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
471 '''abort the transaction (generally called on error, or when the |
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
472 transaction is not explicitly committed before going out of |
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
473 scope)''' |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
474 self._abort() |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
475 |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
476 def _writeundo(self): |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
477 """write transaction data for possible future undo call""" |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
478 if self.undoname is None: |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
479 return |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
480 undobackupfile = self.opener.open("%s.backupfiles" % self.undoname, 'w') |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
481 undobackupfile.write('%d\n' % version) |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
482 for l, f, b, c in self._backupentries: |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
483 if not f: # temporary file |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
484 continue |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
485 if not b: |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
486 u = '' |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
487 else: |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
488 if l not in self._vfsmap and c: |
26754
e7e1528cf200
spelling: fix typo in transaction error messages
Matt Mackall <mpm@selenic.com>
parents:
26753
diff
changeset
|
489 self.report("couldn't remove %s: unknown cache location" |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
490 "%s\n" % (b, l)) |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
491 continue |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
492 vfs = self._vfsmap[l] |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
493 base, name = vfs.split(b) |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
494 assert name.startswith(self.journal), name |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
495 uname = name.replace(self.journal, self.undoname, 1) |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
496 u = vfs.reljoin(base, uname) |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
497 util.copyfile(vfs.join(b), vfs.join(u), hardlink=True) |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
498 undobackupfile.write("%s\0%s\0%s\0%d\n" % (l, f, u, c)) |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
499 undobackupfile.close() |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
500 |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
501 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
502 def _abort(self): |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
503 self.count = 0 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
504 self.usages = 0 |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
505 self.file.close() |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
506 self._backupsfile.close() |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
507 |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
508 try: |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
509 if not self.entries and not self._backupentries: |
26753
96dd93de548c
transaction: reorder unlinking .hg/journal and .hg/journal.backupfiles
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
26587
diff
changeset
|
510 if self._backupjournal: |
96dd93de548c
transaction: reorder unlinking .hg/journal and .hg/journal.backupfiles
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
26587
diff
changeset
|
511 self.opener.unlink(self._backupjournal) |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
512 if self.journal: |
20087
cf3b8285af00
transaction: take journal file path relative to vfs to use file API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20084
diff
changeset
|
513 self.opener.unlink(self.journal) |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
514 return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
515 |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
516 self.report(_("transaction abort!\n")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
517 |
108 | 518 try: |
23764
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
519 for cat in sorted(self._abortcallback): |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
520 self._abortcallback[cat](self) |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
521 _playback(self.journal, self.report, self.opener, self._vfsmap, |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
522 self.entries, self._backupentries, False) |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
523 self.report(_("rollback completed\n")) |
25183
0d0ed375fbdf
recover: catch any exception, not just Exception
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
24721
diff
changeset
|
524 except BaseException: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
525 self.report(_("rollback failed - please run hg recover\n")) |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
526 finally: |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
527 self.journal = None |
26576
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
528 self.releasefn(self, False) # notify failure of transaction |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
529 |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
530 def rollback(opener, vfsmap, file, report): |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
531 """Rolls back the transaction contained in the given file |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
532 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
533 Reads the entries in the specified file, and the corresponding |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
534 '*.backupfiles' file, to recover from an incomplete transaction. |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
535 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
536 * `file`: a file containing a list of entries, specifying where |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
537 to truncate each file. The file should contain a list of |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
538 file\0offset pairs, delimited by newlines. The corresponding |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
539 '*.backupfiles' file should contain a list of file\0backupfile |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
540 pairs, delimited by \0. |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
541 """ |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
542 entries = [] |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
543 backupentries = [] |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
544 |
20087
cf3b8285af00
transaction: take journal file path relative to vfs to use file API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
20084
diff
changeset
|
545 fp = opener.open(file) |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
546 lines = fp.readlines() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
547 fp.close() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
548 for l in lines: |
20524
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
549 try: |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
550 f, o = l.split('\0') |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
551 entries.append((f, int(o), None)) |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
552 except ValueError: |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
553 report(_("couldn't read journal entry %r!\n") % l) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
554 |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
555 backupjournal = "%s.backupfiles" % file |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
556 if opener.exists(backupjournal): |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
557 fp = opener.open(backupjournal) |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
558 lines = fp.readlines() |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
559 if lines: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
560 ver = lines[0][:-1] |
23064
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
561 if ver == str(version): |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
562 for line in lines[1:]: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
563 if line: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
564 # Shave off the trailing newline |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
565 line = line[:-1] |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
566 l, f, b, c = line.split('\0') |
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
567 backupentries.append((l, f, b, bool(c))) |
23064
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
568 else: |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
569 report(_("journal was created by a different version of " |
24721
774ee9800146
transaction: add missing newline to message
Michael O'Connor <moconnor@janestreet.com>
parents:
24283
diff
changeset
|
570 "Mercurial\n")) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
571 |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
572 _playback(file, report, opener, vfsmap, entries, backupentries) |