Patchwork [3,of,5] shelve: use an --unshelve parameter instead of a command

login
register
mail settings
Submitter David Soria Parra
Date Sept. 17, 2013, 3:55 p.m.
Message ID <4a6bc39240c0f556ab3a.1379433319@achird.localdomain>
Download mbox | patch
Permalink /patch/2507/
State Changes Requested, archived
Headers show

Comments

David Soria Parra - Sept. 17, 2013, 3:55 p.m.
# HG changeset patch
# User David Soria Parra <dsp@experimentalworks.net>
# Date 1379432862 -7200
#      Tue Sep 17 17:47:42 2013 +0200
# Node ID 4a6bc39240c0f556ab3ab7eabfde347aadba3287
# Parent  f533657af87051e0a7a3d6ffc30a9dd7d2415d5a
shelve: use an --unshelve parameter instead of a command

Most Mercurial commands use a parameter to indicate the reverse
operation e.g. hg bookmark/hg bookmark -d, hg tag/hg tag --remove,
We add an --unshelve parameter and drop the unshelve command to
match the UI of recently added commands.
Martin Geisler - Sept. 17, 2013, 9:21 p.m.
David Soria Parra <dsp@experimentalworks.net> writes:

> # HG changeset patch
> # User David Soria Parra <dsp@experimentalworks.net>
> # Date 1379432862 -7200
> #      Tue Sep 17 17:47:42 2013 +0200
> # Node ID 4a6bc39240c0f556ab3ab7eabfde347aadba3287
> # Parent  f533657af87051e0a7a3d6ffc30a9dd7d2415d5a
> shelve: use an --unshelve parameter instead of a command

Cool that you're working on this extension!

Without having tried the extension, I don't think I'll like that.

> Most Mercurial commands use a parameter to indicate the reverse
> operation e.g. hg bookmark/hg bookmark -d, hg tag/hg tag --remove,
> We add an --unshelve parameter and drop the unshelve command to
> match the UI of recently added commands.

I think those commands (in particular 'hg tag --remove') are rare and so
specifying a flag can be okay. I'm imagining that I'll be shelving and
unshelving a log, just like I 'hg qnew' and 'hg qpop' a lot today.

Top-level commands makes a difference here: when typing 'hg shel...' my
brain will know what I'm doing and I can press TAB and be done. Having
to type 'hg shel<TAB> --unsh' turns unshelving into a compound action:
first I type the command and TAB, then I type a flag. There is a brief
pause after I type TAB where I check that the right thing was completed
and that interrupts the flow. Typing SPC is another small cognetive
interuption since spaces separate words and actions.

I also feel like I stutter when I write 'hg shelve --unshelve' :)

I know I can make an 'unshelve = shelve --unshelve' alias.

> @@ -498,7 +491,7 @@
>                                 *revertfiles, no_backup=True)
>                  raise error.InterventionRequired(
>                      _("unresolved conflicts (see 'hg resolve', then "
> -                      "'hg unshelve --continue')"))
> +                      "'hg shelve --unshelve --continue')"))

This doesn't look as clean as 'hg unshelve --continue' to me. There are
now two flags to shelve, both of which selects a major mode of
operation. It seems simpler to me to tell the user: you executed 'hg
unshelve' and it broke, now fix the mess and run 'hg unshelve --cont' to
continue.
David Soria Parra - Sept. 19, 2013, 4:29 a.m.
On 09/17/2013 11:21 PM, Martin Geisler wrote:
> This doesn't look as clean as 'hg unshelve --continue' to me. There are
> now two flags to shelve, both of which selects a major mode of
> operation. It seems simpler to me to tell the user: you executed 'hg
> unshelve' and it broke, now fix the mess and run 'hg unshelve --cont' to
> continue.

I used an parameter --unshelve instead of a command due to the previous
discussion on the extension. I personally don't have a preference, but
it was suggested that we don't use an "unshelve" command. This way all
the parameters are defined on the same command. Would you prefer
"--apply" maybe?

Matt and rest: Any suggestions on the UI bits?
Siddharth Agarwal - Sept. 19, 2013, 4:31 a.m.
On 09/18/2013 09:29 PM, David Soria Parra wrote:
> I used an parameter --unshelve instead of a command due to the previous
> discussion on the extension. I personally don't have a preference, but
> it was suggested that we don't use an "unshelve" command. This way all
> the parameters are defined on the same command. Would you prefer
> "--apply" maybe?
>
> Matt and rest: Any suggestions on the UI bits?

I'd prefer unshelve too.
Augie Fackler - Sept. 19, 2013, 2:37 p.m.
On Wed, Sep 18, 2013 at 09:31:51PM -0700, Siddharth Agarwal wrote:
> On 09/18/2013 09:29 PM, David Soria Parra wrote:
> >I used an parameter --unshelve instead of a command due to the previous
> >discussion on the extension. I personally don't have a preference, but
> >it was suggested that we don't use an "unshelve" command. This way all
> >the parameters are defined on the same command. Would you prefer
> >"--apply" maybe?
> >
> >Matt and rest: Any suggestions on the UI bits?
>
> I'd prefer unshelve too.

