git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* tracking branch for a rebase
@ 2009-09-04 13:54 Pete Wyckoff
  2009-09-04 14:31 ` Michael J Gruber
  0 siblings, 1 reply; 39+ messages in thread
From: Pete Wyckoff @ 2009-09-04 13:54 UTC (permalink / raw)
  To: git

I received an interesting question today.

If "git pull" knows what remote tracking brach to pull from,
why doesn't "git rebase" automatically know I want to rebase
on top of my remote tracking branch?

He had done a "git remote update", reviewed the changes, and now
wants to rebase his changes on top of the new upstream.

I told him about git pull --rebase, and branch.name.rebase,
but didn't have an easy answer to the "what is my remote tracking
branch" question in this case.

All the information is in git config branch.name.{remote,merge},
but I can't find anything that just answers that question.  Nor
did I have a good answer for why "git rebase" doesn't just default
to rebasing the current branch on top of the tracking branch.

Thoughts?

		-- Pete

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-04 13:54 tracking branch for a rebase Pete Wyckoff
@ 2009-09-04 14:31 ` Michael J Gruber
  2009-09-04 18:18   ` Jeff King
  0 siblings, 1 reply; 39+ messages in thread
From: Michael J Gruber @ 2009-09-04 14:31 UTC (permalink / raw)
  To: Pete Wyckoff; +Cc: git

Pete Wyckoff venit, vidit, dixit 04.09.2009 15:54:
> I received an interesting question today.
> 
> If "git pull" knows what remote tracking brach to pull from,
> why doesn't "git rebase" automatically know I want to rebase
> on top of my remote tracking branch?
> 
> He had done a "git remote update", reviewed the changes, and now
> wants to rebase his changes on top of the new upstream.
> 
> I told him about git pull --rebase, and branch.name.rebase,
> but didn't have an easy answer to the "what is my remote tracking
> branch" question in this case.

I guess he knows that branch if he reviewed it... More seriously,

git for-each-ref --format='%(upstream)' refs/heads/hisbranch

will return the upstream of hisbranch.

> 
> All the information is in git config branch.name.{remote,merge},
> but I can't find anything that just answers that question.  Nor
> did I have a good answer for why "git rebase" doesn't just default
> to rebasing the current branch on top of the tracking branch.

Maybe because nobody has cared. Doing a "git pull --rebase" is not
equivalent (it may fetch more refs), but close enough for many people.

There was an initiative by Dscho a while ago to introduce a shortcut for
the upstream, which was dwarfed by the lack reserved characters for
refnames. Maybe 1.7 time frame would be a good time to change this?

Making this the default for rebase without arguments may meet some
objections (oh no, I didn't mean to rebase), but I guess it's worth trying.

Michael

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-04 14:31 ` Michael J Gruber
@ 2009-09-04 18:18   ` Jeff King
  2009-09-04 18:59     ` Björn Steinbrink
  0 siblings, 1 reply; 39+ messages in thread
From: Jeff King @ 2009-09-04 18:18 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Pete Wyckoff, git

On Fri, Sep 04, 2009 at 04:31:57PM +0200, Michael J Gruber wrote:

> Making [rebase against upstream] the default for rebase without
> arguments may meet some objections (oh no, I didn't mean to rebase),
> but I guess it's worth trying.

FWIW, that has been a patch I have been meaning to do for a while. I
don't see it as any more error-prone than "git pull" without arguments.
In either case, you can always recover with a reset from the reflog.

The biggest question is whether it should respect branch.*.merge, or
just branch.*.rebase (I never use the latter simply because I never use
"git pull", but I think it is probably reasonable to restrict it to
cases where you said you are interested in rebasing in general).

-Peff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-04 18:18   ` Jeff King
@ 2009-09-04 18:59     ` Björn Steinbrink
  2009-09-05  6:12       ` Jeff King
  0 siblings, 1 reply; 39+ messages in thread
From: Björn Steinbrink @ 2009-09-04 18:59 UTC (permalink / raw)
  To: Jeff King; +Cc: Michael J Gruber, Pete Wyckoff, git

On 2009.09.04 14:18:46 -0400, Jeff King wrote:
> On Fri, Sep 04, 2009 at 04:31:57PM +0200, Michael J Gruber wrote:
> 
> > Making [rebase against upstream] the default for rebase without
> > arguments may meet some objections (oh no, I didn't mean to rebase),
> > but I guess it's worth trying.
> 
> FWIW, that has been a patch I have been meaning to do for a while. I
> don't see it as any more error-prone than "git pull" without arguments.
> In either case, you can always recover with a reset from the reflog.

Note that with:
	branch.foo.remote = origin
	branch.foo.merge = refs/heads/foo

"git pull --rebase" is not the same as:
"git fetch origin && git rebase origin/foo", but:

git fetch origin && git rebase --onto origin/foo $reflog_merge_base

Where $reflog_merge_base is the first merge base is found between the
current branch head, and the reflog entries for origin/foo.


Same deal for "git pull --rebase origin bla", which is not:
"git fetch origin bla && git rebase FETCH_HEAD", but:

git fetch origin && git rebase --onto FETCH_HEAD $reflog_merge_base

Where again $reflog_merge_base is found by looking at the reflog for
origin/foo.

It does that to try to automatically handle cases where upstream has
been rebased. I'm not completely sure whether I like or hate that.
Especially the "git pull --rebase <remote> <refspec>" case seems very
weird to me. And if "rebase" is to pickup the same default as "pull", I
guess it should also show the same behaviour, but just skips the "fetch"
part?

> The biggest question is whether it should respect branch.*.merge, or
> just branch.*.rebase (I never use the latter simply because I never use
> "git pull", but I think it is probably reasonable to restrict it to
> cases where you said you are interested in rebasing in general).

Hm, you'll probably want "git merge" to pickup the default as well then,
right? And that should only do so if branch.*.rebase is not set. So
effectively, you still have to use the right command, but can skip the
argument. Having to deal a lot with git-svn, I also regulary use its
"git svn rebase --local", which means "just rebase, don't fetch".

Now, basically "git svn rebase" is pretty much git-svn's "pull". Maybe
its idea could be taken, so we get "git pull --local" to just skip the
fetch part, but keep "git rebase" and "git merge" 'dumb', requiring
explicit arguments.

(In the past, I once argued for deprecating "pull", and having
merge/rebase doing the fetch as well, with a --local argument that stops
them from doing so. That was probably mostly due to the fact that I ran
into too many people that simply didn't understood that "git pull" is
not "svn up". I still kind of like the idea, but seeing just how often I
use rebase/merge with already fetched stuff, I can see how having to use
a --local flag with them all the time would be quite a PITA, but now,
having the --local flag for "pull" seems to make sense to me.)

Björn

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-04 18:59     ` Björn Steinbrink
@ 2009-09-05  6:12       ` Jeff King
  2009-09-05 14:01         ` Björn Steinbrink
  0 siblings, 1 reply; 39+ messages in thread
From: Jeff King @ 2009-09-05  6:12 UTC (permalink / raw)
  To: Björn Steinbrink; +Cc: Michael J Gruber, Pete Wyckoff, git

On Fri, Sep 04, 2009 at 08:59:49PM +0200, Björn Steinbrink wrote:

> "git pull --rebase" is not the same as:
> "git fetch origin && git rebase origin/foo", but:
> 
> git fetch origin && git rebase --onto origin/foo $reflog_merge_base
> 
> Where $reflog_merge_base is the first merge base is found between the
> current branch head, and the reflog entries for origin/foo.

Thanks, I didn't know about the trick (not being, as I mentioned, a pull
--rebase user). I can see arguments for or against a rebase-default
using that feature. On one hand, it simplifies the explanation for
people going between "pull --rebase" and "fetch && rebase". And I think
it should generally Do What You Mean in the case that upstream hasn't
rebased. Are there cases you know of where it will do the wrong thing?

I don't know if people would be confused that "git rebase" does not
exactly default to "git rebase $upstream", which is at least easy to
explain.

> > The biggest question is whether it should respect branch.*.merge, or
> > just branch.*.rebase (I never use the latter simply because I never use
> > "git pull", but I think it is probably reasonable to restrict it to
> > cases where you said you are interested in rebasing in general).
> 
> Hm, you'll probably want "git merge" to pickup the default as well then,
> right? And that should only do so if branch.*.rebase is not set. So
> effectively, you still have to use the right command, but can skip the
> argument. Having to deal a lot with git-svn, I also regulary use its
> "git svn rebase --local", which means "just rebase, don't fetch".

I hadn't considered whether "git merge" should get a default. To be
honest, my intended use case was not really to replace pull, but as a
shorthand for running "git rebase -i". Upstream has the published
commits, so it is a nice shortcut to say "let me munge all of the
commits that I haven't published yet".

Of course the "published" status of those commits is not guaranteed
(they might have been published in another branch, your
tracking refs might not be up to date, etc) but I think it's a good rule
of thumb.

And by automating the shorthand we reduce the chance of errors. For
example, I usually base my topic branches from origin/master. But the
other day I happened to be building a new branch, jk/date, off of
lt/approxidate, salvaged from origin/pu. I did "git rebase -i
origin/master" and accidentally rewrote the early part of
lt/approxidate.

> Now, basically "git svn rebase" is pretty much git-svn's "pull". Maybe
> its idea could be taken, so we get "git pull --local" to just skip the
> fetch part, but keep "git rebase" and "git merge" 'dumb', requiring
> explicit arguments.

That wouldn't help me, because you can't "pull -i". :)

-Peff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-05  6:12       ` Jeff King
@ 2009-09-05 14:01         ` Björn Steinbrink
  2009-09-05 14:28           ` Jeff King
  2009-09-05 17:59           ` Junio C Hamano
  0 siblings, 2 replies; 39+ messages in thread
From: Björn Steinbrink @ 2009-09-05 14:01 UTC (permalink / raw)
  To: Jeff King; +Cc: Michael J Gruber, Pete Wyckoff, git

On 2009.09.05 02:12:50 -0400, Jeff King wrote:
> On Fri, Sep 04, 2009 at 08:59:49PM +0200, Björn Steinbrink wrote:
> 
> > "git pull --rebase" is not the same as:
> > "git fetch origin && git rebase origin/foo", but:
> > 
> > git fetch origin && git rebase --onto origin/foo $reflog_merge_base
> > 
> > Where $reflog_merge_base is the first merge base is found between the
> > current branch head, and the reflog entries for origin/foo.
> 
> Thanks, I didn't know about the trick (not being, as I mentioned, a pull
> --rebase user). I can see arguments for or against a rebase-default
> using that feature. On one hand, it simplifies the explanation for
> people going between "pull --rebase" and "fetch && rebase". And I think
> it should generally Do What You Mean in the case that upstream hasn't
> rebased. Are there cases you know of where it will do the wrong thing?
> 
> I don't know if people would be confused that "git rebase" does not
> exactly default to "git rebase $upstream", which is at least easy to
> explain.

