mercurial/commands.py
changeset 42541 3de4f17f4824
parent 42529 5f2f6912c9e6
child 42542 2e1d9414ff71
--- a/mercurial/commands.py	Fri Jun 28 22:57:48 2019 +0530
+++ b/mercurial/commands.py	Fri Jun 28 21:31:34 2019 +0530
@@ -58,6 +58,7 @@
     rewriteutil,
     scmutil,
     server,
+    shelve as shelvemod,
     state as statemod,
     streamclone,
     tags as tagsmod,
@@ -5324,6 +5325,106 @@
     service = server.createservice(ui, repo, opts)
     return server.runservice(opts, initfn=service.init, runfn=service.run)
 
+@command('shelve',
+         [('A', 'addremove', None,
+           _('mark new/missing files as added/removed before shelving')),
+          ('u', 'unknown', None,
+           _('store unknown files in the shelve')),
+          ('', 'cleanup', None,
+           _('delete all shelved changes')),
+          ('', 'date', '',
+           _('shelve with the specified commit date'), _('DATE')),
+          ('d', 'delete', None,
+           _('delete the named shelved change(s)')),
+          ('e', 'edit', False,
+           _('invoke editor on commit messages')),
+          ('k', 'keep', False,
+           _('shelve, but keep changes in the working directory')),
+          ('l', 'list', None,
+           _('list current shelves')),
+          ('m', 'message', '',
+           _('use text as shelve message'), _('TEXT')),
+          ('n', 'name', '',
+           _('use the given name for the shelved commit'), _('NAME')),
+          ('p', 'patch', None,
+           _('output patches for changes (provide the names of the shelved '
+             'changes as positional arguments)')),
+          ('i', 'interactive', None,
+           _('interactive mode, only works while creating a shelve')),
+          ('', 'stat', None,
+           _('output diffstat-style summary of changes (provide the names of '
+             'the shelved changes as positional arguments)')
+           )] + cmdutil.walkopts,
+         _('hg shelve [OPTION]... [FILE]...'),
+         helpcategory=command.CATEGORY_WORKING_DIRECTORY)
+def shelve(ui, repo, *pats, **opts):
+    '''save and set aside changes from the working directory
+
+    Shelving takes files that "hg status" reports as not clean, saves
+    the modifications to a bundle (a shelved change), and reverts the
+    files so that their state in the working directory becomes clean.
+
+    To restore these changes to the working directory, using "hg
+    unshelve"; this will work even if you switch to a different
+    commit.
+
+    When no files are specified, "hg shelve" saves all not-clean
+    files. If specific files or directories are named, only changes to
+    those files are shelved.
+
+    In bare shelve (when no files are specified, without interactive,
+    include and exclude option), shelving remembers information if the
+    working directory was on newly created branch, in other words working
+    directory was on different branch than its first parent. In this
+    situation unshelving restores branch information to the working directory.
+
+    Each shelved change has a name that makes it easier to find later.
+    The name of a shelved change defaults to being based on the active
+    bookmark, or if there is no active bookmark, the current named
+    branch.  To specify a different name, use ``--name``.
+
+    To see a list of existing shelved changes, use the ``--list``
+    option. For each shelved change, this will print its name, age,
+    and description; use ``--patch`` or ``--stat`` for more details.
+
+    To delete specific shelved changes, use ``--delete``. To delete
+    all shelved changes, use ``--cleanup``.
+    '''
+    opts = pycompat.byteskwargs(opts)
+    allowables = [
+        ('addremove', {'create'}), # 'create' is pseudo action
+        ('unknown', {'create'}),
+        ('cleanup', {'cleanup'}),
+#       ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
+        ('delete', {'delete'}),
+        ('edit', {'create'}),
+        ('keep', {'create'}),
+        ('list', {'list'}),
+        ('message', {'create'}),
+        ('name', {'create'}),
+        ('patch', {'patch', 'list'}),
+        ('stat', {'stat', 'list'}),
+    ]
+    def checkopt(opt):
+        if opts.get(opt):
+            for i, allowable in allowables:
+                if opts[i] and opt not in allowable:
+                    raise error.Abort(_("options '--%s' and '--%s' may not be "
+                                       "used together") % (opt, i))
+            return True
+    if checkopt('cleanup'):
+        if pats:
+            raise error.Abort(_("cannot specify names when using '--cleanup'"))
+        return shelvemod.cleanupcmd(ui, repo)
+    elif checkopt('delete'):
+        return shelvemod.deletecmd(ui, repo, pats)
+    elif checkopt('list'):
+        return shelvemod.listcmd(ui, repo, pats, opts)
+    elif checkopt('patch') or checkopt('stat'):
+        return shelvemod.patchcmds(ui, repo, pats, opts)
+    else:
+        return shelvemod.createcmd(ui, repo, pats, opts)
+
 _NOTTERSE = 'nothing'
 
 @command('status|st',
@@ -6052,6 +6153,59 @@
 
     return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
 
+@command('unshelve',
+         [('a', 'abort', None,
+           _('abort an incomplete unshelve operation')),
+          ('c', 'continue', None,
+           _('continue an incomplete unshelve operation')),
+          ('k', 'keep', None,
+           _('keep shelve after unshelving')),
+          ('n', 'name', '',
+           _('restore shelved change with given name'), _('NAME')),
+          ('t', 'tool', '', _('specify merge tool')),
+          ('', 'date', '',
+           _('set date for temporary commits (DEPRECATED)'), _('DATE'))],
+         _('hg unshelve [[-n] SHELVED]'),
+         helpcategory=command.CATEGORY_WORKING_DIRECTORY)
+def unshelve(ui, repo, *shelved, **opts):
+    """restore a shelved change to the working directory
+
+    This command accepts an optional name of a shelved change to
+    restore. If none is given, the most recent shelved change is used.
+
+    If a shelved change is applied successfully, the bundle that
+    contains the shelved changes is moved to a backup location
+    (.hg/shelve-backup).
+
+    Since you can restore a shelved change on top of an arbitrary
+    commit, it is possible that unshelving will result in a conflict
+    between your changes and the commits you are unshelving onto. If
+    this occurs, you must resolve the conflict, then use
+    ``--continue`` to complete the unshelve operation. (The bundle
+    will not be moved until you successfully complete the unshelve.)
+
+    (Alternatively, you can use ``--abort`` to abandon an unshelve
+    that causes a conflict. This reverts the unshelved changes, and
+    leaves the bundle in place.)
+
+    If bare shelved change (when no files are specified, without interactive,
+    include and exclude option) was done on newly created branch it would
+    restore branch information to the working directory.
+
+    After a successful unshelve, the shelved changes are stored in a
+    backup directory. Only the N most recent backups are kept. N
+    defaults to 10 but can be overridden using the ``shelve.maxbackups``
+    configuration option.
+
+    .. container:: verbose
+
+       Timestamp in seconds is used to decide order of backups. More
+       than ``maxbackups`` backups are kept, if same timestamp
+       prevents from deciding exact order of them, for safety.
+    """
+    with repo.wlock():
+        return shelvemod._dounshelve(ui, repo, *shelved, **opts)
+
 @command('update|up|checkout|co',
     [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
     ('c', 'check', None, _('require clean working directory')),