mercurial/transaction.py
author Raphaël Gomès <rgomes@octobus.net>
Tue, 27 Jul 2021 21:45:27 +0200
branchstable
changeset 47815 b30a53ffbf9b
parent 47422 88439c6fbafc
child 48676 3f618484eeb6
permissions -rw-r--r--
debugcommands: introduce a debug command to repair repos affected by issue6528 This command is quite basic and slow, it will loop over the entirety of the filelogs in the repository and check each revision for corruption, then fixes the affected filelogs. It takes under 25 minutes for Mozilla-Central on my not-top-of-the-line laptop, using the `--to-report` and `--from-report` options will make this pretty tolerable to use, I think. This change also introduces a test for the fix. Differential Revision: https://phab.mercurial-scm.org/D11239
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
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46063
diff changeset
     9
# Copyright 2005, 2006 Olivia Mackall <olivia@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
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
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    24
from .utils import stringutil
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    25
23313
991098579940 transaction: set backupentries version to proper value
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23312
diff changeset
    26
version = 2
23064
5dc888b79e70 transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents: 23063
diff changeset
    27
28830
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
    28
# 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
    29
# 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
    30
# the changelog having been written).
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    31
postfinalizegenerators = {b'bookmarks', b'dirstate'}
28830
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
    32
44406
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
    33
GEN_GROUP_ALL = b'all'
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
    34
GEN_GROUP_PRE_FINALIZE = b'prefinalize'
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
    35
GEN_GROUP_POST_FINALIZE = b'postfinalize'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    36
28830
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
    37
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    38
def active(func):
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    39
    def _active(self, *args, **kwds):
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
    40
        if self._count == 0:
45738
5df1655edf42 transaction: use ProgrammingError for when an committed transaction is used
Martin von Zweigbergk <martinvonz@google.com>
parents: 44543
diff changeset
    41
            raise error.ProgrammingError(
5df1655edf42 transaction: use ProgrammingError for when an committed transaction is used
Martin von Zweigbergk <martinvonz@google.com>
parents: 44543
diff changeset
    42
                b'cannot use transaction when it is already committed/aborted'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    43
            )
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    44
        return func(self, *args, **kwds)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    45
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    46
    return _active
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    47
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    48
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    49
def _playback(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    50
    journal,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    51
    report,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    52
    opener,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    53
    vfsmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    54
    entries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    55
    backupentries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    56
    unlink=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    57
    checkambigfiles=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    58
):
47286
18415fc918a1 recover: only apply last journal record per file (issue6423)
Joerg Sonnenberger <joerg@bec.de>
parents: 46819
diff changeset
    59
    for f, o in sorted(dict(entries).items()):
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    60
        if o or not unlink:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    61
            checkambig = checkambigfiles and (f, b'') in checkambigfiles
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    62
            try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    63
                fp = opener(f, b'a', checkambig=checkambig)
42963
8502f76dbfd7 transaction: detect an attempt to truncate-to-extend on playback, raise error
Kyle Lippincott <spectral@google.com>
parents: 41365
diff changeset
    64
                if fp.tell() < o:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    65
                    raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    66
                        _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    67
                            b"attempted to truncate %s to %d bytes, but it was "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    68
                            b"already %d bytes\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    69
                        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    70
                        % (f, o, fp.tell())
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    71
                    )
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
    72
                fp.truncate(o)
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
    73
                fp.close()
9686
ddf2adf88b89 transaction: more specific exceptions, os.unlink can raise OSError
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9220
diff changeset
    74
            except IOError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    75
                report(_(b"failed to truncate %s\n") % f)
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    76
                raise
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    77
        else:
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
    78
            try:
20084
a3378a1b0a05 transaction: unlink target file via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17424
diff changeset
    79
                opener.unlink(f)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
    80
            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
    81
                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
    82
                    raise
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
    83
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
    84
    backupfiles = []
23309
7eb520f5efe4 transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23291
diff changeset
    85
    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
    86
        if l not in vfsmap and c:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    87
            report(b"couldn't handle %s: unknown cache location %s\n" % (b, l))
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
    88
        vfs = vfsmap[l]
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    89
        try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    90
            if f and b:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    91
                filepath = vfs.join(f)
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
    92
                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
    93
                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
    94
                try:
33279
7912404b70f2 transaction: apply checkambig=True only on limited files for similarity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33278
diff changeset
    95
                    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
    96
                    backupfiles.append(b)
47418
22e21deed474 transaction: explain why some recovery failed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47307
diff changeset
    97
                except IOError as exc:
22e21deed474 transaction: explain why some recovery failed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47307
diff changeset
    98
                    e_msg = stringutil.forcebytestr(exc)
22e21deed474 transaction: explain why some recovery failed
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47307
diff changeset
    99
                    report(_(b"failed to recover %s (%s)\n") % (f, e_msg))
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   100
            else:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   101
                target = f or b
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   102
                try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   103
                    vfs.unlink(target)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25658
diff changeset
   104
                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
   105
                    if inst.errno != errno.ENOENT:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   106
                        raise
41365
876494fd967d cleanup: delete lots of unused local variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 41107
diff changeset
   107
        except (IOError, OSError, error.Abort):
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   108
            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
   109
                raise
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   110
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   111
    backuppath = b"%s.backupfiles" % journal
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   112
    if opener.exists(backuppath):
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   113
        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
   114
    opener.unlink(journal)
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   115
    try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   116
        for f in backupfiles:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   117
            if opener.exists(f):
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   118
                opener.unlink(f)
41365
876494fd967d cleanup: delete lots of unused local variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 41107
diff changeset
   119
    except (IOError, OSError, error.Abort):
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   120
        # 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
   121
        pass
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   122
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   123
33793
bbbbd3c30bfc util: add base class for transactional context managers
Martin von Zweigbergk <martinvonz@google.com>
parents: 33279
diff changeset
   124
class transaction(util.transactional):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   125
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   126
        self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   127
        report,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   128
        opener,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   129
        vfsmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   130
        journalname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   131
        undoname=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   132
        after=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   133
        createmode=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   134
        validator=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   135
        releasefn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   136
        checkambigfiles=None,
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   137
        name='<unnamed>',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   138
    ):
20881
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   139
        """Begin a new transaction
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   140
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   141
        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
   142
        an exception.
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   143
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   144
        * `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
   145
        * `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
   146
        * `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
   147
87bca10a06ed transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33087
diff changeset
   148
        `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
   149
        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
   150
        for corresponded files.
20881
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   151
        """
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   152
        self._count = 1
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   153
        self._usages = 1
39683
337d6e0fd9c9 transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39682
diff changeset
   154
        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
   155
        # a vfs to the store content
39682
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   156
        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
   157
        # 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
   158
        vfsmap = vfsmap.copy()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   159
        vfsmap[b''] = opener  # set default value
23310
5bd1f6572db0 transaction: pass a vfs map to the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23309
diff changeset
   160
        self._vfsmap = vfsmap
39681
0d7b9db85675 transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39680
diff changeset
   161
        self._after = after
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   162
        self._offsetmap = {}
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   163
        self._newfiles = set()
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   164
        self._journal = journalname
39675
da9ce63bfa9b transaction: make undoname a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39674
diff changeset
   165
        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
   166
        self._queue = []
26576
9e0aaac0d9eb transaction: add releasefn to notify the end of a transaction scope
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 25986
diff changeset
   167
        # 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
   168
        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
   169
            releasefn = lambda tr, success: None
39678
040007cd3d81 transaction: make releasefn a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39677
diff changeset
   170
        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
   171
39680
264d56954dda transaction: make checkambigfiles a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39679
diff changeset
   172
        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
   173
        if checkambigfiles:
39680
264d56954dda transaction: make checkambigfiles a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39679
diff changeset
   174
            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
   175
39685
4024c363cd33 transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39684
diff changeset
   176
        self._names = [name]
36819
aff5996f3043 transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 36735
diff changeset
   177
32261
976681123416 transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31648
diff changeset
   178
        # 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
   179
        # transaction.