I think I would too, but [alias] unshelve = shelve --unshelve is
pretty easy, and consistency with core commands like tag isn't
valueless.

(Not sure which one I want in the end. Merely being the devil's
advocate here.)

> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
Sean Farley - Sept. 19, 2013, 4:51 p.m.
sid0@fb.com writes:

> On 09/18/2013 09:29 PM, David Soria Parra wrote:
>> I used an parameter --unshelve instead of a command due to the previous
>> discussion on the extension. I personally don't have a preference, but
>> it was suggested that we don't use an "unshelve" command. This way all
>> the parameters are defined on the same command. Would you prefer
>> "--apply" maybe?
>>
>> Matt and rest: Any suggestions on the UI bits?
>
> I'd prefer unshelve too.

For what it's worth, I also prefer unshelve.
Martin Geisler - Sept. 19, 2013, 9:34 p.m.
Augie Fackler <raf@durin42.com> writes:

> On Wed, Sep 18, 2013 at 09:31:51PM -0700, Siddharth Agarwal wrote:
>> On 09/18/2013 09:29 PM, David Soria Parra wrote:
>> >I used an parameter --unshelve instead of a command due to the
>> >previous discussion on the extension. I personally don't have a
>> >preference, but it was suggested that we don't use an "unshelve"
>> >command. This way all the parameters are defined on the same
>> >command. Would you prefer "--apply" maybe?
>> >
>> >Matt and rest: Any suggestions on the UI bits?
>>
>> I'd prefer unshelve too.
>
> I think I would too, but [alias] unshelve = shelve --unshelve is
> pretty easy,

It is easy, but only some users will discover the alias functionality
and only some of them will think of adding an alias.

I like my software to come with good defaults -- I actually don't like
changing it too much from those defaults. Partly because I like to think
that there is an integrity to the system that I may disturb and partly
because those customizations don't automatically move with me to other
systems.

As a result I'm relying heavily on the defaults. As an example, I've
been using Emacs for 10+ years now. I have only added a single custom
keybinding and that's even one I don't use any longer. I've enabled a
bunch of modes, and customized some settings, but only for things that
comes with the emacs-goodies-el Debian package.

The above probably sounds crazy for people used to customizing
everything on their system :) But if there are others like me, then we
should pay extra attention to good out-of-the-box defaults.

> and consistency with core commands like tag isn't valueless.

I'm somehow okay with 'hg tag': it has a primary job (adding a tag) that
it does without flags. It has a more rare job (removing a tag) where you
need a flag. A separate command (tags) lists the tags. The same applies
to the branch and branches commands.

For shelve, I think that shelving and unshelving will occur about
equally often -- after all, what good is a shelved change if you don't
eventually unshelve it :)

That suggests to me that a flag is less attractive.
Matt Mackall - Sept. 19, 2013, 9:41 p.m.
On Wed, 2013-09-18 at 21:31 -0700, Siddharth Agarwal wrote:
> On 09/18/2013 09:29 PM, David Soria Parra wrote:
> > I used an parameter --unshelve instead of a command due to the previous
> > discussion on the extension. I personally don't have a preference, but
> > it was suggested that we don't use an "unshelve" command. This way all
> > the parameters are defined on the same command. Would you prefer
> > "--apply" maybe?
> >
> > Matt and rest: Any suggestions on the UI bits?
> 
> I'd prefer unshelve too.

Ok, let's look at the precedents.

First, git. We generally don't usually appeal to git for UI inspiration,
but as this particular command is modeled off of git stash, it makes
sense. The git synopsis looks like this:

       git stash list [<options>]
       git stash show [<stash>]
       git stash drop [-q|--quiet] [<stash>]
       git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
       git stash branch <branchname> [<stash>]
       git stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
                    [-u|--include-untracked] [-a|--all] [<message>]]
       git stash clear
       git stash create

Now let's look at 'the other shelve extension':

	hg shelve [--name x] [--append] [--all]
	hg shelve --list
	hg unshelve

We've got a bunch of commands of the form foo/foos to make/list:

	tag/tags
	bookmark/bookmarks
	branch/branches

..but these each have a different way to unmark:

	tag --remove (-r is rev, -d is date)
        bookmark -d/--delete (let's fix this!)
        hg commit --close-branch

We've also got resolve and bisect which have a bunch of "subcommands":

	resolve
	resolve -l
	resolve -m/-u
	bisect -r/-g/-b/-s

And we've got mq, which has _many_ commands, but one each for
create/list/apply.

So I think there are three possibilities which are really consistent
with our existing UI:

a) one command with suboptions (like resolve)

	hg shelve [name]
	hg shelve -l/--list
	hg shelve -u/--unshelve (or -p/--pop) [name]

b) two commands (like tags/bookmarks)

	hg shelve [name]
	hg shelves
	hg shelve --u [name]

