mercurial/transaction.py
author Pierre-Yves David <pierre-yves.david@fb.com>
Wed, 12 Nov 2014 14:47:48 +0000
changeset 23318 fc73293f6060
parent 23317 197e17be5407
child 23354 918c77775df6
permissions -rw-r--r--
transaction: drop special handling for phases and bookmarks generation We are still doing double backups, but now that we have proper location handling this is less of an issue. Dropping this simplifies the code before we add some pending-related logic. This also ensures we actually test the new 'location' mechanism.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2470
diff changeset
     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
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10228
diff changeset
    12
# GNU General Public License version 2 or any later version.
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    13
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
    14
from i18n import _
23315
66275ecc73c1 addbackup: handle file in subdirectory
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23314
diff changeset
    15
import os
20886
203908968644 transaction: drop extra import caught by pyflakes
Matt Mackall <mpm@selenic.com>
parents: 20882
diff changeset
    16
import errno
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
    17
import error, util
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    18
23313
991098579940 transaction: set backupentries version to proper value
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23312
diff changeset
    19
version = 2
23064
5dc888b79e70 transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents: 23063
diff changeset
    20
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    21
def active(func):
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    22
    def _active(self, *args, **kwds):
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    23
        if self.count == 0:
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    24
            raise error.Abort(_(
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    25
                '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
    26
        return func(self, *args, **kwds)
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    27
    return _active
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    28
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
    29
def _playback(journal, report, opener, vfsmap, entries, backupentries,
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
    30
              unlink=True):
22204
f8dc6599da5d cleanup: name unused variables using convention of leading _
Mads Kiilerich <madski@unity3d.com>
parents: 22199
diff changeset
    31
    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
    32
        if o or not unlink:
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    33
            try:
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
    34
                fp = opener(f, 'a')
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
    35
                fp.truncate(o)
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
    36
                fp.close()
9686
ddf2adf88b89 transaction: more specific exceptions, os.unlink can raise OSError
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9220
diff changeset
    37
            except IOError:
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    38
                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
    39
                raise
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    40
        else:
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    41
            try:
20084
a3378a1b0a05 transaction: unlink target file via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17424
diff changeset
    42
                opener.unlink(f)
9686
ddf2adf88b89 transaction: more specific exceptions, os.unlink can raise OSError
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9220
diff changeset
    43
            except (IOError, OSError), inst:
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    44
                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
    45
                    raise
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
    46
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
    47
    backupfiles = []
23309
7eb520f5efe4 transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23291
diff changeset
    48
    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
    49
        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
    50
            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
    51
                        % (b, l))
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
    52
        vfs = vfsmap[l]
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    53
        try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    54
            if f and b:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    55
                filepath = vfs.join(f)
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    56
                backuppath = vfs.join(b)
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    57
                try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    58
                    util.copyfile(backuppath, filepath)
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    59
                    backupfiles.append(b)
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    60
                except IOError:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    61
                    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
    62
            else:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    63
                target = f or b
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    64
                try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    65
                    vfs.unlink(target)
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    66
                except (IOError, OSError), inst:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    67
                    if inst.errno != errno.ENOENT:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    68
                        raise
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    69
        except (IOError, OSError, util.Abort), inst:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    70
            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
    71
                raise
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
    72
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
    73
    opener.unlink(journal)
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
    74
    backuppath = "%s.backupfiles" % journal
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
    75
    if opener.exists(backuppath):
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
    76
        opener.unlink(backuppath)
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    77
    try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    78
        for f in backupfiles:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    79
            if opener.exists(f):
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    80
                opener.unlink(f)
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    81
    except (IOError, OSError, util.Abort), inst:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    82
        # 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
    83
        pass
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    84
1559
59b3639df0a9 Convert all classes to new-style classes by deriving them from object.
Eric Hopper <hopper@omnifarious.org>
parents: 1541
diff changeset
    85
class transaction(object):
23310
5bd1f6572db0 transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23309
diff changeset
    86
    def __init__(self, report, opener, vfsmap, journal, after=None,
5bd1f6572db0 transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23309
diff changeset
    87
                 createmode=None, onclose=None, onabort=None):
20881
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    88
        """Begin a new transaction
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    89
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    90
        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
    91
        an exception.
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    92
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    93
        * `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
    94
        * `createmode`: the mode of the journal file that will be created
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    95
        * `onclose`: called as the transaction is closing, but before it is
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    96
        closed
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    97
        * `onabort`: called as the transaction is aborting, but before any files
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    98
        have been truncated
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
    99
        """
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   100
        self.count = 1
11230
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   101
        self.usages = 1
582
df8a5a0098d4 Remove all remaining print statements
mpm@selenic.com
parents: 573
diff changeset
   102
        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
   103
        # a vfs to the store content
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   104
        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
   105
        # 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
   106
        vfsmap = vfsmap.copy()
5bd1f6572db0 transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23309
diff changeset
   107
        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
   108
        self._vfsmap = vfsmap
95
589f507bb259 Beginnings of transaction undo support
mpm@selenic.com
parents: 43
diff changeset
   109
        self.after = after
20881
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   110
        self.onclose = onclose
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   111
        self.onabort = onabort
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   112
        self.entries = []
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   113
        self.map = {}
23279
e245775f8fd3 transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23278
diff changeset
   114
        self.journal = journal
e245775f8fd3 transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23278
diff changeset
   115
        self._queue = []
e245775f8fd3 transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23278
diff changeset
   116
        # 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
   117
        self.hookargs = {}
e245775f8fd3 transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23278
diff changeset
   118
        self.file = opener.open(self.journal, "w")
e245775f8fd3 transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23278
diff changeset
   119
23309
7eb520f5efe4 transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23291
diff changeset
   120
        # 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
   121
        # - 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
   122
        # - 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
   123
        # - 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
   124
        #   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
   125
        # (cache is currently unused)
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   126
        self._backupentries = []
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   127
        self._backupmap = {}
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   128
        self._backupjournal = "%s.backupfiles" % journal
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   129
        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
   130
        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
   131
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
   132
        if createmode is not None:
20087
cf3b8285af00 transaction: take journal file path relative to vfs to use file API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20084
diff changeset
   133
            opener.chmod(self.journal, createmode & 0666)
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   134
            opener.chmod(self._backupjournal, createmode & 0666)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   135
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   136
        # 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
   137
        self._filegenerators = {}
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   138
        # hold callbalk to write pending data for hooks
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   139
        self._pendingcallback = {}
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   140
        # 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
   141
        self._anypending = False
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   142
        # 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
   143
        self._finalizecallback = {}
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   144
        # hold callbalk for post transaction close
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   145
        self._postclosecallback = {}
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   146
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   147
    def __del__(self):
558
0ceea19182a9 transaction: __del__ should do nothing if the journal already exists
mpm@selenic.com
parents: 515
diff changeset
   148
        if self.journal:
9693
c40a1ee20aa5 transaction: always remove empty journal on abort
Sune Foldager <cryo@cyanite.org>
parents: 9686
diff changeset
   149
            self._abort()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   150
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   151
    @active
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   152
    def startgroup(self):
23250
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   153
        """delay registration of file entry
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   154
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   155
        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
   156
        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
   157
        self._queue.append([])
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   158
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   159
    @active
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   160
    def endgroup(self):
23250
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   161
        """apply delayed registration of file entry.
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   162
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   163
        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
   164
        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
   165
        q = self._queue.pop()
23253
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   166
        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
   167
            self._addentry(f, o, data)
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   168
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   169
    @active
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   170
    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
   171
        """record the state of an append-only file before update"""
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   172
        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
   173
            return
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   174
        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
   175
            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
   176
            return
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   177
23253
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   178
        self._addentry(file, offset, data)
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   179
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   180
    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
   181
        """add a append-only entry to memory and on-disk state"""
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   182
        if file in self.map or file in self._backupmap:
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   183
            return
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   184
        self.entries.append((file, offset, data))
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   185
        self.map[file] = len(self.entries) - 1
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   186
        # add enough data to the journal to do the truncate
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   187
        self.file.write("%s\0%d\n" % (file, offset))
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   188
        self.file.flush()
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   189
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   190
    @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
   191
    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
   192
        """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
   193
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   194
        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
   195
        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
   196
        aborting.
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   197
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   198
        * `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
   199
        * `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
   200
        """
23251
85c634ff395a transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23250
diff changeset
   201
        if self._queue:
85c634ff395a transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23250
diff changeset
   202
            msg = 'cannot use transaction.addbackup inside "group"'
85c634ff395a transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23250
diff changeset
   203
            raise RuntimeError(msg)
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   204
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   205
        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
   206
            return
23315
66275ecc73c1 addbackup: handle file in subdirectory
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23314
diff changeset
   207
        dirname, filename = os.path.split(file)
66275ecc73c1 addbackup: handle file in subdirectory
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23314
diff changeset
   208
        backupfilename = "%s.backup.%s" % (self.journal, filename)
66275ecc73c1 addbackup: handle file in subdirectory
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23314
diff changeset
   209
        backupfile = os.path.join(dirname, backupfilename)
23316
fc3670f41d3e transaction: use 'location' instead of 'vfs' in the addbackup method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23315
diff changeset
   210
        vfs = self._vfsmap[location]
22663
4c6198737ad8 transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22662
diff changeset
   211
        if vfs.exists(file):
4c6198737ad8 transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22662
diff changeset
   212
            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
   213
            backuppath = vfs.join(backupfile)
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   214
            util.copyfiles(filepath, backuppath, hardlink=hardlink)
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   215
        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
   216
            backupfile = ''
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   217
23316
fc3670f41d3e transaction: use 'location' instead of 'vfs' in the addbackup method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23315
diff changeset
   218
        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
   219
b04263c38a92 transaction: extract backupentry registration in a dedicated function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23282
diff changeset
   220
    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
   221
        """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
   222
        self._backupentries.append(entry)
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   223
        self._backupmap[file] = 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
   224
        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
   225
        self._backupsfile.flush()
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   226
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   227
    @active
23291
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   228
    def registertmp(self, tmpfile):
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   229
        """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
   230
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   231
        Such file will be delete when the transaction exit (on both failure and
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   232
        success).
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   233
        """
23309
7eb520f5efe4 transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23291
diff changeset
   234
        self._addbackupentry(('', '', tmpfile, False))
23291
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   235
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   236
    @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
   237
    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
   238
                         location=''):
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   239
        """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
   240
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   241
        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
   242
        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
   243
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   244
        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
   245
        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
   246
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   247
        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
   248
        final write of such file.
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   249
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   250
        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
   251
        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
   252
        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
   253
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   254
        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
   255
        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
   256
197e17be5407 transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23316
diff changeset
   257
        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
   258
        outside of the the standard directory for transaction. It should match
197e17be5407 transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23316
diff changeset
   259
        one of the key of the `transaction.vfsmap` dictionnary.
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   260
        """
22663
4c6198737ad8 transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22662
diff changeset
   261
        # 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
   262
        # 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
   263
        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
   264
23102
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   265
    def _generatefiles(self):
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   266
        # write files registered for generation
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   267
        for entry in sorted(self._filegenerators.values()):
23317
197e17be5407 transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23316
diff changeset
   268
            order, filenames, genfunc, location = entry
197e17be5407 transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23316
diff changeset
   269
            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
   270
            files = []
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   271
            try:
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   272
                for name in filenames:
23318
fc73293f6060 transaction: drop special handling for phases and bookmarks generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23317
diff changeset
   273
                    self.addbackup(name, location=location)
23102
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   274
                    files.append(vfs(name, 'w', atomictemp=True))
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   275
                genfunc(*files)
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   276
            finally:
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   277
                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
   278
                    f.close()
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   279
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   280
    @active
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   281
    def find(self, file):
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   282
        if file in self.map:
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   283
            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
   284
        if file in self._backupmap:
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   285
            return self._backupentries[self._backupmap[file]]
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   286
        return None
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   287
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   288
    @active
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   289
    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
   290
        '''
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   291
        replace can only replace already committed entries
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   292
        that are not pending in the queue
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   293
        '''
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   294
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   295
        if file not in self.map:
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   296
            raise KeyError(file)
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   297
        index = self.map[file]
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   298
        self.entries[index] = (file, offset, data)
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   299
        self.file.write("%s\0%d\n" % (file, offset))
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   300
        self.file.flush()
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   301
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   302
    @active
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   303
    def nest(self):
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   304
        self.count += 1
11230
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   305
        self.usages += 1
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   306
        return self
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   307
11230
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   308
    def release(self):
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   309
        if self.count > 0:
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   310
            self.usages -= 1
11685
aade8f133d11 cleanup: typos
Patrick Mezard <pmezard@gmail.com>
parents: 11230
diff changeset
   311
        # if the transaction scopes are left without being closed, fail
11230
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   312
        if self.count > 0 and self.usages == 0:
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   313
            self._abort()
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   314
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   315
    def running(self):
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   316
        return self.count > 0
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   317
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   318
    def addpending(self, category, callback):
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   319
        """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
   320
23280
b01c491af0cf transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23279
diff changeset
   321
        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
   322
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   323
        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
   324
        with a newer callback.
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   325
        """
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   326
        self._pendingcallback[category] = callback
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   327
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   328
    @active
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   329
    def writepending(self):
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   330
        '''write pending file to temporary version
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   331
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   332
        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
   333
        categories = sorted(self._pendingcallback)
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   334
        for cat in categories:
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   335
            # 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
   336
            any = self._pendingcallback.pop(cat)(self)
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   337
            self._anypending = self._anypending or any
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   338
        return self._anypending
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   339
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   340
    @active
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   341
    def addfinalize(self, category, callback):
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   342
        """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
   343
23281
f60ed8cf4afc transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23280
diff changeset
   344
        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
   345
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   346
        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
   347
        newer callbacks.
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   348
        """
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   349
        self._finalizecallback[category] = callback
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   350
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   351
    @active
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   352
    def addpostclose(self, category, callback):
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   353
        """add a callback to be called after the transaction is closed
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   354
23282
6c1351352b6c transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
   355
        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
   356
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   357
        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
   358
        with a newer callback.
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   359
        """
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   360
        self._postclosecallback[category] = callback
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   361
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   362
    @active
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   363
    def close(self):
9220
8a4da1388553 transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents: 9094
diff changeset
   364
        '''commit the transaction'''
23290
59513ec76748 transaction: always generate file on close
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23283
diff changeset
   365
        if self.count == 1:
23103
29bfa964d6d8 transaction: only generate file when we actually close the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23102
diff changeset
   366
            self._generatefiles()
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   367
            categories = sorted(self._finalizecallback)
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   368
            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
   369
                self._finalizecallback[cat](self)
23290
59513ec76748 transaction: always generate file on close
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23283
diff changeset
   370
            if self.onclose is not None:
59513ec76748 transaction: always generate file on close
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23283
diff changeset
   371
                self.onclose()
20881
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   372
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   373
        self.count -= 1
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   374
        if self.count != 0:
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   375
            return
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   376
        self.file.close()
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   377
        self._backupsfile.close()
23291
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   378
        # cleanup temporary files
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   379
        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
   380
            if l not in self._vfsmap and c:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   381
                self.report("couldn't remote %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
   382
                            % (b, l))
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   383
                continue
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
   384
            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
   385
            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
   386
                try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   387
                    vfs.unlink(b)
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   388
                except (IOError, OSError, util.Abort), inst:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   389
                    if not c:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   390
                        raise
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   391
                    # Abort may be raise by read only opener
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   392
                    self.report("couldn't remote %s: %s\n"
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   393
                                % (vfs.join(b), inst))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   394
        self.entries = []
95
589f507bb259 Beginnings of transaction undo support
mpm@selenic.com
parents: 43
diff changeset
   395
        if self.after:
785
46a8dd3145cc Fix undo after aborted commit bug
mpm@selenic.com
parents: 582
diff changeset
   396
            self.after()
20087
cf3b8285af00 transaction: take journal file path relative to vfs to use file API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20084
diff changeset
   397
        if self.opener.isfile(self.journal):
cf3b8285af00 transaction: take journal file path relative to vfs to use file API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20084
diff changeset
   398
            self.opener.unlink(self.journal)
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   399
        if self.opener.isfile(self._backupjournal):
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   400
            self.opener.unlink(self._backupjournal)
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   401
            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
   402
                if l not in self._vfsmap and c:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   403
                    self.report("couldn't remote %s: unknown cache location"
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   404
                                "%s\n" % (b, l))
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   405
                    continue
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
   406
                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
   407
                if 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
   408
                    try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   409
                        vfs.unlink(b)
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   410
                    except (IOError, OSError, util.Abort), inst:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   411
                        if not c:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   412
                            raise
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   413
                        # Abort may be raise by read only opener
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   414
                        self.report("couldn't remote %s: %s\n"
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   415
                                    % (vfs.join(b), inst))
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   416
        self._backupentries = []
573
fbfbd4e506c3 transaction: nullify journal after close()
mpm@selenic.com
parents: 558
diff changeset
   417
        self.journal = None
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   418
        # run post close action
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   419
        categories = sorted(self._postclosecallback)
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   420
        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
   421
            self._postclosecallback[cat](self)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   422
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   423
    @active
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   424
    def abort(self):
9220
8a4da1388553 transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents: 9094
diff changeset
   425
        '''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
   426
        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
   427
        scope)'''
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   428
        self._abort()
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   429
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   430
    def _abort(self):
8290
560af1bbfd6e transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents: 8289
diff changeset
   431
        self.count = 0
11230
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   432
        self.usages = 0
8290
560af1bbfd6e transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents: 8289
diff changeset
   433
        self.file.close()
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   434
        self._backupsfile.close()
8290
560af1bbfd6e transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents: 8289
diff changeset
   435
20881
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   436
        if self.onabort is not None:
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   437
            self.onabort()
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   438
10228
056c366fea8c transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9693
diff changeset
   439
        try:
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   440
            if not self.entries and not self._backupentries:
10228
056c366fea8c transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9693
diff changeset
   441
                if self.journal:
20087
cf3b8285af00 transaction: take journal file path relative to vfs to use file API via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20084
diff changeset
   442
                    self.opener.unlink(self.journal)
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   443
                if self._backupjournal:
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   444
                    self.opener.unlink(self._backupjournal)
10228
056c366fea8c transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9693
diff changeset
   445
                return
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   446
10228
056c366fea8c transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9693
diff changeset
   447
            self.report(_("transaction abort!\n"))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   448
108
8d55c2d72c7c Warn if we fail to truncate something
mpm@selenic.com
parents: 95
diff changeset
   449
            try:
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
   450
                _playback(self.journal, self.report, self.opener, self._vfsmap,
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   451
                          self.entries, self._backupentries, False)
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   452
                self.report(_("rollback completed\n"))
16689
f366d4c2ff34 cleanup: replace naked excepts with except Exception: ...
Brodie Rao <brodie@sf.io>
parents: 13408
diff changeset
   453
            except Exception:
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   454
                self.report(_("rollback failed - please run hg recover\n"))
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   455
        finally:
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   456
            self.journal = None
8290
560af1bbfd6e transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents: 8289
diff changeset
   457
560af1bbfd6e transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents: 8289
diff changeset
   458
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
   459
def rollback(opener, vfsmap, file, report):
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   460
    """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
   461
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   462
    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
   463
    '*.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
   464
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   465
    * `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
   466
    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
   467
    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
   468
    '*.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
   469
    pairs, delimited by \0.
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   470
    """
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   471
    entries = []
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   472
    backupentries = []
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   473
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
   474
    fp = opener.open(file)
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
   475
    lines = fp.readlines()
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
   476
    fp.close()
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
   477
    for l in lines:
20524
28b8ff84db3f journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents: 20087
diff changeset
   478
        try:
28b8ff84db3f journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents: 20087
diff changeset
   479
            f, o = l.split('\0')
28b8ff84db3f journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents: 20087
diff changeset
   480
            entries.append((f, int(o), None))
28b8ff84db3f journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents: 20087
diff changeset
   481
        except ValueError:
28b8ff84db3f journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents: 20087
diff changeset
   482
            report(_("couldn't read journal entry %r!\n") % l)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   483
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   484
    backupjournal = "%s.backupfiles" % file
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   485
    if opener.exists(backupjournal):
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   486
        fp = opener.open(backupjournal)
23065
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   487
        lines = fp.readlines()
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   488
        if lines:
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   489
            ver = lines[0][:-1]
23064
5dc888b79e70 transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents: 23063
diff changeset
   490
            if ver == str(version):
23065
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   491
                for line in lines[1:]:
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   492
                    if line:
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   493
                        # Shave off the trailing newline
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   494
                        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
   495
                        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
   496
                        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
   497
            else:
23309
7eb520f5efe4 transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23291
diff changeset
   498
                report(_("journal was created by a different version of "
23064
5dc888b79e70 transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents: 23063
diff changeset
   499
                         "Mercurial"))
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   500
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
   501
    _playback(file, report, opener, vfsmap, entries, backupentries)