976681123416 transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31648
diff changeset
   180
        self.changes = {}
976681123416 transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31648
diff changeset
   181
23279
e245775f8fd3 transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23278
diff changeset
   182
        # 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
   183
        self.hookargs = {}
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   184
        self._file = opener.open(self._journal, b"w+")
23279
e245775f8fd3 transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23278
diff changeset
   185
23309
7eb520f5efe4 transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23291
diff changeset
   186
        # 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
   187
        # - 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
   188
        # - 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
   189
        # - 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
   190
        #   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
   191
        # (cache is currently unused)
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   192
        self._backupentries = []
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   193
        self._backupmap = {}
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   194
        self._backupjournal = b"%s.backupfiles" % self._journal
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   195
        self._backupsfile = opener.open(self._backupjournal, b'w')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   196
        self._backupsfile.write(b'%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
   197
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
   198
        if createmode is not None:
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   199
            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
   200
            opener.chmod(self._backupjournal, createmode & 0o666)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   201
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   202
        # 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
   203
        self._filegenerators = {}
23543
4dd8a6a1240d spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23513
diff changeset
   204
        # 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
   205
        self._pendingcallback = {}
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   206
        # 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
   207
        self._anypending = False
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   208
        # 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
   209
        self._finalizecallback = {}
44543
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   210
        # holds callback to call when validating the transaction
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   211
        # should raise exception if anything is wrong
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   212
        self._validatecallback = {}
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   213
        if validator is not None:
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   214
            self._validatecallback[b'001-userhooks'] = validator
23543
4dd8a6a1240d spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23513
diff changeset
   215
        # 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
   216
        self._postclosecallback = {}
23764
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   217
        # holds callbacks to call during abort
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   218
        self._abortcallback = {}
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   219
36819
aff5996f3043 transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 36735
diff changeset
   220
    def __repr__(self):
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   221
        name = '/'.join(self._names)
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   222
        return '<transaction name=%s, count=%d, usages=%d>' % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   223
            name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   224
            self._count,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   225
            self._usages,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   226
        )
36819
aff5996f3043 transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 36735
diff changeset
   227
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   228
    def __del__(self):
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   229
        if self._journal:
9693
c40a1ee20aa5 transaction: always remove empty journal on abort
Sune Foldager <cryo@cyanite.org>
parents: 9686
diff changeset
   230
            self._abort()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   231
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   232
    @active
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   233
    def startgroup(self):
23250
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   234
        """delay registration of file entry
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   235
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   236
        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
   237
        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
   238
        self._queue.append([])
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   239
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   240
    @active
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   241
    def endgroup(self):
23250
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   242
        """apply delayed registration of file entry.
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   243
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   244
        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
   245
        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
   246
        q = self._queue.pop()
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   247
        for f, o in q:
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   248
            self._addentry(f, o)
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   249
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   250
    @active
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   251
    def add(self, file, offset):
23252
70809438c644 transaction: document `tr.add`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23251
diff changeset
   252
        """record the state of an append-only file before update"""
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   253
        if (
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   254
            file in self._newfiles
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   255
            or file in self._offsetmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   256
            or file in self._backupmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   257
        ):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   258
            return
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   259
        if self._queue:
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   260
            self._queue[-1].append((file, offset))
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   261
            return
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   262
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   263
        self._addentry(file, offset)
23253
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   264
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   265
    def _addentry(self, file, offset):
23253
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   266
        """add a append-only entry to memory and on-disk state"""
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   267
        if (
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   268
            file in self._newfiles
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   269
            or file in self._offsetmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   270
            or file in self._backupmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   271
        ):
23253
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   272
            return
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   273
        if offset:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   274
            self._offsetmap[file] = offset
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   275
        else:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   276
            self._newfiles.add(file)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   277
        # add enough data to the journal to do the truncate
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   278
        self._file.write(b"%s\0%d\n" % (file, offset))
39677
d27fde3e023e transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39676
diff changeset
   279
        self._file.flush()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   280
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   281
    @active
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   282
    def addbackup(self, file, hardlink=True, location=b''):
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   283
        """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
   284
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   285
        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
   286
        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
   287
        aborting.
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   288
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   289
        * `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
   290
        * `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
   291
        """
