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