Mercurial > hg-stable
annotate mercurial/transaction.py @ 30451:41a8106789ca
util: implement zstd compression engine
Now that zstd is vendored and being built (in some configurations), we
can implement a compression engine for zstd!
The zstd engine is a little different from existing engines. Because
it may not always be present, we have to defer load the module in case
importing it fails. We facilitate this via a cached property that holds
a reference to the module or None. The "available" method is
implemented to reflect reality.
The zstd engine declares its ability to handle bundles using the
"zstd" human name and the "ZS" internal name. The latter was chosen
because internal names are 2 characters (by only convention I think)
and "ZS" seems reasonable.
The engine, like others, supports specifying the compression level.
However, there are no consumers of this API that yet pass in that
argument. I have plans to change that, so stay tuned.
Since all we need to do to support bundle generation with a new
compression engine is implement and register the compression engine,
bundle generation with zstd "just works!" Tests demonstrating this
have been added.
How does performance of zstd for bundle generation compare? On the
mozilla-unified repo, `hg bundle --all -t <engine>-v2` yields the
following on my i7-6700K on Linux:
engine CPU time bundle size vs orig size throughput
none 97.0s 4,054,405,584 100.0% 41.8 MB/s
bzip2 (l=9) 393.6s 975,343,098 24.0% 10.3 MB/s
gzip (l=6) 184.0s 1,140,533,074 28.1% 22.0 MB/s
zstd (l=1) 108.2s 1,119,434,718 27.6% 37.5 MB/s
zstd (l=2) 111.3s 1,078,328,002 26.6% 36.4 MB/s
zstd (l=3) 113.7s 1,011,823,727 25.0% 35.7 MB/s
zstd (l=4) 116.0s 1,008,965,888 24.9% 35.0 MB/s
zstd (l=5) 121.0s 977,203,148 24.1% 33.5 MB/s
zstd (l=6) 131.7s 927,360,198 22.9% 30.8 MB/s
zstd (l=7) 139.0s 912,808,505 22.5% 29.2 MB/s
zstd (l=12) 198.1s 854,527,714 21.1% 20.5 MB/s
zstd (l=18) 681.6s 789,750,690 19.5% 5.9 MB/s
On compression, zstd for bundle generation delivers:
* better compression than gzip with significantly less CPU utilization
* better than bzip2 compression ratios while still being significantly
faster than gzip
* ability to aggressively tune compression level to achieve
significantly smaller bundles
That last point is important. With clone bundles, a server can
pre-generate a bundle file, upload it to a static file server, and
redirect clients to transparently download it during clone. The server
could choose to produce a zstd bundle with the highest compression
settings possible. This would take a very long time - a magnitude
longer than a typical zstd bundle generation - but the result would
be hundreds of megabytes smaller! For the clone volume we do at
Mozilla, this could translate to petabytes of bandwidth savings
per year and faster clones (due to smaller transfer size).
I don't have detailed numbers to report on decompression. However,
zstd decompression is fast: >1 GB/s output throughput on this machine,
even through the Python bindings. And it can do that regardless of the
compression level of the input. By the time you have enough data to
worry about overhead of decompression, you have plenty of other things
to worry about performance wise.
zstd is wins all around. I can't wait to implement support for it
on the wire protocol and in revlogs.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 11 Nov 2016 01:10:07 -0800 |
parents | 599912a62ff6 |
children | 8defc7d9adae |
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 |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
26 # These are the file generators that should only be executed after the |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
27 # finalizers are done, since they rely on the output of the finalizers (like |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
28 # the changelog having been written). |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
29 postfinalizegenerators = set([ |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
30 'bookmarks', |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
31 'dirstate' |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
32 ]) |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
33 |
29297
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
34 gengroupall='all' |
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
35 gengroupprefinalize='prefinalize' |
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
36 gengrouppostfinalize='postfinalize' |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
37 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
38 def active(func): |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
39 def _active(self, *args, **kwds): |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
40 if self.count == 0: |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
41 raise error.Abort(_( |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
42 '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
|
43 return func(self, *args, **kwds) |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
44 return _active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
45 |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
46 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
|
47 unlink=True): |
22204
f8dc6599da5d
cleanup: name unused variables using convention of leading _
Mads Kiilerich <madski@unity3d.com>
parents:
22199
diff
changeset
|
48 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
|
49 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
|
50 try: |
30006
599912a62ff6
transaction: open a file with checkambig=True to avoid file stat ambiguity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29353
diff
changeset
|
51 fp = opener(f, 'a', checkambig=True) |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
52 fp.truncate(o) |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
53 fp.close() |
9686
ddf2adf88b89
transaction: more specific exceptions, os.unlink can raise OSError
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9220
diff
changeset
|
54 except IOError: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
55 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
|
56 raise |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
57 else: |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
58 try: |
20084
a3378a1b0a05
transaction: unlink target file via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17424
diff
changeset
|
59 opener.unlink(f) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25658
diff
changeset
|
60 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
|
61 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
|
62 raise |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
63 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
64 backupfiles = [] |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
65 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
|
66 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
|
67 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
|
68 % (b, l)) |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
69 vfs = vfsmap[l] |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
70 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
71 if f and b: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
72 filepath = vfs.join(f) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
73 backuppath = vfs.join(b) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
74 try: |
29353
a9ccd9af48ef
transaction: avoid ambiguity of file stat at restoring from backup
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29299
diff
changeset
|
75 util.copyfile(backuppath, filepath, checkambig=True) |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
76 backupfiles.append(b) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
77 except IOError: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
78 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
|
79 else: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
80 target = f or b |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
81 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
82 vfs.unlink(target) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25658
diff
changeset
|
83 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
|
84 if inst.errno != errno.ENOENT: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
85 raise |
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 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
|
88 raise |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
89 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
90 backuppath = "%s.backupfiles" % journal |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
91 if opener.exists(backuppath): |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
92 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
|
93 opener.unlink(journal) |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
94 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
95 for f in backupfiles: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
96 if opener.exists(f): |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
97 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
|
98 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
|
99 # 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
|
100 pass |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
101 |
1559
59b3639df0a9
Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents:
1541
diff
changeset
|
102 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
|
103 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
|
104 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
|
105 """Begin a new transaction |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
106 |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
107 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
|
108 an exception. |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
109 |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
110 * `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
|
111 * `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
|
112 * `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
|
113 """ |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
114 self.count = 1 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
115 self.usages = 1 |
582 | 116 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
|
117 # a vfs to the store content |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
118 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
|
119 # 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
|
120 vfsmap = vfsmap.copy() |
5bd1f6572db0
transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23309
diff
changeset
|
121 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
|
122 self._vfsmap = vfsmap |
95 | 123 self.after = after |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
124 self.entries = [] |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
125 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
|
126 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
|
127 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
|
128 self._queue = [] |
24283
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
129 # 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
|
130 # 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
|
131 # target user is repository hooks. |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
132 if validator is None: |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
133 validator = lambda tr: None |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
134 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
|
135 # 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
|
136 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
|
137 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
|
138 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
|
139 |
23279
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
140 # 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
|
141 self.hookargs = {} |
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
142 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
|
143 |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
144 # 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
|
145 # - 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
|
146 # - 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
|
147 # - 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
|
148 # 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
|
149 # (cache is currently unused) |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
150 self._backupentries = [] |
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
151 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
|
152 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
|
153 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
|
154 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
|
155 |
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
|
156 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
|
157 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
|
158 opener.chmod(self._backupjournal, createmode & 0o666) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
159 |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
160 # 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
|
161 self._filegenerators = {} |
23543
4dd8a6a1240d
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
23513
diff
changeset
|
162 # 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
|
163 self._pendingcallback = {} |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
164 # 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
|
165 self._anypending = False |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
166 # 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
|
167 self._finalizecallback = {} |
23543
4dd8a6a1240d
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
23513
diff
changeset
|
168 # 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
|
169 self._postclosecallback = {} |
23764
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
170 # holds callbacks to call during abort |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
171 self._abortcallback = {} |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
172 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
173 def __del__(self): |
558
0ceea19182a9
transaction: __del__ should do nothing if the journal already exists
mpm@selenic.com
parents:
515
diff
changeset
|
174 if self.journal: |
9693
c40a1ee20aa5
transaction: always remove empty journal on abort
Sune Foldager <cryo@cyanite.org>
parents:
9686
diff
changeset
|
175 self._abort() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
176 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
177 @active |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
178 def startgroup(self): |
23250
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
179 """delay registration of file entry |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
180 |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
181 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
|
182 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
|
183 self._queue.append([]) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
184 |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
185 @active |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
186 def endgroup(self): |
23250
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
187 """apply delayed registration of file entry. |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
188 |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
189 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
|
190 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
|
191 q = self._queue.pop() |
23253
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
192 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
|
193 self._addentry(f, o, data) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
194 |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
195 @active |
2084 | 196 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
|
197 """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
|
198 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
|
199 return |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
200 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
|
201 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
|
202 return |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
203 |
23253
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
204 self._addentry(file, offset, data) |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
205 |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
206 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
|
207 """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
|
208 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
|
209 return |
2084 | 210 self.entries.append((file, offset, data)) |
211 self.map[file] = len(self.entries) - 1 | |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
212 # 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
|
213 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
|
214 self.file.flush() |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
215 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
216 @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
|
217 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
|
218 """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
|
219 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
220 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
|
221 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
|
222 aborting. |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
223 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
224 * `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
|
225 * `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
|
226 """ |
23251
85c634ff395a
transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23250
diff
changeset
|
227 if self._queue: |
85c634ff395a
transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23250
diff
changeset
|
228 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
|
229 raise RuntimeError(msg) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
230 |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
231 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
|
232 return |
23582
7559dc8c4238
vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23581
diff
changeset
|
233 vfs = self._vfsmap[location] |
7559dc8c4238
vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23581
diff
changeset
|
234 dirname, filename = vfs.split(file) |
23315
66275ecc73c1
addbackup: handle file in subdirectory
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23314
diff
changeset
|
235 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
|
236 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
|
237 if vfs.exists(file): |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
238 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
|
239 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
|
240 util.copyfile(filepath, backuppath, hardlink=hardlink) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
241 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
|
242 backupfile = '' |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
243 |
23316
fc3670f41d3e
transaction: use 'location' instead of 'vfs' in the addbackup method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23315
diff
changeset
|
244 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
|
245 |
b04263c38a92
transaction: extract backupentry registration in a dedicated function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23282
diff
changeset
|
246 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
|
247 """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
|
248 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
|
249 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
|
250 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
|
251 self._backupsfile.flush() |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
252 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
253 @active |
23354
918c77775df6
transaction: accept a 'location' argument for registertmp
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23318
diff
changeset
|
254 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
|
255 """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
|
256 |
23355
7faa55c20b0e
transaction: fix some docstring grammar
Matt Mackall <mpm@selenic.com>
parents:
23354
diff
changeset
|
257 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
|
258 failure and success). |
23291
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
259 """ |
23354
918c77775df6
transaction: accept a 'location' argument for registertmp
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23318
diff
changeset
|
260 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
|
261 |
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
262 @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
|
263 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
|
264 location=''): |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
265 """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
|
266 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
267 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
|
268 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
|
269 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
270 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
|
271 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
|
272 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
273 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
|
274 final write of such file. |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
275 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
276 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
|
277 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
|
278 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
|
279 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
280 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
|
281 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
|
282 |
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
283 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
|
284 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
|
285 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
|
286 """ |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
287 # 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
|
288 # 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
|
289 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
|
290 |
29297
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
291 def _generatefiles(self, suffix='', group=gengroupall): |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
292 # 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
|
293 any = False |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
294 for id, entry in sorted(self._filegenerators.iteritems()): |
23357
ba033f461f00
transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23356
diff
changeset
|
295 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
|
296 order, filenames, genfunc, location = entry |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
297 |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
298 # for generation at closing, check if it's before or after finalize |
29297
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
299 postfinalize = group == gengrouppostfinalize |
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
300 if (group != gengroupall and |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
301 (id in postfinalizegenerators) != (postfinalize)): |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
302 continue |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
303 |
23317
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
304 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
|
305 files = [] |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
306 try: |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
307 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
|
308 name += suffix |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
309 if suffix: |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
310 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
|
311 else: |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
312 self.addbackup(name, location=location) |
29299
76b07a5c064b
transaction: avoid ambiguity of file stat at closing transaction
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29297
diff
changeset
|
313 files.append(vfs(name, 'w', atomictemp=True, |
76b07a5c064b
transaction: avoid ambiguity of file stat at closing transaction
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29297
diff
changeset
|
314 checkambig=not suffix)) |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
315 genfunc(*files) |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
316 finally: |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
317 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
|
318 f.close() |
23357
ba033f461f00
transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23356
diff
changeset
|
319 return any |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
320 |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
321 @active |
2084 | 322 def find(self, file): |
323 if file in self.map: | |
324 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
|
325 if file in self._backupmap: |
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
326 return self._backupentries[self._backupmap[file]] |
2084 | 327 return None |
328 | |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
329 @active |
2084 | 330 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
|
331 ''' |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
332 replace can only replace already committed entries |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
333 that are not pending in the queue |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
334 ''' |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
335 |
2084 | 336 if file not in self.map: |
337 raise KeyError(file) | |
338 index = self.map[file] | |
339 self.entries[index] = (file, offset, data) | |
340 self.file.write("%s\0%d\n" % (file, offset)) | |
341 self.file.flush() | |
342 | |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
343 @active |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
344 def nest(self): |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
345 self.count += 1 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
346 self.usages += 1 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
347 return self |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
348 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
349 def release(self): |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
350 if self.count > 0: |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
351 self.usages -= 1 |
11685 | 352 # 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
|
353 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
|
354 self._abort() |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
355 |
27862
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
356 def __enter__(self): |
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
357 return self |
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
358 |
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
359 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
|
360 try: |
24361fb68cba
transaction: abort transaction during hook exception
Durham Goode <durham@fb.com>
parents:
27862
diff
changeset
|
361 if exc_type is None: |
24361fb68cba
transaction: abort transaction during hook exception
Durham Goode <durham@fb.com>
parents:
27862
diff
changeset
|
362 self.close() |
24361fb68cba
transaction: abort transaction during hook exception
Durham Goode <durham@fb.com>
parents:
27862
diff
changeset
|
363 finally: |
24361fb68cba
transaction: abort transaction during hook exception
Durham Goode <durham@fb.com>
parents:
27862
diff
changeset
|
364 self.release() |
27862
b2145c195f24
transaction: turn a transaction into a Python context manager
Bryan O'Sullivan <bryano@fb.com>
parents:
27662
diff
changeset
|
365 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
366 def running(self): |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
367 return self.count > 0 |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
368 |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
369 def addpending(self, category, callback): |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
370 """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
|
371 |
23280
b01c491af0cf
transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23279
diff
changeset
|
372 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
|
373 |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
374 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
|
375 with a newer callback. |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
376 """ |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
377 self._pendingcallback[category] = callback |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
378 |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
379 @active |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
380 def writepending(self): |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
381 '''write pending file to temporary version |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
382 |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
383 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
|
384 categories = sorted(self._pendingcallback) |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
385 for cat in categories: |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
386 # 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
|
387 any = self._pendingcallback.pop(cat)(self) |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
388 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
|
389 self._anypending |= self._generatefiles(suffix='.pending') |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
390 return self._anypending |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
391 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
392 @active |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
393 def addfinalize(self, category, callback): |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
394 """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
|
395 |
23281
f60ed8cf4afc
transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23280
diff
changeset
|
396 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
|
397 |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
398 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
|
399 newer callbacks. |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
400 """ |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
401 self._finalizecallback[category] = callback |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
402 |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
403 @active |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
404 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
|
405 """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
|
406 |
23282
6c1351352b6c
transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23281
diff
changeset
|
407 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
|
408 |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
409 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
|
410 with a newer callback. |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
411 """ |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
412 self._postclosecallback[category] = callback |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
413 |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
414 @active |
23764
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
415 def addabort(self, category, callback): |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
416 """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
|
417 |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
418 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
|
419 |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
420 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
|
421 with a newer callback. |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
422 """ |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
423 self._abortcallback[category] = callback |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
424 |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
425 @active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
426 def close(self): |
9220
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
427 '''commit the transaction''' |
23290
59513ec76748
transaction: always generate file on close
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23283
diff
changeset
|
428 if self.count == 1: |
24283
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
429 self.validator(self) # will raise exception if needed |
29297
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
430 self._generatefiles(group=gengroupprefinalize) |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
431 categories = sorted(self._finalizecallback) |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
432 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
|
433 self._finalizecallback[cat](self) |
28960
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
434 # Prevent double usage and help clear cycles. |
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
435 self._finalizecallback = None |
29297
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
436 self._generatefiles(group=gengrouppostfinalize) |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
437 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
438 self.count -= 1 |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
439 if self.count != 0: |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
440 return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
441 self.file.close() |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
442 self._backupsfile.close() |
23291
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
443 # cleanup temporary files |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
444 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
|
445 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
|
446 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
|
447 % (b, l)) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
448 continue |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
449 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
|
450 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
|
451 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
452 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
|
453 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
|
454 if not c: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
455 raise |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
456 # 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
|
457 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
|
458 % (vfs.join(b), inst)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
459 self.entries = [] |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
460 self._writeundo() |
95 | 461 if self.after: |
785 | 462 self.after() |
26753
96dd93de548c
transaction: reorder unlinking .hg/journal and .hg/journal.backupfiles
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
26587
diff
changeset
|
463 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
|
464 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
|
465 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
|
466 self.opener.unlink(self.journal) |
27662
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
467 for l, _f, b, c in self._backupentries: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
468 if l not in self._vfsmap and c: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
469 self.report("couldn't remove %s: unknown cache location" |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
470 "%s\n" % (b, l)) |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
471 continue |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
472 vfs = self._vfsmap[l] |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
473 if b and vfs.exists(b): |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
474 try: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
475 vfs.unlink(b) |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
476 except (IOError, OSError, error.Abort) as inst: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
477 if not c: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
478 raise |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
479 # Abort may be raise by read only opener |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
480 self.report("couldn't remove %s: %s\n" |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
481 % (vfs.join(b), inst)) |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
482 self._backupentries = [] |
573 | 483 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
|
484 |
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
485 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
|
486 |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
487 # run post close action |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
488 categories = sorted(self._postclosecallback) |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
489 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
|
490 self._postclosecallback[cat](self) |
28960
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
491 # Prevent double usage and help clear cycles. |
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
492 self._postclosecallback = None |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
493 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
494 @active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
495 def abort(self): |
9220
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
496 '''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
|
497 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
|
498 scope)''' |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
499 self._abort() |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
500 |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
501 def _writeundo(self): |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
502 """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
|
503 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
|
504 return |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
505 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
|
506 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
|
507 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
|
508 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
|
509 continue |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
510 if not b: |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
511 u = '' |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
512 else: |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
513 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
|
514 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
|
515 "%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
|
516 continue |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
517 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
|
518 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
|
519 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
|
520 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
|
521 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
|
522 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
|
523 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
|
524 undobackupfile.close() |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
525 |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
526 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
527 def _abort(self): |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
528 self.count = 0 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
529 self.usages = 0 |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
530 self.file.close() |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
531 self._backupsfile.close() |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
532 |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
533 try: |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
534 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
|
535 if self._backupjournal: |
96dd93de548c
transaction: reorder unlinking .hg/journal and .hg/journal.backupfiles
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
26587
diff
changeset
|
536 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
|
537 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
|
538 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
|
539 return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
540 |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
541 self.report(_("transaction abort!\n")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
542 |
108 | 543 try: |
23764
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
544 for cat in sorted(self._abortcallback): |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
545 self._abortcallback[cat](self) |
28960
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
546 # Prevent double usage and help clear cycles. |
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
547 self._abortcallback = None |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
548 _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
|
549 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
|
550 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
|
551 except BaseException: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
552 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
|
553 finally: |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
554 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
|
555 self.releasefn(self, False) # notify failure of transaction |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
556 |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
557 def rollback(opener, vfsmap, file, report): |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
558 """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
|
559 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
560 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
|
561 '*.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
|
562 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
563 * `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
|
564 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
|
565 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
|
566 '*.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
|
567 pairs, delimited by \0. |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
568 """ |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
569 entries = [] |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
570 backupentries = [] |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
571 |
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
|
572 fp = opener.open(file) |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
573 lines = fp.readlines() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
574 fp.close() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
575 for l in lines: |
20524
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
576 try: |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
577 f, o = l.split('\0') |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
578 entries.append((f, int(o), None)) |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
579 except ValueError: |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
580 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
|
581 |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
582 backupjournal = "%s.backupfiles" % file |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
583 if opener.exists(backupjournal): |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
584 fp = opener.open(backupjournal) |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
585 lines = fp.readlines() |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
586 if lines: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
587 ver = lines[0][:-1] |
23064
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
588 if ver == str(version): |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
589 for line in lines[1:]: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
590 if line: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
591 # Shave off the trailing newline |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
592 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
|
593 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
|
594 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
|
595 else: |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
596 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
|
597 "Mercurial\n")) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
598 |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
599 _playback(file, report, opener, vfsmap, entries, backupentries) |