mercurial/transaction.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Wed, 15 Mar 2023 13:20:12 +0100
branchstable
changeset 50339 86dc9e097bed
parent 50338 cab3defe6d3b
child 50340 4c1061b3e55a
permissions -rw-r--r--
transaction: move the restoration of backup file in a small closure We are about to use that logic in two different location, making is a small reusable closure prepares that.
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
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    14
import errno
50296
dda43856ef96 undo-files: add a undoname closure to the _write_undo method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50293
diff changeset
    15
import os
25986
89049011f304 transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    16
89049011f304 transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    17
from .i18n import _
89049011f304 transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    18
from . import (
89049011f304 transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    19
    error,
36735
ef345f9e4295 transaction: fix an error string with bytestr() on a repr()d value
Augie Fackler <augie@google.com>
parents: 35832
diff changeset
    20
    pycompat,
25986
89049011f304 transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    21
    util,
89049011f304 transaction: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    22
)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    23
from .utils import stringutil
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    24
23313
991098579940 transaction: set backupentries version to proper value
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23312
diff changeset
    25
version = 2
23064
5dc888b79e70 transactions: add version number to journal.backupfiles
Durham Goode <durham@fb.com>
parents: 23063
diff changeset
    26
44406
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
    27
GEN_GROUP_ALL = b'all'
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
    28
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
    29
GEN_GROUP_POST_FINALIZE = b'postfinalize'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    30
28830
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
    31
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    32
def active(func):
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    33
    def _active(self, *args, **kwds):
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
    34
        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
    35
            raise error.ProgrammingError(
5df1655edf42 transaction: use ProgrammingError for when an committed transaction is used
Martin von Zweigbergk <martinvonz@google.com>
parents: 44543
diff changeset
    36
                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
    37
            )
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    38
        return func(self, *args, **kwds)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    39
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
    40
    return _active
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    41
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    42
50302
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    43
UNDO_BACKUP = b'%s.backupfiles'
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    44
50300
7ce9862fca7c undo-files: relies on a explicit list of possible undo files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50299
diff changeset
    45
UNDO_FILES_MAY_NEED_CLEANUP = [
50304
862969b6c359 undo-files: cleanup legacy files when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50303
diff changeset
    46
    # legacy entries that might exists on disk from previous version:
862969b6c359 undo-files: cleanup legacy files when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50303
diff changeset
    47
    (b'store', b'%s.narrowspec'),
862969b6c359 undo-files: cleanup legacy files when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50303
diff changeset
    48
    (b'plain', b'%s.narrowspec.dirstate'),
862969b6c359 undo-files: cleanup legacy files when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50303
diff changeset
    49
    (b'plain', b'%s.branch'),
862969b6c359 undo-files: cleanup legacy files when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50303
diff changeset
    50
    (b'plain', b'%s.bookmarks'),
862969b6c359 undo-files: cleanup legacy files when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50303
diff changeset
    51
    (b'store', b'%s.phaseroots'),
862969b6c359 undo-files: cleanup legacy files when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50303
diff changeset
    52
    (b'plain', b'%s.dirstate'),
862969b6c359 undo-files: cleanup legacy files when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50303
diff changeset
    53
    # files actually in uses today:
50302
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    54
    (b'plain', b'%s.desc'),
50300
7ce9862fca7c undo-files: relies on a explicit list of possible undo files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50299
diff changeset
    55
    # Always delete undo last to make sure we detect that a clean up is needed if
7ce9862fca7c undo-files: relies on a explicit list of possible undo files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50299
diff changeset
    56
    # the process is interrupted.
50302
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    57
    (b'store', b'%s'),
50300
7ce9862fca7c undo-files: relies on a explicit list of possible undo files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50299
diff changeset
    58
]
7ce9862fca7c undo-files: relies on a explicit list of possible undo files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50299
diff changeset
    59
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    60
50302
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    61
def cleanup_undo_files(report, vfsmap, undo_prefix=b'undo'):
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    62
    """remove "undo" files used by the rollback logic
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    63
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    64
    This is useful to prevent rollback running in situation were it does not
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    65
    make sense. For example after a strip.
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    66
    """
50302
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    67
    backup_listing = UNDO_BACKUP % undo_prefix
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    68
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    69
    backup_entries = []
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    70
    undo_files = []
50301
d89eecf9605e undo-files: no longer pass the `repo` to `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50300
diff changeset
    71
    svfs = vfsmap[b'store']
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    72
    try:
50302
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    73
        with svfs(backup_listing) as f:
50301
d89eecf9605e undo-files: no longer pass the `repo` to `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50300
diff changeset
    74
            backup_entries = read_backup_files(report, f)
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    75
    except OSError as e:
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    76
        if e.errno != errno.ENOENT:
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    77
            msg = _(b'could not read %s: %s\n')
50302
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    78
            msg %= (svfs.join(backup_listing), stringutil.forcebytestr(e))
50301
d89eecf9605e undo-files: no longer pass the `repo` to `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50300
diff changeset
    79
            report(msg)
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    80
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    81
    for location, f, backup_path, c in backup_entries:
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    82
        if location in vfsmap and backup_path:
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    83
            undo_files.append((vfsmap[location], backup_path))
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    84
50302
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    85
    undo_files.append((svfs, backup_listing))
50300
7ce9862fca7c undo-files: relies on a explicit list of possible undo files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50299
diff changeset
    86
    for location, undo_path in UNDO_FILES_MAY_NEED_CLEANUP:
50302
94a8c354242b undo-files: make the undo-prefix configurable in `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50301
diff changeset
    87
        undo_files.append((vfsmap[location], undo_path % undo_prefix))
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    88
    for undovfs, undofile in undo_files:
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    89
        try:
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    90
            undovfs.unlink(undofile)
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    91
        except OSError as e:
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    92
            if e.errno != errno.ENOENT:
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    93
                msg = _(b'error removing %s: %s\n')
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    94
                msg %= (undovfs.join(undofile), stringutil.forcebytestr(e))