c) three commands (like mq)

	hg shelve [name]
	hg shelves
	hg unshelve [name]

My preference is for the first. If a year from now, we discover everyone
wants unshelve and/or shelves, we can add that. But it's bit harder to
take commands away.
Matt Mackall - Sept. 19, 2013, 9:44 p.m.
On Thu, 2013-09-19 at 23:34 +0200, Martin Geisler wrote:

> For shelve, I think that shelving and unshelving will occur about
> equally often -- after all, what good is a shelved change if you don't
> eventually unshelve it :)

This is a pretty good argument. I might be swayed.
Antoine Pitrou - Sept. 20, 2013, 5:55 a.m.
On Thu, 19 Sep 2013 23:34:55 +0200
Martin Geisler <martin@geisler.net> wrote:
> Augie Fackler <raf@durin42.com> writes:
> 
> > On Wed, Sep 18, 2013 at 09:31:51PM -0700, Siddharth Agarwal wrote:
> >> On 09/18/2013 09:29 PM, David Soria Parra wrote:
> >> >I used an parameter --unshelve instead of a command due to the
> >> >previous discussion on the extension. I personally don't have a
> >> >preference, but it was suggested that we don't use an "unshelve"
> >> >command. This way all the parameters are defined on the same
> >> >command. Would you prefer "--apply" maybe?
> >> >
> >> >Matt and rest: Any suggestions on the UI bits?
> >>
> >> I'd prefer unshelve too.
> >
> > I think I would too, but [alias] unshelve = shelve --unshelve is
> > pretty easy,
> 
> It is easy, but only some users will discover the alias functionality
> and only some of them will think of adding an alias.
> 
> I like my software to come with good defaults -- I actually don't like
> changing it too much from those defaults. Partly because I like to think
> that there is an integrity to the system that I may disturb and partly
> because those customizations don't automatically move with me to other
> systems.

Another reason is to make Mercurial easier to teach. "Ok, Mercurial
doesn't have an unshelve command, but you can emulate it by defining an
alias there in your .hgrc" is a pretty pointless distraction.

(also, the average user will actually never define any aliases, they
will just keep pestering against the tool)

Regards

Antoine.
Laurens Holst - Sept. 20, 2013, 9:32 a.m.
Op 19-09-13 16:37, Augie Fackler schreef:
> On Wed, Sep 18, 2013 at 09:31:51PM -0700, Siddharth Agarwal wrote:
>> On 09/18/2013 09:29 PM, David Soria Parra wrote:
>>> I used an parameter --unshelve instead of a command due to the previous
>>> discussion on the extension. I personally don't have a preference, but
>>> it was suggested that we don't use an "unshelve" command. This way all
>>> the parameters are defined on the same command. Would you prefer
>>> "--apply" maybe?
>>>
>>> Matt and rest: Any suggestions on the UI bits?
>> I'd prefer unshelve too.
> I think I would too, but [alias] unshelve = shelve --unshelve is
> pretty easy, and consistency with core commands like tag isn't
> valueless.
>
> (Not sure which one I want in the end. Merely being the devil's
> advocate here.)

Actually I’m thinking rather the opposite...

It always seemed to me that in Mercurial the secondary arguments are 
more like commands, whereas in git the secondary is more like a 
namespace. Cf. hg tag / hg tags vs. git tag / git tag -l, etc. It 
happens that I prefer the Mercurial way.

Note that unshelve is different from tag --remove because unshelving is 
a very very common operation whereas removing a tag is uncommon, not 
even worthy of a shorthand option. Also unshelve does a lot with your 
working copy.

If you’re looking for consistency, think more about bundle / unbundle.

So I’d rather see shelve / unshelve, it seems more consistent with the 
philosophy behind mercurial commands.

~Laurens
Laurens Holst - Sept. 20, 2013, 9:43 a.m.
Op 19-09-13 23:41, Matt Mackall schreef:
> On Wed, 2013-09-18 at 21:31 -0700, Siddharth Agarwal wrote:
>> On 09/18/2013 09:29 PM, David Soria Parra wrote:
>>> I used an parameter --unshelve instead of a command due to the previous
>>> discussion on the extension. I personally don't have a preference, but
>>> it was suggested that we don't use an "unshelve" command. This way all
>>> the parameters are defined on the same command. Would you prefer
>>> "--apply" maybe?
>>>
>>> Matt and rest: Any suggestions on the UI bits?
>> I'd prefer unshelve too.
> Ok, let's look at the precedents.
>
> First, git. We generally don't usually appeal to git for UI inspiration,
> but as this particular command is modeled off of git stash, it makes
> sense. The git synopsis looks like this:
>
>         git stash list [<options>]
>         git stash show [<stash>]
>         git stash drop [-q|--quiet] [<stash>]
>         git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]
>         git stash branch <branchname> [<stash>]
>         git stash [save [--patch] [-k|--[no-]keep-index] [-q|--quiet]
>                      [-u|--include-untracked] [-a|--all] [<message>]]
>         git stash clear
>         git stash create
>
> Now let's look at 'the other shelve extension':
>
> 	hg shelve [--name x] [--append] [--all]
> 	hg shelve --list
> 	hg unshelve
>
> We've got a bunch of commands of the form foo/foos to make/list:
>
> 	tag/tags
> 	bookmark/bookmarks

