Mercurial > hg-stable
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 |
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 | 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() |