50301
d89eecf9605e undo-files: no longer pass the `repo` to `cleanup_undo_files`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50300
diff changeset
    95
                report(msg)
50299
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    96
3d0b5760851c undo-files: move the undo cleanup code in the transaction module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50297
diff changeset
    97
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    98
def _playback(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
    99
    journal,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   100
    report,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   101
    opener,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   102
    vfsmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   103
    entries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   104
    backupentries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   105
    unlink=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   106
    checkambigfiles=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   107
):
50339
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   108
    backupfiles = []
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   109
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   110
    def restore_one_backup(vfs, f, b, checkambig):
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   111
        filepath = vfs.join(f)
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   112
        backuppath = vfs.join(b)
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   113
        try:
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   114
            util.copyfile(backuppath, filepath, checkambig=checkambig)
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   115
            backupfiles.append((vfs, b))
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   116
        except IOError as exc:
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   117
            e_msg = stringutil.forcebytestr(exc)
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   118
            report(_(b"failed to recover %s (%s)\n") % (f, e_msg))
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   119
            raise
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   120
47286
18415fc918a1 recover: only apply last journal record per file (issue6423)
Joerg Sonnenberger <joerg@bec.de>
parents: 46819
diff changeset
   121
    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
   122
        if o or not unlink:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   123
            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
   124
            try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   125
                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
   126
                if fp.tell() < o:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   127
                    raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   128
                        _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   129
                            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
   130
                            b"already %d bytes\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   131
                        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   132
                        % (f, o, fp.tell())
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   133
                    )
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
   134
                fp.truncate(o)
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
   135
                fp.close()
9686
ddf2adf88b89 transaction: more specific exceptions, os.unlink can raise OSError
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9220
diff changeset
   136
            except IOError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   137
                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
   138
                raise
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   139
        else:
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   140
            try:
20084
a3378a1b0a05 transaction: unlink target file via vfs
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17424
diff changeset
   141
                opener.unlink(f)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48913
diff changeset
   142
            except FileNotFoundError:
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48913
diff changeset
   143
                pass
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   144
23309
7eb520f5efe4 transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23291
diff changeset
   145
    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
   146
        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
   147
            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
   148
        vfs = vfsmap[l]
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   149
        try:
50339
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   150
            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
   151
            if f and b:
50339
86dc9e097bed transaction: move the restoration of backup file in a small closure
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50338
diff changeset
   152
                restore_one_backup(vfs, f, b, checkambig)
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   153
            else:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   154
                target = f or b
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   155
                try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   156
                    vfs.unlink(target)
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48913
diff changeset
   157
                except FileNotFoundError:
50337
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   158
                    # This is fine because
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   159
                    #
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   160
                    # either we are trying to delete the main file, and it is
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   161
                    # already deleted.
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   162
                    #
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   163
                    # or we are trying to delete a temporary file and it is
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   164
                    # already deleted.
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   165
                    #
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   166
                    # in both case, our target result (delete the file) is
70ca1f09ceca transaction: add clarifying comment about why ignoring some error is fine
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50336
diff changeset
   167
                    # already achieved.
49306
2e726c934fcd py3: catch FileNotFoundError instead of checking errno == ENOENT
Manuel Jacob <me@manueljacob.de>
parents: 48913
diff changeset
   168
                    pass
41365
876494fd967d cleanup: delete lots of unused local variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 41107
diff changeset
   169
        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
   170
            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
   171
                raise
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   172
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   173
    backuppath = b"%s.backupfiles" % journal
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   174
    if opener.exists(backuppath):
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   175
        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
   176
    opener.unlink(journal)
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   177
    try:
50336
90276164333a transaction: properly clean up backup file outside of .hg/store/
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50304
diff changeset
   178
        for vfs, f in backupfiles:
90276164333a transaction: properly clean up backup file outside of .hg/store/
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50304
diff changeset
   179
            if vfs.exists(f):
90276164333a transaction: properly clean up backup file outside of .hg/store/
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50304
diff changeset
   180
                vfs.unlink(f)
41365
876494fd967d cleanup: delete lots of unused local variables
Martin von Zweigbergk <martinvonz@google.com>
parents: 41107
diff changeset
   181
    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
   182
        # 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
   183
        pass
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   184
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   185
33793
bbbbd3c30bfc util: add base class for transactional context managers
Martin von Zweigbergk <martinvonz@google.com>
parents: 33279
diff changeset
   186
class transaction(util.transactional):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   187
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   188
        self,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   189
        report,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   190
        opener,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   191
        vfsmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   192
        journalname,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   193
        undoname=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   194
        after=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   195
        createmode=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   196
        validator=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   197
        releasefn=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   198
        checkambigfiles=None,
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   199
        name='<unnamed>',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   200
    ):
