threads / rfc / 27220

RFC patchsha1_name: interpret ~n as HEAD~n

Subject: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

## tl;dr

17 messages between Apr 29, 2011 and May 7, 2011. Diffs are folded; open one to read it.

replies: 16people: 7as markdown or json

Michael J Gruber· Apr 29, 2011, 15:53 UTC · lore

HEAD~n is often used for rebase invocations etc. Make it use the same default we use in other places, i.e. ~n == HEAD~n.

Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>
---
I haven't checked the side effects but find this super useful. Stop
me right now if this is a bad idea...
An alternative patch subject for this would have been:
sha1_name: We don't need no hg revision numbers, stupid!
---
 sha1_name.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
Show changes to sha1_name.c +4 −1
diff --git a/sha1_name.c b/sha1_name.c
index 69cd6c8..5d52eac 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -480,7 +480,10 @@ static int get_nth_ancestor(const char *name, int len,
 	struct commit *commit;
 	int ret;
 
-	ret = get_sha1_1(name, len, sha1);
+	if (len)
+		ret = get_sha1_1(name, len, sha1);
+	else
+		ret = get_sha1("HEAD", sha1);
 	if (ret)
 		return ret;
 	commit = lookup_commit_reference(sha1);
-- 
1.7.5.250.g4493b
Junio C Hamano· Apr 29, 2011, 16:21 UTC · re: Michael J Gruber · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Michael J Gruber <git@drmicha.warpmail.net> writes:
> HEAD~n is often used for rebase invocations etc.
I thought rebase invocations these days use @{u}.
Michael J Gruber· May 1, 2011, 08:30 UTC · re: Junio C Hamano · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

On Fri, 29 Apr 2011 09:21 -0700, "Junio C Hamano" <gitster@pobox.com> wrote:

Show 6 quoted lines
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
> > HEAD~n is often used for rebase invocations etc.
> 
> I thought rebase invocations these days use @{u}.
> 

I meant "rebase -i", sorry. And in fact I mostly mean those cases where I want to "amend" a commit which is not the top most one.

Michael
Matthieu Moy· May 1, 2011, 09:04 UTC · re: Michael J Gruber · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

"Michael J Gruber" <git@drmicha.warpmail.net> writes:
Show 13 quoted lines
> On Fri, 29 Apr 2011 09:21 -0700, "Junio C Hamano" <gitster@pobox.com>
> wrote:
>> Michael J Gruber <git@drmicha.warpmail.net> writes:
>> 
>> > HEAD~n is often used for rebase invocations etc.
>> 
>> I thought rebase invocations these days use @{u}.
>> 
>
> I meant "rebase -i", sorry. And in fact I mostly mean those cases where
> I want to "amend" a commit which is not the top most one.
>
> Michael
... and Junio is right that
  git rebase -i @{u}
usually does the right thing: let you amend any of the unpushed commits.
-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Junio C Hamano· May 1, 2011, 18:34 UTC · re: Michael J Gruber · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

"Michael J Gruber" <git@drmicha.warpmail.net> writes:
> I meant "rebase -i", sorry. And in fact I mostly mean those cases where
> I want to "amend" a commit which is not the top most one.

I also see myself getting tempted to say "rebase -i -2" every once in a while; it seems to go well with "log -2" especially when the history is linear.

Matthieu Moy· May 1, 2011, 21:21 UTC · re: Junio C Hamano · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Junio C Hamano <gitster@pobox.com> writes:
Show 8 quoted lines
> "Michael J Gruber" <git@drmicha.warpmail.net> writes:
>
>> I meant "rebase -i", sorry. And in fact I mostly mean those cases where
>> I want to "amend" a commit which is not the top most one.
>
> I also see myself getting tempted to say "rebase -i -2" every once in a
> while; it seems to go well with "log -2" especially when the history is
> linear.

I like that. As easy to type (or more, depending on the keyboard) as ~2, but no nasty interaction with the shell. OTOH, that would be a special-case for rebase only (i.e. doesn't make "git show HEAD~2" easier to type), but that's the most common case.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
Jeff King· Apr 29, 2011, 22:34 UTC · re: Michael J Gruber · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

On Fri, Apr 29, 2011 at 05:53:15PM +0200, Michael J Gruber wrote:
> HEAD~n is often used for rebase invocations etc. Make it use the same
> default we use in other places, i.e. ~n == HEAD~n.

Hmm. It certainly makes sense in that we often default emptiness to HEAD, but I don't think we can extend this syntax to other things. For example, seeing ~n makes me think that ^n or ^{tree} would work. But of course "^" at the beginning of a ref means something completely different. So it's not completely consistent.

Consistency-wise, I'm not sure if it makes things better or worse. Obviously we have "foo.." with an implicit HEAD. You could argue that ".." is a different operator altogether, and that any operator that is a "ref modifier" like "~" or "^" needs to have a non-implicit ref. But that gets muddier with "@{4.hours.ago}", which also takes an implicit value, except that it isn't exactly HEAD. It's the branch pointed to by HEAD.

So there really isn't a lot of consistency, I guess. It also conflicts a little with the shell's "~user" syntax, though presumably you don't have users named "1" and "2".

-Peff
Sverre Rabbelier· Apr 29, 2011, 23:23 UTC · re: Jeff King · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Heya,
On Sat, Apr 30, 2011 at 00:34, Jeff King <peff@peff.net> wrote:
> So there really isn't a lot of consistency, I guess.  It also conflicts
> a little with the shell's "~user" syntax, though presumably you don't
> have users named "1" and "2".

FWIW, I like the patch, mainly because I dislike typing HEAD~n (I usually mispel it as HEA~n) and agree with peff's analysis, we're such a long way from being any form of consistent that I don't see this breaking any user expectations.

-- 
Cheers,

Sverre Rabbelier
Mikael Magnusson· May 7, 2011, 02:24 UTC · re: Sverre Rabbelier · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

On 30 April 2011 01:23, Sverre Rabbelier <srabbelier@gmail.com> wrote:
Show 11 quoted lines
> Heya,
>
> On Sat, Apr 30, 2011 at 00:34, Jeff King <peff@peff.net> wrote:
>> So there really isn't a lot of consistency, I guess.  It also conflicts
>> a little with the shell's "~user" syntax, though presumably you don't
>> have users named "1" and "2".
>
> FWIW, I like the patch, mainly because I dislike typing HEAD~n (I
> usually mispel it as HEA~n) and agree with peff's analysis, we're such
> a long way from being any form of consistent that I don't see this
> breaking any user expectations.

Something I always set up in the skeleton dir ($prefix/share/git-core/templates) after installing git is echo 'ref: HEAD' > h it makes life so much easier :).

-- 
Mikael Magnusson
Andreas Schwab· Apr 29, 2011, 23:31 UTC · re: Jeff King · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Jeff King <peff@peff.net> writes:
> It also conflicts a little with the shell's "~user" syntax, though
> presumably you don't have users named "1" and "2".
Well, you sorta do if you did use pushd.
Andreas.
-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Junio C Hamano· Apr 30, 2011, 05:33 UTC · re: Andreas Schwab · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Andreas Schwab <schwab@linux-m68k.org> writes:
Show 6 quoted lines
> Jeff King <peff@peff.net> writes:
>
>> It also conflicts a little with the shell's "~user" syntax, though
>> presumably you don't have users named "1" and "2".
>
> Well, you sorta do if you did use pushd.

Yeah, I was also worried about that. Or some arcane system misinterpreting "~0" as the home directory of root ;-)

