diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -6158,6 +6158,8 @@ _('abort an incomplete unshelve operation')), ('c', 'continue', None, _('continue an incomplete unshelve operation')), + ('i', 'interactive', None, + _('use interactive mode')), ('k', 'keep', None, _('keep shelve after unshelving')), ('n', 'name', '', @@ -6165,7 +6167,7 @@ ('t', 'tool', '', _('specify merge tool')), ('', 'date', '', _('set date for temporary commits (DEPRECATED)'), _('DATE'))], - _('hg unshelve [[-n] SHELVED]'), + _('hg unshelve [OPTION]... [FILE]... [-n SHELVED]'), helpcategory=command.CATEGORY_WORKING_DIRECTORY) def unshelve(ui, repo, *shelved, **opts): """restore a shelved change to the working directory diff --git a/mercurial/shelve.py b/mercurial/shelve.py --- a/mercurial/shelve.py +++ b/mercurial/shelve.py @@ -772,7 +772,9 @@ """Rebase restored commit from its original location to a destination""" # If the shelve is not immediately on top of the commit # we'll be merging with, rebase it to be on top. - if tmpwctx.node() == shelvectx.p1().node(): + interactive = opts.get('interactive') + pats = [] + if tmpwctx.node() == shelvectx.p1().node() and not interactive: return shelvectx overrides = { @@ -797,10 +799,25 @@ with repo.dirstate.parentchange(): repo.setparents(tmpwctx.node(), nodemod.nullid) - newnode = repo.commit(text=shelvectx.description(), - extra=shelvectx.extra(), - user=shelvectx.user(), - date=shelvectx.date()) + if not interactive: + newnode = repo.commit(text=shelvectx.description(), + extra=shelvectx.extra(), + user=shelvectx.user(), + date=shelvectx.date()) + else: + opts['message'] = shelvectx.description() + commitfunc = getcommitfunc(shelvectx.extra(), + interactive=True, editor=True) + newnode = cmdutil.dorecord(ui, repo, commitfunc, None, False, + cmdutil.recordfilter, *pats, + **pycompat.strkwargs(opts)) + if set(shelvectx.files()) - set(repo[newnode].files()): + snode = repo.commit(text=shelvectx.description(), + extra=shelvectx.extra(), + user=shelvectx.user(), + date=shelvectx.date()) + m = scmutil.matchfiles(repo, repo[snode].files()) + _shelvecreatedcommit(repo, snode, basename, m) if newnode is None: # If it ended up being a no-op commit, then the normal @@ -852,6 +869,7 @@ opts = pycompat.byteskwargs(opts) abortf = opts.get('abort') continuef = opts.get('continue') + interactive = opts.get('interactive') if not abortf and not continuef: cmdutil.checkunfinished(repo) shelved = list(shelved) @@ -938,19 +956,22 @@ if shelvectx.branch() != shelvectx.p1().branch(): branchtorestore = shelvectx.branch() + allfiles = shelvectx.files() shelvectx = _rebaserestoredcommit(ui, repo, opts, tr, oldtiprev, basename, pctx, tmpwctx, shelvectx, branchtorestore, activebookmark) + filesinclude = shelvectx.files() overrides = {('ui', 'forcemerge'): opts.get('tool', '')} with ui.configoverride(overrides, 'unshelve'): mergefiles(ui, repo, pctx, shelvectx) restorebranch(ui, repo, branchtorestore) - _forgetunknownfiles(repo, shelvectx, addedbefore) + if not interactive or (interactive and allfiles == filesinclude): + _forgetunknownfiles(repo, shelvectx, addedbefore) - shelvedstate.clear(repo) - _finishunshelve(repo, oldtiprev, tr, activebookmark) - unshelvecleanup(ui, repo, basename, opts) + shelvedstate.clear(repo) + _finishunshelve(repo, oldtiprev, tr, activebookmark) + unshelvecleanup(ui, repo, basename, opts) finally: if tr: tr.release() diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -349,7 +349,7 @@ tags: template tip: patch, git, style, template unbundle: update - unshelve: abort, continue, keep, name, tool, date + unshelve: abort, continue, interactive, keep, name, tool, date update: clean, check, merge, date, rev, tool verify: full version: template diff --git a/tests/test-shelve.t b/tests/test-shelve.t --- a/tests/test-shelve.t +++ b/tests/test-shelve.t @@ -1155,3 +1155,95 @@ [255] $ cd .. + +-- test for interactive mode on unshelve + + $ hg init a + $ cd a + $ echo > b + $ hg ci -Am b + adding b + $ echo > c + $ echo > d + $ hg add . + adding c + adding d + $ hg shelve + shelved as default + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ echo > e + $ hg add e + $ hg ci -m e + $ hg shelve --patch + default (1s ago) changes to: b + + diff --git a/c b/c + new file mode 100644 + --- /dev/null + +++ b/c + @@ -0,0 +1,1 @@ + + + diff --git a/d b/d + new file mode 100644 + --- /dev/null + +++ b/d + @@ -0,0 +1,1 @@ + + + $ hg unshelve -i < y + > y + > y + > n + > EOF + unshelving change 'default' + rebasing shelved changes + diff --git a/c b/c + new file mode 100644 + examine changes to 'c'? [Ynesfdaq?] y + + @@ -0,0 +1,1 @@ + + + record change 1/2 to 'c'? [Ynesfdaq?] y + + diff --git a/d b/d + new file mode 100644 + examine changes to 'd'? [Ynesfdaq?] y + + @@ -0,0 +1,1 @@ + + + record change 2/2 to 'd'? [Ynesfdaq?] n + + $ ls + b + c + e +-- shelve should not contain `c` now + $ hg shelve --patch + default (1s ago) changes to: b + + diff --git a/d b/d + new file mode 100644 + --- /dev/null + +++ b/d + @@ -0,0 +1,1 @@ + + + $ hg unshelve -i < y + > y + > EOF + unshelving change 'default' + rebasing shelved changes + diff --git a/d b/d + new file mode 100644 + examine changes to 'd'? [Ynesfdaq?] y + + @@ -0,0 +1,1 @@ + + + record this change to 'd'? [Ynesfdaq?] y + + $ ls + b + c + d + e + $ hg shelve --list