20881
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   201
        """Begin a new transaction
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   202
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   203
        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
   204
        an exception.
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   205
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   206
        * `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
   207
        * `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
   208
        * `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
   209
87bca10a06ed transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33087
diff changeset
   210
        `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
   211
        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
   212
        for corresponded files.
20881
3c47677a8d04 transaction: add onclose/onabort hook for pre-close logic
Durham Goode <durham@fb.com>
parents: 20524
diff changeset
   213
        """
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   214
        self._count = 1
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   215
        self._usages = 1
39683
337d6e0fd9c9 transaction: make report a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39682
diff changeset
   216
        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
   217
        # a vfs to the store content
39682
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   218
        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
   219
        # 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
   220
        vfsmap = vfsmap.copy()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   221
        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
   222
        self._vfsmap = vfsmap
39681
0d7b9db85675 transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39680
diff changeset
   223
        self._after = after
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   224
        self._offsetmap = {}
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   225
        self._newfiles = set()
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   226
        self._journal = journalname
50297
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   227
        self._journal_files = []
39675
da9ce63bfa9b transaction: make undoname a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39674
diff changeset
   228
        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
   229
        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
   230
        # 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
   231
        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
   232
            releasefn = lambda tr, success: None
39678
040007cd3d81 transaction: make releasefn a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39677
diff changeset
   233
        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
   234
39680
264d56954dda transaction: make checkambigfiles a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39679
diff changeset
   235
        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
   236
        if checkambigfiles:
39680
264d56954dda transaction: make checkambigfiles a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39679
diff changeset
   237
            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
   238
39685
4024c363cd33 transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39684
diff changeset
   239
        self._names = [name]
36819
aff5996f3043 transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 36735
diff changeset
   240
32261
976681123416 transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31648
diff changeset
   241
        # 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
   242
        # transaction.
976681123416 transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31648
diff changeset
   243
        self.changes = {}
976681123416 transaction: introduce "changes" dictionary to precisely track updates
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31648
diff changeset
   244
23279
e245775f8fd3 transaction: gather backupjournal logic together in the __init__
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23278
diff changeset
   245
        # 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
   246
        self.hookargs = {}
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   247
        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
   248
23309
7eb520f5efe4 transaction: change the on disk format for backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23291
diff changeset
   249
        # 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
   250
        # - 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
   251
        # - 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
   252
        # - 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
   253
        #   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
   254
        # (cache is currently unused)
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   255
        self._backupentries = []
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   256
        self._backupmap = {}
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   257
        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
   258
        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
   259
        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
   260
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
   261
        if createmode is not None:
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   262
            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
   263
            opener.chmod(self._backupjournal, createmode & 0o666)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   264
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   265
        # 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
   266
        self._filegenerators = {}
23543
4dd8a6a1240d spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23513
diff changeset
   267
        # 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
   268
        self._pendingcallback = {}
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   269
        # 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
   270
        self._anypending = False
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   271
        # 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
   272
        self._finalizecallback = {}
44543
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   273
        # 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
   274
        # should raise exception if anything is wrong
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   275
        self._validatecallback = {}
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   276
        if validator is not None:
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   277
            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
   278
        # 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
   279
        self._postclosecallback = {}
23764
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   280
        # holds callbacks to call during abort
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   281
        self._abortcallback = {}
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   282
36819
aff5996f3043 transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 36735
diff changeset
   283
    def __repr__(self):
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   284
        name = '/'.join(self._names)
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   285
        return '<transaction name=%s, count=%d, usages=%d>' % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   286
            name,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   287
            self._count,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   288
            self._usages,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   289
        )
36819
aff5996f3043 transaction: add a name and a __repr__ implementation (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 36735
diff changeset
   290
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   291
    def __del__(self):
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   292
        if self._journal:
9693
c40a1ee20aa5 transaction: always remove empty journal on abort
Sune Foldager <cryo@cyanite.org>
parents: 9686
diff changeset
   293
            self._abort()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   294
48676
3f618484eeb6 transaction: add a way to know a transaction has been finalized
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47422
diff changeset
   295
    @property
3f618484eeb6 transaction: add a way to know a transaction has been finalized
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47422
diff changeset
   296
    def finalized(self):
3f618484eeb6 transaction: add a way to know a transaction has been finalized
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47422
diff changeset
   297
        return self._finalizecallback is None
3f618484eeb6 transaction: add a way to know a transaction has been finalized
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47422
diff changeset
   298
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   299
    @active
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   300
    def startgroup(self):
23250
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   301
        """delay registration of file entry
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   302
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   303
        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
   304
        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
   305
        self._queue.append([])
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   306
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   307
    @active
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   308
    def endgroup(self):
23250
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   309
        """apply delayed registration of file entry.
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   310
8919dc7f2dbb transaction: document startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23249
diff changeset
   311
        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
   312
        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
   313
        q = self._queue.pop()
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   314
        for f, o in q:
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   315
            self._addentry(f, o)
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   316
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   317
    @active
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   318
    def add(self, file, offset):
23252
70809438c644 transaction: document `tr.add`
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23251
diff changeset
   319
        """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
   320
        if (
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   321
            file in self._newfiles
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   322
            or file in self._offsetmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   323
            or file in self._backupmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   324
        ):
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   325
            return
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   326
        if self._queue:
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   327
            self._queue[-1].append((file, offset))
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   328
            return
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   329
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   330
        self._addentry(file, offset)
23253
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   331
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   332
    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
   333
        """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
   334
        if (
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   335
            file in self._newfiles
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   336
            or file in self._offsetmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   337
            or file in self._backupmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   338
        ):
23253
8d84b7a2dd91 transaction: factorise append-only file registration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23252
diff changeset
   339
            return
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   340
        if offset:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   341
            self._offsetmap[file] = offset
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   342
        else:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   343
            self._newfiles.add(file)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   344
        # 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
   345
        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
   346
        self._file.flush()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   347
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   348
    @active
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   349
    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
   350
        """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
   351
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   352
        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
   353
        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
   354
        aborting.
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   355
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   356
        * `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
   357
        * `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
   358
        """
23251
85c634ff395a transaction: drop backupentries logic from startgroup and endgroup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23250
diff changeset
   359
        if self._queue:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   360
            msg = b'cannot use transaction.addbackup inside "group"'
31648
8defc7d9adae transaction: use ProgrammingError
Jun Wu <quark@fb.com>
parents: 30002
diff changeset
   361
            raise error.ProgrammingError(msg)
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   362
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   363
        if (
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   364
            file in self._newfiles
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   365
            or file in self._offsetmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   366
            or file in self._backupmap
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   367
        ):
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   368
            return
23582
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   369
        vfs = self._vfsmap[location]
7559dc8c4238 vfs: add a 'split' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23581
diff changeset
   370
        dirname, filename = vfs.split(file)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   371
        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
   372
        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
   373
        if vfs.exists(file):
4c6198737ad8 transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22662
diff changeset
   374
            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
   375
            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
   376
            util.copyfile(filepath, backuppath, hardlink=hardlink)
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   377
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   378
            backupfile = b''
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   379
23316
fc3670f41d3e transaction: use 'location' instead of 'vfs' in the addbackup method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23315
diff changeset
   380
        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
   381
b04263c38a92 transaction: extract backupentry registration in a dedicated function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23282
diff changeset
   382
    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
   383
        """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
   384
        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
   385
        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
   386
        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
   387
        self._backupsfile.flush()
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   388
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   389
    @active
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   390
    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
   391
        """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
   392
23355
7faa55c20b0e transaction: fix some docstring grammar
Matt Mackall <mpm@selenic.com>
parents: 23354
diff changeset
   393
        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
   394
        failure and success).
