Mercurial > hg
annotate mercurial/state.py @ 38128:1cba497491be
narrow: only wrap dirstate functions once, instead of per-reposetup
chg will call reposetup multiple times, and we would end up double-wrapping (or
worse) the dirstate functions; this can cause issues like OSError 'No such file
or directory' during rebase operations, when we go to double-delete our
narrowspec backup file.
Differential Revision: https://phab.mercurial-scm.org/D3559
author | Kyle Lippincott <spectral@google.com> |
---|---|
date | Wed, 16 May 2018 14:59:32 -0700 |
parents | b7e5c53a779e |
children | dce718404ce6 |
rev | line source |
---|---|
38103
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
1 # state.py - writing and reading state files in Mercurial |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
2 # |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
3 # Copyright 2018 Pulkit Goyal <pulkitmgoyal@gmail.com> |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
4 # |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
7 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
8 """ |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
9 This file contains class to wrap the state for commands and other |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
10 related logic. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
11 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
12 All the data related to the command state is stored as dictionary in the object. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
13 The class has methods using which the data can be stored to disk in a file under |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
14 .hg/ directory. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
15 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
16 We store the data on disk in cbor, for which we use the third party cbor library |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
17 to serialize and deserialize data. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
18 """ |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
19 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
20 from __future__ import absolute_import |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
21 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
22 from .thirdparty import cbor |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
23 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
24 from . import ( |
38106
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
25 error, |
38103
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
26 util, |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
27 ) |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
28 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
29 class cmdstate(object): |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
30 """a wrapper class to store the state of commands like `rebase`, `graft`, |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
31 `histedit`, `shelve` etc. Extensions can also use this to write state files. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
32 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
33 All the data for the state is stored in the form of key-value pairs in a |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
34 dictionary. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
35 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
36 The class object can write all the data to a file in .hg/ directory and |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
37 can populate the object data reading that file. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
38 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
39 Uses cbor to serialize and deserialize data while writing and reading from |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
40 disk. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
41 """ |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
42 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
43 def __init__(self, repo, fname, opts=None): |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
44 """ repo is the repo object |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
45 fname is the file name in which data should be stored in .hg directory |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
46 opts is a dictionary of data of the statefile |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
47 """ |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
48 self._repo = repo |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
49 self.fname = fname |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
50 |
38104
36a5a1239a15
state: don't have a dict like interface for cmdstate class
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38103
diff
changeset
|
51 def read(self): |
36a5a1239a15
state: don't have a dict like interface for cmdstate class
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38103
diff
changeset
|
52 """read the existing state file and return a dict of data stored""" |
36a5a1239a15
state: don't have a dict like interface for cmdstate class
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38103
diff
changeset
|
53 return self._read() |
38103
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
54 |
38106
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
55 def save(self, version, data): |
38103
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
56 """write all the state data stored to .hg/<filename> file |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
57 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
58 we use third-party library cbor to serialize data to write in the file. |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
59 """ |
38106
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
60 if not isinstance(version, int): |
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
61 raise error.ProgrammingError("version of state file should be" |
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
62 " an integer") |
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
63 |
38103
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
64 with self._repo.vfs(self.fname, 'wb', atomictemp=True) as fp: |
38126
bdc4079ceb16
state: fix usage of an unassigned variable
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38106
diff
changeset
|
65 fp.write('%d\n' % version) |
38105
18c6d8b565bf
state: set canonical=True to write deterministically
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38104
diff
changeset
|
66 cbor.dump(self.opts, fp, canonical=True) |
38103
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
67 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
68 def _read(self): |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
69 """reads the state file and returns a dictionary which contain |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
70 data in the same format as it was before storing""" |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
71 with self._repo.vfs(self.fname, 'rb') as fp: |
38106
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
72 try: |
38127
b7e5c53a779e
state: temporary silence pyflakes warning by removing variable assignment
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38126
diff
changeset
|
73 int(fp.readline()) |
38106
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
74 except ValueError: |
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
75 raise error.ProgrammingError("unknown version of state file" |
a0e4d654bceb
state: write the version number in plain text on top of state files
Pulkit Goyal <7895pulkit@gmail.com>
parents:
38105
diff
changeset
|
76 " found") |
38103
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
77 return cbor.load(fp) |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
78 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
79 def delete(self): |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
80 """drop the state file if exists""" |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
81 util.unlinkpath(self._repo.vfs.join(self.fname), ignoremissing=True) |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
82 |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
83 def exists(self): |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
84 """check whether the state file exists or not""" |
a2f83661f721
state: import the file to write state files from evolve extension
Pulkit Goyal <7895pulkit@gmail.com>
parents:
diff
changeset
|
85 return self._repo.vfs.exists(self.fname) |