Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/state.py @ 42539:12243f15d53e
statecheck: added support for STATES
This removes `STATES` from `state.py` and adds support to
`statecheck` class to handle its features.
`getrepostate()` function is modified accordingly.
This adds a method 'cmdutil.addunfinished()' for appending to
the unfinishedstate list so as to keep 'merge' and 'bisect' at the last.
This also makes two separate message formats for `checkunfinished()` and
`getrepostate()` as there were previously present.
Results of test changed are shown.
Differential Revision: https://phab.mercurial-scm.org/D6503
author | Taapas Agrawal <taapas2897@gmail.com> |
---|---|
date | Sun, 09 Jun 2019 02:12:58 +0530 |
parents | 5bddd2244814 |
children | 0231032729c4 |
comparison
equal
deleted
inserted
replaced
42538:5bddd2244814 | 42539:12243f15d53e |
---|---|
96 It also has the ability to register and determine the states of any new | 96 It also has the ability to register and determine the states of any new |
97 multistep operation or multistep command extension. | 97 multistep operation or multistep command extension. |
98 """ | 98 """ |
99 | 99 |
100 def __init__(self, opname, fname, clearable=False, allowcommit=False, | 100 def __init__(self, opname, fname, clearable=False, allowcommit=False, |
101 cmdmsg="", cmdhint=""): | 101 reportonly=False, stopflag=False, cmdmsg="", cmdhint="", |
102 statushint=""): | |
102 """opname is the name the command or operation | 103 """opname is the name the command or operation |
103 fname is the file name in which data should be stored in .hg directory. | 104 fname is the file name in which data should be stored in .hg directory. |
104 It is None for merge command. | 105 It is None for merge command. |
105 clearable boolean determines whether or not interrupted states can be | 106 clearable boolean determines whether or not interrupted states can be |
106 cleared by running `hg update -C .` which in turn deletes the | 107 cleared by running `hg update -C .` which in turn deletes the |
107 state file. | 108 state file. |
108 allowcommit boolean decides whether commit is allowed during interrupted | 109 allowcommit boolean decides whether commit is allowed during interrupted |
109 state or not. | 110 state or not. |
111 reportonly flag is used for operations like bisect where we just | |
112 need to detect the operation using 'hg status --verbose' | |
113 stopflag is a boolean that determines whether or not a command supports | |
114 --stop flag | |
110 cmdmsg is used to pass a different status message in case standard | 115 cmdmsg is used to pass a different status message in case standard |
111 message of the format "abort: cmdname in progress" is not desired. | 116 message of the format "abort: cmdname in progress" is not desired. |
112 cmdhint is used to pass a different hint message in case standard | 117 cmdhint is used to pass a different hint message in case standard |
113 message of the format use 'hg cmdname --continue' or | 118 message of the format "To continue: hg cmdname --continue |
114 'hg cmdname --abort'" is not desired. | 119 To abort: hg cmdname --abort" is not desired. |
120 statushint is used to pass a different status message in case standard | |
121 message of the format ('To continue: hg cmdname --continue' | |
122 'To abort: hg cmdname --abort') is not desired | |
115 """ | 123 """ |
116 self._opname = opname | 124 self._opname = opname |
117 self._fname = fname | 125 self._fname = fname |
118 self._clearable = clearable | 126 self._clearable = clearable |
119 self._allowcommit = allowcommit | 127 self._allowcommit = allowcommit |
120 self._cmdhint = cmdhint | 128 self._cmdhint = cmdhint |
129 self._statushint = statushint | |
121 self._cmdmsg = cmdmsg | 130 self._cmdmsg = cmdmsg |
131 self._stopflag = stopflag | |
132 self._reportonly = reportonly | |
133 | |
134 def statusmsg(self): | |
135 """returns the hint message corresponding to the command for | |
136 hg status --verbose | |
137 """ | |
138 if not self._statushint: | |
139 hint = (_('To continue: hg %s --continue\n' | |
140 'To abort: hg %s --abort') % (self._opname, | |
141 self._opname)) | |
142 if self._stopflag: | |
143 hint = hint + (_('\nTo stop: hg %s --stop') % | |
144 (self._opname)) | |
145 return hint | |
146 return self._statushint | |
122 | 147 |
123 def hint(self): | 148 def hint(self): |
124 """returns the hint message corresponding to the command""" | 149 """returns the hint message corresponding to an interrupted |
150 operation | |
151 """ | |
125 if not self._cmdhint: | 152 if not self._cmdhint: |
126 return (_("use 'hg %s --continue' or 'hg %s --abort'") % | 153 return (_("use 'hg %s --continue' or 'hg %s --abort'") % |
127 (self._opname, self._opname)) | 154 (self._opname, self._opname)) |
128 return self._cmdhint | 155 return self._cmdhint |
129 | 156 |
132 if not self._cmdmsg: | 159 if not self._cmdmsg: |
133 return _('%s in progress') % (self._opname) | 160 return _('%s in progress') % (self._opname) |
134 return self._cmdmsg | 161 return self._cmdmsg |
135 | 162 |
136 def isunfinished(self, repo): | 163 def isunfinished(self, repo): |
137 """determines whether a multi-step operation is in progress or not""" | 164 """determines whether a multi-step operation is in progress |
138 return repo.vfs.exists(self._fname) | 165 or not |
166 """ | |
167 if self._opname == 'merge': | |
168 return len(repo[None].parents()) > 1 | |
169 else: | |
170 return repo.vfs.exists(self._fname) | |
139 | 171 |
140 # A list of statecheck objects for multistep operations like graft. | 172 # A list of statecheck objects for multistep operations like graft. |
141 _unfinishedstates = [] | 173 _unfinishedstates = [] |
142 | 174 |
143 def addunfinished(opname, **kwargs): | 175 def addunfinished(opname, **kwargs): |
144 """this registers a new command or operation to unfinishedstates | 176 """this registers a new command or operation to unfinishedstates |
145 """ | 177 """ |
146 statecheckobj = _statecheck(opname, **kwargs) | 178 statecheckobj = _statecheck(opname, **kwargs) |
147 _unfinishedstates.append(statecheckobj) | 179 if opname == 'merge': |
148 | 180 _unfinishedstates.append(statecheckobj) |
149 addunfinished( | 181 else: |
150 'graft', fname='graftstate', clearable=True, | 182 _unfinishedstates.insert(0, statecheckobj) |
151 cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop") | 183 |
184 addunfinished( | |
185 'graft', fname='graftstate', clearable=True, stopflag=True, | |
186 cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop"), | |
152 ) | 187 ) |
153 addunfinished( | 188 addunfinished( |
154 'update', fname='updatestate', clearable=True, | 189 'update', fname='updatestate', clearable=True, |
155 cmdmsg=_('last update was interrupted'), | 190 cmdmsg=_('last update was interrupted'), |
156 cmdhint=_("use 'hg update' to get a consistent checkout") | 191 cmdhint=_("use 'hg update' to get a consistent checkout"), |
157 ) | 192 statushint=_("To continue: hg update") |
158 | 193 ) |
159 def _commentlines(raw): | 194 addunfinished( |
160 '''Surround lineswith a comment char and a new line''' | 195 'bisect', fname='bisect.state', allowcommit=True, reportonly=True, |
161 lines = raw.splitlines() | 196 statushint=_('To mark the changeset good: hg bisect --good\n' |
162 commentedlines = ['# %s' % line for line in lines] | 197 'To mark the changeset bad: hg bisect --bad\n' |
163 return '\n'.join(commentedlines) + '\n' | 198 'To abort: hg bisect --reset\n') |
164 | 199 ) |
165 def _helpmessage(continuecmd, abortcmd): | 200 addunfinished( |
166 msg = _('To continue: %s\n' | 201 'merge', fname=None, clearable=True, allowcommit=True, |
167 'To abort: %s') % (continuecmd, abortcmd) | 202 cmdmsg=_('outstanding uncommitted merge'), |
168 return _commentlines(msg) | 203 statushint=_('To continue: hg commit\n' |
169 | 204 'To abort: hg merge --abort'), |
170 def _rebasemsg(): | 205 cmdhint=_("use 'hg commit' or 'hg merge --abort'") |
171 return _helpmessage('hg rebase --continue', 'hg rebase --abort') | |
172 | |
173 def _histeditmsg(): | |
174 return _helpmessage('hg histedit --continue', 'hg histedit --abort') | |
175 | |
176 def _unshelvemsg(): | |
177 return _helpmessage('hg unshelve --continue', 'hg unshelve --abort') | |
178 | |
179 def _graftmsg(): | |
180 return _helpmessage('hg graft --continue', 'hg graft --abort') | |
181 | |
182 def _mergemsg(): | |
183 return _helpmessage('hg commit', 'hg merge --abort') | |
184 | |
185 def _bisectmsg(): | |
186 msg = _('To mark the changeset good: hg bisect --good\n' | |
187 'To mark the changeset bad: hg bisect --bad\n' | |
188 'To abort: hg bisect --reset\n') | |
189 return _commentlines(msg) | |
190 | |
191 def fileexistspredicate(filename): | |
192 return lambda repo: repo.vfs.exists(filename) | |
193 | |
194 def _mergepredicate(repo): | |
195 return len(repo[None].parents()) > 1 | |
196 | |
197 STATES = ( | |
198 # (state, predicate to detect states, helpful message function) | |
199 ('histedit', fileexistspredicate('histedit-state'), _histeditmsg), | |
200 ('bisect', fileexistspredicate('bisect.state'), _bisectmsg), | |
201 ('graft', fileexistspredicate('graftstate'), _graftmsg), | |
202 ('unshelve', fileexistspredicate('shelvedstate'), _unshelvemsg), | |
203 ('rebase', fileexistspredicate('rebasestate'), _rebasemsg), | |
204 # The merge state is part of a list that will be iterated over. | |
205 # They need to be last because some of the other unfinished states may also | |
206 # be in a merge or update state (eg. rebase, histedit, graft, etc). | |
207 # We want those to have priority. | |
208 ('merge', _mergepredicate, _mergemsg), | |
209 ) | 206 ) |
210 | 207 |
211 def getrepostate(repo): | 208 def getrepostate(repo): |
212 # experimental config: commands.status.skipstates | 209 # experimental config: commands.status.skipstates |
213 skip = set(repo.ui.configlist('commands', 'status.skipstates')) | 210 skip = set(repo.ui.configlist('commands', 'status.skipstates')) |
214 for state, statedetectionpredicate, msgfn in STATES: | 211 for state in _unfinishedstates: |
215 if state in skip: | 212 if state._opname in skip: |
216 continue | 213 continue |
217 if statedetectionpredicate(repo): | 214 if state.isunfinished(repo): |
218 return (state, statedetectionpredicate, msgfn) | 215 return (state._opname, state.statusmsg()) |