Actually, you have just “bookmarks”. “bookmark” is an alias.

> 	branch/branches
>
> ..but these each have a different way to unmark:
>
> 	tag --remove (-r is rev, -d is date)
>          bookmark -d/--delete (let's fix this!)
>          hg commit --close-branch
>
> We've also got resolve and bisect which have a bunch of "subcommands":
>
> 	resolve
> 	resolve -l
> 	resolve -m/-u
> 	bisect -r/-g/-b/-s
>
> And we've got mq, which has _many_ commands, but one each for
> create/list/apply.

I think you’re notably forgetting “bundle” and “unbundle”, which is 
actually very similar in function.

> So I think there are three possibilities which are really consistent
> with our existing UI:
>
> a) one command with suboptions (like resolve)
>
> 	hg shelve [name]
> 	hg shelve -l/--list
> 	hg shelve -u/--unshelve (or -p/--pop) [name]
>
> b) two commands (like tags/bookmarks)
>
> 	hg shelve [name]
> 	hg shelves
> 	hg shelve --u [name]
>
> c) three commands (like mq)
>
> 	hg shelve [name]
> 	hg shelves
> 	hg unshelve [name]
>
> My preference is for the first. If a year from now, we discover everyone
> wants unshelve and/or shelves, we can add that. But it's bit harder to
> take commands away.
My preference is the third. It seems consistent with tag / tags and 
bundle / unbundle, and provides convenient access to the most important 
things.

If we would really want to limit the number of commands, I guess for 
“shelves” one could use the same trick that “bookmarks” does, where 
“bookmark” is simply an alias; whether to create or list them solely 
depends on whether a name is specified. So if you type “hg bookmark” it 
will list them, and if you type “hg bookmarks x” it will bookmark.

But to be honest that’s not my preference, seems a bit like a hack, a 
pure technical reason for a UI choice.

~Laurens
Pierre-Yves David - Sept. 20, 2013, 3:09 p.m.
On 09/19/2013 11:41 PM, Matt Mackall wrote:

> We've got a bunch of commands of the form foo/foos to make/list:
>
> 	tag/tags
> 	bookmark/bookmarks
> 	branch/branches

Note that:

1) There is only one `bookmarks` command. `bookmark` works as a short forms

2) The <COMMAND>/<COMMAND>s forms block the use of short form on the 
command line:

hg: command 'bran' is ambiguous:
     branch branches

> So I think there are three possibilities which are really consistent
> with our existing UI:
>
> a) one command with suboptions (like resolve)
>
> 	hg shelve [name]
> 	hg shelve -l/--list
> 	hg shelve -u/--unshelve (or -p/--pop) [name]
>
> b) two commands (like tags/bookmarks)
>
> 	hg shelve [name]
> 	hg shelves
> 	hg shelve --u [name]
>
> c) three commands (like mq)
>
> 	hg shelve [name]
> 	hg shelves
> 	hg unshelve [name]
>
> My preference is for the first. If a year from now, we discover everyone
> wants unshelve and/or shelves, we can add that. But it's bit harder to
> take commands away.
This discussions seems to lack a summary of the action that shelve do:

A) Two main actions:

     1. create a shelve
     2. apply a shelve

B) Two secondary action

     1. list/view shelve (including output of a shelve content)
     2. delete shelve

(i dunno how git manage to build 8 commands from there)

The initial proposal was:

     - hg shelve: create, list, delete-all
     - hg unshelve: apply

 From there the proposal of moving all actions in a single command made 
some sense.

However I (and some other people) would expect `unshelve` commands And a 
lot of people have made valid argument for it. But what do we do from 
secondary actions if we have two commands ?

I cannot see strong arguments to keep them only on the shelve creation 
command (except it's named shelve)

So I see 3 new options

1) We could have both command hold them:

     hg shelve: create (list, delete)
     hg unshelve: apply (list, delete)

     pro: simple and explicit
     con: two commands for the same thing sounds weird

2) We could have a single command with both action at the same level 
(like resolve)

     hg shelves: (list of shelve (safe, no-op action by default))
     hg shelves --create (-c)
     hg shelves --apply (-a)
     hg shelves --delete (-d)
     hg shelve --export (-e)

    pro: single command.
    con: I always hated resolve UI.

3) introduce a third level of command in mercurial (hg <concept> <action>):

     hg shelve list
     hg shelve create
     hg shelve apply
     hg shelve delete
     hg shelve export

     pro: Other things in mercurial could use this concept.
     con: I'm feeling the burning eyes on Matt on me.


Note: If I undertand correctly, the current UI lack:
     - export of a single shelve as patch
     - delete of a single shelve
