annotate mercurial/dirstateguard.py @ 47012:222a42ac5b2d stable

dirstateguard: use mktemp-like functionality to generate the backup filenames Previously these were generated with names like: `dirstate.backup.commit.<memory address of dirstateguard>` This could cause problems if two hg commands ran at the same time that used the same memory address, (which is apparently not uncommon if chg is involved), as memory addresses are not unique across processes. This issue was reported in the post-review comments on http://phab.mercurial-scm.org/D9952. Differential Revision: https://phab.mercurial-scm.org/D10504
author Kyle Lippincott <spectral@google.com>
date Tue, 20 Apr 2021 13:01:47 -0700
parents d4ba4d51f85f
children 6000f5b25c9b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
30497
751639bf6fc4 dirstateguard: move to new module so I can break some layering violations
Augie Fackler <augie@google.com>
parents: 30482
diff changeset
1 # dirstateguard.py - class to allow restoring dirstate after failure
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
2 #
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 45957
diff changeset
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8210
diff changeset
5 # 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: 10249
diff changeset
6 # GNU General Public License version 2 or any later version.
2874
4ec58b157265 refactor text diff/patch code.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
7
28322
ebd0e86bdf89 cmdutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28313
diff changeset
8 from __future__ import absolute_import
ebd0e86bdf89 cmdutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28313
diff changeset
9
47012
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
10 import os
28322
ebd0e86bdf89 cmdutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28313
diff changeset
11 from .i18n import _
ebd0e86bdf89 cmdutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28313
diff changeset
12
ebd0e86bdf89 cmdutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28313
diff changeset
13 from . import (
ebd0e86bdf89 cmdutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28313
diff changeset
14 error,
38908
ad24b581e4d9 narrow: call narrowspec.{save,restore,clear}backup directly
Martin von Zweigbergk <martinvonz@google.com>
parents: 33814
diff changeset
15 narrowspec,
47012
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
16 requirements,
33814
bbbbd3c30bfc util: add base class for transactional context managers
Martin von Zweigbergk <martinvonz@google.com>
parents: 33691
diff changeset
17 util,
28322
ebd0e86bdf89 cmdutil: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28313
diff changeset
18 )
27624
d46db4390715 resolve: suggest the next action
timeless <timeless@mozdev.org>
parents: 27622
diff changeset
19
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
20
33814
bbbbd3c30bfc util: add base class for transactional context managers
Martin von Zweigbergk <martinvonz@google.com>
parents: 33691
diff changeset
21 class dirstateguard(util.transactional):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43077
diff changeset
22 """Restore dirstate at unexpected failure.
24991
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
23
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
24 At the construction, this class does:
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
25
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
26 - write current ``repo.dirstate`` out, and
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
27 - save ``.hg/dirstate`` into the backup file
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
28
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
29 This restores ``.hg/dirstate`` from backup file, if ``release()``
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
30 is invoked before ``close()``.
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
31
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
32 This just removes the backup file at ``close()`` before ``release()``.
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 43077
diff changeset
33 """
24991
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
34
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
35 def __init__(self, repo, name):
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
36 self._repo = repo
30182
144d8fe266d9 cmdutil: satisfy expections in dirstateguard.__del__, even if __init__ fails
Mads Kiilerich <madski@unity3d.com>
parents: 30151
diff changeset
37 self._active = False
144d8fe266d9 cmdutil: satisfy expections in dirstateguard.__del__, even if __init__ fails
Mads Kiilerich <madski@unity3d.com>
parents: 30151
diff changeset
38 self._closed = False
47012
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
39
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
40 def getname(prefix):
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
41 fd, fname = repo.vfs.mkstemp(prefix=prefix)
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
42 os.close(fd)
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
43 return fname
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
44
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
45 self._backupname = getname(b'dirstate.backup.%s.' % name)
33440
ec306bc6915b dirstate: update backup functions to take full backup filename
Adam Simpkins <simpkins@fb.com>
parents: 30497
diff changeset
46 repo.dirstate.savebackup(repo.currenttransaction(), self._backupname)
47012
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
47 # Don't make this the empty string, things may join it with stuff and
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
48 # blindly try to unlink it, which could be bad.
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
49 self._narrowspecbackupname = None
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
50 if requirements.NARROW_REQUIREMENT in repo.requirements:
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
51 self._narrowspecbackupname = getname(
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
52 b'narrowspec.backup.%s.' % name
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
53 )
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
54 narrowspec.savewcbackup(repo, self._narrowspecbackupname)
24991
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
55 self._active = True
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
56
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
57 def __del__(self):
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
58 if self._active: # still active
24991
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
59 # this may occur, even if this class is used correctly:
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
60 # for example, releasing other resources like transaction
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
61 # may raise exception before ``dirstateguard.release`` in
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
62 # ``release(tr, ....)``.
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
63 self._abort()
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
64
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
65 def close(self):
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
66 if not self._active: # already inactivated
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
67 msg = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
68 _(b"can't close already inactivated backup: %s")
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
69 % self._backupname
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
70 )
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26579
diff changeset
71 raise error.Abort(msg)
24991
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
72
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
73 self._repo.dirstate.clearbackup(
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
74 self._repo.currenttransaction(), self._backupname
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
75 )
47012
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
76 if self._narrowspecbackupname:
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
77 narrowspec.clearwcbackup(self._repo, self._narrowspecbackupname)
24991
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
78 self._active = False
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
79 self._closed = True
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
80
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
81 def _abort(self):
47012
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
82 if self._narrowspecbackupname:
222a42ac5b2d dirstateguard: use mktemp-like functionality to generate the backup filenames
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
83 narrowspec.restorewcbackup(self._repo, self._narrowspecbackupname)
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
84 self._repo.dirstate.restorebackup(
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
85 self._repo.currenttransaction(), self._backupname
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
86 )
24991
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
87 self._active = False
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
88
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
89 def release(self):
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
90 if not self._closed:
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
91 if not self._active: # already inactivated
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
92 msg = (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
93 _(b"can't release already inactivated backup: %s")
43075
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
94 % self._backupname
57875cf423c9 style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents: 41227
diff changeset
95 )
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26579
diff changeset
96 raise error.Abort(msg)
24991
4169a4f83548 cmdutil: add class to restore dirstate during unexpected failure
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24988
diff changeset
97 self._abort()