Mercurial > hg
annotate mercurial/transaction.py @ 40626:87a872555e90
revlog: detect incomplete revlog reads
_readsegment() is supposed to return N bytes of revlog revision
data starting at a file offset. Surprisingly, its behavior before
this patch never verified that it actually read and returned N
bytes! Instead, it would perform the read(), then return whatever
data was available. And even more surprisingly, nothing in the
call chain appears to have been validating that it received all
the data it was expecting.
This behavior could lead to partial or incomplete revision chunks
being operated on. This could result in e.g. cached deltas being
applied against incomplete base revisions. The delta application
process would happily perform this operation. Only hash
verification would detect the corruption and save us.
This commit changes the behavior of raw revlog reading to validate
that we actually read() the number of bytes that were requested.
We will raise a more specific error faster, rather than possibly
have it go undetected or manifest later in the call stack, at
delta application or hash verification.
Differential Revision: https://phab.mercurial-scm.org/D5266
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 13 Nov 2018 12:30:59 -0800 |
parents | aca09df32819 |
children | 3e2c02836420 |
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, |
36735
ef345f9e4295
transaction: fix an error string with bytestr() on a repr()d value
Augie Fackler <augie@google.com>
parents:
35832
diff
changeset
|
21 pycompat, |
25986
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
22 util, |
89049011f304
transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25660
diff
changeset
|
23 ) |
40579
aca09df32819
transaction: display data about why the transaction failed to rollback
Boris Feld <boris.feld@octobus.net>
parents:
39686
diff
changeset
|
24 from .utils import ( |
aca09df32819
transaction: display data about why the transaction failed to rollback
Boris Feld <boris.feld@octobus.net>
parents:
39686
diff
changeset
|
25 stringutil, |
aca09df32819
transaction: display data about why the transaction failed to rollback
Boris Feld <boris.feld@octobus.net>
parents:
39686
diff
changeset
|
26 ) |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
27 |
23313
991098579940
transaction: set backupentries version to proper value
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23312
diff
changeset
|
28 version = 2 |
23064
5dc888b79e70
transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents:
23063
diff
changeset
|
29 |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
30 # 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
|
31 # 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
|
32 # the changelog having been written). |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
32261
diff
changeset
|
33 postfinalizegenerators = { |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
34 'bookmarks', |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
35 'dirstate' |
32291
bd872f64a8ba
cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents:
32261
diff
changeset
|
36 } |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
37 |
29297
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
38 gengroupall='all' |
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
39 gengroupprefinalize='prefinalize' |
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
40 gengrouppostfinalize='postfinalize' |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
41 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
42 def active(func): |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
43 def _active(self, *args, **kwds): |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
44 if self._count == 0: |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
45 raise error.Abort(_( |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
46 '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
|
47 return func(self, *args, **kwds) |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
48 return _active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
49 |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
50 def _playback(journal, report, opener, vfsmap, entries, backupentries, |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
51 unlink=True, checkambigfiles=None): |
22204
f8dc6599da5d
cleanup: name unused variables using convention of leading _
Mads Kiilerich <madski@unity3d.com>
parents:
22199
diff
changeset
|
52 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
|
53 if o or not unlink: |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
54 checkambig = checkambigfiles and (f, '') in checkambigfiles |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
55 try: |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
56 fp = opener(f, 'a', checkambig=checkambig) |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
57 fp.truncate(o) |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
58 fp.close() |
9686
ddf2adf88b89
transaction: more specific exceptions, os.unlink can raise OSError
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9220
diff
changeset
|
59 except IOError: |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
60 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
|
61 raise |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
62 else: |
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
63 try: |
20084
a3378a1b0a05
transaction: unlink target file via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
17424
diff
changeset
|
64 opener.unlink(f) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25658
diff
changeset
|
65 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
|
66 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
|
67 raise |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
68 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
69 backupfiles = [] |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
70 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
|
71 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
|
72 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
|
73 % (b, l)) |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
74 vfs = vfsmap[l] |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
75 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
76 if f and b: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
77 filepath = vfs.join(f) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
78 backuppath = vfs.join(b) |
33279
7912404b70f2
transaction: apply checkambig=True only on limited files for similarity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33278
diff
changeset
|
79 checkambig = checkambigfiles and (f, l) in checkambigfiles |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
80 try: |
33279
7912404b70f2
transaction: apply checkambig=True only on limited files for similarity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33278
diff
changeset
|
81 util.copyfile(backuppath, filepath, checkambig=checkambig) |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
82 backupfiles.append(b) |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
83 except IOError: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
84 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
|
85 else: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
86 target = f or b |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
87 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
88 vfs.unlink(target) |
25660
328739ea70c3
global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25658
diff
changeset
|
89 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
|
90 if inst.errno != errno.ENOENT: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
91 raise |
26587
56b2bcea2529
error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
26576
diff
changeset
|
92 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
|
93 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
|
94 raise |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
95 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
96 backuppath = "%s.backupfiles" % journal |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
97 if opener.exists(backuppath): |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
98 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
|
99 opener.unlink(journal) |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
100 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
101 for f in backupfiles: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
102 if opener.exists(f): |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
103 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
|
104 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
|
105 # 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
|
106 pass |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
107 |
33793
bbbbd3c30bfc
util: add base class for transactional context managers
Martin von Zweigbergk <martinvonz@google.com>
parents:
33279
diff
changeset
|
108 class transaction(util.transactional): |
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
|
109 def __init__(self, report, opener, vfsmap, journalname, undoname=None, |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
110 after=None, createmode=None, validator=None, releasefn=None, |
36819
aff5996f3043
transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
36735
diff
changeset
|
111 checkambigfiles=None, name=r'<unnamed>'): |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
112 """Begin a new transaction |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
113 |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
114 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
|
115 an exception. |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
116 |
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
117 * `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
|
118 * `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
|
119 * `releasefn`: called after releasing (with transaction and result) |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
120 |
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
121 `checkambigfiles` is a set of (path, vfs-location) tuples, |
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
122 which determine whether file stat ambiguity should be avoided |
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
123 for corresponded files. |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
124 """ |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
125 self._count = 1 |
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
126 self._usages = 1 |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
127 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
|
128 # a vfs to the store content |
39682
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
129 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
|
130 # 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
|
131 vfsmap = vfsmap.copy() |
5bd1f6572db0
transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23309
diff
changeset
|
132 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
|
133 self._vfsmap = vfsmap |
39681
0d7b9db85675
transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39680
diff
changeset
|
134 self._after = after |
39686
3d22aef3ecd5
transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39685
diff
changeset
|
135 self._entries = [] |
39684
1a68c9b1920d
transaction: make map a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39683
diff
changeset
|
136 self._map = {} |
39676
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
137 self._journal = journalname |
39675
da9ce63bfa9b
transaction: make undoname a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39674
diff
changeset
|
138 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
|
139 self._queue = [] |
24283
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
140 # 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
|
141 # 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
|
142 # target user is repository hooks. |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
143 if validator is None: |
ef22cfff7052
transaction: add a validation stage
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23904
diff
changeset
|
144 validator = lambda tr: None |
39679
ebbba3ba3f66
transaction: make validator a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39678
diff
changeset
|
145 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
|
146 # 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
|
147 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
|
148 releasefn = lambda tr, success: None |
39678
040007cd3d81
transaction: make releasefn a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39677
diff
changeset
|
149 self._releasefn = releasefn |
26576
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
150 |
39680
264d56954dda
transaction: make checkambigfiles a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39679
diff
changeset
|
151 self._checkambigfiles = set() |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
152 if checkambigfiles: |
39680
264d56954dda
transaction: make checkambigfiles a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39679
diff
changeset
|
153 self._checkambigfiles.update(checkambigfiles) |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
154 |
39685
4024c363cd33
transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39684
diff
changeset
|
155 self._names = [name] |
36819
aff5996f3043
transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
36735
diff
changeset
|
156 |
32261
976681123416
transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31648
diff
changeset
|
157 # A dict dedicated to precisely tracking the changes introduced in the |
976681123416
transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31648
diff
changeset
|
158 # transaction. |
976681123416
transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31648
diff
changeset
|
159 self.changes = {} |
976681123416
transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
31648
diff
changeset
|
160 |
23279
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
161 # 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
|
162 self.hookargs = {} |
39677
d27fde3e023e
transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39676
diff
changeset
|
163 self._file = opener.open(self._journal, "w") |
23279
e245775f8fd3
transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23278
diff
changeset
|
164 |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
165 # 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
|
166 # - 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
|
167 # - 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
|
168 # - 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
|
169 # 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
|
170 # (cache is currently unused) |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
171 self._backupentries = [] |
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
172 self._backupmap = {} |
39676
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
173 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
|
174 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
|
175 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
|
176 |
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
|
177 if createmode is not None: |
39676
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
178 opener.chmod(self._journal, createmode & 0o666) |
25658
e93036747902
global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25302
diff
changeset
|
179 opener.chmod(self._backupjournal, createmode & 0o666) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
180 |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
181 # 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
|
182 self._filegenerators = {} |
23543
4dd8a6a1240d
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
23513
diff
changeset
|
183 # 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
|
184 self._pendingcallback = {} |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
185 # 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
|
186 self._anypending = False |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
187 # 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
|
188 self._finalizecallback = {} |
23543
4dd8a6a1240d
spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents:
23513
diff
changeset
|
189 # 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
|
190 self._postclosecallback = {} |
23764
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
191 # holds callbacks to call during abort |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
192 self._abortcallback = {} |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
193 |
36819
aff5996f3043
transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
36735
diff
changeset
|
194 def __repr__(self): |
39685
4024c363cd33
transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39684
diff
changeset
|
195 name = r'/'.join(self._names) |
36819
aff5996f3043
transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
36735
diff
changeset
|
196 return (r'<transaction name=%s, count=%d, usages=%d>' % |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
197 (name, self._count, self._usages)) |
36819
aff5996f3043
transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
36735
diff
changeset
|
198 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
199 def __del__(self): |
39676
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
200 if self._journal: |
9693
c40a1ee20aa5
transaction: always remove empty journal on abort
Sune Foldager <cryo@cyanite.org>
parents:
9686
diff
changeset
|
201 self._abort() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
202 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
203 @active |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
204 def startgroup(self): |
23250
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
205 """delay registration of file entry |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
206 |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
207 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
|
208 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
|
209 self._queue.append([]) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
210 |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
211 @active |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
212 def endgroup(self): |
23250
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
213 """apply delayed registration of file entry. |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
214 |
8919dc7f2dbb
transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23249
diff
changeset
|
215 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
|
216 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
|
217 q = self._queue.pop() |
23253
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
218 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
|
219 self._addentry(f, o, data) |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
220 |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
221 @active |
2084 | 222 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
|
223 """record the state of an append-only file before update""" |
39684
1a68c9b1920d
transaction: make map a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39683
diff
changeset
|
224 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
|
225 return |
8363
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
226 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
|
227 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
|
228 return |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
229 |
23253
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
230 self._addentry(file, offset, data) |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
231 |
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
232 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
|
233 """add a append-only entry to memory and on-disk state""" |
39684
1a68c9b1920d
transaction: make map a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39683
diff
changeset
|
234 if file in self._map or file in self._backupmap: |
23253
8d84b7a2dd91
transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23252
diff
changeset
|
235 return |
39686
3d22aef3ecd5
transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39685
diff
changeset
|
236 self._entries.append((file, offset, data)) |
3d22aef3ecd5
transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39685
diff
changeset
|
237 self._map[file] = len(self._entries) - 1 |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
238 # add enough data to the journal to do the truncate |
39677
d27fde3e023e
transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39676
diff
changeset
|
239 self._file.write("%s\0%d\n" % (file, offset)) |
d27fde3e023e
transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39676
diff
changeset
|
240 self._file.flush() |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
241 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
242 @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
|
243 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
|
244 """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
|
245 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
246 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
|
247 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
|
248 aborting. |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
249 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
250 * `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
|
251 * `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
|
252 """ |
23251
85c634ff395a
transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23250
diff
changeset
|
253 if self._queue: |
85c634ff395a
transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23250
diff
changeset
|
254 msg = 'cannot use transaction.addbackup inside "group"' |
31648 | 255 raise error.ProgrammingError(msg) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
256 |
39684
1a68c9b1920d
transaction: make map a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39683
diff
changeset
|
257 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
|
258 return |
23582
7559dc8c4238
vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23581
diff
changeset
|
259 vfs = self._vfsmap[location] |
7559dc8c4238
vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23581
diff
changeset
|
260 dirname, filename = vfs.split(file) |
39676
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
261 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
|
262 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
|
263 if vfs.exists(file): |
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
264 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
|
265 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
|
266 util.copyfile(filepath, backuppath, hardlink=hardlink) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
267 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
|
268 backupfile = '' |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
269 |
23316
fc3670f41d3e
transaction: use 'location' instead of 'vfs' in the addbackup method
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23315
diff
changeset
|
270 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
|
271 |
b04263c38a92
transaction: extract backupentry registration in a dedicated function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23282
diff
changeset
|
272 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
|
273 """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
|
274 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
|
275 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
|
276 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
|
277 self._backupsfile.flush() |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
278 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
279 @active |
23354
918c77775df6
transaction: accept a 'location' argument for registertmp
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23318
diff
changeset
|
280 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
|
281 """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
|
282 |
23355
7faa55c20b0e
transaction: fix some docstring grammar
Matt Mackall <mpm@selenic.com>
parents:
23354
diff
changeset
|
283 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
|
284 failure and success). |
23291
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
285 """ |
23354
918c77775df6
transaction: accept a 'location' argument for registertmp
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23318
diff
changeset
|
286 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
|
287 |
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
288 @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
|
289 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
|
290 location=''): |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
291 """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
|
292 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
293 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
|
294 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
|
295 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
296 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
|
297 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
|
298 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
299 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
|
300 final write of such file. |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
301 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
302 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
|
303 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
|
304 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
|
305 |
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
306 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
|
307 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
|
308 |
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
309 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
|
310 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
|
311 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
|
312 """ |
22663
4c6198737ad8
transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22662
diff
changeset
|
313 # 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
|
314 # 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
|
315 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
|
316 |
33056
2312e70cf78b
rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents:
32558
diff
changeset
|
317 @active |
2312e70cf78b
rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents:
32558
diff
changeset
|
318 def removefilegenerator(self, genid): |
2312e70cf78b
rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents:
32558
diff
changeset
|
319 """reverse of addfilegenerator, remove a file generator function""" |
2312e70cf78b
rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents:
32558
diff
changeset
|
320 if genid in self._filegenerators: |
2312e70cf78b
rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents:
32558
diff
changeset
|
321 del self._filegenerators[genid] |
2312e70cf78b
rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents:
32558
diff
changeset
|
322 |
29297
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
323 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
|
324 # 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
|
325 any = False |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
326 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
|
327 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
|
328 order, filenames, genfunc, location = entry |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
329 |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
330 # 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
|
331 postfinalize = group == gengrouppostfinalize |
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
332 if (group != gengroupall and |
28830
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
333 (id in postfinalizegenerators) != (postfinalize)): |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
334 continue |
a5009789960c
transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents:
27924
diff
changeset
|
335 |
23317
197e17be5407
transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23316
diff
changeset
|
336 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
|
337 files = [] |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
338 try: |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
339 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
|
340 name += suffix |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
341 if suffix: |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
342 self.registertmp(name, location=location) |
33279
7912404b70f2
transaction: apply checkambig=True only on limited files for similarity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33278
diff
changeset
|
343 checkambig = False |
23356
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
344 else: |
140c21fbf4eb
transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23355
diff
changeset
|
345 self.addbackup(name, location=location) |
39680
264d56954dda
transaction: make checkambigfiles a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39679
diff
changeset
|
346 checkambig = (name, location) in self._checkambigfiles |
29299
76b07a5c064b
transaction: avoid ambiguity of file stat at closing transaction
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29297
diff
changeset
|
347 files.append(vfs(name, 'w', atomictemp=True, |
33279
7912404b70f2
transaction: apply checkambig=True only on limited files for similarity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33278
diff
changeset
|
348 checkambig=checkambig)) |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
349 genfunc(*files) |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
350 finally: |
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
351 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
|
352 f.close() |
23357
ba033f461f00
transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23356
diff
changeset
|
353 return any |
23102
16da812ad970
transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23065
diff
changeset
|
354 |
22078
feb4797c676e
transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
22077
diff
changeset
|
355 @active |
2084 | 356 def find(self, file): |
39684
1a68c9b1920d
transaction: make map a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39683
diff
changeset
|
357 if file in self._map: |
39686
3d22aef3ecd5
transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39685
diff
changeset
|
358 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
|
359 if file in self._backupmap: |
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
360 return self._backupentries[self._backupmap[file]] |
2084 | 361 return None |
362 | |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
363 @active |
2084 | 364 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
|
365 ''' |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
366 replace can only replace already committed entries |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
367 that are not pending in the queue |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
368 ''' |
c8e81f557da7
transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents:
8294
diff
changeset
|
369 |
39684
1a68c9b1920d
transaction: make map a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39683
diff
changeset
|
370 if file not in self._map: |
2084 | 371 raise KeyError(file) |
39684
1a68c9b1920d
transaction: make map a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39683
diff
changeset
|
372 index = self._map[file] |
39686
3d22aef3ecd5
transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39685
diff
changeset
|
373 self._entries[index] = (file, offset, data) |
39677
d27fde3e023e
transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39676
diff
changeset
|
374 self._file.write("%s\0%d\n" % (file, offset)) |
d27fde3e023e
transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39676
diff
changeset
|
375 self._file.flush() |
2084 | 376 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
377 @active |
36819
aff5996f3043
transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents:
36735
diff
changeset
|
378 def nest(self, name=r'<unnamed>'): |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
379 self._count += 1 |
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
380 self._usages += 1 |
39685
4024c363cd33
transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39684
diff
changeset
|
381 self._names.append(name) |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
382 return self |
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
383 |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
384 def release(self): |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
385 if self._count > 0: |
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
386 self._usages -= 1 |
39685
4024c363cd33
transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39684
diff
changeset
|
387 if self._names: |
4024c363cd33
transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39684
diff
changeset
|
388 self._names.pop() |
11685 | 389 # if the transaction scopes are left without being closed, fail |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
390 if self._count > 0 and self._usages == 0: |
11230
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
391 self._abort() |
5116a077c3da
make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents:
10282
diff
changeset
|
392 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
393 def running(self): |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
394 return self._count > 0 |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
395 |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
396 def addpending(self, category, callback): |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
397 """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
|
398 |
23280
b01c491af0cf
transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23279
diff
changeset
|
399 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
|
400 |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
401 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
|
402 with a newer callback. |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
403 """ |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
404 self._pendingcallback[category] = callback |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
405 |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
406 @active |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
407 def writepending(self): |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
408 '''write pending file to temporary version |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
409 |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
410 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
|
411 categories = sorted(self._pendingcallback) |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
412 for cat in categories: |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
413 # 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
|
414 any = self._pendingcallback.pop(cat)(self) |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
415 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
|
416 self._anypending |= self._generatefiles(suffix='.pending') |
23202
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
417 return self._anypending |
ea5af863fbff
transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23103
diff
changeset
|
418 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
419 @active |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
420 def addfinalize(self, category, callback): |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
421 """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
|
422 |
23281
f60ed8cf4afc
transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23280
diff
changeset
|
423 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
|
424 |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
425 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
|
426 newer callbacks. |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
427 """ |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
428 self._finalizecallback[category] = callback |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
429 |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
430 @active |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
431 def addpostclose(self, category, callback): |
33087
fcd1c483f5ea
strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents:
33056
diff
changeset
|
432 """add or replace a callback to be called after the transaction closed |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
433 |
23282
6c1351352b6c
transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23281
diff
changeset
|
434 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
|
435 |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
436 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
|
437 with a newer callback. |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
438 """ |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
439 self._postclosecallback[category] = callback |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
440 |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
441 @active |
33087
fcd1c483f5ea
strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents:
33056
diff
changeset
|
442 def getpostclose(self, category): |
fcd1c483f5ea
strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents:
33056
diff
changeset
|
443 """return a postclose callback added before, or None""" |
fcd1c483f5ea
strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents:
33056
diff
changeset
|
444 return self._postclosecallback.get(category, None) |
fcd1c483f5ea
strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents:
33056
diff
changeset
|
445 |
fcd1c483f5ea
strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents:
33056
diff
changeset
|
446 @active |
23764
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
447 def addabort(self, category, callback): |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
448 """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
|
449 |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
450 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
|
451 |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
452 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
|
453 with a newer callback. |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
454 """ |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
455 self._abortcallback[category] = callback |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
456 |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
457 @active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
458 def close(self): |
9220
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
459 '''commit the transaction''' |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
460 if self._count == 1: |
39679
ebbba3ba3f66
transaction: make validator a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39678
diff
changeset
|
461 self._validator(self) # will raise exception if needed |
ebbba3ba3f66
transaction: make validator a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39678
diff
changeset
|
462 self._validator = None # Help prevent cycles. |
29297
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
463 self._generatefiles(group=gengroupprefinalize) |
23204
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
464 categories = sorted(self._finalizecallback) |
10beda5bd2b7
transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23202
diff
changeset
|
465 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
|
466 self._finalizecallback[cat](self) |
28960
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
467 # Prevent double usage and help clear cycles. |
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
468 self._finalizecallback = None |
29297
50fef8252820
style: remove namespace class
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
29296
diff
changeset
|
469 self._generatefiles(group=gengrouppostfinalize) |
20881
3c47677a8d04
transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents:
20524
diff
changeset
|
470 |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
471 self._count -= 1 |
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
472 if self._count != 0: |
1806
a2c69737e65e
Automatic nesting into running transactions in the same repository.
mason@suse.com
parents:
1559
diff
changeset
|
473 return |
39677
d27fde3e023e
transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39676
diff
changeset
|
474 self._file.close() |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
475 self._backupsfile.close() |
23291
03d2d6931836
transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23290
diff
changeset
|
476 # cleanup temporary files |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
477 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
|
478 if l not in self._vfsmap and c: |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
479 self._report("couldn't remove %s: unknown cache location %s\n" |
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
480 % (b, l)) |
23312
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
481 continue |
23311
64ab33ffba14
transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23310
diff
changeset
|
482 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
|
483 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
|
484 try: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
485 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
|
486 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
|
487 if not c: |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
488 raise |
006e9ef05c31
transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23311
diff
changeset
|
489 # Abort may be raise by read only opener |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
490 self._report("couldn't remove %s: %s\n" |
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
491 % (vfs.join(b), inst)) |
39686
3d22aef3ecd5
transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39685
diff
changeset
|
492 self._entries = [] |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
493 self._writeundo() |
39681
0d7b9db85675
transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39680
diff
changeset
|
494 if self._after: |
0d7b9db85675
transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39680
diff
changeset
|
495 self._after() |
0d7b9db85675
transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39680
diff
changeset
|
496 self._after = None # Help prevent cycles. |
39682
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
497 if self._opener.isfile(self._backupjournal): |
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
498 self._opener.unlink(self._backupjournal) |
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
499 if self._opener.isfile(self._journal): |
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
500 self._opener.unlink(self._journal) |
27662
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
501 for l, _f, b, c in self._backupentries: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
502 if l not in self._vfsmap and c: |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
503 self._report("couldn't remove %s: unknown cache location" |
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
504 "%s\n" % (b, l)) |
27662
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
505 continue |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
506 vfs = self._vfsmap[l] |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
507 if b and vfs.exists(b): |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
508 try: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
509 vfs.unlink(b) |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
510 except (IOError, OSError, error.Abort) as inst: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
511 if not c: |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
512 raise |
f7ab50c721ac
transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents:
26754
diff
changeset
|
513 # Abort may be raise by read only opener |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
514 self._report("couldn't remove %s: %s\n" |
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
515 % (vfs.join(b), inst)) |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
516 self._backupentries = [] |
39676
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
517 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
|
518 |
39678
040007cd3d81
transaction: make releasefn a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39677
diff
changeset
|
519 self._releasefn(self, True) # notify success of closing transaction |
040007cd3d81
transaction: make releasefn a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39677
diff
changeset
|
520 self._releasefn = None # Help prevent cycles. |
26576
9e0aaac0d9eb
transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
25986
diff
changeset
|
521 |
23220
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
522 # run post close action |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
523 categories = sorted(self._postclosecallback) |
3f543f6be500
transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23204
diff
changeset
|
524 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
|
525 self._postclosecallback[cat](self) |
28960
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
526 # Prevent double usage and help clear cycles. |
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
527 self._postclosecallback = None |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
528 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
529 @active |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
530 def abort(self): |
9220
8a4da1388553
transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents:
9094
diff
changeset
|
531 '''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
|
532 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
|
533 scope)''' |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
534 self._abort() |
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
535 |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
536 def _writeundo(self): |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
537 """write transaction data for possible future undo call""" |
39675
da9ce63bfa9b
transaction: make undoname a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39674
diff
changeset
|
538 if self._undoname is None: |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
539 return |
39682
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
540 undobackupfile = self._opener.open("%s.backupfiles" % self._undoname, |
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
541 'w') |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
542 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
|
543 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
|
544 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
|
545 continue |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
546 if not b: |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
547 u = '' |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
548 else: |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
549 if l not in self._vfsmap and c: |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
550 self._report("couldn't remove %s: unknown cache location" |
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
551 "%s\n" % (b, l)) |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
552 continue |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
553 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
|
554 base, name = vfs.split(b) |
39676
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
555 assert name.startswith(self._journal), name |
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
556 uname = name.replace(self._journal, self._undoname, 1) |
23904
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
557 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
|
558 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
|
559 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
|
560 undobackupfile.close() |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
561 |
d251da5e0e84
transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23903
diff
changeset
|
562 |
8289
fe8a3e56039f
transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents:
8225
diff
changeset
|
563 def _abort(self): |
39674
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
564 self._count = 0 |
3e8952c0cb45
transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents:
36819
diff
changeset
|
565 self._usages = 0 |
39677
d27fde3e023e
transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39676
diff
changeset
|
566 self._file.close() |
23249
84720eab4fbd
transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23248
diff
changeset
|
567 self._backupsfile.close() |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
568 |
10228
056c366fea8c
transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
9693
diff
changeset
|
569 try: |
39686
3d22aef3ecd5
transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39685
diff
changeset
|
570 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
|
571 if self._backupjournal: |
39682
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
572 self._opener.unlink(self._backupjournal) |
39676
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
573 if self._journal: |
39682
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
574 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
|
575 return |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
576 |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
577 self._report(_("transaction abort!\n")) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
578 |
108 | 579 try: |
23764
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
580 for cat in sorted(self._abortcallback): |
d486e52352e8
transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents:
23727
diff
changeset
|
581 self._abortcallback[cat](self) |
28960
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
582 # Prevent double usage and help clear cycles. |
14e683d6b273
transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents:
28830
diff
changeset
|
583 self._abortcallback = None |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
584 _playback(self._journal, self._report, self._opener, |
39686
3d22aef3ecd5
transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39685
diff
changeset
|
585 self._vfsmap, self._entries, self._backupentries, |
39682
b590f4763aba
transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39681
diff
changeset
|
586 False, checkambigfiles=self._checkambigfiles) |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
587 self._report(_("rollback completed\n")) |
40579
aca09df32819
transaction: display data about why the transaction failed to rollback
Boris Feld <boris.feld@octobus.net>
parents:
39686
diff
changeset
|
588 except BaseException as exc: |
39683
337d6e0fd9c9
transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39682
diff
changeset
|
589 self._report(_("rollback failed - please run hg recover\n")) |
40579
aca09df32819
transaction: display data about why the transaction failed to rollback
Boris Feld <boris.feld@octobus.net>
parents:
39686
diff
changeset
|
590 self._report(_("(failure reason: %s)\n") |
aca09df32819
transaction: display data about why the transaction failed to rollback
Boris Feld <boris.feld@octobus.net>
parents:
39686
diff
changeset
|
591 % stringutil.forcebytestr(exc)) |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
592 finally: |
39676
77c4e2ae9f07
transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39675
diff
changeset
|
593 self._journal = None |
39678
040007cd3d81
transaction: make releasefn a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39677
diff
changeset
|
594 self._releasefn(self, False) # notify failure of transaction |
040007cd3d81
transaction: make releasefn a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents:
39677
diff
changeset
|
595 self._releasefn = None # Help prevent cycles. |
8290
560af1bbfd6e
transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents:
8289
diff
changeset
|
596 |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
597 def rollback(opener, vfsmap, file, report, checkambigfiles=None): |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
598 """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
|
599 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
600 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
|
601 '*.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
|
602 |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
603 * `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
|
604 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
|
605 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
|
606 '*.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
|
607 pairs, delimited by \0. |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
608 |
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
609 `checkambigfiles` is a set of (path, vfs-location) tuples, |
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
610 which determine whether file stat ambiguity should be avoided at |
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
611 restoring corresponded files. |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
612 """ |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
613 entries = [] |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
614 backupentries = [] |
8294
48a382c23226
transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents:
8290
diff
changeset
|
615 |
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
|
616 fp = opener.open(file) |
13400
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
617 lines = fp.readlines() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
618 fp.close() |
14f3795a5ed7
explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents:
11685
diff
changeset
|
619 for l in lines: |
20524
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
620 try: |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
621 f, o = l.split('\0') |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
622 entries.append((f, int(o), None)) |
28b8ff84db3f
journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents:
20087
diff
changeset
|
623 except ValueError: |
36735
ef345f9e4295
transaction: fix an error string with bytestr() on a repr()d value
Augie Fackler <augie@google.com>
parents:
35832
diff
changeset
|
624 report( |
ef345f9e4295
transaction: fix an error string with bytestr() on a repr()d value
Augie Fackler <augie@google.com>
parents:
35832
diff
changeset
|
625 _("couldn't read journal entry %r!\n") % pycompat.bytestr(l)) |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
626 |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
627 backupjournal = "%s.backupfiles" % file |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
628 if opener.exists(backupjournal): |
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
629 fp = opener.open(backupjournal) |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
630 lines = fp.readlines() |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
631 if lines: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
632 ver = lines[0][:-1] |
35832
aad39713ef35
transaction: fix hg version check when loading journal
Augie Fackler <augie@google.com>
parents:
33793
diff
changeset
|
633 if ver == (b'%d' % version): |
23065
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
634 for line in lines[1:]: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
635 if line: |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
636 # Shave off the trailing newline |
963f311e3a81
transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents:
23064
diff
changeset
|
637 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
|
638 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
|
639 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
|
640 else: |
23309
7eb520f5efe4
transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents:
23291
diff
changeset
|
641 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
|
642 "Mercurial\n")) |
20882
5dffd06f1e50
transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents:
20881
diff
changeset
|
643 |
33278
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
644 _playback(file, report, opener, vfsmap, entries, backupentries, |
87bca10a06ed
transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
33087
diff
changeset
|
645 checkambigfiles=checkambigfiles) |