Durham Goode - Sept. 20, 2013, 11:20 p.m.
On 9/20/13 2:32 AM, "Laurens Holst" <laurens.nospam@grauw.nl> wrote:

>Op 19-09-13 16:37, Augie Fackler schreef:
>> On Wed, Sep 18, 2013 at 09:31:51PM -0700, Siddharth Agarwal wrote:
>>> On 09/18/2013 09:29 PM, David Soria Parra wrote:
>>>> I used an parameter --unshelve instead of a command due to the
>>>>previous
>>>> discussion on the extension. I personally don't have a preference, but
>>>> it was suggested that we don't use an "unshelve" command. This way all
>>>> the parameters are defined on the same command. Would you prefer
>>>> "--apply" maybe?
>>>>
>>>> Matt and rest: Any suggestions on the UI bits?
>>> I'd prefer unshelve too.
>> I think I would too, but [alias] unshelve = shelve --unshelve is
>> pretty easy, and consistency with core commands like tag isn't
>> valueless.
>>
>> (Not sure which one I want in the end. Merely being the devil's
>> advocate here.)
>
>Actually I¹m thinking rather the opposite...
>
>It always seemed to me that in Mercurial the secondary arguments are
>more like commands, whereas in git the secondary is more like a
>namespace. Cf. hg tag / hg tags vs. git tag / git tag -l, etc. It
>happens that I prefer the Mercurial way.
>
>Note that unshelve is different from tag --remove because unshelving is
>a very very common operation whereas removing a tag is uncommon, not
>even worthy of a shorthand option. Also unshelve does a lot with your
>working copy.
>
>If you¹re looking for consistency, think more about bundle / unbundle.
>
>So I¹d rather see shelve / unshelve, it seems more consistent with the
>philosophy behind mercurial commands.
>
>~Laurens
>

+1 on unshelve as a separate command.  I find it infinitely more
intuitive, and having it as a separate command allows us to stick unshelve
specific parameters on it without worrying about affecting the shelve
command.
Tim Delaney - Sept. 21, 2013, 12:08 a.m.
On 21 September 2013 09:20, Durham Goode <durham@fb.com> wrote:

> +1 on unshelve as a separate command

... having it as a separate command allows us to stick unshelve
> specific parameters on it without worrying about affecting the shelve
> command.


To me that is the most compelling reason to have unshelve as a separate
command.

Tim Delaney
Martin Geisler - Sept. 21, 2013, 4:22 p.m.
Matt Mackall <mpm@selenic.com> writes:

> We've got a bunch of commands of the form foo/foos to make/list:
>
> 	tag/tags
> 	bookmark/bookmarks
> 	branch/branches

Most of our commands follow the 'hg <verb>' pattern: add, remove, push,
and pull. Some old commands use 'hg <noun>' instead, e.g., heads,
parents, and manifest.

The words above share an interesting feature: tag, bookmark, and branch
can all be used as both verbs and nouns. This makes the plural form
particularly nice for listing the objects and the singular form can be
read as a verb denoting the action you want Mercurial to do.

For this case, the noun is "shelf" and the verb is "shelve":

  http://www.merriam-webster.com/dictionary/shelf (plural: "shelves")
  http://www.merriam-webster.com/dictionary/shelve

That could be taken as an argument for having 'hg shelves' for listing
shelves and 'hg shelve' (verb) for making shelves.

In general, I think it is nice if the action implied by the verb isn't
changed completely by a flag. So 'hg revert --all' is good, the flag
extends the command to work on all files. By this logic, 'hg shelve
--unshelve' since the verb is reversed.

A command like 'hg bookmark --delete' is also good since "bookmark" can
be read as a noun. Without a flag "bookmark" becomes a verb and the
command does it's primary action: bookmarking a changeset. I'm not sure
if this logic I just made up extends to other commands.

> a) one command with suboptions (like resolve)
>
> 	hg shelve [name]
> 	hg shelve -l/--list
> 	hg shelve -u/--unshelve (or -p/--pop) [name]

I somewhat dislike the resolve command. Whenever I have to explain it to
somebody, I notice that the 'resolve' part becomes an almost irrelevant
part since all the good stuff is in its --list and --mark flags. That
is, I think it would be easier to explain fictive 'hg mergestate' and
'hg remerge' commands instead of the resolve command.

Bisect feels similarly flawed to me: its command line options are not
really options any longer. They could have been replaced with a
mandatory argument instead and the command would work the same. (This is
almost true: while testing this I learned that 'hg bisect' alone will
update to the revision that needs testing.)

> b) two commands (like tags/bookmarks)
>
> 	hg shelve [name]
> 	hg shelves
> 	hg shelve --u [name]
>
> c) three commands (like mq)
>
> 	hg shelve [name]
> 	hg shelves
> 	hg unshelve [name]
>
> My preference is for the first. If a year from now, we discover
> everyone wants unshelve and/or shelves, we can add that. But it's bit
> harder to take commands away.