23251
85c634ff395a transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23250
diff changeset
   292
        if self._queue:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   293
            msg = b'cannot use transaction.addbackup inside "group"'
31648
8defc7d9adae transaction: use ProgrammingError
Jun Wu <quark@fb.com>
parents: 30002
diff changeset
   294
            raise error.ProgrammingError(msg)
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   295
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   296
        if (
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   297
            file in self._newfiles
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   298
            or file in self._offsetmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   299
            or file in self._backupmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   300
        ):
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   301
            return
23582
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   302
        vfs = self._vfsmap[location]
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   303
        dirname, filename = vfs.split(file)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   304
        backupfilename = b"%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
   305
        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
   306
        if vfs.exists(file):
4c6198737ad8 transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22662
diff changeset
   307
            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
   308
            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
   309
            util.copyfile(filepath, backuppath, hardlink=hardlink)
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   310
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   311
            backupfile = b''
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   312
23316
fc3670f41d3e transaction: use 'location' instead of 'vfs' in the addbackup method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23315
diff changeset
   313
        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
   314
b04263c38a92 transaction: extract backupentry registration in a dedicated function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23282
diff changeset
   315
    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
   316
        """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
   317
        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
   318
        self._backupmap[entry[1]] = len(self._backupentries) - 1
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   319
        self._backupsfile.write(b"%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
   320
        self._backupsfile.flush()
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   321
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   322
    @active
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   323
    def registertmp(self, tmpfile, location=b''):
23291
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   324
        """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
   325
23355
7faa55c20b0e transaction: fix some docstring grammar
Matt Mackall <mpm@selenic.com>
parents: 23354
diff changeset
   326
        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
   327
        failure and success).
23291
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   328
        """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   329
        self._addbackupentry((location, b'', tmpfile, False))
23291
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   330
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   331
    @active
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   332
    def addfilegenerator(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   333
        self, genid, filenames, genfunc, order=0, location=b''
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   334
    ):
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   335
        """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
   336
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   337
        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
   338
        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
   339
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   340
        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
   341
        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
   342
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   343
        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
   344
        final write of such file.
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   345
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   346
        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
   347
        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
   348
        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
   349
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   350
        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
   351
        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
   352
197e17be5407 transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23316
diff changeset
   353
        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
   354
        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
   355
        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
   356
        """
22663
4c6198737ad8 transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22662
diff changeset
   357
        # 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
   358
        # 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
   359
        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
   360
33056
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   361
    @active
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   362
    def removefilegenerator(self, genid):
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   363
        """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
   364
        if genid in self._filegenerators:
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   365
            del self._filegenerators[genid]
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   366
44406
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
   367
    def _generatefiles(self, suffix=b'', group=GEN_GROUP_ALL):
23102
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   368
        # 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
   369
        any = False
44407
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   370
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   371
        if group == GEN_GROUP_ALL:
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   372
            skip_post = skip_pre = False
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   373
        else:
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   374
            skip_pre = group == GEN_GROUP_POST_FINALIZE
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   375
            skip_post = group == GEN_GROUP_PRE_FINALIZE
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   376
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
   377
        for id, entry in sorted(pycompat.iteritems(self._filegenerators)):
23357
ba033f461f00 transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23356
diff changeset
   378
            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
   379
            order, filenames, genfunc, location = entry
28830
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
   380
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
   381
            # for generation at closing, check if it's before or after finalize
44407
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   382
            is_post = id in postfinalizegenerators
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   383
            if skip_post and is_post:
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   384
                continue
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   385
            elif skip_pre and not is_post:
28830
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
   386
                continue
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
   387
23317
197e17be5407 transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23316
diff changeset
   388
            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
   389
            files = []
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   390
            try:
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   391
                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
   392
                    name += suffix
140c21fbf4eb transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23355
diff changeset
   393
                    if suffix:
140c21fbf4eb transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23355
diff changeset
   394
                        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
   395
                        checkambig = False