23291
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   395
        """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   396
        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
   397
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   398
    @active
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   399
    def addfilegenerator(
48685
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   400
        self,
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   401
        genid,
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   402
        filenames,
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   403
        genfunc,
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   404
        order=0,
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   405
        location=b'',
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   406
        post_finalize=False,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   407
    ):
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   408
        """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
   409
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   410
        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
   411
        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
   412
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   413
        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
   414
        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
   415
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   416
        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
   417
        final write of such file.
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   418
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   419
        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
   420
        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
   421
        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
   422
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   423
        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
   424
        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
   425
197e17be5407 transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23316
diff changeset
   426
        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
   427
        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
   428
        one of the key of the `transaction.vfsmap` dictionary.
48685
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   429
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   430
        The `post_finalize` argument can be set to `True` for file generation
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   431
        that must be run after the transaction has been finalized.
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   432
        """
22663
4c6198737ad8 transaction: allow generating file outside of store
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22662
diff changeset
   433
        # 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
   434
        # but for bookmarks that are handled outside this mechanism.
48685
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   435
        entry = (order, filenames, genfunc, location, post_finalize)
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   436
        self._filegenerators[genid] = entry
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   437
33056
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   438
    @active
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   439
    def removefilegenerator(self, genid):
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   440
        """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
   441
        if genid in self._filegenerators:
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   442
            del self._filegenerators[genid]
2312e70cf78b rebase: clean up rebasestate from active transaction
Jun Wu <quark@fb.com>
parents: 32558
diff changeset
   443
44406
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
   444
    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
   445
        # 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
   446
        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
   447
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   448
        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
   449
            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
   450
        else:
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   451
            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
   452
            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
   453
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   454
        for id, entry in sorted(self._filegenerators.items()):
23357
ba033f461f00 transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23356
diff changeset
   455
            any = True
48685
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   456
            order, filenames, genfunc, location, post_finalize = entry
28830
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
   457
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
   458
            # for generation at closing, check if it's before or after finalize
48685
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   459
            if skip_post and post_finalize:
44407
f6798c1a80fa transaction: clarify the logic around pre-finalize/post-finalize
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44406
diff changeset
   460
                continue
48685
21ac6aedd5e5 transaction: do not rely on a global variable to post_finalize file
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48684
diff changeset
   461
            elif skip_pre and not post_finalize:
28830
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
   462
                continue
a5009789960c transaction: allow running file generators after finalizers
Durham Goode <durham@fb.com>
parents: 27924
diff changeset
   463
23317
197e17be5407 transaction: use 'location' instead of 'vfs' objects for file generation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23316
diff changeset
   464
            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
   465
            files = []
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   466
            try:
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   467
                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
   468
                    name += suffix
140c21fbf4eb transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23355
diff changeset
   469
                    if suffix:
140c21fbf4eb transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23355
diff changeset
   470
                        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
   471
                        checkambig = False
23356
140c21fbf4eb transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23355
diff changeset
   472
                    else:
140c21fbf4eb transaction: allow generating files with a suffix
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23355
diff changeset
   473
                        self.addbackup(name, location=location)
39680
264d56954dda transaction: make checkambigfiles a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39679
diff changeset
   474
                        checkambig = (name, location) in self._checkambigfiles
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   475
                    files.append(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   476
                        vfs(name, b'w', atomictemp=True, checkambig=checkambig)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   477
                    )
23102
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   478
                genfunc(*files)