I agree it sounds better to tell users "We've made things easier in this
release with a new command". Internally, I guess the code will look
about the same in both cases since we'll be marking flags or commands
with DEPRECATED and redirecting some logic.
Pierre-Yves David - Sept. 22, 2013, 10:31 p.m.
On 09/21/2013 06:22 PM, Martin Geisler wrote:
> Matt Mackall<mpm@selenic.com>  writes:
>
>> We've got a bunch of commands of the form foo/foos to make/list:
>>
>> 	tag/tags
>> 	bookmark/bookmarks
>> 	branch/branches
> Most of our commands follow the 'hg<verb>' pattern: add, remove, push,
> and pull. Some old commands use 'hg<noun>' instead, e.g., heads,
> parents, and manifest.

There is active command and passive command. noun tend to be used by 
passive command (eg: hg heads vs hg listheads, hg summary vs hg summarize)

> The words above share an interesting feature: tag, bookmark, and branch
> can all be used as both verbs and nouns. This makes the plural form
> particularly nice for listing the objects and the singular form can be
> read as a verb denoting the action you want Mercurial to do.
>
> For this case, the noun is "shelf" and the verb is "shelve":
>
>    http://www.merriam-webster.com/dictionary/shelf (plural: "shelves")
>    http://www.merriam-webster.com/dictionary/shelve
>
> That could be taken as an argument for having 'hg shelves' for listing
> shelves and 'hg shelve' (verb) for making shelves.

As I noted in a previous email, `shelve` + `shelves` prevents the use of 
short form. There is only two commandes that suffer from this now: 
tag/tags and branch/branches.
`tag` is a short form by itself and branch is not so frequently used in 
a sequence of action (in regard to usage of commit, or mq for example)

> In general, I think it is nice if the action implied by the verb isn't
> changed completely by a flag. So 'hg revert --all' is good, the flag
> extends the command to work on all files. By this logic, 'hg shelve
> --unshelve' since the verb is reversed.
>
> A command like 'hg bookmark --delete' is also good since "bookmark" can
> be read as a noun. Without a flag "bookmark" becomes a verb and the
> command does it's primary action: bookmarking a changeset. I'm not sure
> if this logic I just made up extends to other commands.

If we used --apply instead of --unshelve. That would fit your description.

(note saying I like it. Just saying that there is a flag based version 
that looks less silly on this aspect)
Gilles Moris - Sept. 23, 2013, 5:34 a.m.
> > A command like 'hg bookmark --delete' is also good since "bookmark" can
> > be read as a noun. Without a flag "bookmark" becomes a verb and the
> > command does it's primary action: bookmarking a changeset. I'm not sure
> > if this logic I just made up extends to other commands.
> 
> If we used --apply instead of --unshelve. That would fit your description.
> 
> (note saying I like it. Just saying that there is a flag based version 
> that looks less silly on this aspect)

Just my 2 cents: what I does not like about a using an option, "--apply", "--
unshelve" or whatever, is that I am going to have to use first --help to dig in 
the help to learn that.
That's why I prefer a "hg unshelve" sub-command.

Regards.
Gilles.
Martin Geisler - Sept. 23, 2013, 6:50 a.m.
Pierre-Yves David <pierre-yves.david@ens-lyon.org> writes:

> On 09/21/2013 06:22 PM, Martin Geisler wrote:
>> Matt Mackall<mpm@selenic.com>  writes:
>>
>>> We've got a bunch of commands of the form foo/foos to make/list:
>>>
>>> 	tag/tags
>>> 	bookmark/bookmarks
>>> 	branch/branches
>> Most of our commands follow the 'hg<verb>' pattern: add, remove,
>> push, and pull. Some old commands use 'hg<noun>' instead, e.g.,
>> heads, parents, and manifest.
>
> There is active command and passive command. noun tend to be used by
> passive command (eg: hg heads vs hg listheads, hg summary vs hg
> summarize)
>
>> The words above share an interesting feature: tag, bookmark, and
>> branch can all be used as both verbs and nouns. This makes the plural
>> form particularly nice for listing the objects and the singular form
>> can be read as a verb denoting the action you want Mercurial to do.
>>
>> For this case, the noun is "shelf" and the verb is "shelve":
>>
>>    http://www.merriam-webster.com/dictionary/shelf (plural: "shelves")
>>    http://www.merriam-webster.com/dictionary/shelve
>>
>> That could be taken as an argument for having 'hg shelves' for
>> listing shelves and 'hg shelve' (verb) for making shelves.
>
> As I noted in a previous email, `shelve` + `shelves` prevents the use
> of short form. There is only two commandes that suffer from this now:
> tag/tags and branch/branches.
>
> `tag` is a short form by itself and branch is not so frequently used
> in a sequence of action (in regard to usage of commit, or mq for
> example)

Yeah, it feels unfortunate to me to have one core command shadow another
like that, but I don't remember it being a problem in practice. I think
that is because it's rare that I create a tag and even rarer that I
delete one.