23356
140c21fbf4eb transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23355
diff changeset
   396
                    else:
140c21fbf4eb transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23355
diff changeset
   397
                        self.addbackup(name, location=location)
39680
264d56954dda transaction: make checkambigfiles a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39679
diff changeset
   398
                        checkambig = (name, location) in self._checkambigfiles
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   399
                    files.append(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   400
                        vfs(name, b'w', atomictemp=True, checkambig=checkambig)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   401
                    )
23102
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   402
                genfunc(*files)
41107
3e2c02836420 transaction: do not overwrite atomic-temp files on error
Yuya Nishihara <yuya@tcha.org>
parents: 40579
diff changeset
   403
                for f in files:
3e2c02836420 transaction: do not overwrite atomic-temp files on error
Yuya Nishihara <yuya@tcha.org>
parents: 40579
diff changeset
   404
                    f.close()
3e2c02836420 transaction: do not overwrite atomic-temp files on error
Yuya Nishihara <yuya@tcha.org>
parents: 40579
diff changeset
   405
                # skip discard() loop since we're sure no open file remains
3e2c02836420 transaction: do not overwrite atomic-temp files on error
Yuya Nishihara <yuya@tcha.org>
parents: 40579
diff changeset
   406
                del files[:]
23102
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   407
            finally:
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   408
                for f in files:
41107
3e2c02836420 transaction: do not overwrite atomic-temp files on error
Yuya Nishihara <yuya@tcha.org>
parents: 40579
diff changeset
   409
                    f.discard()
23357
ba033f461f00 transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23356
diff changeset
   410
        return any
23102
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   411
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   412
    @active
45870
a6f08085edfe transaction: rename find to findoffset and drop backup file support
Joerg Sonnenberger <joerg@bec.de>
parents: 45869
diff changeset
   413
    def findoffset(self, file):
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   414
        if file in self._newfiles:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   415
            return 0
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   416
        return self._offsetmap.get(file)
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   417
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   418
    @active
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   419
    def readjournal(self):
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   420
        self._file.seek(0)
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   421
        entries = []
46063
88de2639901b transaction: windows workaround for missing line iteration support
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   422
        for l in self._file.readlines():
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   423
            file, troffset = l.split(b'\0')
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   424
            entries.append((file, int(troffset)))
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   425
        return entries
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   426
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   427
    @active
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   428
    def replace(self, file, offset):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   429
        """
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   430
        replace can only replace already committed entries
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   431
        that are not pending in the queue
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   432
        """
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   433
        if file in self._newfiles:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   434
            if not offset:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   435
                return
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   436
            self._newfiles.remove(file)
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   437
            self._offsetmap[file] = offset
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   438
        elif file in self._offsetmap:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   439
            if not offset:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   440
                del self._offsetmap[file]
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   441
                self._newfiles.add(file)
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   442
            else:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   443
                self._offsetmap[file] = offset
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   444
        else:
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   445
            raise KeyError(file)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   446
        self._file.write(b"%s\0%d\n" % (file, offset))
39677
d27fde3e023e transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39676
diff changeset
   447
        self._file.flush()
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   448
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   449
    @active
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   450
    def nest(self, name='<unnamed>'):
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   451
        self._count += 1
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   452
        self._usages += 1
39685
4024c363cd33 transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39684
diff changeset
   453
        self._names.append(name)
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   454
        return self
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   455
11230
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   456
    def release(self):
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   457
        if self._count > 0:
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   458
            self._usages -= 1
39685
4024c363cd33 transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39684
diff changeset
   459
        if self._names:
4024c363cd33 transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39684
diff changeset
   460
            self._names.pop()