41107
3e2c02836420 transaction: do not overwrite atomic-temp files on error
Yuya Nishihara <yuya@tcha.org>
parents: 40579
diff changeset
   479
                for f in files:
3e2c02836420 transaction: do not overwrite atomic-temp files on error
Yuya Nishihara <yuya@tcha.org>
parents: 40579
diff changeset
   480
                    f.close()
3e2c02836420 transaction: do not overwrite atomic-temp files on error
Yuya Nishihara <yuya@tcha.org>
parents: 40579
diff changeset
   481
                # 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
   482
                del files[:]
23102
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   483
            finally:
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   484
                for f in files:
41107
3e2c02836420 transaction: do not overwrite atomic-temp files on error
Yuya Nishihara <yuya@tcha.org>
parents: 40579
diff changeset
   485
                    f.discard()
23357
ba033f461f00 transaction: have _generatefile return a boolean
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23356
diff changeset
   486
        return any
23102
16da812ad970 transaction: extract file generation into its own function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23065
diff changeset
   487
22078
feb4797c676e transaction: add a file generation mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22077
diff changeset
   488
    @active
45870
a6f08085edfe transaction: rename find to findoffset and drop backup file support
Joerg Sonnenberger <joerg@bec.de>
parents: 45869
diff changeset
   489
    def findoffset(self, file):
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   490
        if file in self._newfiles:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   491
            return 0
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   492
        return self._offsetmap.get(file)
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   493
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   494
    @active
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   495
    def readjournal(self):
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   496
        self._file.seek(0)
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   497
        entries = []
46063
88de2639901b transaction: windows workaround for missing line iteration support
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   498
        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
   499
            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
   500
            entries.append((file, int(troffset)))
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   501
        return entries
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   502
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   503
    @active
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   504
    def replace(self, file, offset):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   505
        """
8363
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   506
        replace can only replace already committed entries
c8e81f557da7 transaction: add atomic groups to transaction logic
Henrik Stuart <hg@hstuart.dk>
parents: 8294
diff changeset
   507
        that are not pending in the queue
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   508
        """
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   509
        if file in self._newfiles:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   510
            if not offset:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   511
                return
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   512
            self._newfiles.remove(file)
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   513
            self._offsetmap[file] = offset
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   514
        elif file in self._offsetmap:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   515
            if not offset:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   516
                del self._offsetmap[file]
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   517
                self._newfiles.add(file)
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   518
            else:
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   519
                self._offsetmap[file] = offset
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   520
        else:
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   521
            raise KeyError(file)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   522
        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
   523
        self._file.flush()
2084
Chris Mason <mason@suse.com>
parents: 1806
diff changeset
   524
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   525
    @active
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   526
    def nest(self, name='<unnamed>'):
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   527
        self._count += 1
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   528
        self._usages += 1
39685
4024c363cd33 transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39684
diff changeset
   529
        self._names.append(name)
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   530
        return self
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   531
11230
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   532
    def release(self):
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   533
        if self._count > 0:
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   534
            self._usages -= 1
39685
4024c363cd33 transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39684
diff changeset
   535
        if self._names:
4024c363cd33 transaction: make names a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39684
diff changeset
   536
            self._names.pop()
11685
aade8f133d11 cleanup: typos
Patrick Mezard <pmezard@gmail.com>
parents: 11230
diff changeset
   537
        # 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
   538
        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
   539
            self._abort()