>> In general, I think it is nice if the action implied by the verb
>> isn't changed completely by a flag. So 'hg revert --all' is good, the
>> flag extends the command to work on all files. By this logic, 'hg
>> shelve --unshelve' since the verb is reversed.
>>
>> A command like 'hg bookmark --delete' is also good since "bookmark"
>> can be read as a noun. Without a flag "bookmark" becomes a verb and
>> the command does it's primary action: bookmarking a changeset. I'm
>> not sure if this logic I just made up extends to other commands.
>
> If we used --apply instead of --unshelve. That would fit your
> description.

That would then be

  hg shelf --apply

for unshelving to go with the "singular noun" rule I made up previously.
That command is then a bit silly: we don't have other singular noun
commands since most of our things are plural.

I started thinking about this when looking at Git: there "stash" is used
as the command and that is both a singular noun and a verb, which makes

  git stash          # create a stash (verb, primary action)
  git stash --apply  # apply the stash (singular noun plus verb flag)

consistent with our bookmark command.

I don't really know how important these consistency rules are or how
long we can stretch the metaphors.

> (note saying I like it. Just saying that there is a flag based version
> that looks less silly on this aspect)

Yeah, it's a good point.
Matt Mackall - Sept. 23, 2013, 6:06 p.m.
Ok, looks like we'll be doing:

shelve
unshelve
shelve --list/etc.

Patch

diff --git a/hgext/shelve.py b/hgext/shelve.py
--- a/hgext/shelve.py
+++ b/hgext/shelve.py
@@ -11,7 +11,7 @@ 
 and reverts those changes, resetting the working directory to a clean
 state.
 
-Later on, the "hg unshelve" command restores the changes saved by "hg
+Later on, the "hg shelve --unshelve" command restores the changes saved by "hg
 shelve". Changes can be restored even after updating to a different
 parent, in which case Mercurial's merge machinery will resolve any
 conflicts if necessary.
@@ -384,7 +384,8 @@ 
         if [f for f in ms if ms[f] == 'u']:
             raise util.Abort(
                 _("unresolved conflicts, can't continue"),
-                hint=_("see 'hg resolve', then 'hg unshelve --continue'"))
+                hint=_("see 'hg resolve', then 'hg shelve --unshelve "
+                       "--continue'"))
         finishmerge(ui, repo, ms, state.stripnodes, state.name, opts)
         lock = repo.lock()
         repair.strip(ui, repo, state.stripnodes, backup='none', topic='shelve')
@@ -393,15 +394,7 @@ 
     finally:
         lockmod.release(lock, wlock)
 
-@command('unshelve',
-         [('a', 'abort', None,
-           _('abort an incomplete unshelve operation')),
-          ('c', 'continue', None,
-           _('continue an incomplete unshelve operation')),
-          ('', 'keep', None,
-           _('save shelved change'))],
-         _('hg unshelve [SHELVED]'))
-def unshelve(ui, repo, *shelved, **opts):
+def unshelvecmd(ui, repo, shelved, opts):
     '''restore a shelved change to the working directory
 
     This command accepts an optional name of a shelved change to
@@ -498,7 +491,7 @@ 
                                *revertfiles, no_backup=True)
                 raise error.InterventionRequired(
                     _("unresolved conflicts (see 'hg resolve', then "
-                      "'hg unshelve --continue')"))
+                      "'hg shelve --unshelve --continue')"))
             finishmerge(ui, repo, ms, stripnodes, basename, opts)
         else:
             parent = tip.parents()[0]
@@ -520,12 +513,18 @@ 
 @command('shelve',
          [('A', 'addremove', None,
            _('mark new/missing files as added/removed before shelving')),
+          ('a', 'abort', None,
+           _('abort an incomplete unshelve operation')),
+          ('c', 'continue', None,
+           _('continue an incomplete unshelve operation')),
           ('', 'cleanup', None,
            _('delete all shelved changes')),
           ('', 'date', '',
            _('shelve with the specified commit date'), _('DATE')),
           ('d', 'delete', None,
            _('delete the named shelved change(s)')),
+          ('', 'keep', None,
+           _('save shelved change')),
           ('l', 'list', None,
            _('list current shelves')),
           ('m', 'message', '',
@@ -535,7 +534,9 @@ 
           ('p', 'patch', None,
            _('show patch')),
           ('', 'stat', None,
-           _('output diffstat-style summary of changes'))],
+           _('output diffstat-style summary of changes')),
+          ('', 'unshelve', None,
+           _('unshelve the last shelved change'))],
          _('hg shelve'))
 def shelvecmd(ui, repo, *pats, **opts):
     '''save and set aside changes from the working directory
@@ -571,14 +572,20 @@ 
                     raise util.Abort(_("options '--%s' and '--%s' may not be "
                                        "used together") % (opt, i))
             return True