For me, the confusion would arise from the fact that "git rebase"
(without args) would seem like a "pull --rebase" without the fetch, but
isn't. And to reducing the difference to just the fetch would require a
quite change in bahaviour.

Currently, when branch.<name>.merge is set:
"git rebase <upstream>" ==> Can't really be done with "pull --rebase"
"git pull --rebase [...]" ==> Can't be done with "rebase" alone.

Currently, "pull" is a convenience thing, and thus may do more magic,
while "rebase" is dumb, and needs arguments. Starting to add _different_
magic to rebase seems wrong to me.

> And by automating the shorthand we reduce the chance of errors. For
> example, I usually base my topic branches from origin/master. But the
> other day I happened to be building a new branch, jk/date, off of
> lt/approxidate, salvaged from origin/pu. I did "git rebase -i
> origin/master" and accidentally rewrote the early part of
> lt/approxidate.

Hm, I'd prefer a shorthand for "upstream for this branch", instead of
magic defaults.

> > Now, basically "git svn rebase" is pretty much git-svn's "pull". Maybe
> > its idea could be taken, so we get "git pull --local" to just skip the
> > fetch part, but keep "git rebase" and "git merge" 'dumb', requiring
> > explicit arguments.
> 
> That wouldn't help me, because you can't "pull -i". :)

I probably shouldn't tell anyone, as it's a crude hack, but "git pull
--rebase -s -i" does the trick... *hides*

Björn

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-05 14:01         ` Björn Steinbrink
@ 2009-09-05 14:28           ` Jeff King
  2009-09-07  5:05             ` Junio C Hamano
  2009-09-05 17:59           ` Junio C Hamano
  1 sibling, 1 reply; 39+ messages in thread
From: Jeff King @ 2009-09-05 14:28 UTC (permalink / raw)
  To: Björn Steinbrink; +Cc: Michael J Gruber, Pete Wyckoff, git

On Sat, Sep 05, 2009 at 04:01:27PM +0200, Björn Steinbrink wrote:

> > And by automating the shorthand we reduce the chance of errors. For
> > example, I usually base my topic branches from origin/master. But the
> > other day I happened to be building a new branch, jk/date, off of
> > lt/approxidate, salvaged from origin/pu. I did "git rebase -i
> > origin/master" and accidentally rewrote the early part of
> > lt/approxidate.
> 
> Hm, I'd prefer a shorthand for "upstream for this branch", instead of
> magic defaults.

The more I think about, the more I think that is the right solution.
Because magic defaults for "rebase -i" don't help when you want to do
"gitk $UPSTREAM..".

The previous discussion on the topic seems to be here:

  http://article.gmane.org/gmane.comp.version-control.git/113666

And apparently you and I both participated in the discussion, which I
totally forgot about.

Looks like the discussion ended with people liking the idea but not
knowing what the specifier should look like. Maybe tightening the ref
syntax a bit to allow more extensible "special" refs is a good v1.7.0
topic? I dunno.

> > That wouldn't help me, because you can't "pull -i". :)
> 
> I probably shouldn't tell anyone, as it's a crude hack, but "git pull
> --rebase -s -i" does the trick... *hides*

OK, that's just sick. :)

-Peff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-05 14:01         ` Björn Steinbrink
  2009-09-05 14:28           ` Jeff King
@ 2009-09-05 17:59           ` Junio C Hamano
  1 sibling, 0 replies; 39+ messages in thread
From: Junio C Hamano @ 2009-09-05 17:59 UTC (permalink / raw)
  To: Björn Steinbrink; +Cc: Jeff King, Michael J Gruber, Pete Wyckoff, git

Björn Steinbrink <B.Steinbrink@gmx.de> writes:

> For me, the confusion would arise from the fact that "git rebase"
> (without args) would seem like a "pull --rebase" without the fetch, but
> isn't.

It is true that one popular way to explain 'git pull' is:

    'git pull' is 'git fetch' followed by 'git merge'.

These three command names in the sentence merely refer to the concepts of
what they do.

It is left up to the readers to extend the concepts to concrete command
line to suit the needs for their situation.  For example you would
restate the above general explanation into this form:

       'git pull git.git master' is 'git fetch git.git master' followed by
       'git merge FETCH_HEAD'

when updating your tree with the master branch of upstream git.git
repository.

Don't confuse the general concept with concrete syntax.

    'git pull --rebase' is 'git fetch' followed by 'git rebase'

is exactly the same deal.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-05 14:28           ` Jeff King
@ 2009-09-07  5:05             ` Junio C Hamano
  2009-09-07  8:14               ` Michael J Gruber
  2009-09-07  8:43               ` Jeff King
  0 siblings, 2 replies; 39+ messages in thread
From: Junio C Hamano @ 2009-09-07  5:05 UTC (permalink / raw)
  To: Jeff King; +Cc: Björn Steinbrink, Michael J Gruber, Pete Wyckoff, git

Jeff King <peff@peff.net> writes:

>> Hm, I'd prefer a shorthand for "upstream for this branch", instead of
>> magic defaults.
>
> The more I think about, the more I think that is the right solution.
> Because magic defaults for "rebase -i" don't help when you want to do
> "gitk $UPSTREAM..".
>
> The previous discussion on the topic seems to be here:
>
>   http://article.gmane.org/gmane.comp.version-control.git/113666
>
> And apparently you and I both participated in the discussion, which I
> totally forgot about.
>
> Looks like the discussion ended with people liking the idea but not
> knowing what the specifier should look like. Maybe tightening the ref
> syntax a bit to allow more extensible "special" refs is a good v1.7.0
> topic? I dunno.

At-mark currently is reserved for anything that uses reflog, but we can
say that it is to specify operations on refs (as opposed to caret and
tilde are to specify operations on object names).

It specifies what ref to work on with the operand on its left side (and an
empty string stands for "HEAD"), and what operation is done to it by what
is in {} on the right side of it.  This view is quite consistent with the
following existing uses of the notation:

	ref@{number}	-- nth reflog entry
        ref@{time}	-- ref back then
	@{-number}	-- nth branch switching

So perhaps ref@{upstream}, or any string that is not a number and cannot
be time, can trigger the magic operation on the ref with ref@{magic}
syntax?

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-07  5:05             ` Junio C Hamano
@ 2009-09-07  8:14               ` Michael J Gruber
  2009-09-07  8:25                 ` Junio C Hamano
  2009-09-07  8:43               ` Jeff King
  1 sibling, 1 reply; 39+ messages in thread
From: Michael J Gruber @ 2009-09-07  8:14 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Björn Steinbrink, Pete Wyckoff, git

Junio C Hamano venit, vidit, dixit 07.09.2009 07:05:
> Jeff King <peff@peff.net> writes:
> 
>>> Hm, I'd prefer a shorthand for "upstream for this branch", instead of
>>> magic defaults.
>>
>> The more I think about, the more I think that is the right solution.
>> Because magic defaults for "rebase -i" don't help when you want to do
>> "gitk $UPSTREAM..".
>>
>> The previous discussion on the topic seems to be here:
>>
>>   http://article.gmane.org/gmane.comp.version-control.git/113666
>>
>> And apparently you and I both participated in the discussion, which I
>> totally forgot about.
>>
>> Looks like the discussion ended with people liking the idea but not
>> knowing what the specifier should look like. Maybe tightening the ref
>> syntax a bit to allow more extensible "special" refs is a good v1.7.0
>> topic? I dunno.
> 
> At-mark currently is reserved for anything that uses reflog, but we can
> say that it is to specify operations on refs (as opposed to caret and
> tilde are to specify operations on object names).
> 
> It specifies what ref to work on with the operand on its left side (and an
> empty string stands for "HEAD"), and what operation is done to it by what
> is in {} on the right side of it.  This view is quite consistent with the
> following existing uses of the notation:
> 
> 	ref@{number}	-- nth reflog entry
>         ref@{time}	-- ref back then
> 	@{-number}	-- nth branch switching
> 
> So perhaps ref@{upstream}, or any string that is not a number and cannot
> be time, can trigger the magic operation on the ref with ref@{magic}
> syntax?

Even @{} is not taken so far... Alternatively, most people associate '^'
with 'up', just the way we use it for "upwards parentship" ref^ (and
somewhat the way we use it for upwards/backwards tag reference
relationship resolving ref^{type}), so
@^
or
@{^}
would be an option. Read "at upstream" :)

Michael

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-07  8:14               ` Michael J Gruber
@ 2009-09-07  8:25                 ` Junio C Hamano
  2009-09-07  8:44                   ` Jeff King
  0 siblings, 1 reply; 39+ messages in thread
From: Junio C Hamano @ 2009-09-07  8:25 UTC (permalink / raw)
  To: Michael J Gruber; +Cc: Jeff King, Björn Steinbrink, Pete Wyckoff, git

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

> @^

"@" itself is not reserved, even though "@{" is, so this is not an
option.

> @{^}

This _could_ work, although it is rather cryptic.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-07  5:05             ` Junio C Hamano
  2009-09-07  8:14               ` Michael J Gruber
@ 2009-09-07  8:43               ` Jeff King
  2009-09-07  9:29                 ` Johannes Schindelin
  1 sibling, 1 reply; 39+ messages in thread
From: Jeff King @ 2009-09-07  8:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Björn Steinbrink, Michael J Gruber, Pete Wyckoff, git

On Sun, Sep 06, 2009 at 10:05:21PM -0700, Junio C Hamano wrote:

> At-mark currently is reserved for anything that uses reflog, but we can
> say that it is to specify operations on refs (as opposed to caret and
> tilde are to specify operations on object names).

I assume you meant that @{} is reserved; my reading of the previous
discussion was that "foo@bar" is still valid.

> It specifies what ref to work on with the operand on its left side (and an
> empty string stands for "HEAD"), and what operation is done to it by what
> is in {} on the right side of it.  This view is quite consistent with the
> following existing uses of the notation:
> 
> 	ref@{number}	-- nth reflog entry
>         ref@{time}	-- ref back then
> 	@{-number}	-- nth branch switching
> 
> So perhaps ref@{upstream}, or any string that is not a number and cannot
> be time, can trigger the magic operation on the ref with ref@{magic}
> syntax?