Andreas Schwab· Apr 30, 2011, 09:09 UTC · re: Junio C Hamano · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Junio C Hamano <gitster@pobox.com> writes:
Show 11 quoted lines
> Andreas Schwab <schwab@linux-m68k.org> writes:
>
>> Jeff King <peff@peff.net> writes:
>>
>>> It also conflicts a little with the shell's "~user" syntax, though
>>> presumably you don't have users named "1" and "2".
>>
>> Well, you sorta do if you did use pushd.
>
> Yeah, I was also worried about that.  Or some arcane system
> misinterpreting "~0" as the home directory of root ;-)
On non-arcane systems ~0 is expanded to the current directory.
Andreas.
-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Michael J Gruber· May 2, 2011, 08:42 UTC · re: Andreas Schwab · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Andreas Schwab venit, vidit, dixit 30.04.2011 11:09:
Show 18 quoted lines
> Junio C Hamano <gitster@pobox.com> writes:
> 
>> Andreas Schwab <schwab@linux-m68k.org> writes:
>>
>>> Jeff King <peff@peff.net> writes:
>>>
>>>> It also conflicts a little with the shell's "~user" syntax, though
>>>> presumably you don't have users named "1" and "2".
>>>
>>> Well, you sorta do if you did use pushd.
>>
>> Yeah, I was also worried about that.  Or some arcane system
>> misinterpreting "~0" as the home directory of root ;-)
> 
> On non-arcane systems ~0 is expanded to the current directory.
> 
> Andreas.
> 
[cumulative reply :)]