-    if checkopt('cleanup', 'addremove delete list message name patch stat'):
+    if checkopt('cleanup', 'addremove unshelve delete list '
+                           'message name patch stat'):
         if pats:
             raise util.Abort(_("cannot specify names when using '--cleanup'"))
         return cleanupcmd(ui, repo)
-    elif checkopt('delete', 'addremove cleanup list message name patch stat'):
+    elif checkopt('delete','addremove unshelve abort continue '
+                           'cleanup list keep message name patch stat'):
         return deletecmd(ui, repo, pats)
-    elif checkopt('list', 'addremove cleanup delete message name'):
+    elif checkopt('list', 'addremove unshelve abort continue cleanup delete '
+                          'keep message name'):
         return listcmd(ui, repo, pats, opts)
+    elif checkopt('unshelve', 'addremove cleanup delete message name '
+                              'patch stat name'):
+        return unshelvecmd(ui, repo, pats, opts)
     else:
         for i in ('patch', 'stat'):
             if opts[i]:
diff --git a/tests/test-shelve.t b/tests/test-shelve.t
--- a/tests/test-shelve.t
+++ b/tests/test-shelve.t
@@ -93,7 +93,7 @@ 
 local edits should prevent a shelved change from applying
 
   $ echo e>>a/a
-  $ hg unshelve
+  $ hg shelve --unshelve
   unshelving change 'default-01'
   the following shelved files have been modified:
     a/a
@@ -106,7 +106,7 @@ 
 
 apply it and make sure our state is as expected
 
-  $ hg unshelve
+  $ hg shelve --unshelve
   unshelving change 'default-01'
   adding changesets
   adding manifests
@@ -122,10 +122,10 @@ 
   R b/b
   $ hg shelve -l
 
-  $ hg unshelve
+  $ hg shelve --unshelve
   abort: no shelved changes to apply!
   [255]
-  $ hg unshelve foo
+  $ hg shelve --unshelve foo
   abort: shelved change 'foo' not found
   [255]
 
@@ -155,7 +155,7 @@ 
 
 and now "a/a" should reappear
 
-  $ hg unshelve -q wibble
+  $ hg shelve --unshelve -q wibble
   $ hg status -C
   M a/a
   A b.rename/b
@@ -180,7 +180,7 @@ 
 
 force a conflicted merge to occur
 
-  $ hg unshelve
+  $ hg shelve --unshelve
   unshelving change 'default'
   adding changesets
   adding manifests
@@ -191,7 +191,7 @@ 
   merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
   2 files updated, 0 files merged, 1 files removed, 1 files unresolved
   use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
-  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  unresolved conflicts (see 'hg resolve', then 'hg shelve --unshelve --continue')
   [1]
 
 ensure that we have a merge with unresolved conflicts
@@ -258,7 +258,7 @@ 
   A foo/foo
   R b/b
   ? a/a.orig
-  $ hg unshelve -a
+  $ hg shelve --unshelve -a
   unshelve of 'default' aborted
   $ hg heads -q
   2:ceefc37abe1e
@@ -276,7 +276,7 @@ 
 
 try to continue with no unshelve underway
 
-  $ hg unshelve -c
+  $ hg shelve --unshelve -c
   abort: no unshelve operation underway
   [255]
   $ hg status
@@ -285,23 +285,23 @@ 
 
 redo the unshelve to get a conflict
 
-  $ hg unshelve -q
+  $ hg shelve --unshelve -q
   warning: conflicts during merge.
   merging a/a incomplete! (edit conflicts, then use 'hg resolve --mark')
-  unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
+  unresolved conflicts (see 'hg resolve', then 'hg shelve --unshelve --continue')
   [1]
 
 attempt to continue
 
-  $ hg unshelve -c
+  $ hg shelve --unshelve -c
   abort: unresolved conflicts, can't continue
-  (see 'hg resolve', then 'hg unshelve --continue')
+  (see 'hg resolve', then 'hg shelve --unshelve --continue')
   [255]
 
   $ hg revert -r . a/a
   $ hg resolve -m a/a
 
-  $ hg unshelve -c
+  $ hg shelve --unshelve -c
   unshelve of 'default' complete
 
 ensure the repo is as we hope
@@ -339,7 +339,7 @@ 
   $ chmod +x a/a
   $ hg shelve -q -n execbit a/a
   $ hg status a/a
-  $ hg unshelve -q execbit
+  $ hg shelve --unshelve -q execbit
   $ hg status a/a
   M a/a
   $ hg revert a/a
@@ -352,7 +352,7 @@ 
   $ ln -s foo a/a
   $ hg shelve -q -n symlink a/a
   $ hg status a/a
-  $ hg unshelve -q symlink
+  $ hg shelve --unshelve -q symlink
   $ hg status a/a
   M a/a
   $ hg revert a/a
@@ -370,7 +370,7 @@ 
 
 if we resolve a conflict while unshelving, the unshelve should succeed
 
-  $ HGMERGE=true hg unshelve
+  $ HGMERGE=true hg shelve --unshelve
   unshelving change 'default'
   adding changesets
   adding manifests