I think using @{} is a reasonable extension format. It's easy to read
and syntactically obvious. We need to watch out for conflicts with
things that might be valid times, but that is an easy thing to check
when adding new keywords. The only danger would be some extension
specifier that used arbitrary input, but that would probably be prefixed
with a keyword (and I can't even think of an example extension that
would want arbitrary input).

My only two complaints with ref@{upstream} are (and I don't think either
is a show-stopper, but maybe something we can improve on).

  1. It is a nice abstraction, but it doesn't save typing in most cases.
     "origin" is shorter than "master@{upstream}". One of the desired
     features in the last thread was that it be very short (which isn't
     to say we can't introduce @{upstream} _now_ and add a shorter
     synonym later on).

  2. I assume @{upstream} will be equivalent to HEAD@{upstream}. What
     should it do? The most useful thing to me would be to find the
     upstream for the current branch. But that is actually quite
     different from how HEAD@{1} works, which looks at the reflog for
     HEAD and not the branch.

     Maybe this is an inconsistency we can live with. The features are,
     after all, only syntactically related. I was just hoping to keep
     things as simple as possible for users to understand (and they
     often take semantic clues from syntax).

And some final thinking out loud in this area (i.e., these ideas are, I
think, somewhat half baked):

We already have some reserved uppercase ref names like HEAD, FETCH_HEAD,
ORIG_HEAD, and MERGE_HEAD.  One option would be to declare all-caps
names as reserved and allow UPSTREAM for the feature in question. I can
think of two arguments against it:

 1. The obvious one, that somebody somewhere is using all-caps and we
    are breaking their setup.

 2. It is not syntactically obvious to the user that it is not a real
    ref, but rather a magic name. Users are accustomed to punctuation
    introducing magic, so @{upstream} is probably better in that regard.

So I think that is a bad idea. But what about allowing "ref aliases"?
Obviously a static one like "f" for "foo" is kind of lame. But if you
could use the extension syntax, like:

  git config refalias.% '@{upstream}'

then we can let people set up whatever shorthand they think is sane (and
without worrying about clobbering unlikely-but-allowed setups, since
they are in control of their setup).

Like I said, I am not sure that is not half-baked. ;)

-Peff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-07  8:25                 ` Junio C Hamano
@ 2009-09-07  8:44                   ` Jeff King
  2009-09-07  9:06                     ` Michael J Gruber
  0 siblings, 1 reply; 39+ messages in thread
From: Jeff King @ 2009-09-07  8:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Michael J Gruber, Björn Steinbrink, Pete Wyckoff, git

On Mon, Sep 07, 2009 at 01:25:38AM -0700, Junio C Hamano wrote:

> > @{^}
> 
> This _could_ work, although it is rather cryptic.

But an identifier composed entirely of punctuation? It might help git
catch on with perl programmers. ;)

-Peff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-07  8:44                   ` Jeff King
@ 2009-09-07  9:06                     ` Michael J Gruber
  0 siblings, 0 replies; 39+ messages in thread
From: Michael J Gruber @ 2009-09-07  9:06 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Björn Steinbrink, Pete Wyckoff, git

Jeff King venit, vidit, dixit 07.09.2009 10:44:
> On Mon, Sep 07, 2009 at 01:25:38AM -0700, Junio C Hamano wrote:
> 
>>> @{^}
>> 
>> This _could_ work, although it is rather cryptic.
> 
> But an identifier composed entirely of punctuation? It might help
> git catch on with perl programmers. ;)

Right, that was the true agenda hidden only partially behind the plain
association between ^ and up ;)

Michael (having exactly zero perl fu)

P.S.: @ may not be reserved, and neither @^, but 1.7 should allow us to
reserve some symbols/combinations with a "low damage probability".
People may have a@b refnames (git-svn users for sure), but @^?

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-07  8:43               ` Jeff King
@ 2009-09-07  9:29                 ` Johannes Schindelin
  2009-09-07  9:53                   ` Michael J Gruber
  2009-09-09 10:45                   ` Jeff King
  0 siblings, 2 replies; 39+ messages in thread
From: Johannes Schindelin @ 2009-09-07  9:29 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git

Hi,

On Mon, 7 Sep 2009, Jeff King wrote:

> On Sun, Sep 06, 2009 at 10:05:21PM -0700, Junio C Hamano wrote:
> 
> > 	ref@{number}	-- nth reflog entry
> >         ref@{time}	-- ref back then
> > 	@{-number}	-- nth branch switching
> > 
> > So perhaps ref@{upstream}, or any string that is not a number and cannot
> > be time, can trigger the magic operation on the ref with ref@{magic}
> > syntax?
> 
> I think using @{} is a reasonable extension format.

Sorry to enter this thread that late, but I did not realize that it 
touches my %<branch> work.

Your proposal leads to something like "master@{upstream}@{2.days.ago}", 
which looks ugly.  And it is much more to type.

I still think that it is not too-much asked for to require the 
"refs/heads/" prefix if somebody starts her branch names with "%".

Or did I miss something (as I do not have time to read long mails these 
days, I tend to read only the short, to-the-point ones; I allowed myself 
to only skim over the rest of your mail)?

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-07  9:29                 ` Johannes Schindelin
@ 2009-09-07  9:53                   ` Michael J Gruber
  2009-09-08 23:17                     ` Julian Phillips
  2009-09-09 10:45                   ` Jeff King
  1 sibling, 1 reply; 39+ messages in thread
From: Michael J Gruber @ 2009-09-07  9:53 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Jeff King, Junio C Hamano, Björn Steinbrink, Pete Wyckoff,
	git

Johannes Schindelin venit, vidit, dixit 07.09.2009 11:29:
> Hi,
> 
> On Mon, 7 Sep 2009, Jeff King wrote:
> 
>> On Sun, Sep 06, 2009 at 10:05:21PM -0700, Junio C Hamano wrote:
>>
>>> 	ref@{number}	-- nth reflog entry
>>>         ref@{time}	-- ref back then
>>> 	@{-number}	-- nth branch switching
>>>
>>> So perhaps ref@{upstream}, or any string that is not a number and cannot
>>> be time, can trigger the magic operation on the ref with ref@{magic}
>>> syntax?
>>
>> I think using @{} is a reasonable extension format.
> 
> Sorry to enter this thread that late, but I did not realize that it 
> touches my %<branch> work.
> 
> Your proposal leads to something like "master@{upstream}@{2.days.ago}", 
> which looks ugly.  And it is much more to type.
> 
> I still think that it is not too-much asked for to require the 
> "refs/heads/" prefix if somebody starts her branch names with "%".
> 
> Or did I miss something (as I do not have time to read long mails these 
> days, I tend to read only the short, to-the-point ones; I allowed myself 
> to only skim over the rest of your mail)?

Solution needs to be:
- practical (short, clear)
- not too brutal (on existing users of legal "exotic" refnames)
- extensible (for later uses)

Michael
152 chars for Dscho :)

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-07  9:53                   ` Michael J Gruber
@ 2009-09-08 23:17                     ` Julian Phillips
  0 siblings, 0 replies; 39+ messages in thread
From: Julian Phillips @ 2009-09-08 23:17 UTC (permalink / raw)
  To: Michael J Gruber
  Cc: Johannes Schindelin, Jeff King, Junio C Hamano,
	Björn Steinbrink, Pete Wyckoff, git

On Mon, 7 Sep 2009, Michael J Gruber wrote:

> Solution needs to be:
> - practical (short, clear)
> - not too brutal (on existing users of legal "exotic" refnames)
> - extensible (for later uses)

How about '/^' and 'ref/^'?  Since you can't create a ref ending / ...

-- 
Julian

  ---
When you ask a question, do you truly want to know the answer, or are you
merely flaunting your power?

   -- DMITRI HARKONNEN, Notes to My Sons

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-07  9:29                 ` Johannes Schindelin
  2009-09-07  9:53                   ` Michael J Gruber
@ 2009-09-09 10:45                   ` Jeff King
  2009-09-10  6:42                     ` Junio C Hamano
  1 sibling, 1 reply; 39+ messages in thread
From: Jeff King @ 2009-09-09 10:45 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Junio C Hamano, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git

On Mon, Sep 07, 2009 at 11:29:50AM +0200, Johannes Schindelin wrote:

> > I think using @{} is a reasonable extension format.
> 
> Sorry to enter this thread that late, but I did not realize that it 
> touches my %<branch> work.
> 
> Your proposal leads to something like "master@{upstream}@{2.days.ago}", 
> which looks ugly.  And it is much more to type.
> 
> I still think that it is not too-much asked for to require the 
> "refs/heads/" prefix if somebody starts her branch names with "%".

I don't have a problem with restricting branch names starting with "%".
However, I do think "%.." is a bit ugly to read. And I am somewhat
concerned that we are eating the last reasonable available
meta-character for this feature, which will make things even harder next
time somebody suggests a clever feature. Which is why the discussion
turned to a generic extension syntax.

I wonder if it is worth adding @{upstream} now, which is fairly safe,
letting it cook for a while, and then adding a "%" alias later after the
concept has proved itself (and people say "I like this feature, but it
really is too much to type").

-Peff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-09 10:45                   ` Jeff King
@ 2009-09-10  6:42                     ` Junio C Hamano
  2009-09-10  7:47                       ` Johannes Schindelin
  0 siblings, 1 reply; 39+ messages in thread
From: Junio C Hamano @ 2009-09-10  6:42 UTC (permalink / raw)
  To: Jeff King
  Cc: Johannes Schindelin, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git

Jeff King <peff@peff.net> writes:

> I wonder if it is worth adding @{upstream} now, which is fairly safe,
> letting it cook for a while, and then adding a "%" alias later after the
> concept has proved itself (and people say "I like this feature, but it
> really is too much to type").

That's a sane suggestion, I think.  We can always have a descriptive
longhand (e.g. "branch@{upstream}") and later add a shorthand for often
used ones (e.g. "branch^up", "branch/.up" --- the former is possible
because it cannot be upth parent of the commit at the tip of the branch,
and the latter is possible because component of hierarchical refname
cannot begin with a dot).

I find a prefix % not descriptive enough (besides being ugly); if it were
"^branch", as some people said, it would probably have matched its meaning
"up", but that notation is already taken for "uninteresting".  If we are
going to use funny symbol as a notation to invoke magic, I think it is
easier for new people if we limit the number of symbols used.  We already
have ^n, ^{type} and ~n magic, all of which operate on objects and peel
them in three different ways.

Then there currently is only one kind of magic that works on refs and it
is spelled as ref@{magic}.  Let's try not to introduce more notation
before it is absolutely necessary.

When I say there is only one kind of magic notation for refs, I am
primarily talking about the end-user perception.  @{time}, @{number} and
@{-number} all do their magic using the reflog, but that is about _how_
they do what they do.  End-user perception begins with _what_ they do, and
at that level, the magic consistently works on refs and different genie is
summoned depending on what is inside {}.

The @{upstream} thing won't be using reflog to do its job, but that is
about _how_ it is implemented, and the end users don't care.

What is more important is _what_ it does.  Given a ref, the @{} magic
notation finds something that is related to the ref.  @{time} and
@{number} finds what the ref itself used to point at. @{-number}
(applicable only to HEAD ref) finds the ref it used to point at.  And
@{upstream} will find another ref that it merges from (or rebases onto).

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-10  6:42                     ` Junio C Hamano
@ 2009-09-10  7:47                       ` Johannes Schindelin
  2009-09-10  9:36                         ` [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch Johannes Schindelin
  2009-09-11  4:54                         ` tracking branch for a rebase Junio C Hamano
  0 siblings, 2 replies; 39+ messages in thread
From: Johannes Schindelin @ 2009-09-10  7:47 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Björn Steinbrink, Michael J Gruber, Pete Wyckoff,
	git

Hi,

On Wed, 9 Sep 2009, Junio C Hamano wrote:

> I find a prefix % not descriptive enough (besides being ugly); if it were
> "^branch", as some people said, it would probably have matched its meaning
> "up", but that notation is already taken for "uninteresting".

How about ^^branch? *ducks*

Seriously again, I think that ^{tracking} (with shorthand ^t, maybe) is 
not too shabby an option.  The point is: if we make this unattractive 
enough by requiring a lot of typing, we will never get to the point where 
it is popular enough to make a shorthand: it just will not be used at all.

> When I say there is only one kind of magic notation for refs, I am
> primarily talking about the end-user perception.  @{time}, @{number} and
> @{-number} all do their magic using the reflog, but that is about _how_
> they do what they do.  End-user perception begins with _what_ they do, and
> at that level, the magic consistently works on refs and different genie is
> summoned depending on what is inside {}.
> 
> The @{upstream} thing won't be using reflog to do its job, but that is
> about _how_ it is implemented, and the end users don't care.

Ah, I get what you're saying.  @{2.days.ago} says something about this 
branch locally, but @{upstream} says something about this branch remotely 
(well, our local cache).  From that view point, it makes sense.

But my point stands: @{upstream} is too awkward to type.  Let's have _at 
least_ a shortcut '@{up}'.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10  7:47                       ` Johannes Schindelin
@ 2009-09-10  9:36                         ` Johannes Schindelin
  2009-09-10  9:44                           ` Michael J Gruber
  2009-09-10 14:16                           ` Jeff King
  2009-09-11  4:54                         ` tracking branch for a rebase Junio C Hamano
  1 sibling, 2 replies; 39+ messages in thread
From: Johannes Schindelin @ 2009-09-10  9:36 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Björn Steinbrink, Michael J Gruber, Pete Wyckoff,
	git


Often, it is quite interesting to inspect the branch tracked by a given
branch.  This patch introduces a nice notation to get at the tracked
branch: '<branch>@{tracked}' can be used to access that tracked branch.

A special shortcut '@{tracked}' refers to the branch tracked by the
current branch.

Suggested by Pasky.

The syntax was suggested by Junio.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	I decided that I like @{tracked} better than @{upstream} (which
	reads to me more like the upstream _repository_), but hey, I made
	the code flexible enough to change that at a whim.

 Documentation/git-rev-parse.txt |    4 ++
 sha1_name.c                     |   37 ++++++++++++++++++++--
 t/t1506-rev-parse-tracked.sh    |   64 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+), 3 deletions(-)
 create mode 100755 t/t1506-rev-parse-tracked.sh

diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 82045a2..09a2145 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -231,6 +231,10 @@ when you run 'git-merge'.
 * The special construct '@\{-<n>\}' means the <n>th branch checked out
   before the current one.
 
+* The suffix '@{tracked}' to a ref (short form 'blabla@{t}') refers to
+  the branch tracked by that ref.  If no ref was specified, it means the
+  branch tracked by the current branch.
+
 * A suffix '{caret}' to a revision parameter means the first parent of
   that commit object.  '{caret}<n>' means the <n>th parent (i.e.
   'rev{caret}'
diff --git a/sha1_name.c b/sha1_name.c
index 44bb62d..a886846 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -5,6 +5,7 @@
 #include "blob.h"
 #include "tree-walk.h"
 #include "refs.h"
+#include "remote.h"
 
 static int find_short_object_filename(int len, const char *name, unsigned char *sha1)
 {
@@ -238,9 +239,24 @@ static int ambiguous_path(const char *path, int len)
 	return slash;
 }
 
+static inline int tracked_suffix(const char *string, int len)
+{
+	const char *suffix[] = { "@{tracked}", "@{t}" };
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(suffix); i++) {
+		int suffix_len = strlen(suffix[i]);
+		if (len >= suffix_len && !memcmp(string + len - suffix_len,
+					suffix[i], suffix_len))
+			return suffix_len;
+	}
+	return 0;
+}
+
 /*
  * *string and *len will only be substituted, and *string returned (for
- * later free()ing) if the string passed in is of the form @{-<n>}.
+ * later free()ing) if the string passed in is of the form @{-<n>} or
+ * of the form <branch>@{tracked}.
  */
 static char *substitute_branch_name(const char **string, int *len)
 {
@@ -254,6 +270,19 @@ static char *substitute_branch_name(const char **string, int *len)
 		return (char *)*string;
 	}
 
+	ret = tracked_suffix(*string, *len);
+	if (ret) {
+		char *ref = xstrndup(*string, *len - ret);
+		struct branch *tracking = branch_get(*ref ? ref : NULL);
+
+		free(ref);
+		if (tracking->merge && tracking->merge[0]->dst) {
+			*string = xstrdup(tracking->merge[0]->dst);
+			*len = strlen(*string);
+			return (char *)*string;
+		}
+	}
+
 	return NULL;
 }
 
@@ -340,8 +369,10 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 	if (len && str[len-1] == '}') {
 		for (at = len-2; at >= 0; at--) {
 			if (str[at] == '@' && str[at+1] == '{') {
-				reflog_len = (len-1) - (at+2);
-				len = at;
+				if (!tracked_suffix(str + at, len - at)) {
+					reflog_len = (len-1) - (at+2);
+					len = at;
+				}
 				break;
 			}
 		}
diff --git a/t/t1506-rev-parse-tracked.sh b/t/t1506-rev-parse-tracked.sh
new file mode 100755
index 0000000..89193e1
--- /dev/null
+++ b/t/t1506-rev-parse-tracked.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+test_description='test <branch>@{tracked} syntax'
+
+. ./test-lib.sh
+
+
+test_expect_success 'setup' '
+
+	test_commit 1 &&
+	git checkout -b side &&
+	test_commit 2 &&
+	git checkout master &&
+	git clone . clone &&
+	test_commit 3 &&
+	(cd clone &&
+	 test_commit 4 &&
+	 git branch --track my-side origin/side)
+
+'
+
+full_name () {
+	(cd clone &&
+	 git rev-parse --symbolic-full-name "$@")
+}
+
+commit_subject () {
+	(cd clone &&
+	 git show -s --pretty=format:%s "$@")
+}
+
+test_expect_success '@{tracked} resolves to correct full name' '
+	test refs/remotes/origin/master = "$(full_name @{tracked})"
+'
+
+test_expect_success '@{t} resolves to correct full name' '
+	test refs/remotes/origin/master = "$(full_name @{t})"
+'
+
+test_expect_success 'my-side@{tracked} resolves to correct full name' '
+	test refs/remotes/origin/side = "$(full_name my-side@{t})"
+'
+
+test_expect_success 'my-side@{t} resolves to correct commit' '
+	git checkout side &&
+	test_commit 5 &&
+	(cd clone && git fetch) &&
+	test 2 = "$(commit_subject my-side)" &&
+	test 5 = "$(commit_subject my-side@{t})"
+'
+
+test_expect_success 'not-tracking@{t} fails' '
+	test_must_fail full_name non-tracking@{t} &&
+	(cd clone && git checkout --no-track -b non-tracking) &&
+	test_must_fail full_name non-tracking@{t}
+'
+
+test_expect_success '<branch>@{t}@{1} resolves correctly' '
+	test_commit 6 &&
+	(cd clone && git fetch) &&
+	test 5 = $(commit_subject my-side@{t}@{1})
+'
+
+test_done
-- 
1.6.4.313.g3d9e3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10  9:36                         ` [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch Johannes Schindelin
@ 2009-09-10  9:44                           ` Michael J Gruber
  2009-09-10 10:14                             ` Johannes Schindelin
  2009-09-10 10:18                             ` Johan Herland
  2009-09-10 14:16                           ` Jeff King
  1 sibling, 2 replies; 39+ messages in thread
From: Michael J Gruber @ 2009-09-10  9:44 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Junio C Hamano, Jeff King, Björn Steinbrink, Pete Wyckoff,
	git

Johannes Schindelin venit, vidit, dixit 10.09.2009 11:36:
> 
> Often, it is quite interesting to inspect the branch tracked by a given
> branch.  This patch introduces a nice notation to get at the tracked
> branch: '<branch>@{tracked}' can be used to access that tracked branch.
> 
> A special shortcut '@{tracked}' refers to the branch tracked by the
> current branch.

Sorry, I didn't know the name of the long form was up for discussion.
But it should certainly coincide with the key which for-each-ref uses,
shouldn't it? I don't care whether tracked or upstream, but
for-each-ref's "upstream" has set the precedent.

> 
> Suggested by Pasky.
> 
> The syntax was suggested by Junio.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
> 
> 	I decided that I like @{tracked} better than @{upstream} (which
> 	reads to me more like the upstream _repository_), but hey, I made
> 	the code flexible enough to change that at a whim.
> 
>  Documentation/git-rev-parse.txt |    4 ++
>  sha1_name.c                     |   37 ++++++++++++++++++++--
>  t/t1506-rev-parse-tracked.sh    |   64 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 102 insertions(+), 3 deletions(-)
>  create mode 100755 t/t1506-rev-parse-tracked.sh
> 
> diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
> index 82045a2..09a2145 100644
> --- a/Documentation/git-rev-parse.txt
> +++ b/Documentation/git-rev-parse.txt
> @@ -231,6 +231,10 @@ when you run 'git-merge'.
>  * The special construct '@\{-<n>\}' means the <n>th branch checked out
>    before the current one.
>  
> +* The suffix '@{tracked}' to a ref (short form 'blabla@{t}') refers to
> +  the branch tracked by that ref.  If no ref was specified, it means the
> +  branch tracked by the current branch.
> +
>  * A suffix '{caret}' to a revision parameter means the first parent of
>    that commit object.  '{caret}<n>' means the <n>th parent (i.e.
>    'rev{caret}'
> diff --git a/sha1_name.c b/sha1_name.c
> index 44bb62d..a886846 100644
> --- a/sha1_name.c
> +++ b/sha1_name.c
> @@ -5,6 +5,7 @@
>  #include "blob.h"
>  #include "tree-walk.h"
>  #include "refs.h"
> +#include "remote.h"
>  
>  static int find_short_object_filename(int len, const char *name, unsigned char *sha1)
>  {
> @@ -238,9 +239,24 @@ static int ambiguous_path(const char *path, int len)
>  	return slash;
>  }
>  
> +static inline int tracked_suffix(const char *string, int len)
> +{
> +	const char *suffix[] = { "@{tracked}", "@{t}" };
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(suffix); i++) {
> +		int suffix_len = strlen(suffix[i]);
> +		if (len >= suffix_len && !memcmp(string + len - suffix_len,
> +					suffix[i], suffix_len))
> +			return suffix_len;
> +	}
> +	return 0;
> +}
> +
>  /*
>   * *string and *len will only be substituted, and *string returned (for
> - * later free()ing) if the string passed in is of the form @{-<n>}.
> + * later free()ing) if the string passed in is of the form @{-<n>} or
> + * of the form <branch>@{tracked}.
>   */
>  static char *substitute_branch_name(const char **string, int *len)
>  {
> @@ -254,6 +270,19 @@ static char *substitute_branch_name(const char **string, int *len)
>  		return (char *)*string;
>  	}
>  
> +	ret = tracked_suffix(*string, *len);
> +	if (ret) {
> +		char *ref = xstrndup(*string, *len - ret);
> +		struct branch *tracking = branch_get(*ref ? ref : NULL);
> +
> +		free(ref);
> +		if (tracking->merge && tracking->merge[0]->dst) {
> +			*string = xstrdup(tracking->merge[0]->dst);
> +			*len = strlen(*string);
> +			return (char *)*string;
> +		}
> +	}
> +
>  	return NULL;
>  }
>  
> @@ -340,8 +369,10 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
>  	if (len && str[len-1] == '}') {
>  		for (at = len-2; at >= 0; at--) {
>  			if (str[at] == '@' && str[at+1] == '{') {
> -				reflog_len = (len-1) - (at+2);
> -				len = at;
> +				if (!tracked_suffix(str + at, len - at)) {
> +					reflog_len = (len-1) - (at+2);
> +					len = at;
> +				}
>  				break;
>  			}
>  		}
> diff --git a/t/t1506-rev-parse-tracked.sh b/t/t1506-rev-parse-tracked.sh
> new file mode 100755
> index 0000000..89193e1
> --- /dev/null
> +++ b/t/t1506-rev-parse-tracked.sh
> @@ -0,0 +1,64 @@
> +#!/bin/sh
> +
> +test_description='test <branch>@{tracked} syntax'
> +
> +. ./test-lib.sh
> +
> +
> +test_expect_success 'setup' '
> +
> +	test_commit 1 &&
> +	git checkout -b side &&
> +	test_commit 2 &&
> +	git checkout master &&
> +	git clone . clone &&
> +	test_commit 3 &&
> +	(cd clone &&
> +	 test_commit 4 &&
> +	 git branch --track my-side origin/side)
> +
> +'
> +
> +full_name () {
> +	(cd clone &&
> +	 git rev-parse --symbolic-full-name "$@")
> +}
> +
> +commit_subject () {
> +	(cd clone &&
> +	 git show -s --pretty=format:%s "$@")
> +}
> +
> +test_expect_success '@{tracked} resolves to correct full name' '
> +	test refs/remotes/origin/master = "$(full_name @{tracked})"
> +'
> +
> +test_expect_success '@{t} resolves to correct full name' '
> +	test refs/remotes/origin/master = "$(full_name @{t})"
> +'
> +
> +test_expect_success 'my-side@{tracked} resolves to correct full name' '
> +	test refs/remotes/origin/side = "$(full_name my-side@{t})"
> +'
> +
> +test_expect_success 'my-side@{t} resolves to correct commit' '
> +	git checkout side &&
> +	test_commit 5 &&
> +	(cd clone && git fetch) &&
> +	test 2 = "$(commit_subject my-side)" &&
> +	test 5 = "$(commit_subject my-side@{t})"
> +'
> +
> +test_expect_success 'not-tracking@{t} fails' '
> +	test_must_fail full_name non-tracking@{t} &&
> +	(cd clone && git checkout --no-track -b non-tracking) &&
> +	test_must_fail full_name non-tracking@{t}
> +'
> +
> +test_expect_success '<branch>@{t}@{1} resolves correctly' '
> +	test_commit 6 &&
> +	(cd clone && git fetch) &&
> +	test 5 = $(commit_subject my-side@{t}@{1})
> +'
> +
> +test_done

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10  9:44                           ` Michael J Gruber
@ 2009-09-10 10:14                             ` Johannes Schindelin
  2009-09-10 10:18                             ` Johan Herland
  1 sibling, 0 replies; 39+ messages in thread
From: Johannes Schindelin @ 2009-09-10 10:14 UTC (permalink / raw)
  To: Michael J Gruber
  Cc: Junio C Hamano, Jeff King, Björn Steinbrink, Pete Wyckoff,
	git

Hi,

On Thu, 10 Sep 2009, Michael J Gruber wrote:

> Johannes Schindelin venit, vidit, dixit 10.09.2009 11:36:
> > 
> > Often, it is quite interesting to inspect the branch tracked by a given
> > branch.  This patch introduces a nice notation to get at the tracked
> > branch: '<branch>@{tracked}' can be used to access that tracked branch.
> > 
> > A special shortcut '@{tracked}' refers to the branch tracked by the
> > current branch.
> 
> Sorry, I didn't know the name of the long form was up for discussion.
> But it should certainly coincide with the key which for-each-ref uses,
> shouldn't it? I don't care whether tracked or upstream, but
> for-each-ref's "upstream" has set the precedent.

You're right.

sed -i -e 's/@{tracked}/@{upstream}/g' -e 's/@{t}/@{u}/g' $PATCH

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10  9:44                           ` Michael J Gruber
  2009-09-10 10:14                             ` Johannes Schindelin
@ 2009-09-10 10:18                             ` Johan Herland
  2009-09-10 10:59                               ` Michael J Gruber
  2009-09-10 11:11                               ` Jeff King
  1 sibling, 2 replies; 39+ messages in thread
From: Johan Herland @ 2009-09-10 10:18 UTC (permalink / raw)
  To: git
  Cc: Michael J Gruber, Johannes Schindelin, Junio C Hamano, Jeff King,
	Björn Steinbrink, Pete Wyckoff

On Thursday 10 September 2009, Michael J Gruber wrote:
> Johannes Schindelin venit, vidit, dixit 10.09.2009 11:36:
> > Often, it is quite interesting to inspect the branch tracked by a
> > given branch.  This patch introduces a nice notation to get at the
> > tracked branch: '<branch>@{tracked}' can be used to access that
> > tracked branch.
> >
> > A special shortcut '@{tracked}' refers to the branch tracked by the
> > current branch.
>
> Sorry, I didn't know the name of the long form was up for discussion.
> But it should certainly coincide with the key which for-each-ref
> uses, shouldn't it? I don't care whether tracked or upstream, but
> for-each-ref's "upstream" has set the precedent.

...and 'git branch --track' set an even earlier precedent...


...Johan


-- 
Johan Herland, <johan@herland.net>
www.herland.net

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 10:18                             ` Johan Herland
@ 2009-09-10 10:59                               ` Michael J Gruber
  2009-09-10 12:29                                 ` Johan Herland
  2009-09-10 11:11                               ` Jeff King
  1 sibling, 1 reply; 39+ messages in thread
From: Michael J Gruber @ 2009-09-10 10:59 UTC (permalink / raw)
  To: Johan Herland
  Cc: git, Michael J Gruber, Johannes Schindelin, Junio C Hamano,
	Jeff King, Björn Steinbrink, Pete Wyckoff

Johan Herland venit, vidit, dixit 10.09.2009 12:18:
> On Thursday 10 September 2009, Michael J Gruber wrote:
>> Johannes Schindelin venit, vidit, dixit 10.09.2009 11:36:
>>> Often, it is quite interesting to inspect the branch tracked by a
>>> given branch.  This patch introduces a nice notation to get at the
>>> tracked branch: '<branch>@{tracked}' can be used to access that
>>> tracked branch.
>>>
>>> A special shortcut '@{tracked}' refers to the branch tracked by the
>>> current branch.
>>
>> Sorry, I didn't know the name of the long form was up for discussion.
>> But it should certainly coincide with the key which for-each-ref
>> uses, shouldn't it? I don't care whether tracked or upstream, but
>> for-each-ref's "upstream" has set the precedent.
> 
> ...and 'git branch --track' set an even earlier precedent...

an unfortunate one, yes. It brings us back to an old discussion. The
consensus was what's in the glossary:

       tracking branch
           A regular git branch that is used to follow changes from
another repository. A tracking branch should
           not contain direct modifications or have local commits made
to it. A tracking branch can usually be
           identified as the right-hand-side ref in a Pull: refspec.

I.e., a tracking branch is something under refs/remotes/ (usually; I'll
use that simplification).

If I checkout -b myworkonit refs/remotes/origin/theirstuff then
myworkonit *does not track* origin/theirstuff according to the glossary
(but git checkout says so, unfortunately, and the option is named
likewise); rather, it has origin/theirstuff as its upstream.

In fact, refs/remotes/origin/theirstuff tracks whatever the name is on
the left hand side of the correspondig fetch refspec.

Maybe this is a good time to either

- change the definition of "tracking branch" (to one having an upstream
which is in refs/remotes/; and call "remote upbranch" what's in
refs/remotes/) or
- rename the option and output of git checkout -b/git branch --track.

Accordingly, either tracked or something else (such as upstream) would
be appropriate for the for-each-ref key and the ref specifier.

Cheers,
Michael

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 10:18                             ` Johan Herland
  2009-09-10 10:59                               ` Michael J Gruber
@ 2009-09-10 11:11                               ` Jeff King
  2009-09-10 18:29                                 ` Junio C Hamano
  1 sibling, 1 reply; 39+ messages in thread
From: Jeff King @ 2009-09-10 11:11 UTC (permalink / raw)
  To: Johan Herland
  Cc: git, Michael J Gruber, Johannes Schindelin, Junio C Hamano,
	Björn Steinbrink, Pete Wyckoff

On Thu, Sep 10, 2009 at 12:18:06PM +0200, Johan Herland wrote:

> > > A special shortcut '@{tracked}' refers to the branch tracked by the
> > > current branch.
> >
> > Sorry, I didn't know the name of the long form was up for discussion.
> > But it should certainly coincide with the key which for-each-ref
> > uses, shouldn't it? I don't care whether tracked or upstream, but
> > for-each-ref's "upstream" has set the precedent.
> 
> ...and 'git branch --track' set an even earlier precedent...

FWIW, that came about from this discussion:

  http://article.gmane.org/gmane.comp.version-control.git/115765

-Peff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 10:59                               ` Michael J Gruber
@ 2009-09-10 12:29                                 ` Johan Herland
  2009-09-10 13:35                                   ` Johannes Schindelin
  0 siblings, 1 reply; 39+ messages in thread
From: Johan Herland @ 2009-09-10 12:29 UTC (permalink / raw)
  To: git
  Cc: Michael J Gruber, Johannes Schindelin, Junio C Hamano, Jeff King,
	Björn Steinbrink, Pete Wyckoff

On Thursday 10 September 2009, Michael J Gruber wrote:
> Johan Herland venit, vidit, dixit 10.09.2009 12:18:
> > On Thursday 10 September 2009, Michael J Gruber wrote:
> >> Johannes Schindelin venit, vidit, dixit 10.09.2009 11:36:
> >>> Often, it is quite interesting to inspect the branch tracked by a
> >>> given branch.  This patch introduces a nice notation to get at
> >>> the tracked branch: '<branch>@{tracked}' can be used to access
> >>> that tracked branch.
> >>>
> >>> A special shortcut '@{tracked}' refers to the branch tracked by
> >>> the current branch.
> >>
> >> Sorry, I didn't know the name of the long form was up for
> >> discussion. But it should certainly coincide with the key which
> >> for-each-ref uses, shouldn't it? I don't care whether tracked or
> >> upstream, but for-each-ref's "upstream" has set the precedent.
> >
> > ...and 'git branch --track' set an even earlier precedent...
>
> an unfortunate one, yes. It brings us back to an old discussion. The
> consensus was what's in the glossary:

[snip]

> Maybe this is a good time to either
>
> - change the definition of "tracking branch" (to one having an
> upstream which is in refs/remotes/; and call "remote upbranch" what's
> in refs/remotes/) or
> - rename the option and output of git checkout -b/git branch --track.
>
> Accordingly, either tracked or something else (such as upstream)
> would be appropriate for the for-each-ref key and the ref specifier.

Sure, as someone else already stated, I don't care too much what it's 
named, as long as the naming is consistent across all of git. We do 
have an unforunate name clash between remote-tracking branches (i.e. 
branches under refs/remotes/) and 'tracking' branches (i.e. 'git 
branch --track') [1], and I believe 1.7.0 would be a nice opportunity 
to clean this up.

I think I vote for the second option, renaming 'git branch --track' 
to 'git branch --upstream', and s/@{tracked}/@{upstream}/.


Have fun! :)

...Johan

[1]: And also tracked and untracked files, although I believe that is 
unambiguous in most cases.


-- 
Johan Herland, <johan@herland.net>
www.herland.net

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 12:29                                 ` Johan Herland
@ 2009-09-10 13:35                                   ` Johannes Schindelin
  2009-09-10 14:17                                     ` Michael J Gruber
  0 siblings, 1 reply; 39+ messages in thread
From: Johannes Schindelin @ 2009-09-10 13:35 UTC (permalink / raw)
  To: Johan Herland
  Cc: git, Michael J Gruber, Junio C Hamano, Jeff King,
	Björn Steinbrink, Pete Wyckoff

Hi,

On Thu, 10 Sep 2009, Johan Herland wrote:

> I think I vote for the second option, renaming 'git branch --track' 
> to 'git branch --upstream', and s/@{tracked}/@{upstream}/.

That does not make any sense, as that --track is to be understood as a 
verb.  How do you "upstream a branch"?

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10  9:36                         ` [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch Johannes Schindelin
  2009-09-10  9:44                           ` Michael J Gruber
@ 2009-09-10 14:16                           ` Jeff King
  2009-09-10 14:26                             ` Jeff King
  2009-09-10 15:22                             ` [PATCH] Introduce <branch>@{tracked} " Johannes Schindelin
  1 sibling, 2 replies; 39+ messages in thread
From: Jeff King @ 2009-09-10 14:16 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Junio C Hamano, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git

On Thu, Sep 10, 2009 at 11:36:42AM +0200, Johannes Schindelin wrote:

> diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
> index 82045a2..09a2145 100644
> --- a/Documentation/git-rev-parse.txt
> +++ b/Documentation/git-rev-parse.txt
> @@ -231,6 +231,10 @@ when you run 'git-merge'.
>  * The special construct '@\{-<n>\}' means the <n>th branch checked out
>    before the current one.
>  
> +* The suffix '@{tracked}' to a ref (short form 'blabla@{t}') refers to
> +  the branch tracked by that ref.  If no ref was specified, it means the
> +  branch tracked by the current branch.
> +

It looks like the code dereferences symbolic refs when doing the lookup
(so HEAD@{t} will find the upstream of the current branch), which I
think is the best thing to do. However, that does make it behave
slightly differently than HEAD@{2.minutes.ago}, so it may be worth
adding a sentence to this paragraph like:

  If the ref is a symbolic ref, it is dereferenced before searching
  for the upstream ref.

And we may want to add a test for HEAD, as well.

Also, I seem to be able to stimulate a segfault on a detached HEAD, but
I haven't investigated it yet.

-Peff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 13:35                                   ` Johannes Schindelin
@ 2009-09-10 14:17                                     ` Michael J Gruber
  0 siblings, 0 replies; 39+ messages in thread
From: Michael J Gruber @ 2009-09-10 14:17 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Johan Herland, git, Junio C Hamano, Jeff King,
	Björn Steinbrink, Pete Wyckoff

Johannes Schindelin venit, vidit, dixit 10.09.2009 15:35:
> Hi,
> 
> On Thu, 10 Sep 2009, Johan Herland wrote:
> 
>> I think I vote for the second option, renaming 'git branch --track' 
>> to 'git branch --upstream', and s/@{tracked}/@{upstream}/.
> 
> That does not make any sense, as that --track is to be understood as a 
> verb.  How do you "upstream a branch"?

Well, that brunch also got its granma wrong tho his speeling is right ;)

Seriously: In

git branch --track branch1 branch2

who tracks whom if you read "--track" as a verb?
So, "--track" can only be understood as an attribute to the main (first)
argument, saying it's tracking something. Just as --upstream could be
read as an attribute meaning "has an upstream".

(Note also how different this is from how -b works for checkout, -b
actually taking an argument: git checkout -b branch1 branch2)

Cheers,
Michael

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 14:16                           ` Jeff King
@ 2009-09-10 14:26                             ` Jeff King
  2009-09-10 15:24                               ` Johannes Schindelin
  2009-09-10 15:22                             ` [PATCH] Introduce <branch>@{tracked} " Johannes Schindelin
  1 sibling, 1 reply; 39+ messages in thread
From: Jeff King @ 2009-09-10 14:26 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Junio C Hamano, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git

On Thu, Sep 10, 2009 at 10:16:18AM -0400, Jeff King wrote:

> And we may want to add a test for HEAD, as well.
> 
> Also, I seem to be able to stimulate a segfault on a detached HEAD, but
> I haven't investigated it yet.

Found it. We should probably squash this in:

diff --git a/sha1_name.c b/sha1_name.c
index a886846..ef4ec11 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -276,7 +276,7 @@ static char *substitute_branch_name(const char **string, int *len)
 		struct branch *tracking = branch_get(*ref ? ref : NULL);
 
 		free(ref);
-		if (tracking->merge && tracking->merge[0]->dst) {
+		if (tracking && tracking->merge && tracking->merge[0]->dst) {
 			*string = xstrdup(tracking->merge[0]->dst);
 			*len = strlen(*string);
 			return (char *)*string;
diff --git a/t/t1506-rev-parse-tracked.sh b/t/t1506-rev-parse-tracked.sh
index 89193e1..2be5b75 100755
--- a/t/t1506-rev-parse-tracked.sh
+++ b/t/t1506-rev-parse-tracked.sh
@@ -61,4 +61,15 @@ test_expect_success '<branch>@{t}@{1} resolves correctly' '
 	test 5 = $(commit_subject my-side@{t}@{1})
 '
 
+test_expect_success 'HEAD@{t} dereferences HEAD' '
+	(cd clone && git checkout master) &&
+	test refs/remotes/origin/master = "$(full_name HEAD@{t})"
+'
+
+test_expect_success 'HEAD@{t} and @{t} on detached HEAD fail' '
+	(cd clone && git checkout master^0) &&
+	test_must_fail full_name @{t} &&
+	test_must_fail full_name HEAD@{t}
+'
+
 test_done

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 14:16                           ` Jeff King
  2009-09-10 14:26                             ` Jeff King
@ 2009-09-10 15:22                             ` Johannes Schindelin
  1 sibling, 0 replies; 39+ messages in thread
From: Johannes Schindelin @ 2009-09-10 15:22 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git

Hi,

On Thu, 10 Sep 2009, Jeff King wrote:

> Also, I seem to be able to stimulate a segfault on a detached HEAD, but 
> I haven't investigated it yet.

Aaargh!

Mikachu pointed that out recently, provided a test, I fixed it, and in the 
meantime I managed to forget about it!

/me needs to do less things per day.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 14:26                             ` Jeff King
@ 2009-09-10 15:24                               ` Johannes Schindelin
  2009-09-10 15:25                                 ` [PATCH v2] Introduce <branch>@{upstream} " Johannes Schindelin
  0 siblings, 1 reply; 39+ messages in thread
From: Johannes Schindelin @ 2009-09-10 15:24 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git

Hi,

On Thu, 10 Sep 2009, Jeff King wrote:

> On Thu, Sep 10, 2009 at 10:16:18AM -0400, Jeff King wrote:
> 
> diff --git a/sha1_name.c b/sha1_name.c
> index a886846..ef4ec11 100644
> --- a/sha1_name.c
> +++ b/sha1_name.c
> @@ -276,7 +276,7 @@ static char *substitute_branch_name(const char **string, int *len)
>  		struct branch *tracking = branch_get(*ref ? ref : NULL);
>  
>  		free(ref);
> -		if (tracking->merge && tracking->merge[0]->dst) {
> +		if (tracking && tracking->merge && tracking->merge[0]->dst) {

Almost.

My version dies if tracking is NULL.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH v2] Introduce <branch>@{upstream} as shortcut to the tracked branch
  2009-09-10 15:24                               ` Johannes Schindelin
@ 2009-09-10 15:25                                 ` Johannes Schindelin
  2009-09-10 15:55                                   ` Jeff King
  0 siblings, 1 reply; 39+ messages in thread
From: Johannes Schindelin @ 2009-09-10 15:25 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git


Often, it is quite interesting to inspect the branch tracked by a given
branch.  This patch introduces a nice notation to get at the tracked
branch: '<branch>@{upstream}' can be used to access that tracked branch.

A special shortcut '@{upstream}' refers to the branch tracked by the
current branch.

Suggested by Pasky.

The syntax was suggested by Junio.

A test for a now-fixed crash was provided by Mikael Magnusson.

The crash has been pointed out by Peff again (because this here developer
managed to forget about the fix).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---

	Changes since v1:
	- changed to @{upstream} (and @{u})
	- included the fix I forgot about

 Documentation/git-rev-parse.txt |    4 ++
 sha1_name.c                     |   39 ++++++++++++++++++++--
 t/t1506-rev-parse-tracked.sh    |   69 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 109 insertions(+), 3 deletions(-)
 create mode 100755 t/t1506-rev-parse-tracked.sh

diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 82045a2..09a2145 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -231,6 +231,10 @@ when you run 'git-merge'.
 * The special construct '@\{-<n>\}' means the <n>th branch checked out
   before the current one.
 
+* The suffix '@{upstream}' to a ref (short form 'blabla@{u}') refers to
+  the branch tracked by that ref.  If no ref was specified, it means the
+  branch tracked by the current branch.
+
 * A suffix '{caret}' to a revision parameter means the first parent of
   that commit object.  '{caret}<n>' means the <n>th parent (i.e.
   'rev{caret}'
diff --git a/sha1_name.c b/sha1_name.c
index 44bb62d..ae4280e 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -5,6 +5,7 @@
 #include "blob.h"
 #include "tree-walk.h"
 #include "refs.h"
+#include "remote.h"
 
 static int find_short_object_filename(int len, const char *name, unsigned char *sha1)
 {
@@ -238,9 +239,24 @@ static int ambiguous_path(const char *path, int len)
 	return slash;
 }
 
+static inline int tracked_suffix(const char *string, int len)
+{
+	const char *suffix[] = { "@{upstream}", "@{u}" };
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(suffix); i++) {
+		int suffix_len = strlen(suffix[i]);
+		if (len >= suffix_len && !memcmp(string + len - suffix_len,
+					suffix[i], suffix_len))
+			return suffix_len;
+	}
+	return 0;
+}
+
 /*
  * *string and *len will only be substituted, and *string returned (for
- * later free()ing) if the string passed in is of the form @{-<n>}.
+ * later free()ing) if the string passed in is of the form @{-<n>} or
+ * of the form <branch>@{upstream}.
  */
 static char *substitute_branch_name(const char **string, int *len)
 {
@@ -254,6 +270,21 @@ static char *substitute_branch_name(const char **string, int *len)
 		return (char *)*string;
 	}
 
+	ret = tracked_suffix(*string, *len);
+	if (ret) {
+		char *ref = xstrndup(*string, *len - ret);
+		struct branch *tracking = branch_get(*ref ? ref : NULL);
+
+		free(ref);
+		if (!tracking)
+			die ("No tracking branch found for '%s'", ref);
+		if (tracking->merge && tracking->merge[0]->dst) {
+			*string = xstrdup(tracking->merge[0]->dst);
+			*len = strlen(*string);
+			return (char *)*string;
+		}
+	}
+
 	return NULL;
 }
 
@@ -340,8 +371,10 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 	if (len && str[len-1] == '}') {
 		for (at = len-2; at >= 0; at--) {
 			if (str[at] == '@' && str[at+1] == '{') {
-				reflog_len = (len-1) - (at+2);
-				len = at;
+				if (!tracked_suffix(str + at, len - at)) {
+					reflog_len = (len-1) - (at+2);
+					len = at;
+				}
 				break;
 			}
 		}
diff --git a/t/t1506-rev-parse-tracked.sh b/t/t1506-rev-parse-tracked.sh
new file mode 100755
index 0000000..72d0579
--- /dev/null
+++ b/t/t1506-rev-parse-tracked.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+test_description='test <branch>@{upstream} syntax'
+
+. ./test-lib.sh
+
+
+test_expect_success 'setup' '
+
+	test_commit 1 &&
+	git checkout -b side &&
+	test_commit 2 &&
+	git checkout master &&
+	git clone . clone &&
+	test_commit 3 &&
+	(cd clone &&
+	 test_commit 4 &&
+	 git branch --track my-side origin/side)
+
+'
+
+full_name () {
+	(cd clone &&
+	 git rev-parse --symbolic-full-name "$@")
+}
+
+commit_subject () {
+	(cd clone &&
+	 git show -s --pretty=format:%s "$@")
+}
+
+test_expect_success '@{upstream} resolves to correct full name' '
+	test refs/remotes/origin/master = "$(full_name @{upstream})"
+'
+
+test_expect_success '@{u} resolves to correct full name' '
+	test refs/remotes/origin/master = "$(full_name @{u})"
+'
+
+test_expect_success 'my-side@{upstream} resolves to correct full name' '
+	test refs/remotes/origin/side = "$(full_name my-side@{u})"
+'
+
+test_expect_success 'my-side@{u} resolves to correct commit' '
+	git checkout side &&
+	test_commit 5 &&
+	(cd clone && git fetch) &&
+	test 2 = "$(commit_subject my-side)" &&
+	test 5 = "$(commit_subject my-side@{u})"
+'
+
+test_expect_success 'not-tracking@{u} fails' '
+	test_must_fail full_name non-tracking@{u} &&
+	(cd clone && git checkout --no-track -b non-tracking) &&
+	test_must_fail full_name non-tracking@{u}
+'
+
+test_expect_success '<branch>@{u}@{1} resolves correctly' '
+	test_commit 6 &&
+	(cd clone && git fetch) &&
+	test 5 = $(commit_subject my-side@{u}@{1})
+'
+
+test_expect_success '% without specifying branch crashes on a detached HEAD' '
+	git checkout HEAD^0 &&
+	test_must_fail git rev-parse @{u}
+'
+
+test_done
-- 
1.6.4.313.g3d9e3

^ permalink raw reply related	[flat|nested] 39+ messages in thread

* Re: [PATCH v2] Introduce <branch>@{upstream} as shortcut to the tracked branch
  2009-09-10 15:25                                 ` [PATCH v2] Introduce <branch>@{upstream} " Johannes Schindelin
@ 2009-09-10 15:55                                   ` Jeff King
  2009-09-10 16:18                                     ` Johannes Schindelin
  0 siblings, 1 reply; 39+ messages in thread
From: Jeff King @ 2009-09-10 15:55 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Junio C Hamano, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git

On Thu, Sep 10, 2009 at 05:25:57PM +0200, Johannes Schindelin wrote:

> 	Changes since v1:
> 	- changed to @{upstream} (and @{u})

Hmm. After applying v2, I accidentally tried "git rev-parse @{t}" and
was surprised to find that it worked! The problem, of course, is that we
saw that it was not one of our keywords and therefore dumped it into
approxidate, which happily converted it into the current time, and
provided me with HEAD@{now}.

Which is sad, because it means "HEAD@{usptream}" will silently produce
incorrect results.

I don't see a way around it, though, short of tightening approxidate's
parsing. Maybe it could keep a flag for "I noticed _anything_ of value
in this string", and we could barf if it isn't set. That would still
allow arbitrary stuff like:

  the 6th of july

and keep Linus' favorite

  I ate 6 hot dogs in July.

but disallow the most obviously wrong dates like:

  t
  usptream
  total bogosity

> +	ret = tracked_suffix(*string, *len);
> +	if (ret) {
> +		char *ref = xstrndup(*string, *len - ret);
> +		struct branch *tracking = branch_get(*ref ? ref : NULL);
> +
> +		free(ref);
> +		if (!tracking)
> +			die ("No tracking branch found for '%s'", ref);
> +		if (tracking->merge && tracking->merge[0]->dst) {
> +			*string = xstrdup(tracking->merge[0]->dst);
> +			*len = strlen(*string);
> +			return (char *)*string;
> +		}
> +	}
> +

I don't think it is a good idea to die for !tracking, but not for
!tracking->merge. That leads to inconsistent user-visible results:

  $ git checkout HEAD^0
  $ git rev-parse HEAD@{u}
  fatal: No tracking branch found for 'HEAD'
  $ git rev-parse bogus@{u}
  bogus@{u}
  fatal: ambiguous argument 'bogus@{u}': unknown revision or path not in the working tree.
  Use '--' to separate paths from revisions

Shouldn't both cases say the same thing?

Also, your die message has two problems:

 1. It looks at ref immediately after it is free'd, spewing junk.

 2. Ref can be the empty string, which gives you the ugly:

       fatal: No tracking branch found for ''

    Should we munge that into HEAD (or "the current branch") for the
    user?

-Peff

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH v2] Introduce <branch>@{upstream} as shortcut to the tracked branch
  2009-09-10 15:55                                   ` Jeff King
@ 2009-09-10 16:18                                     ` Johannes Schindelin
  0 siblings, 0 replies; 39+ messages in thread
From: Johannes Schindelin @ 2009-09-10 16:18 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Björn Steinbrink, Michael J Gruber,
	Pete Wyckoff, git

Hi,

On Thu, 10 Sep 2009, Jeff King wrote:

> I wrote:
> 
> > +	ret = tracked_suffix(*string, *len);
> > +	if (ret) {
> > +		char *ref = xstrndup(*string, *len - ret);
> > +		struct branch *tracking = branch_get(*ref ? ref : NULL);
> > +
> > +		free(ref);
> > +		if (!tracking)
> > +			die ("No tracking branch found for '%s'", ref);
> > +		if (tracking->merge && tracking->merge[0]->dst) {
> > +			*string = xstrdup(tracking->merge[0]->dst);
> > +			*len = strlen(*string);
> > +			return (char *)*string;
> > +		}
> > +	}
> > +
> 
> I don't think it is a good idea to die for !tracking, but not for
> !tracking->merge. That leads to inconsistent user-visible results:
> 
>   $ git checkout HEAD^0
>   $ git rev-parse HEAD@{u}
>   fatal: No tracking branch found for 'HEAD'
>   $ git rev-parse bogus@{u}
>   bogus@{u}
>   fatal: ambiguous argument 'bogus@{u}': unknown revision or path not in the working tree.
>   Use '--' to separate paths from revisions
> 
> Shouldn't both cases say the same thing?
> 
> Also, your die message has two problems:
> 
>  1. It looks at ref immediately after it is free'd, spewing junk.
> 
>  2. Ref can be the empty string, which gives you the ugly:
> 
>        fatal: No tracking branch found for ''
> 
>     Should we munge that into HEAD (or "the current branch") for the
>     user?

All true, but I cannot take care of it today.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 11:11                               ` Jeff King
@ 2009-09-10 18:29                                 ` Junio C Hamano
  2009-10-02 14:54                                   ` Björn Steinbrink
  0 siblings, 1 reply; 39+ messages in thread
From: Junio C Hamano @ 2009-09-10 18:29 UTC (permalink / raw)
  To: Jeff King
  Cc: Johan Herland, git, Michael J Gruber, Johannes Schindelin,
	Junio C Hamano, Björn Steinbrink, Pete Wyckoff

Jeff King <peff@peff.net> writes:

> On Thu, Sep 10, 2009 at 12:18:06PM +0200, Johan Herland wrote:
>
>> > > A special shortcut '@{tracked}' refers to the branch tracked by the
>> > > current branch.
>> >
>> > Sorry, I didn't know the name of the long form was up for discussion.
>> > But it should certainly coincide with the key which for-each-ref
>> > uses, shouldn't it? I don't care whether tracked or upstream, but
>> > for-each-ref's "upstream" has set the precedent.
>> 
>> ...and 'git branch --track' set an even earlier precedent...
>
> FWIW, that came about from this discussion:
>
>   http://article.gmane.org/gmane.comp.version-control.git/115765

After re-reading the discussion in the thread that contains the quoted
article, it sounds like we may want to fix "branch --track X Y".  X does
not "track" Y in the same sense as origin/master "tracks" master at
origin.  Rather, X builds on Y.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: tracking branch for a rebase
  2009-09-10  7:47                       ` Johannes Schindelin
  2009-09-10  9:36                         ` [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch Johannes Schindelin
@ 2009-09-11  4:54                         ` Junio C Hamano
  1 sibling, 0 replies; 39+ messages in thread
From: Junio C Hamano @ 2009-09-11  4:54 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Jeff King, Björn Steinbrink, Michael J Gruber, Pete Wyckoff,
	git

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> How about ^^branch? *ducks*

You'd better duck.

Just like %branch, it is a selfish and short-sighted "good enough for this
particular case but there is no room for extending it" hack that I have
serious problem with.  It closes the door for people who come later, and
such an attitude is okay only if this is _the last great invention_ and
there is no more great feature that deserves short-and-sweet notation to
come.  It might be the _latest_ great invention, but chances are that it
won't be the last.

> Seriously again, I think that ^{tracking} (with shorthand ^t, maybe) is 
> not too shabby an option.  The point is: if we make this unattractive 
> enough by requiring a lot of typing, we will never get to the point where 
> it is popular enough to make a shorthand: it just will not be used at all.

I actually think it is the other way around.

If it is so useful to be able to specify the ref your branch is based on
by applying a magic to the name of your branch, the users will use it even
if it is rather long to type, as long as the feature is easy to discover
and remember, and then they will demand a short-hand.

If on the other hand users say "Hey, I know can say 'git log X@{upstream}'
but why bother?  I always build my branch X on top of origin/X anyway, so
I'd forego that feature and type 'git log origin/X'.  It's not worth my
time to type that long magic," then the feature is not as useful as you
hoped.  And there is no point in coming up with a short-hand syntax for
it.

I personally suspect that users love to use the feature _despite_ the
initial lack of short-hand, and we would end up adding some short-hand,
and that would be a far better proof that the feature itself is useful
than "it is used just %X happens to be shorter than origin/X".

But before that happens, I'd rather not waste short-hand notations, such
as @{t} or @{u}, that will be in short-supply in the longer term.

^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch
  2009-09-10 18:29                                 ` Junio C Hamano
@ 2009-10-02 14:54                                   ` Björn Steinbrink
  0 siblings, 0 replies; 39+ messages in thread
From: Björn Steinbrink @ 2009-10-02 14:54 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Johan Herland, git, Michael J Gruber,
	Johannes Schindelin, Pete Wyckoff, i.am

On 2009.09.10 11:29:54 -0700, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
> 
> > On Thu, Sep 10, 2009 at 12:18:06PM +0200, Johan Herland wrote:
> >
> >> > > A special shortcut '@{tracked}' refers to the branch tracked by the
> >> > > current branch.
> >> >
> >> > Sorry, I didn't know the name of the long form was up for discussion.
> >> > But it should certainly coincide with the key which for-each-ref
> >> > uses, shouldn't it? I don't care whether tracked or upstream, but
> >> > for-each-ref's "upstream" has set the precedent.
> >> 
> >> ...and 'git branch --track' set an even earlier precedent...
> >
> > FWIW, that came about from this discussion:
> >
> >   http://article.gmane.org/gmane.comp.version-control.git/115765
> 
> After re-reading the discussion in the thread that contains the quoted
> article, it sounds like we may want to fix "branch --track X Y".  X does
> not "track" Y in the same sense as origin/master "tracks" master at
> origin.  Rather, X builds on Y.

FWIW, I just had a discussion on #git with Jim Ramsay (lack) about that.
We agreed that "branch --track" is unfortunate and causes confusion,
when it comes to the term "tracking branch" (which the glossary
basically defines to be something in the refs/remotes/ namespace, at
least something you never commit to), as people also start to use that
for branch heads that have an "upstream branch" set in the
configuration.

Jim initially preferred the term "linked", while I argued for the option
to be called --upstream (potentially with the possibility to say
--upstream=rebase or --upstream=merge, the default being "merge", unless
branch.autosetuprebase is set).

We could (I think) to some degree agree that "upstream" is quite good,
although we couldn't find a short and sweet term to describe the branch
head that has a configured upstream branch (some ideas were "upstreamed
branch", "uplinked branch", "downstream branch" and some more, which I
all dislike). After having read the glossary and finding "upstream
branch" in there, I'm even more in favor of using the "upstream" term in
some form.

During the discussion, there were some requests (again) for a command
that allows to change branch.<name>.remote and branch.<name>.merge for
already existing branch heads. With that extra input, I'd now favor:

git branch --set-upstream X Y

because that's potentially reusable for the "change upstream for an
existing branch" case, though I'm totally clueless how to actually do
that, given that "git branch" uses flags to switch between "create new
branch" and "operate on existing branch". So reusing a flag won't
(easily) do the trick, at least not without special casing that could be
dangerous. You could, for example, accidently change the upstream for an
existing branch, while you meant to create a new one.

It's a bit sad that we don't have subcommands for "git branch" like we
do for "git remote", that would make the whole thing a lot easier, but
it's way too late to change that, I guess. At least having "git branch
<name>" default to be "git branch add <name>" would make some branch
names "invalid" for that shortform. So that looks like a no-go.

Björn

^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2009-10-02 14:54 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-04 13:54 tracking branch for a rebase Pete Wyckoff
2009-09-04 14:31 ` Michael J Gruber
2009-09-04 18:18   ` Jeff King
2009-09-04 18:59     ` Björn Steinbrink
2009-09-05  6:12       ` Jeff King
2009-09-05 14:01         ` Björn Steinbrink
2009-09-05 14:28           ` Jeff King
2009-09-07  5:05             ` Junio C Hamano
2009-09-07  8:14               ` Michael J Gruber
2009-09-07  8:25                 ` Junio C Hamano
2009-09-07  8:44                   ` Jeff King
2009-09-07  9:06                     ` Michael J Gruber
2009-09-07  8:43               ` Jeff King
2009-09-07  9:29                 ` Johannes Schindelin
2009-09-07  9:53                   ` Michael J Gruber
2009-09-08 23:17                     ` Julian Phillips
2009-09-09 10:45                   ` Jeff King
2009-09-10  6:42                     ` Junio C Hamano
2009-09-10  7:47                       ` Johannes Schindelin
2009-09-10  9:36                         ` [PATCH] Introduce <branch>@{tracked} as shortcut to the tracked branch Johannes Schindelin
2009-09-10  9:44                           ` Michael J Gruber
2009-09-10 10:14                             ` Johannes Schindelin
2009-09-10 10:18                             ` Johan Herland
2009-09-10 10:59                               ` Michael J Gruber
2009-09-10 12:29                                 ` Johan Herland
2009-09-10 13:35                                   ` Johannes Schindelin
2009-09-10 14:17                                     ` Michael J Gruber
2009-09-10 11:11                               ` Jeff King
2009-09-10 18:29                                 ` Junio C Hamano
2009-10-02 14:54                                   ` Björn Steinbrink
2009-09-10 14:16                           ` Jeff King
2009-09-10 14:26                             ` Jeff King
2009-09-10 15:24                               ` Johannes Schindelin
2009-09-10 15:25                                 ` [PATCH v2] Introduce <branch>@{upstream} " Johannes Schindelin
2009-09-10 15:55                                   ` Jeff King
2009-09-10 16:18                                     ` Johannes Schindelin
2009-09-10 15:22                             ` [PATCH] Introduce <branch>@{tracked} " Johannes Schindelin
2009-09-11  4:54                         ` tracking branch for a rebase Junio C Hamano
2009-09-05 17:59           ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).