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

17 messages from 2011-04-29 to 2011-05-07. Participants: Michael J Gruber, Junio C Hamano, Jeff King, Sverre Rabbelier, Andreas Schwab, Matthieu Moy, Mikael Magnusson.
Thread: https://gitlist.dev/t/27220

## Michael J Gruber, 2011-04-29 15:53

Subject: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <6c53916752bf79178113157291fd675ead0804c9.1304092338.git.git@drmicha.warpmail.net>
URL: https://gitlist.dev/e/6c53916752bf79178113157291fd675ead0804c9.1304092338.git.git%40drmicha.warpmail.net

```
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(-)

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, 2011-04-29 16:21

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <7vfwp1yqnq.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vfwp1yqnq.fsf%40alter.siamese.dyndns.org
In-Reply-To: <6c53916752bf79178113157291fd675ead0804c9.1304092338.git.git@drmicha.warpmail.net>

```
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}.

```

## Jeff King, 2011-04-29 22:34

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <20110429223433.GA3434@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20110429223433.GA3434%40sigill.intra.peff.net
In-Reply-To: <6c53916752bf79178113157291fd675ead0804c9.1304092338.git.git@drmicha.warpmail.net>

```
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, 2011-04-29 23:23

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <BANLkTi=7_-TF63Y9MRHZ_XirSUD6RAC9kw@mail.gmail.com>
URL: https://gitlist.dev/e/BANLkTi%3D7_-TF63Y9MRHZ_XirSUD6RAC9kw%40mail.gmail.com
In-Reply-To: <20110429223433.GA3434@sigill.intra.peff.net>

```
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

```

## Andreas Schwab, 2011-04-29 23:31

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <m2k4ecy6rv.fsf@igel.home>
URL: https://gitlist.dev/e/m2k4ecy6rv.fsf%40igel.home
In-Reply-To: <20110429223433.GA3434@sigill.intra.peff.net>

```
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, 2011-04-30 05:33

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <7vfwp0uwu4.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vfwp0uwu4.fsf%40alter.siamese.dyndns.org
In-Reply-To: <m2k4ecy6rv.fsf@igel.home>

```
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 ;-)

```

## Andreas Schwab, 2011-04-30 09:09

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <m21v0kw1es.fsf@igel.home>
URL: https://gitlist.dev/e/m21v0kw1es.fsf%40igel.home
In-Reply-To: <7vfwp0uwu4.fsf@alter.siamese.dyndns.org>

```
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.

-- 
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, 2011-05-01 08:30

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <1304238652.9638.1446946253@webmail.messagingengine.com>
URL: https://gitlist.dev/e/1304238652.9638.1446946253%40webmail.messagingengine.com
In-Reply-To: <7vfwp1yqnq.fsf@alter.siamese.dyndns.org>

```
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

```

## Matthieu Moy, 2011-05-01 09:04

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <vpqoc3mg5bd.fsf@bauges.imag.fr>
URL: https://gitlist.dev/e/vpqoc3mg5bd.fsf%40bauges.imag.fr
In-Reply-To: <1304238652.9638.1446946253@webmail.messagingengine.com>

```
"Michael J Gruber" <git@drmicha.warpmail.net> writes:

> 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, 2011-05-01 18:34

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <7vfwoys20u.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vfwoys20u.fsf%40alter.siamese.dyndns.org
In-Reply-To: <1304238652.9638.1446946253@webmail.messagingengine.com>

```
"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, 2011-05-01 21:21

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <vpqsjsy15i0.fsf@bauges.imag.fr>
URL: https://gitlist.dev/e/vpqsjsy15i0.fsf%40bauges.imag.fr
In-Reply-To: <7vfwoys20u.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano <gitster@pobox.com> writes:

> "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/

```

## Michael J Gruber, 2011-05-02 08:42

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <4DBE6E77.3030703@drmicha.warpmail.net>
URL: https://gitlist.dev/e/4DBE6E77.3030703%40drmicha.warpmail.net
In-Reply-To: <m21v0kw1es.fsf@igel.home>

```
Andreas Schwab venit, vidit, dixit 30.04.2011 11:09:
> 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, 2011-05-02 11:04

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <4DBE8FD8.90303@drmicha.warpmail.net>
URL: https://gitlist.dev/e/4DBE8FD8.90303%40drmicha.warpmail.net
In-Reply-To: <BANLkTinxszGhtYobuvci5Yi8eTHW+pi2wA@mail.gmail.com>

```
Junio C Hamano venit, vidit, dixit 02.05.2011 12:25:
> 
> 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, 2011-05-02 16:33

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <7v7ha9ngsf.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v7ha9ngsf.fsf%40alter.siamese.dyndns.org
In-Reply-To: <4DBE8FD8.90303@drmicha.warpmail.net>

```
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, 2011-05-02 17:49

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <4DBEEEAA.3000004@drmicha.warpmail.net>
URL: https://gitlist.dev/e/4DBEEEAA.3000004%40drmicha.warpmail.net
In-Reply-To: <7v7ha9ngsf.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano venit, vidit, dixit 02.05.2011 18:33:
> 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, 2011-05-02 20:14

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <vpq62pssvun.fsf@bauges.imag.fr>
URL: https://gitlist.dev/e/vpq62pssvun.fsf%40bauges.imag.fr
In-Reply-To: <4DBEEEAA.3000004@drmicha.warpmail.net>

```
Michael J Gruber <git@drmicha.warpmail.net> writes:

>> 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/

```

## Mikael Magnusson, 2011-05-07 02:24

Subject: Re: [RFC/largely untested/PATCH] sha1_name: interpret ~n as HEAD~n
Message-ID: <BANLkTinsWpXYN+Zejph6toidZWFAkprcYw@mail.gmail.com>
URL: https://gitlist.dev/e/BANLkTinsWpXYN%2BZejph6toidZWFAkprcYw%40mail.gmail.com
In-Reply-To: <BANLkTi=7_-TF63Y9MRHZ_XirSUD6RAC9kw@mail.gmail.com>

```
On 30 April 2011 01:23, Sverre Rabbelier <srabbelier@gmail.com> wrote:
> 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

```