11685
aade8f133d11 cleanup: typos
Patrick Mezard <pmezard@gmail.com>
parents: 11230
diff changeset
   461
        # 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
   462
        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
   463
            self._abort()
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   464
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   465
    def running(self):
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   466
        return self._count > 0
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   467
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   468
    def addpending(self, category, callback):
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   469
        """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
   470
23280
b01c491af0cf transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23279
diff changeset
   471
        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
   472
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   473
        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
   474
        with a newer callback.
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   475
        """
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   476
        self._pendingcallback[category] = callback
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   477
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   478
    @active
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   479
    def writepending(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   480
        """write pending file to temporary version
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   481
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   482
        This is used to allow hooks to view a transaction before commit"""
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   483
        categories = sorted(self._pendingcallback)
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   484
        for cat in categories:
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   485
            # 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
   486
            any = self._pendingcallback.pop(cat)(self)
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   487
            self._anypending = self._anypending or any
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   488
        self._anypending |= self._generatefiles(suffix=b'.pending')
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   489
        return self._anypending
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   490
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   491
    @active
44056
8e09551206f5 transaction: add a `hasfinalize` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   492
    def hasfinalize(self, category):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   493
        """check is a callback already exist for a category"""
44056
8e09551206f5 transaction: add a `hasfinalize` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   494
        return category in self._finalizecallback
8e09551206f5 transaction: add a `hasfinalize` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   495
8e09551206f5 transaction: add a `hasfinalize` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   496
    @active
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   497
    def addfinalize(self, category, callback):
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   498
        """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
   499
23281
f60ed8cf4afc transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23280
diff changeset
   500
        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
   501
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   502
        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
   503
        newer callbacks.
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   504
        """
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   505
        self._finalizecallback[category] = callback
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   506
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   507
    @active
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   508
    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
   509
        """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
   510
23282
6c1351352b6c transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
   511
        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
   512
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   513
        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
   514
        with a newer callback.
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   515
        """
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   516
        self._postclosecallback[category] = callback
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   517
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   518
    @active
33087
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33056
diff changeset
   519
    def getpostclose(self, category):
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33056
diff changeset
   520
        """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
   521
        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
   522
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33056
diff changeset
   523
    @active
23764
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   524
    def addabort(self, category, callback):
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   525
        """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
   526
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   527
        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
   528
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   529
        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
   530
        with a newer callback.
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   531
        """
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   532
        self._abortcallback[category] = callback
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   533
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   534
    @active
44543
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   535
    def addvalidator(self, category, callback):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   536
        """adds a callback to be called when validating the transaction.
44543
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   537
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   538
        The transaction will be given as the first argument to the callback.
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   539
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   540
        callback should raise exception if to abort transaction"""
44543
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   541
        self._validatecallback[category] = callback
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   542
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   543
    @active
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   544
    def close(self):
9220
8a4da1388553 transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents: 9094
diff changeset
   545
        '''commit the transaction'''
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   546
        if self._count == 1:
44543
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   547
            for category in sorted(self._validatecallback):
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   548
                self._validatecallback[category](self)
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   549
            self._validatecallback = None  # Help prevent cycles.
44406
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
   550
            self._generatefiles(group=GEN_GROUP_PRE_FINALIZE)
44097
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   551
            while self._finalizecallback:
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   552
                callbacks = self._finalizecallback
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   553
                self._finalizecallback = {}
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   554
                categories = sorted(callbacks)
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   555
                for cat in categories:
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   556
                    callbacks[cat](self)
28960
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   557
            # Prevent double usage and help clear cycles.
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   558
            self._finalizecallback = None
44406
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
   559
            self._generatefiles(group=GEN_GROUP_POST_FINALIZE)
20881
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   560
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   561
        self._count -= 1
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   562
        if self._count != 0:
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   563
            return
39677
d27fde3e023e transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39676
diff changeset
   564
        self._file.close()
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   565
        self._backupsfile.close()
23291
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   566
        # cleanup temporary files
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   567
        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
   568
            if l not in self._vfsmap and c:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   569
                self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   570
                    b"couldn't remove %s: unknown cache location %s\n" % (b, l)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   571
                )
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   572
                continue
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
   573
            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
   574
            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
   575
                try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   576
                    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
   577
                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
   578
                    if not c:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   579
                        raise
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   580
                    # Abort may be raise by read only opener
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   581
                    self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   582
                        b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   583
                    )
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   584
        self._offsetmap = {}
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   585
        self._newfiles = set()
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   586
        self._writeundo()
39681
0d7b9db85675 transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39680
diff changeset
   587
        if self._after:
0d7b9db85675 transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39680
diff changeset
   588
            self._after()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   589
            self._after = None  # Help prevent cycles.
39682
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   590
        if self._opener.isfile(self._backupjournal):
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   591
            self._opener.unlink(self._backupjournal)
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   592
        if self._opener.isfile(self._journal):
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   593
            self._opener.unlink(self._journal)
27662
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   594
        for l, _f, b, c in self._backupentries:
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   595
            if l not in self._vfsmap and c:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   596
                self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   597
                    b"couldn't remove %s: unknown cache location"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   598
                    b"%s\n" % (b, l)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   599
                )
27662
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   600
                continue
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   601
            vfs = self._vfsmap[l]
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   602
            if b and vfs.exists(b):
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   603
                try:
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   604
                    vfs.unlink(b)
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   605
                except (IOError, OSError, error.Abort) as inst:
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   606
                    if not c:
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   607
                        raise
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   608
                    # Abort may be raise by read only opener
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   609
                    self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   610
                        b"couldn't remove %s: %s\n" % (vfs.join(b), inst)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   611
                    )
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   612
        self._backupentries = []
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   613
        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
   614
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   615
        self._releasefn(self, True)  # notify success of closing transaction
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   616
        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
   617
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   618
        # run post close action
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   619
        categories = sorted(self._postclosecallback)
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   620
        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
   621
            self._postclosecallback[cat](self)
28960
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   622
        # Prevent double usage and help clear cycles.
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   623
        self._postclosecallback = None
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   624
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   625
    @active
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   626
    def abort(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   627
        """abort the transaction (generally called on error, or when the
9220
8a4da1388553 transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents: 9094
diff changeset
   628
        transaction is not explicitly committed before going out of
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   629
        scope)"""
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   630
        self._abort()
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   631
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   632
    def _writeundo(self):
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   633
        """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
   634
        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
   635
            return
47422
88439c6fbafc transaction: simplify `undo.backupfiles` file creation with a variable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47420
diff changeset
   636
88439c6fbafc transaction: simplify `undo.backupfiles` file creation with a variable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47420
diff changeset
   637
        undo_backup_path = b"%s.backupfiles" % self._undoname
88439c6fbafc transaction: simplify `undo.backupfiles` file creation with a variable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47420
diff changeset
   638
        undobackupfile = self._opener.open(undo_backup_path, b'w')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   639
        undobackupfile.write(b'%d\n' % version)
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   640
        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
   641
            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
   642
                continue
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   643
            if not b:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   644
                u = b''
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   645
            else:
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   646
                if l not in self._vfsmap and c:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   647
                    self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   648
                        b"couldn't remove %s: unknown cache location"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   649
                        b"%s\n" % (b, l)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   650
                    )
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   651
                    continue
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   652
                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
   653
                base, name = vfs.split(b)
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   654
                assert name.startswith(self._journal), name
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   655
                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
   656
                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
   657
                util.copyfile(vfs.join(b), vfs.join(u), hardlink=True)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   658
            undobackupfile.write(b"%s\0%s\0%s\0%d\n" % (l, f, u, c))
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   659
        undobackupfile.close()
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   660
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   661
    def _abort(self):
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   662
        entries = self.readjournal()
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   663
        self._count = 0
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   664
        self._usages = 0