5116a077c3da make transactions work on non-refcounted python implementations
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 10282
diff changeset
   540
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   541
    def running(self):
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   542
        return self._count > 0
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   543
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   544
    def addpending(self, category, callback):
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   545
        """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
   546
23280
b01c491af0cf transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23279
diff changeset
   547
        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
   548
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   549
        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
   550
        with a newer callback.
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   551
        """
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   552
        self._pendingcallback[category] = callback
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   553
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   554
    @active
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   555
    def writepending(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   556
        """write pending file to temporary version
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   557
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   558
        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
   559
        categories = sorted(self._pendingcallback)
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   560
        for cat in categories:
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   561
            # 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
   562
            any = self._pendingcallback.pop(cat)(self)
23202
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   563
            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
   564
        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
   565
        return self._anypending
ea5af863fbff transaction: add 'writepending' logic
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23103
diff changeset
   566
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   567
    @active
44056
8e09551206f5 transaction: add a `hasfinalize` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   568
    def hasfinalize(self, category):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   569
        """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
   570
        return category in self._finalizecallback
8e09551206f5 transaction: add a `hasfinalize` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   571
8e09551206f5 transaction: add a `hasfinalize` method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
   572
    @active
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   573
    def addfinalize(self, category, callback):
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   574
        """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
   575
23281
f60ed8cf4afc transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23280
diff changeset
   576
        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
   577
23204
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   578
        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
   579
        newer callbacks.
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   580
        """
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   581
        self._finalizecallback[category] = callback
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   582
10beda5bd2b7 transaction: allow registering a finalization callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23202
diff changeset
   583
    @active
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   584
    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
   585
        """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
   586
23282
6c1351352b6c transaction: pass the transaction to 'postclose' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
   587
        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
   588
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   589
        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
   590
        with a newer callback.
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   591
        """
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   592
        self._postclosecallback[category] = callback
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   593
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   594
    @active
33087
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33056
diff changeset
   595
    def getpostclose(self, category):
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33056
diff changeset
   596
        """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
   597
        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
   598
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33056
diff changeset
   599
    @active
23764
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   600
    def addabort(self, category, callback):
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   601
        """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
   602
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   603
        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
   604
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   605
        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
   606
        with a newer callback.
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   607
        """
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   608
        self._abortcallback[category] = callback
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   609
d486e52352e8 transaction: support for callbacks during abort
Gregory Szorc <gregory.szorc@gmail.com>
parents: 23727
diff changeset
   610
    @active
44543
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   611
    def addvalidator(self, category, callback):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   612
        """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
   613
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   614
        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
   615
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   616
        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
   617
        self._validatecallback[category] = callback
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   618
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   619
    @active
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   620
    def close(self):
9220
8a4da1388553 transaction: document close(), abort() methods
Greg Ward <greg-hg@gerg.ca>
parents: 9094
diff changeset
   621
        '''commit the transaction'''
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   622
        if self._count == 1:
44543
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   623
            for category in sorted(self._validatecallback):
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   624
                self._validatecallback[category](self)
36f08ae87ef6 transaction: add functionality to have multiple validators
Pulkit Goyal <7895pulkit@gmail.com>
parents: 44407
diff changeset
   625
            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
   626
            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
   627
            while self._finalizecallback:
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   628
                callbacks = self._finalizecallback
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   629
                self._finalizecallback = {}
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   630
                categories = sorted(callbacks)
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   631
                for cat in categories:
2f1d6180737f transaction: allow finalizer to add finalizer
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44056
diff changeset
   632
                    callbacks[cat](self)
28960
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   633
            # Prevent double usage and help clear cycles.
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   634
            self._finalizecallback = None
44406
baf8c3f944eb transaction: move constant to upper case
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44097
diff changeset
   635
            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
   636
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   637
        self._count -= 1
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   638
        if self._count != 0:
1806
a2c69737e65e Automatic nesting into running transactions in the same repository.
mason@suse.com
parents: 1559
diff changeset
   639
            return
39677
d27fde3e023e transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39676
diff changeset
   640
        self._file.close()
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   641
        self._backupsfile.close()
23291
03d2d6931836 transaction: allow registering a temporary transaction file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23290
diff changeset
   642
        # cleanup temporary files
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   643
        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
   644
            if l not in self._vfsmap and c:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   645
                self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   646
                    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
   647
                )
23312
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   648
                continue
23311
64ab33ffba14 transaction: use the location value when doing backup
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23310
diff changeset
   649
            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
   650
            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
   651
                try:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   652
                    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
   653
                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
   654
                    if not c:
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   655
                        raise
006e9ef05c31 transaction: support cache file in backupentries
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23311
diff changeset
   656
                    # Abort may be raise by read only opener
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   657
                    self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   658
                        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
   659
                    )
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   660
        self._offsetmap = {}
45872
ec73a6a75985 transaction: split new files into a separate set
Joerg Sonnenberger <joerg@bec.de>
parents: 45871
diff changeset
   661
        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
   662
        self._writeundo()
39681
0d7b9db85675 transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39680
diff changeset
   663
        if self._after:
0d7b9db85675 transaction: make after a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39680
diff changeset
   664
            self._after()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   665
            self._after = None  # Help prevent cycles.
39682
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   666
        if self._opener.isfile(self._backupjournal):
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   667
            self._opener.unlink(self._backupjournal)
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   668
        if self._opener.isfile(self._journal):
b590f4763aba transaction: make opener a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39681
diff changeset
   669
            self._opener.unlink(self._journal)
27662
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   670
        for l, _f, b, c in self._backupentries:
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   671
            if l not in self._vfsmap and c:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   672
                self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   673
                    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
   674
                    b"%s\n" % (b, l)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   675
                )
27662
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   676
                continue
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   677
            vfs = self._vfsmap[l]
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   678
            if b and vfs.exists(b):
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   679
                try:
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   680
                    vfs.unlink(b)
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   681
                except (IOError, OSError, error.Abort) as inst:
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   682
                    if not c:
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   683
                        raise
f7ab50c721ac transaction: remove 'if True:'
Martin von Zweigbergk <martinvonz@google.com>
parents: 26754
diff changeset
   684
                    # Abort may be raise by read only opener
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   685
                    self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   686
                        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
   687
                    )
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   688
        self._backupentries = []
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   689
        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
   690
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   691
        self._releasefn(self, True)  # notify success of closing transaction
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   692
        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
   693
23220
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   694
        # run post close action
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   695
        categories = sorted(self._postclosecallback)
3f543f6be500 transaction: allow registering a post-close callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23204
diff changeset
   696
        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
   697
            self._postclosecallback[cat](self)
28960
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   698
        # Prevent double usage and help clear cycles.
