Show More
@@ -1822,7 +1822,7 b' def pullrebase(orig, ui, repo, *args, **' | |||
|
1822 | 1822 | ui.debug('--update and --rebase are not compatible, ignoring ' |
|
1823 | 1823 | 'the update flag\n') |
|
1824 | 1824 | |
|
1825 | cmdutil.checkunfinished(repo) | |
|
1825 | cmdutil.checkunfinished(repo, skipmerge=True) | |
|
1826 | 1826 | cmdutil.bailifchanged(repo, hint=_('cannot pull with rebase: ' |
|
1827 | 1827 | 'please commit or shelve your changes first')) |
|
1828 | 1828 | |
@@ -1950,6 +1950,6 b' def uisetup(ui):' | |||
|
1950 | 1950 | entry[1].append(('t', 'tool', '', |
|
1951 | 1951 | _("specify merge tool for rebase"))) |
|
1952 | 1952 | cmdutil.summaryhooks.add('rebase', summaryhook) |
|
1953 | statemod.addunfinished('rebase', fname='rebasestate') | |
|
1953 | statemod.addunfinished('rebase', fname='rebasestate', stopflag=True) | |
|
1954 | 1954 | cmdutil.afterresolvedstates.append( |
|
1955 | 1955 | ['rebasestate', _('hg rebase --continue')]) |
@@ -32,10 +32,12 b' command = registrar.command(cmdtable)' | |||
|
32 | 32 | testedwith = 'ships-with-hg-core' |
|
33 | 33 | |
|
34 | 34 | def checklocalchanges(repo, force=False): |
|
35 | cmdutil.checkunfinished(repo) | |
|
36 | 35 | s = repo.status() |
|
37 | 36 | if not force: |
|
37 | cmdutil.checkunfinished(repo) | |
|
38 | 38 | cmdutil.bailifchanged(repo) |
|
39 | else: | |
|
40 | cmdutil.checkunfinished(repo, skipmerge=True) | |
|
39 | 41 | return s |
|
40 | 42 | |
|
41 | 43 | def _findupdatetarget(repo, nodes): |
@@ -760,6 +760,8 b' def kwtransplanted(context, mapping):' | |||
|
760 | 760 | def extsetup(ui): |
|
761 | 761 | statemod.addunfinished ( |
|
762 | 762 | 'transplant', fname='transplant/journal', clearable=True, |
|
763 | statushint=_('To continue: hg transplant --continue\n' | |
|
764 | 'To abort: hg update'), | |
|
763 | 765 | cmdhint=_("use 'hg transplant --continue' or 'hg update' to abort") |
|
764 | 766 | ) |
|
765 | 767 |
@@ -623,15 +623,14 b' def morestatus(repo, fm):' | |||
|
623 | 623 | statetuple = statemod.getrepostate(repo) |
|
624 | 624 | label = 'status.morestatus' |
|
625 | 625 | if statetuple: |
|
626 |
state |
|
|
626 | state, helpfulmsg = statetuple | |
|
627 | 627 | statemsg = _('The repository is in an unfinished *%s* state.') % state |
|
628 | 628 | fm.plain('%s\n' % _commentlines(statemsg), label=label) |
|
629 | 629 | conmsg = _conflictsmsg(repo) |
|
630 | 630 | if conmsg: |
|
631 | 631 | fm.plain('%s\n' % conmsg, label=label) |
|
632 | 632 | if helpfulmsg: |
|
633 | helpmsg = helpfulmsg() | |
|
634 | fm.plain('%s\n' % helpmsg, label=label) | |
|
633 | fm.plain('%s\n' % _commentlines(helpfulmsg), label=label) | |
|
635 | 634 | |
|
636 | 635 | def findpossible(cmd, table, strict=False): |
|
637 | 636 | """ |
@@ -3260,7 +3259,7 b' summaryhooks = util.hooks()' | |||
|
3260 | 3259 | summaryremotehooks = util.hooks() |
|
3261 | 3260 | |
|
3262 | 3261 | |
|
3263 | def checkunfinished(repo, commit=False): | |
|
3262 | def checkunfinished(repo, commit=False, skipmerge=False): | |
|
3264 | 3263 | '''Look for an unfinished multistep operation, like graft, and abort |
|
3265 | 3264 | if found. It's probably good to check this right before |
|
3266 | 3265 | bailifchanged(). |
@@ -3268,13 +3267,15 b' def checkunfinished(repo, commit=False):' | |||
|
3268 | 3267 | # Check for non-clearable states first, so things like rebase will take |
|
3269 | 3268 | # precedence over update. |
|
3270 | 3269 | for state in statemod._unfinishedstates: |
|
3271 |
if state._clearable or (commit and state._allowcommit) |
|
|
3270 | if (state._clearable or (commit and state._allowcommit) or | |
|
3271 | state._reportonly): | |
|
3272 | 3272 | continue |
|
3273 | 3273 | if state.isunfinished(repo): |
|
3274 | 3274 | raise error.Abort(state.msg(), hint=state.hint()) |
|
3275 | 3275 | |
|
3276 | 3276 | for s in statemod._unfinishedstates: |
|
3277 |
if not s._clearable or (commit and s._allowcommit) |
|
|
3277 | if (not s._clearable or (commit and s._allowcommit) or | |
|
3278 | (s._opname == 'merge' and skipmerge) or s._reportonly): | |
|
3278 | 3279 | continue |
|
3279 | 3280 | if s.isunfinished(repo): |
|
3280 | 3281 | raise error.Abort(s.msg(), hint=s.hint()) |
@@ -3284,10 +3285,14 b' def clearunfinished(repo):' | |||
|
3284 | 3285 | that are clearable. |
|
3285 | 3286 | ''' |
|
3286 | 3287 | for state in statemod._unfinishedstates: |
|
3288 | if state._reportonly: | |
|
3289 | continue | |
|
3287 | 3290 | if not state._clearable and state.isunfinished(repo): |
|
3288 | 3291 | raise error.Abort(state.msg(), hint=state.hint()) |
|
3289 | 3292 | |
|
3290 | 3293 | for s in statemod._unfinishedstates: |
|
3294 | if s._opname == 'merge' or state._reportonly: | |
|
3295 | continue | |
|
3291 | 3296 | if s._clearable and s.isunfinished(repo): |
|
3292 | 3297 | util.unlink(repo.vfs.join(s._fname)) |
|
3293 | 3298 |
@@ -98,7 +98,8 b' class _statecheck(object):' | |||
|
98 | 98 | """ |
|
99 | 99 | |
|
100 | 100 | def __init__(self, opname, fname, clearable=False, allowcommit=False, |
|
101 |
cmdmsg="", cmdhint="" |
|
|
101 | reportonly=False, stopflag=False, cmdmsg="", cmdhint="", | |
|
102 | statushint=""): | |
|
102 | 103 | """opname is the name the command or operation |
|
103 | 104 | fname is the file name in which data should be stored in .hg directory. |
|
104 | 105 | It is None for merge command. |
@@ -107,21 +108,47 b' class _statecheck(object):' | |||
|
107 | 108 | state file. |
|
108 | 109 | allowcommit boolean decides whether commit is allowed during interrupted |
|
109 | 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 | 115 | cmdmsg is used to pass a different status message in case standard |
|
111 | 116 | message of the format "abort: cmdname in progress" is not desired. |
|
112 | 117 | cmdhint is used to pass a different hint message in case standard |
|
113 |
message of the format u |
|
|
114 |
|
|
|
118 | message of the format "To continue: hg cmdname --continue | |
|
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 | 124 | self._opname = opname |
|
117 | 125 | self._fname = fname |
|
118 | 126 | self._clearable = clearable |
|
119 | 127 | self._allowcommit = allowcommit |
|
120 | 128 | self._cmdhint = cmdhint |
|
129 | self._statushint = statushint | |
|
121 | 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 | 148 | def hint(self): |
|
124 |
"""returns the hint message corresponding to |
|
|
149 | """returns the hint message corresponding to an interrupted | |
|
150 | operation | |
|
151 | """ | |
|
125 | 152 | if not self._cmdhint: |
|
126 | 153 | return (_("use 'hg %s --continue' or 'hg %s --abort'") % |
|
127 | 154 | (self._opname, self._opname)) |
@@ -134,8 +161,13 b' class _statecheck(object):' | |||
|
134 | 161 | return self._cmdmsg |
|
135 | 162 | |
|
136 | 163 | def isunfinished(self, repo): |
|
137 |
"""determines whether a multi-step operation is in progress |
|
|
138 | return repo.vfs.exists(self._fname) | |
|
164 | """determines whether a multi-step operation is in progress | |
|
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 | 172 | # A list of statecheck objects for multistep operations like graft. |
|
141 | 173 | _unfinishedstates = [] |
@@ -144,75 +176,40 b' def addunfinished(opname, **kwargs):' | |||
|
144 | 176 | """this registers a new command or operation to unfinishedstates |
|
145 | 177 | """ |
|
146 | 178 | statecheckobj = _statecheck(opname, **kwargs) |
|
147 | _unfinishedstates.append(statecheckobj) | |
|
179 | if opname == 'merge': | |
|
180 | _unfinishedstates.append(statecheckobj) | |
|
181 | else: | |
|
182 | _unfinishedstates.insert(0, statecheckobj) | |
|
148 | 183 | |
|
149 | 184 | addunfinished( |
|
150 | 'graft', fname='graftstate', clearable=True, | |
|
151 | cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop") | |
|
185 | 'graft', fname='graftstate', clearable=True, stopflag=True, | |
|
186 | cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop"), | |
|
152 | 187 | ) |
|
153 | 188 | addunfinished( |
|
154 | 189 | 'update', fname='updatestate', clearable=True, |
|
155 | 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"), | |
|
192 | statushint=_("To continue: hg update") | |
|
157 | 193 | ) |
|
158 | ||
|
159 | def _commentlines(raw): | |
|
160 | '''Surround lineswith a comment char and a new line''' | |
|
161 | lines = raw.splitlines() | |
|
162 | commentedlines = ['# %s' % line for line in lines] | |
|
163 | return '\n'.join(commentedlines) + '\n' | |
|
164 | ||
|
165 | def _helpmessage(continuecmd, abortcmd): | |
|
166 | msg = _('To continue: %s\n' | |
|
167 | 'To abort: %s') % (continuecmd, abortcmd) | |
|
168 | return _commentlines(msg) | |
|
169 | ||
|
170 | def _rebasemsg(): | |
|
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), | |
|
194 | addunfinished( | |
|
195 | 'bisect', fname='bisect.state', allowcommit=True, reportonly=True, | |
|
196 | statushint=_('To mark the changeset good: hg bisect --good\n' | |
|
197 | 'To mark the changeset bad: hg bisect --bad\n' | |
|
198 | 'To abort: hg bisect --reset\n') | |
|
199 | ) | |
|
200 | addunfinished( | |
|
201 | 'merge', fname=None, clearable=True, allowcommit=True, | |
|
202 | cmdmsg=_('outstanding uncommitted merge'), | |
|
203 | statushint=_('To continue: hg commit\n' | |
|
204 | 'To abort: hg merge --abort'), | |
|
205 | cmdhint=_("use 'hg commit' or 'hg merge --abort'") | |
|
209 | 206 | ) |
|
210 | 207 | |
|
211 | 208 | def getrepostate(repo): |
|
212 | 209 | # experimental config: commands.status.skipstates |
|
213 | 210 | skip = set(repo.ui.configlist('commands', 'status.skipstates')) |
|
214 | for state, statedetectionpredicate, msgfn in STATES: | |
|
215 | if state in skip: | |
|
211 | for state in _unfinishedstates: | |
|
212 | if state._opname in skip: | |
|
216 | 213 | continue |
|
217 |
if state |
|
|
218 |
return (state, state |
|
|
214 | if state.isunfinished(repo): | |
|
215 | return (state._opname, state.statusmsg()) |
@@ -281,6 +281,7 b' Using status to get more context' | |||
|
281 | 281 | |
|
282 | 282 | # To continue: hg graft --continue |
|
283 | 283 | # To abort: hg graft --abort |
|
284 | # To stop: hg graft --stop | |
|
284 | 285 | |
|
285 | 286 | |
|
286 | 287 | Commit while interrupted should fail: |
@@ -44,6 +44,13 b" of the files in a commit we're updating " | |||
|
44 | 44 | commit: 1 unknown (interrupted update) |
|
45 | 45 | update: 1 new changesets (update) |
|
46 | 46 | phases: 2 draft |
|
47 | Detect interrupted update by hg status --verbose | |
|
48 | $ hg status -v | |
|
49 | ? b/nonempty | |
|
50 | # The repository is in an unfinished *update* state. | |
|
51 | ||
|
52 | # To continue: hg update | |
|
53 | ||
|
47 | 54 | |
|
48 | 55 | $ rm b/nonempty |
|
49 | 56 |
@@ -164,7 +164,8 b' plain headers' | |||
|
164 | 164 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved |
|
165 | 165 | use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon |
|
166 | 166 | (no more unresolved files) |
|
167 | abort: cannot manage merge changesets | |
|
167 | abort: outstanding uncommitted merge | |
|
168 | (use 'hg commit' or 'hg merge --abort') | |
|
168 | 169 | $ rm -r sandbox |
|
169 | 170 | |
|
170 | 171 | hg headers |
@@ -243,7 +244,8 b' hg headers' | |||
|
243 | 244 | 0 files updated, 0 files merged, 0 files removed, 1 files unresolved |
|
244 | 245 | use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon |
|
245 | 246 | (no more unresolved files) |
|
246 | abort: cannot manage merge changesets | |
|
247 | abort: outstanding uncommitted merge | |
|
248 | (use 'hg commit' or 'hg merge --abort') | |
|
247 | 249 | $ rm -r sandbox |
|
248 | 250 | |
|
249 | 251 | Test saving last-message.txt |
@@ -82,6 +82,7 b' Conflicting rebase:' | |||
|
82 | 82 | |
|
83 | 83 | # To continue: hg rebase --continue |
|
84 | 84 | # To abort: hg rebase --abort |
|
85 | # To stop: hg rebase --stop | |
|
85 | 86 | |
|
86 | 87 | |
|
87 | 88 | Try to continue without solving the conflict: |
@@ -1153,7 +1153,8 b' Abort unshelve while merging (issue5123)' | |||
|
1153 | 1153 | -- trying to pull in the shelve bits |
|
1154 | 1154 | -- unshelve should abort otherwise, it'll eat my second parent. |
|
1155 | 1155 | $ hg unshelve |
|
1156 | abort: cannot unshelve while merging | |
|
1156 | abort: outstanding uncommitted merge | |
|
1157 | (use 'hg commit' or 'hg merge --abort') | |
|
1157 | 1158 | [255] |
|
1158 | 1159 | |
|
1159 | 1160 | $ cd .. |
@@ -275,6 +275,7 b' before strip of merge parent' | |||
|
275 | 275 | ##strip not allowed with merge in progress |
|
276 | 276 | $ hg strip 4 |
|
277 | 277 | abort: outstanding uncommitted merge |
|
278 | (use 'hg commit' or 'hg merge --abort') | |
|
278 | 279 | [255] |
|
279 | 280 | ##strip allowed --force with merge in progress |
|
280 | 281 | $ hg strip 4 --force |
@@ -40,6 +40,7 b'' | |||
|
40 | 40 | (branch merge, don't forget to commit) |
|
41 | 41 | $ hg transplant 1 |
|
42 | 42 | abort: outstanding uncommitted merge |
|
43 | (use 'hg commit' or 'hg merge --abort') | |
|
43 | 44 | [255] |
|
44 | 45 | $ hg up -qC tip |
|
45 | 46 | $ echo b0 > b1 |
@@ -461,7 +462,7 b" transplant -c shouldn't use an old chang" | |||
|
461 | 462 | baz |
|
462 | 463 | foo |
|
463 | 464 | |
|
464 |
test multiple revisions and -- |
|
|
465 | test multiple revisions, --continue and hg status --verbose | |
|
465 | 466 | |
|
466 | 467 | $ hg up -qC 0 |
|
467 | 468 | $ echo bazbaz > baz |
@@ -481,6 +482,15 b' test multiple revisions and --continue' | |||
|
481 | 482 | abort: transplant in progress |
|
482 | 483 | (use 'hg transplant --continue' or 'hg update' to abort) |
|
483 | 484 | [255] |
|
485 | $ hg status -v | |
|
486 | A bar | |
|
487 | ? baz.rej | |
|
488 | ? foo.rej | |
|
489 | # The repository is in an unfinished *transplant* state. | |
|
490 | ||
|
491 | # To continue: hg transplant --continue | |
|
492 | # To abort: hg update | |
|
493 | ||
|
484 | 494 | $ echo fixed > baz |
|
485 | 495 | $ hg transplant --continue |
|
486 | 496 | 9d6d6b5a8275 transplanted as d80c49962290 |
General Comments 0
You need to be logged in to leave comments.
Login now