39677
d27fde3e023e transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39676
diff changeset
   665
        self._file.close()
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   666
        self._backupsfile.close()
8290
560af1bbfd6e transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents: 8289
diff changeset
   667
10228
056c366fea8c transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9693
diff changeset
   668
        try:
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   669
            if not 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
   670
                if self._backupjournal:
39682
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   671
                    self._opener.unlink(self._backupjournal)
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   672
                if self._journal:
39682
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   673
                    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
   674
                return
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   675
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   676
            self._report(_(b"transaction abort!\n"))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   677
108
8d55c2d72c7c Warn if we fail to truncate something
mpm@selenic.com
parents: 95
diff changeset
   678
            try:
23764
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   679
                for cat in sorted(self._abortcallback):
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   680
                    self._abortcallback[cat](self)
28960
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   681
                # Prevent double usage and help clear cycles.
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   682
                self._abortcallback = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   683
                _playback(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   684
                    self._journal,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   685
                    self._report,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   686
                    self._opener,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   687
                    self._vfsmap,
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   688
                    entries,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   689
                    self._backupentries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   690
                    False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   691
                    checkambigfiles=self._checkambigfiles,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   692
                )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   693
                self._report(_(b"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
   694
            except BaseException as exc:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   695
                self._report(_(b"rollback failed - please run hg recover\n"))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   696
                self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   697
                    _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   698
                )
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   699
        finally:
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   700
            self._journal = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   701
            self._releasefn(self, False)  # notify failure of transaction
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   702
            self._releasefn = None  # Help prevent cycles.
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   703
8290
560af1bbfd6e transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents: 8289
diff changeset
   704
47419
0e4e9c1b4cc8 transaction: extract message about different version in a constants
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47418
diff changeset
   705
BAD_VERSION_MSG = _(
0e4e9c1b4cc8 transaction: extract message about different version in a constants
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47418
diff changeset
   706
    b"journal was created by a different version of Mercurial\n"
0e4e9c1b4cc8 transaction: extract message about different version in a constants
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47418
diff changeset
   707
)
0e4e9c1b4cc8 transaction: extract message about different version in a constants
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47418
diff changeset
   708
0e4e9c1b4cc8 transaction: extract message about different version in a constants
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47418
diff changeset
   709
33278
87bca10a06ed transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33087
diff changeset
   710
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
   711
    """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
   712
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   713
    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
   714
    '*.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
   715
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   716
    * `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
   717
    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
   718
    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
   719
    '*.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
   720
    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
   721
87bca10a06ed transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33087
diff changeset
   722
    `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
   723
    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
   724
    restoring corresponded files.
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   725
    """
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   726
    entries = []
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   727
    backupentries = []
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   728
47307
13dd5bb5492a transaction: trivial refactoring
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47286
diff changeset
   729
    with opener.open(file) as fp:
13dd5bb5492a transaction: trivial refactoring
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47286
diff changeset
   730
        lines = fp.readlines()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
   731
    for l in lines:
20524
28b8ff84db3f journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents: 20087
diff changeset
   732
        try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   733
            f, o = l.split(b'\0')
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   734
            entries.append((f, int(o)))
20524
28b8ff84db3f journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents: 20087
diff changeset
   735
        except ValueError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   736
            report(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   737
                _(b"couldn't read journal entry %r!\n") % pycompat.bytestr(l)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   738
            )
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   739
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   740
    backupjournal = b"%s.backupfiles" % file
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   741
    if opener.exists(backupjournal):
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   742
        fp = opener.open(backupjournal)
23065
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   743
        lines = fp.readlines()
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   744
        if lines:
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   745
            ver = lines[0][:-1]
47420
e7ad2490d623 transaction: clarify a conditionnal about version check
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47419
diff changeset
   746
            if ver != (b'%d' % version):
e7ad2490d623 transaction: clarify a conditionnal about version check
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47419
diff changeset
   747
                report(BAD_VERSION_MSG)
e7ad2490d623 transaction: clarify a conditionnal about version check
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47419
diff changeset
   748
            else:
23065
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   749
                for line in lines[1:]:
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   750
                    if line:
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   751
                        # Shave off the trailing newline
963f311e3a81 transactions: change backupfiles format to use newlines
Durham Goode <durham@fb.com>
parents: 23064
diff changeset
   752
                        line = line[:-1]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   753
                        l, f, b, c = line.split(b'\0')
23309
7eb520f5efe4 transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23291
diff changeset
   754
                        backupentries.append((l, f, b, bool(c)))
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   755
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   756
    _playback(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   757
        file,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   758
        report,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   759
        opener,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   760
        vfsmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   761
        entries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   762
        backupentries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   763
        checkambigfiles=checkambigfiles,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   764
    )