While we could use a short-hand for HEAD also I don't think ~0 really is a concern.

Regarding consistency: We try to have reasonable defaults and try to dwim (which are different things) even if that breaks consistency/systematics, because useful/reasonable and "what I mean" depend on the context.

"^" resp. ".." and "..." are ambiguous and cannot be resolved easily because for most commands they can mean two things resp. require two arguments. (".." and "..." could maybe default do "@{u}..HEAD" etc.)

"~<n>" can only take a revision argument to its left, and also it needs an argument to its left (as opposed to "^"). Therefore we can default it unambiguously and without braking any current usage (that I know of).

Regarding rebase -i -<n>: git-rebase (-i) does not have a log/rev-list like interface at all (just like git-cherry does not), and introducing an argument which looks like it did would just increase the user confusion, I'm afraid.

Michael
Michael J Gruber· May 2, 2011, 11:04 UTC · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Junio C Hamano venit, vidit, dixit 02.05.2011 12:25:
Show 14 quoted lines
> 
> On May 2, 2011 1:42 AM, "Michael J Gruber" <git@drmicha.warpmail.net
> <mailto:git@drmicha.warpmail.net>> wrote:
> 
>> Regarding rebase -i -<n>:
>> git-rebase (-i) does not have a log/rev-list like interface at all (just
>> like git-cherry does not), and introducing an argument which looks like
>> it did would just increase the user confusion, I'm afraid.
> 
> That cuts both ways. Some people can already be confused by it not being
> in line with the log family. Just like format-patch that was born
> without the log family interface later learned it, it is not impossible
> to teach rebase the same, no?
> 

Just because we went in a wrong direction then, is it good to go in the same direction now?

I'm not saying it necessarily was a wrong direction, I just don't consider that an argument.

You can consider my "log --cherry" being part of a long time plan to git rid of "kinda-loggish but not log-like" command interfaces (in that case git-cherry).

