changeset 42581:bb135a784b70

abort: added logic for of hg abort This is part of `GSoC19` project `Implement abort and continue commands`. This patch is part of the `abort plan`. This adds the basic logic for `hg abort`. This command aborts an multistep operation like graft, histedit, rebase, merge and unshelve if they are in an unfinished state. The first part of the logic is determining the unfinished operation from the state detection API under `statemod`. This API is extended to support `hg abort` by adding a method to register the abort logic as a function (here `abortfunc`). Once the unfinished operation is determined the registered logic is used to abort the command. The benefit of this kind of framework is that any new extension developed can support `hg abort` by registering the command and logic under statedetection API. `hg abort` currently supports `--dry-run/-n` flag only. It is used to dry run `hg abort` Further patches sequentially add support for `graft`, `rebase`, `unshelve`, `histedit` and `merge`. Differential Revision: https://phab.mercurial-scm.org/D6566
author Taapas Agrawal <taapas2897@gmail.com>
date Sun, 23 Jun 2019 20:58:01 +0530
parents eb7bd7d64a9d
children 5171937ad0f9
files mercurial/commands.py mercurial/state.py tests/test-blackbox.t tests/test-completion.t tests/test-help.t tests/test-hgweb-json.t
diffstat 6 files changed, 49 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py	Tue Jul 09 10:09:46 2019 -0400
+++ b/mercurial/commands.py	Sun Jun 23 20:58:01 2019 +0530
@@ -131,6 +131,31 @@
 
 # Commands start here, listed alphabetically
 
+@command('abort',
+    dryrunopts, helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
+    helpbasic=True)
+def abort(ui, repo, **opts):
+    """abort an unfinished operation (EXPERIMENTAL)
+
+    Aborts a multistep operation like graft, histedit, rebase, merge,
+    and unshelve if they are in an unfinished state.
+
+    use --dry-run/-n to dry run the command.
+    A new operation can be added to this by registering the operation and
+    abort logic in the unfinishedstates list under statemod.
+    """
+    dryrun = opts.get(r'dry_run')
+    abortstate = cmdutil.getunfinishedstate(repo)
+    if not abortstate:
+        raise error.Abort(_('no operation in progress'))
+    if not abortstate.abortfunc:
+        raise error.Abort((_("%s in progress but does not support 'hg abort'") %
+                            (abortstate._opname)), hint=abortstate.hint())
+    if dryrun:
+        ui.status(_('%s in progress, will be aborted\n') % (abortstate._opname))
+        return
+    return abortstate.abortfunc(ui, repo)
+
 @command('add',
     walkopts + subrepoopts + dryrunopts,
     _('[OPTION]... [FILE]...'),
--- a/mercurial/state.py	Tue Jul 09 10:09:46 2019 -0400
+++ b/mercurial/state.py	Sun Jun 23 20:58:01 2019 +0530
@@ -98,7 +98,8 @@
     """
 
     def __init__(self, opname, fname, clearable, allowcommit, reportonly,
-                 continueflag, stopflag, cmdmsg, cmdhint, statushint):
+                 continueflag, stopflag, cmdmsg, cmdhint, statushint,
+                 abortfunc):
         self._opname = opname
         self._fname = fname
         self._clearable = clearable
@@ -109,6 +110,7 @@
         self._cmdmsg = cmdmsg
         self._cmdhint = cmdhint
         self._statushint = statushint
+        self.abortfunc = abortfunc
 
     def statusmsg(self):
         """returns the hint message corresponding to the command for
@@ -157,7 +159,7 @@
 
 def addunfinished(opname, fname, clearable=False, allowcommit=False,
                   reportonly=False, continueflag=False, stopflag=False,
-                  cmdmsg="", cmdhint="", statushint=""):
+                  cmdmsg="", cmdhint="", statushint="", abortfunc=None):
     """this registers a new command or operation to unfinishedstates
     opname is the name the command or operation
     fname is the file name in which data should be stored in .hg directory.
@@ -181,10 +183,11 @@
     statushint is used to pass a different status message in case standard
     message of the format ('To continue:    hg cmdname --continue'
     'To abort:       hg cmdname --abort') is not desired
+    abortfunc stores the function required to abort an unfinished state.
     """
     statecheckobj = _statecheck(opname, fname, clearable, allowcommit,
                                 reportonly, continueflag, stopflag, cmdmsg,
-                                cmdhint, statushint)
+                                cmdhint, statushint, abortfunc)
     if opname == 'merge':
         _unfinishedstates.append(statecheckobj)
     else:
--- a/tests/test-blackbox.t	Tue Jul 09 10:09:46 2019 -0400
+++ b/tests/test-blackbox.t	Sun Jun 23 20:58:01 2019 +0530
@@ -7,7 +7,7 @@
   > @command(b'crash', [], b'hg crash')
   > def crash(ui, *args, **kwargs):
   >     raise Exception("oops")
-  > @command(b'abort', [], b'hg abort')
+  > @command(b'abortcmd', [], b'hg abortcmd')
   > def abort(ui, *args, **kwargs):
   >     raise error.Abort(b"oops")
   > EOF
@@ -52,10 +52,10 @@
 
 abort exit code
   $ rm ./.hg/blackbox.log
-  $ hg abort 2> /dev/null
+  $ hg abortcmd 2> /dev/null
   [255]
   $ hg blackbox -l 2
-  1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> abort exited 255 after * seconds (glob)
+  1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> abortcmd exited 255 after * seconds (glob)
   1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox -l 2
 
 unhandled exception
--- a/tests/test-completion.t	Tue Jul 09 10:09:46 2019 -0400
+++ b/tests/test-completion.t	Sun Jun 23 20:58:01 2019 +0530
@@ -1,5 +1,6 @@
 Show all commands except debug commands
   $ hg debugcomplete
+  abort
   add
   addremove
   annotate
@@ -59,6 +60,7 @@
 
 Show all commands that start with "a"
   $ hg debugcomplete a
+  abort
   add
   addremove
   annotate
@@ -235,6 +237,7 @@
 
 Show all commands + options
   $ hg debugcommands
+  abort: dry-run
   add: include, exclude, subrepos, dry-run
   addremove: similarity, subrepos, include, exclude, dry-run
   annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template
--- a/tests/test-help.t	Tue Jul 09 10:09:46 2019 -0400
+++ b/tests/test-help.t	Sun Jun 23 20:58:01 2019 +0530
@@ -402,6 +402,7 @@
   
   basic commands:
   
+   abort         abort an unfinished operation (EXPERIMENTAL)
    add           add the specified files on the next commit
    annotate, blame
                  show changeset information by line for each file
@@ -2353,6 +2354,13 @@
   <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
   
   <tr><td>
+  <a href="/help/abort">
+  abort
+  </a>
+  </td><td>
+  abort an unfinished operation (EXPERIMENTAL)
+  </td></tr>
+  <tr><td>
   <a href="/help/add">
   add
   </a>
--- a/tests/test-hgweb-json.t	Tue Jul 09 10:09:46 2019 -0400
+++ b/tests/test-hgweb-json.t	Sun Jun 23 20:58:01 2019 +0530
@@ -1875,6 +1875,10 @@
   {
     "earlycommands": [
       {
+        "summary": "abort an unfinished operation (EXPERIMENTAL)",
+        "topic": "abort"
+      },
+      {
         "summary": "add the specified files on the next commit",
         "topic": "add"
       },