Mercurial > hg
annotate mercurial/transaction.py @ 23088:fe5f044b753d stable
changelog: use headrevsfiltered
2b5940f64750 introduced use of the new filtering headrevs C implementation. It
caught TypeError to detect when to fall back to the implementation that was
compatible with old extensions. That method was however not reliable.
Instead, use the new headrevsfiltered function when passing a filter. It will
reliably fail with AttributeError when an old extension that predates
headrevsfiltered is used.
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Sun, 26 Oct 2014 12:14:12 +0100 |
parents | 963f311e3a81 |
children | 16da812ad970 |
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 |
3891 | 14 from i18n import _ |
20886
203908968644
transaction: drop extra import caught by pyflakes
Matt Mackall <mpm@selenic.com>
parents:
20882
diff
changeset
|
15 import errno |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
16 import error, util |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
17 |
23064
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
18 version = 1 |
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
19 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
20 def active(func): |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
21 def _active(self, *args, **kwds): |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
22 if self.count == 0: |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
23 raise error.Abort(_( |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
24 '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
|
25 return func(self, *args, **kwds) |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
26 return _active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
27 |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
28 def _playback(journal, report, opener, entries, backupentries, unlink=True): |
22204
f8dc6599da5d
cleanup: name unused variables using convention of leading _
Mads Kiilerich <madski@unity3d.com>
parents:
22199
diff
changeset
|
29 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
|
30 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
|
31 try: |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
32 fp = opener(f, 'a') |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
33 fp.truncate(o) |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
34 fp.close() |
9686
ddf2adf88b89
transaction: more specific exceptions, os.unlink can raise OSError
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9220
diff
changeset
|
35 except IOError: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
36 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
|
37 raise |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
38 else: |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
39 try: |
20084
a3378a1b0a05
transaction: unlink target file via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17424
diff
changeset
|
40 opener.unlink(f) |
9686
ddf2adf88b89
transaction: more specific exceptions, os.unlink can raise OSError
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9220
diff
changeset
|
41 except (IOError, OSError), inst: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
42 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
|
43 raise |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
44 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
45 backupfiles = [] |
22204
f8dc6599da5d
cleanup: name unused variables using convention of leading _
Mads Kiilerich <madski@unity3d.com>
parents:
22199
diff
changeset
|
46 for f, b, _ignore in backupentries: |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
47 filepath = opener.join(f) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
48 backuppath = opener.join(b) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
49 try: |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
50 util.copyfile(backuppath, filepath) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
51 backupfiles.append(b) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
52 except IOError: |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
53 report(_("failed to recover %s\n") % f) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
54 raise |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
55 |
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
|
56 opener.unlink(journal) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
57 backuppath = "%s.backupfiles" % journal |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
58 if opener.exists(backuppath): |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
59 opener.unlink(backuppath) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
60 for f in backupfiles: |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
61 opener.unlink(f) |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
62 |
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1541
diff
changeset
|
63 class transaction(object): |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
64 def __init__(self, report, opener, journal, after=None, createmode=None, |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
65 onclose=None, onabort=None): |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
66 """Begin a new transaction |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
67 |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
68 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
|
69 an exception. |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
70 |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
71 * `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
|
72 * `createmode`: the mode of the journal file that will be created |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
73 * `onclose`: called as the transaction is closing, but before it is |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
74 closed |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
75 * `onabort`: called as the transaction is aborting, but before any files |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
76 have been truncated |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
77 """ |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
78 self.count = 1 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
79 self.usages = 1 |
582 | 80 self.report = report |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
81 self.opener = opener |
95 | 82 self.after = after |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
83 self.onclose = onclose |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
84 self.onabort = onabort |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
85 self.entries = [] |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
86 self.backupentries = [] |
42
91f1fa847158
Fix multiple changes to file per transaction
mpm@selenic.com
parents:
13
diff
changeset
|
87 self.map = {} |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
88 self.backupmap = {} |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
89 self.journal = journal |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
90 self._queue = [] |
21150
0d05915b688d
transaction: add a notion of hook arguments
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20886
diff
changeset
|
91 # a dict of arguments to be passed to hooks |
0d05915b688d
transaction: add a notion of hook arguments
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
20886
diff
changeset
|
92 self.hookargs = {} |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
93 |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
94 self.backupjournal = "%s.backupfiles" % 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
|
95 self.file = opener.open(self.journal, "w") |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
96 self.backupsfile = opener.open(self.backupjournal, 'w') |
23064
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
97 self.backupsfile.write('%d\n' % version) |
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
|
98 if createmode is not None: |
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
|
99 opener.chmod(self.journal, createmode & 0666) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
100 opener.chmod(self.backupjournal, createmode & 0666) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
101 |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
102 # 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
|
103 self._filegenerators = {} |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
104 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
105 def __del__(self): |
558
0ceea19182a9
transaction: __del__ should do nothing if the journal already exists
mpm@selenic.com
parents:
515
diff
changeset
|
106 if self.journal: |
9693
c40a1ee20aa5
transaction: always remove empty journal on abort
Sune Foldager <cryo@cyanite.org>
parents:
9686
diff
changeset
|
107 self._abort() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
108 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
109 @active |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
110 def startgroup(self): |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
111 self._queue.append(([], [])) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
112 |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
113 @active |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
114 def endgroup(self): |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
115 q = self._queue.pop() |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
116 self.entries.extend(q[0]) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
117 self.backupentries.extend(q[1]) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
118 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
119 offsets = [] |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
120 backups = [] |
22199
b3e51675f98e
cleanup: avoid _ for local unused tmp variables - that is reserved for i18n
Mads Kiilerich <madski@unity3d.com>
parents:
22078
diff
changeset
|
121 for f, o, _data in q[0]: |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
122 offsets.append((f, o)) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
123 |
22199
b3e51675f98e
cleanup: avoid _ for local unused tmp variables - that is reserved for i18n
Mads Kiilerich <madski@unity3d.com>
parents:
22078
diff
changeset
|
124 for f, b, _data in q[1]: |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
125 backups.append((f, b)) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
126 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
127 d = ''.join(['%s\0%d\n' % (f, o) for f, o in offsets]) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
128 self.file.write(d) |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
129 self.file.flush() |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
130 |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
131 d = ''.join(['%s\0%s\n' % (f, b) for f, b in backups]) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
132 self.backupsfile.write(d) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
133 self.backupsfile.flush() |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
134 |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
135 @active |
2084 | 136 def add(self, file, offset, data=None): |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
137 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
|
138 return |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
139 if self._queue: |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
140 self._queue[-1][0].append((file, offset, data)) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
141 return |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
142 |
2084 | 143 self.entries.append((file, offset, data)) |
144 self.map[file] = len(self.entries) - 1 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
145 # 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
|
146 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
|
147 self.file.flush() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
148 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
149 @active |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
150 def addbackup(self, file, hardlink=True, vfs=None): |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
151 """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
|
152 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
153 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
|
154 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
|
155 aborting. |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
156 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
157 * `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
|
158 * `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
|
159 """ |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
160 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
161 if file in self.map or file in self.backupmap: |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
162 return |
22077
2990ce46fc2d
transaction: backup file in a dedicated "namespace"
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22076
diff
changeset
|
163 backupfile = "%s.backup.%s" % (self.journal, file) |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
164 if vfs is None: |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
165 vfs = self.opener |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
166 if vfs.exists(file): |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
167 filepath = vfs.join(file) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
168 backuppath = self.opener.join(backupfile) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
169 util.copyfiles(filepath, backuppath, hardlink=hardlink) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
170 else: |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
171 self.add(file, 0) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
172 return |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
173 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
174 if self._queue: |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
175 self._queue[-1][1].append((file, backupfile)) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
176 return |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
177 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
178 self.backupentries.append((file, backupfile, None)) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
179 self.backupmap[file] = len(self.backupentries) - 1 |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
180 self.backupsfile.write("%s\0%s\n" % (file, backupfile)) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
181 self.backupsfile.flush() |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
182 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
183 @active |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
184 def addfilegenerator(self, genid, filenames, genfunc, order=0, vfs=None): |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
185 """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
|
186 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
187 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
|
188 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
|
189 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
190 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
|
191 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
|
192 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
193 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
|
194 final write of such file. |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
195 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
196 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
|
197 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
|
198 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
|
199 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
200 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
|
201 generator will be executed. |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
202 """ |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
203 # 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
|
204 # but for bookmarks that are handled outside this mechanism. |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
205 assert vfs is None or filenames == ('bookmarks',) |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
206 self._filegenerators[genid] = (order, filenames, genfunc, vfs) |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
207 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
208 @active |
2084 | 209 def find(self, file): |
210 if file in self.map: | |
211 return self.entries[self.map[file]] | |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
212 if file in self.backupmap: |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
213 return self.backupentries[self.backupmap[file]] |
2084 | 214 return None |
215 | |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
216 @active |
2084 | 217 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
|
218 ''' |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
219 replace can only replace already committed entries |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
220 that are not pending in the queue |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
221 ''' |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
222 |
2084 | 223 if file not in self.map: |
224 raise KeyError(file) | |
225 index = self.map[file] | |
226 self.entries[index] = (file, offset, data) | |
227 self.file.write("%s\0%d\n" % (file, offset)) | |
228 self.file.flush() | |
229 | |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
230 @active |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
231 def nest(self): |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
232 self.count += 1 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
233 self.usages += 1 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
234 return self |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
235 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
236 def release(self): |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
237 if self.count > 0: |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
238 self.usages -= 1 |
11685 | 239 # 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
|
240 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
|
241 self._abort() |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
242 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
243 def running(self): |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
244 return self.count > 0 |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
245 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
246 @active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
247 def close(self): |
9220
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
248 '''commit the transaction''' |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
249 # write files registered for generation |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
250 for entry in sorted(self._filegenerators.values()): |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
251 order, filenames, genfunc, vfs = entry |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
252 if vfs is None: |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
253 vfs = self.opener |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
254 files = [] |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
255 try: |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
256 for name in filenames: |
22662
c4d63f6740b8
transaction: work around and document issue with file backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22204
diff
changeset
|
257 # Some files are already backed up when creating the |
c4d63f6740b8
transaction: work around and document issue with file backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22204
diff
changeset
|
258 # localrepo. Until this is properly fixed we disable the |
c4d63f6740b8
transaction: work around and document issue with file backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22204
diff
changeset
|
259 # backup for them. |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
260 if name not in ('phaseroots', 'bookmarks'): |
22662
c4d63f6740b8
transaction: work around and document issue with file backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22204
diff
changeset
|
261 self.addbackup(name) |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
262 files.append(vfs(name, 'w', atomictemp=True)) |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
263 genfunc(*files) |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
264 finally: |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
265 for f in files: |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
266 f.close() |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
267 |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
268 if self.count == 1 and self.onclose is not None: |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
269 self.onclose() |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
270 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
271 self.count -= 1 |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
272 if self.count != 0: |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
273 return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
274 self.file.close() |
21206
c77418938d05
transaction: fix file descriptor leak for journal.backupfiles
Durham Goode <durham@fb.com>
parents:
21150
diff
changeset
|
275 self.backupsfile.close() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
276 self.entries = [] |
95 | 277 if self.after: |
785 | 278 self.after() |
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
|
279 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
|
280 self.opener.unlink(self.journal) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
281 if self.opener.isfile(self.backupjournal): |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
282 self.opener.unlink(self.backupjournal) |
22204
f8dc6599da5d
cleanup: name unused variables using convention of leading _
Mads Kiilerich <madski@unity3d.com>
parents:
22199
diff
changeset
|
283 for _f, b, _ignore in self.backupentries: |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
284 self.opener.unlink(b) |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
285 self.backupentries = [] |
573 | 286 self.journal = None |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
287 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
288 @active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
289 def abort(self): |
9220
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
290 '''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
|
291 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
|
292 scope)''' |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
293 self._abort() |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
294 |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
295 def _abort(self): |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
296 self.count = 0 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
297 self.usages = 0 |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
298 self.file.close() |
21206
c77418938d05
transaction: fix file descriptor leak for journal.backupfiles
Durham Goode <durham@fb.com>
parents:
21150
diff
changeset
|
299 self.backupsfile.close() |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
300 |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
301 if self.onabort is not None: |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
302 self.onabort() |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
303 |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
304 try: |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
305 if not self.entries and not self.backupentries: |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
306 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
|
307 self.opener.unlink(self.journal) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
308 if self.backupjournal: |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
309 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
|
310 return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
311 |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
312 self.report(_("transaction abort!\n")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
313 |
108 | 314 try: |
10282
08a0f04b56bd
many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents:
10263
diff
changeset
|
315 _playback(self.journal, self.report, self.opener, |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
316 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
|
317 self.report(_("rollback completed\n")) |
16689
f366d4c2ff34
cleanup: replace naked excepts with except Exception: ...
Brodie Rao <brodie@sf.io>
parents:
13408
diff
changeset
|
318 except Exception: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
319 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
|
320 finally: |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
321 self.journal = None |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
322 |
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
323 |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
324 def rollback(opener, file, report): |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
325 """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
|
326 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
327 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
|
328 '*.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
|
329 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
330 * `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
|
331 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
|
332 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
|
333 '*.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
|
334 pairs, delimited by \0. |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
335 """ |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
336 entries = [] |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
337 backupentries = [] |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
338 |
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
|
339 fp = opener.open(file) |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
340 lines = fp.readlines() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
341 fp.close() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
342 for l in lines: |
20524
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
343 try: |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
344 f, o = l.split('\0') |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
345 entries.append((f, int(o), None)) |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
346 except ValueError: |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
347 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
|
348 |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
349 backupjournal = "%s.backupfiles" % file |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
350 if opener.exists(backupjournal): |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
351 fp = opener.open(backupjournal) |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
352 lines = fp.readlines() |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
353 if lines: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
354 ver = lines[0][:-1] |
23064
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
355 if ver == str(version): |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
356 for line in lines[1:]: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
357 if line: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
358 # Shave off the trailing newline |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
359 line = line[:-1] |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
360 f, b = line.split('\0') |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
361 backupentries.append((f, b, None)) |
23064
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
362 else: |
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
363 report(_("journal was created by a newer version of " |
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
364 "Mercurial")) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
365 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
366 _playback(file, report, opener, entries, backupentries) |