Introducing a shortcut ~n for HEAD~n does not introduce new inconsistencies (it's a shortcut for a commit, for every command which takes a commit) - and does not contradict introducing -n at all, btw. But introducing -n means introducing a range like revision argument to a command which does not grok ranges at all, so that is a much deeper decision.

Michael
Junio C Hamano· May 2, 2011, 16:33 UTC · re: Michael J Gruber · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Michael J Gruber <git@drmicha.warpmail.net> writes:
> Introducing a shortcut ~n for HEAD~n does not introduce new
> inconsistencies (it's a shortcut for a commit, for every command which
> takes a commit) - and does not contradict introducing -n at all, btw.
I thought we already ruled out ~n because many shells think ~n is a path.
> But introducing -n means introducing a range like revision argument to a
> command which does not grok ranges at all, so that is a much deeper
> decision.
I do not think so.

When I originally wrote format-patch and rebase, Linus was finishing up making the "range notation" easier to use around rev-list (and later log). It was not apparent to me that what these two commands operated were a range, by deviating from the "log" syntax two commands could take their operand in a more workflow-specific way (which in turn led to a shorter keystrokes, as you only wrote only one endpoint because the other end was implicit).

The original syntax of format-patch (which by the way is still supported) is to give what we call the upstream these days, like this:

	git format-patch origin
which then is internally turned into a moral equivalent of
	git rev-list --no-merges origin..HEAD

to find out which commit to output (and run "git diff-tree -p --stdin" on). The command originally only accepted this short-hand form without giving the users ways to affect underlying "range" any other way. But later we found that it is better allow users to use the "log" syntax, for reasons including:

 - HEAD may not always be the topic you want to submit; and
 - you may not want to submit all commits since the fork point
   (i.e. endpoint might want to be HEAD~4 or mytopic~3).

The history behind "rebase" is pretty similar. Again, with the original syntax you give the "upstream":

	git rebase origin
	git rebase origin mytopic
and again these were internally turned into a moral equivalent of
	... optionally "git checkout mytopic" if given
	git rev-list --no-merges origin..HEAD

to find out which commit to replay on top of the updated base (this is a natural consequence that the original "rebase" was "format-patch" piped into "am").

"git rebase origin.." and "git rebase origin..mytopic" would be a way to express this operation more naturally. The former would rebase the current branch, and the latter would checkout mytopic branch and rebase it.

One extra reason (which does not apply to format-patch) that rebase wasn't done that way was purely technical. Back then, unless you are prepared to parse these range arguments yourself, once you feed them to rev-parse machinery, you wouldn't be able to tell if the user said "origin..mytopic" or "origin..mytopic^0". The former should rebuild mytopic branch while the latter should leave mytopic branch intact and instead give you a rebuilt history for mytopic branch on a detached HEAD.

I think these days the internal rev-parse machinery passes enough information down add_pending_object() codepath (and in a scripted Porcelain, you can say "rev-parse --symbolic origin..HEAD" to pry it apart), so it should be possible to express what range "rebase" wants to operate on in its natural notation that is used by the log family of commands, if we wanted to.

Michael J Gruber· May 2, 2011, 17:49 UTC · re: Junio C Hamano · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Junio C Hamano venit, vidit, dixit 02.05.2011 18:33:
Show 7 quoted lines
> Michael J Gruber <git@drmicha.warpmail.net> writes:
> 
>> Introducing a shortcut ~n for HEAD~n does not introduce new
>> inconsistencies (it's a shortcut for a commit, for every command which
>> takes a commit) - and does not contradict introducing -n at all, btw.
> 
> I thought we already ruled out ~n because many shells think ~n is a path.
You have, apparently ;)

unquoted ~0 conflicts, but unquoted ~n conflicts only when you use pushd (and the stack has n entries; or n+-1, I can't count either...). Even \~2 is shorter than HEAD~2, btw., although I don't consider that viable.

But I understand that I'll have to leave ~n for my private edition.
Michael
Matthieu Moy· May 2, 2011, 20:14 UTC · re: Michael J Gruber · lore

Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n

Michael J Gruber <git@drmicha.warpmail.net> writes:
Show 6 quoted lines
>> I thought we already ruled out ~n because many shells think ~n is a path.
>
> You have, apparently ;)
>
> unquoted ~0 conflicts, but unquoted ~n conflicts only when you use pushd
> (and the stack has n entries; or n+-1, I can't count either...).

The problem is that it makes the behavior rather unpredictible for non-expert:

git log ~2 # great pushd git log ~2 # still great pushd git log ~2 # WTF ?

so we can't teach new users the ~N syntax without quoting if we don't want them to get bad surprises later. \~N is not terribly bad, but I don't think it has a big added value compared to HEAD~N.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/

← back to recent threads