14e683d6b273 transaction: clear callback instances after usage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28830
diff changeset
   699
        self._postclosecallback = None
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   700
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   701
    @active
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   702
    def abort(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45872
diff changeset
   703
        """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
   704
        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
   705
        scope)"""
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   706
        self._abort()
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   707
50297
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   708
    @active
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   709
    def add_journal(self, vfs_id, path):
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   710
        self._journal_files.append((vfs_id, path))
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   711
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   712
    def _writeundo(self):
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   713
        """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
   714
        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
   715
            return
50303
92734603e33e undo-files: clean existing files up before writing new one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50302
diff changeset
   716
        cleanup_undo_files(
92734603e33e undo-files: clean existing files up before writing new one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50302
diff changeset
   717
            self._report,
92734603e33e undo-files: clean existing files up before writing new one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50302
diff changeset
   718
            self._vfsmap,
92734603e33e undo-files: clean existing files up before writing new one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50302
diff changeset
   719
            undo_prefix=self._undoname,
92734603e33e undo-files: clean existing files up before writing new one
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50302
diff changeset
   720
        )
47422
88439c6fbafc transaction: simplify `undo.backupfiles` file creation with a variable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47420
diff changeset
   721
50296
dda43856ef96 undo-files: add a undoname closure to the _write_undo method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50293
diff changeset
   722
        def undoname(fn: bytes) -> bytes:
dda43856ef96 undo-files: add a undoname closure to the _write_undo method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50293
diff changeset
   723
            base, name = os.path.split(fn)
dda43856ef96 undo-files: add a undoname closure to the _write_undo method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50293
diff changeset
   724
            assert name.startswith(self._journal)
dda43856ef96 undo-files: add a undoname closure to the _write_undo method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50293
diff changeset
   725
            new_name = name.replace(self._journal, self._undoname, 1)
dda43856ef96 undo-files: add a undoname closure to the _write_undo method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50293
diff changeset
   726
            return os.path.join(base, new_name)
dda43856ef96 undo-files: add a undoname closure to the _write_undo method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50293
diff changeset
   727
47422
88439c6fbafc transaction: simplify `undo.backupfiles` file creation with a variable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47420
diff changeset
   728
        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
   729
        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
   730
        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
   731
        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
   732
            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
   733
                continue
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   734
            if not b:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   735
                u = b''
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   736
            else:
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   737
                if l not in self._vfsmap and c:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   738
                    self._report(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   739
                        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
   740
                        b"%s\n" % (b, l)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   741
                    )
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   742
                    continue
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   743
                vfs = self._vfsmap[l]
50296
dda43856ef96 undo-files: add a undoname closure to the _write_undo method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50293
diff changeset
   744
                u = undoname(b)
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   745
                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
   746
            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
   747
        undobackupfile.close()
50297
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   748
        for vfs, src in self._journal_files:
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   749
            dest = undoname(src)
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   750
            # if src and dest refer to a same file, vfs.rename is a no-op,
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   751
            # leaving both src and dest on disk. delete dest to make sure
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   752
            # the rename couldn't be such a no-op.
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   753
            vfs.tryunlink(dest)
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   754
            try:
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   755
                vfs.rename(src, dest)
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   756
            except FileNotFoundError:  # journal file does not yet exist
a43f0562220c undo-files: have the transaction directly tracks and manages journal rename
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50296
diff changeset
   757
                pass
23904
d251da5e0e84 transaction: include backup file in the "undo" transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23903
diff changeset
   758
8289
fe8a3e56039f transaction: ensure finished transactions are not reused
Henrik Stuart <hg@hstuart.dk>
parents: 8225
diff changeset
   759
    def _abort(self):
45871
a985c4fb23ca transaction: change list of journal entries into a dictionary
Joerg Sonnenberger <joerg@bec.de>
parents: 45870
diff changeset
   760
        entries = self.readjournal()
39674
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   761
        self._count = 0
3e8952c0cb45 transaction: make count and usages private attributes
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36819
diff changeset
   762
        self._usages = 0
39677
d27fde3e023e transaction: make file a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39676
diff changeset
   763
        self._file.close()
23249
84720eab4fbd transaction: mark backup-related attributes private
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23248
diff changeset
   764
        self._backupsfile.close()
8290
560af1bbfd6e transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents: 8289
diff changeset
   765
49993
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   766
        quick = self._can_quick_abort(entries)
10228
056c366fea8c transaction: initialize self.journal to None after deletion
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9693
diff changeset
   767
        try:
49994
3128018e878b transaction: run abort callback in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49993
diff changeset
   768
            if not quick:
3128018e878b transaction: run abort callback in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49993
diff changeset
   769
                self._report(_(b"transaction abort!\n"))
3128018e878b transaction: run abort callback in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49993
diff changeset
   770
            for cat in sorted(self._abortcallback):
3128018e878b transaction: run abort callback in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49993
diff changeset
   771
                self._abortcallback[cat](self)
3128018e878b transaction: run abort callback in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49993
diff changeset
   772
            # Prevent double usage and help clear cycles.
3128018e878b transaction: run abort callback in all cases
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49993
diff changeset
   773
            self._abortcallback = None
49993
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   774
            if quick:
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   775
                self._do_quick_abort(entries)
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   776
            else:
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   777
                self._do_full_abort(entries)
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   778
        finally:
39676
77c4e2ae9f07 transaction: make journal a private attribute
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39675
diff changeset
   779
            self._journal = None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   780
            self._releasefn(self, False)  # notify failure of transaction
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   781
            self._releasefn = None  # Help prevent cycles.
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   782
49993
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   783
    def _can_quick_abort(self, entries):
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   784
        """False if any semantic content have been written on disk
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   785
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   786
        True if nothing, except temporary files has been writen on disk."""
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   787
        if entries:
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   788
            return False
49995
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   789
        for e in self._backupentries:
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   790
            if e[1]:
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   791
                return False
49993
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   792
        return True
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   793
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   794
    def _do_quick_abort(self, entries):
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   795
        """(Silently) do a quick cleanup (see _can_quick_abort)"""
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   796
        assert self._can_quick_abort(entries)
49995
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   797
        tmp_files = [e for e in self._backupentries if not e[1]]
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   798
        for vfs_id, old_path, tmp_path, xxx in tmp_files:
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   799
            vfs = self._vfsmap[vfs_id]
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   800
            try:
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   801
                vfs.unlink(tmp_path)
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   802
            except FileNotFoundError:
27fd12eca557 transaction: quietly rollback if no other changes than temporary files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49994
diff changeset
   803
                pass
49993
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   804
        if self._backupjournal:
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   805
            self._opener.unlink(self._backupjournal)
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   806
        if self._journal:
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   807
            self._opener.unlink(self._journal)
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   808
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   809
    def _do_full_abort(self, entries):
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   810
        """(Noisily) rollback all the change introduced by the transaction"""
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   811
        try:
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   812
            _playback(
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   813
                self._journal,
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   814
                self._report,
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   815
                self._opener,
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   816
                self._vfsmap,
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   817
                entries,
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   818
                self._backupentries,
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   819
                False,
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   820
                checkambigfiles=self._checkambigfiles,
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   821
            )
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   822
            self._report(_(b"rollback completed\n"))
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   823
        except BaseException as exc:
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   824
            self._report(_(b"rollback failed - please run hg recover\n"))
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   825
            self._report(
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   826
                _(b"(failure reason: %s)\n") % stringutil.forcebytestr(exc)
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   827
            )
2f348babe30d transaction: clarify the "quick abort" scenario
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49306
diff changeset
   828
8290
560af1bbfd6e transaction: reset transaction on abort
Henrik Stuart <hg@hstuart.dk>
parents: 8289
diff changeset
   829
47419
0e4e9c1b4cc8 transaction: extract message about different version in a constants
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47418
diff changeset
   830
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
   831
    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
   832
)
0e4e9c1b4cc8 transaction: extract message about different version in a constants
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47418
diff changeset
   833
0e4e9c1b4cc8 transaction: extract message about different version in a constants
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47418
diff changeset
   834
50293
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   835
def read_backup_files(report, fp):
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   836
    """parse an (already open) backup file an return contained backup entries
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   837
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   838
    entries are in the form: (location, file, backupfile, xxx)
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   839
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   840
    :location:   the vfs identifier (vfsmap's key)
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   841
    :file:       original file path (in the vfs)
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   842
    :backupfile: path of the backup (in the vfs)
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   843
    :cache:      a boolean currently always set to False
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   844
    """
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   845
    lines = fp.readlines()
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   846
    backupentries = []
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   847
    if lines:
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   848
        ver = lines[0][:-1]
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   849
        if ver != (b'%d' % version):
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   850
            report(BAD_VERSION_MSG)
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   851
        else:
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   852
            for line in lines[1:]:
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   853
                if line:
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   854
                    # Shave off the trailing newline
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   855
                    line = line[:-1]
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   856
                    l, f, b, c = line.split(b'\0')
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   857
                    backupentries.append((l, f, b, bool(c)))
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   858
    return backupentries
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   859
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   860
50070
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   861
def rollback(
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   862
    opener,
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   863
    vfsmap,
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   864
    file,
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   865
    report,
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   866
    checkambigfiles=None,
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   867
    skip_journal_pattern=None,
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   868
):
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   869
    """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
   870
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   871
    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
   872
    '*.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
   873
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   874
    * `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
   875
    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
   876
    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
   877
    '*.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
   878
    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
   879
87bca10a06ed transaction: avoid file stat ambiguity only for files in blacklist
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33087
diff changeset
   880
    `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
   881
    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
   882
    restoring corresponded files.
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   883
    """
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   884
    entries = []
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   885
    backupentries = []
8294
48a382c23226 transaction: refactor transaction.abort and rollback to use the same code
Henrik Stuart <hg@hstuart.dk>
parents: 8290
diff changeset
   886
47307
13dd5bb5492a transaction: trivial refactoring
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47286
diff changeset
   887
    with opener.open(file) as fp:
13dd5bb5492a transaction: trivial refactoring
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 47286
diff changeset
   888
        lines = fp.readlines()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 11685
diff changeset
   889
    for l in lines:
20524
28b8ff84db3f journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents: 20087
diff changeset
   890
        try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   891
            f, o = l.split(b'\0')
45869
63edc384d3b7 transaction: drop per-file extra data support
Joerg Sonnenberger <joerg@bec.de>
parents: 45738
diff changeset
   892
            entries.append((f, int(o)))
20524
28b8ff84db3f journal: report parsing errors on recover/rollback (issue4172)
Matt Mackall <mpm@selenic.com>
parents: 20087
diff changeset
   893
        except ValueError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   894
            report(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   895
                _(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
   896
            )
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
   897
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   898
    backupjournal = b"%s.backupfiles" % file
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   899
    if opener.exists(backupjournal):
50293
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   900
        with opener.open(backupjournal) as fp:
5e568d70f54d undo-files: add a utility function to read the backup-files definition
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 50268
diff changeset
   901
            backupentries = read_backup_files(report, fp)
50070
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   902
    if skip_journal_pattern is not None:
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   903
        keep = lambda x: not skip_journal_pattern.match(x[1])
c8f32aa80dca rollback: explicitly skip dirstate rollback when applicable
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49995
diff changeset
   904
        backupentries = [x for x in backupentries if keep(x)]
20882
5dffd06f1e50 transaction: add support for non-append files
Durham Goode <durham@fb.com>
parents: 20881
diff changeset
   905
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   906
    _playback(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   907
        file,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   908
        report,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   909
        opener,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   910
        vfsmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   911
        entries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   912
        backupentries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   913
        checkambigfiles=checkambigfiles,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43050
diff changeset
   914
    )