From: Junio C Hamano <hidden> Date: 2016-06-15 22:47:23
Jeff King [off-list ref] 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).
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:47:23
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
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:47:23
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 <redacted>
---
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
@@ -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}'
@@ -0,0 +1,64 @@+#!/bin/sh++test_description='test <branch>@{tracked} syntax'++../test-lib.sh+++test_expect_success'setup''++test_commit1&&+gitcheckout-bside&&+test_commit2&&+gitcheckoutmaster&&+gitclone.clone&&+test_commit3&&+(cdclone&&+test_commit4&&+gitbranch--trackmy-sideorigin/side)++'++full_name(){+(cdclone&&+gitrev-parse--symbolic-full-name"$@")+}++commit_subject(){+(cdclone&&+gitshow-s--pretty=format:%s"$@")+}++test_expect_success'@{tracked} resolves to correct full name''+testrefs/remotes/origin/master="$(full_name@{tracked})"+'++test_expect_success'@{t} resolves to correct full name''+testrefs/remotes/origin/master="$(full_name@{t})"+'++test_expect_success'my-side@{tracked} resolves to correct full name''+testrefs/remotes/origin/side="$(full_namemy-side@{t})"+'++test_expect_success'my-side@{t} resolves to correct commit''+gitcheckoutside&&+test_commit5&&+(cdclone&&gitfetch)&&+test2="$(commit_subjectmy-side)"&&+test5="$(commit_subjectmy-side@{t})"+'++test_expect_success'not-tracking@{t} fails''+test_must_failfull_namenon-tracking@{t}&&+(cdclone&&gitcheckout--no-track-bnon-tracking)&&+test_must_failfull_namenon-tracking@{t}+'++test_expect_success'<branch>@{t}@{1} resolves correctly''+test_commit6&&+(cdclone&&gitfetch)&&+test5=$(commit_subjectmy-side@{t}@{1})+'++test_done
From: Michael J Gruber <hidden> Date: 2016-06-15 22:47:23
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.
quoted hunk
Suggested by Pasky.
The syntax was suggested by Junio.
Signed-off-by: Johannes Schindelin <redacted>
---
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
@@ -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}'
@@ -0,0 +1,64 @@+#!/bin/sh++test_description='test <branch>@{tracked} syntax'++../test-lib.sh+++test_expect_success'setup''++test_commit1&&+gitcheckout-bside&&+test_commit2&&+gitcheckoutmaster&&+gitclone.clone&&+test_commit3&&+(cdclone&&+test_commit4&&+gitbranch--trackmy-sideorigin/side)++'++full_name(){+(cdclone&&+gitrev-parse--symbolic-full-name"$@")+}++commit_subject(){+(cdclone&&+gitshow-s--pretty=format:%s"$@")+}++test_expect_success'@{tracked} resolves to correct full name''+testrefs/remotes/origin/master="$(full_name@{tracked})"+'++test_expect_success'@{t} resolves to correct full name''+testrefs/remotes/origin/master="$(full_name@{t})"+'++test_expect_success'my-side@{tracked} resolves to correct full name''+testrefs/remotes/origin/side="$(full_namemy-side@{t})"+'++test_expect_success'my-side@{t} resolves to correct commit''+gitcheckoutside&&+test_commit5&&+(cdclone&&gitfetch)&&+test2="$(commit_subjectmy-side)"&&+test5="$(commit_subjectmy-side@{t})"+'++test_expect_success'not-tracking@{t} fails''+test_must_failfull_namenon-tracking@{t}&&+(cdclone&&gitcheckout--no-track-bnon-tracking)&&+test_must_failfull_namenon-tracking@{t}+'++test_expect_success'<branch>@{t}@{1} resolves correctly''+test_commit6&&+(cdclone&&gitfetch)&&+test5=$(commit_subjectmy-side@{t}@{1})+'++test_done
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:47:23
Hi,
On Thu, 10 Sep 2009, Michael J Gruber wrote:
Johannes Schindelin venit, vidit, dixit 10.09.2009 11:36:
quoted
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.
From: Johan Herland <hidden> Date: 2016-06-15 22:47:23
On Thursday 10 September 2009, Michael J Gruber wrote:
Johannes Schindelin venit, vidit, dixit 10.09.2009 11:36:
quoted
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, [off-list ref]
www.herland.net
From: Michael J Gruber <hidden> Date: 2016-06-15 22:47:23
Johan Herland venit, vidit, dixit 10.09.2009 12:18:
On Thursday 10 September 2009, Michael J Gruber wrote:
quoted
Johannes Schindelin venit, vidit, dixit 10.09.2009 11:36:
quoted
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
From: Jeff King <hidden> Date: 2016-06-15 22:47:23
On Thu, Sep 10, 2009 at 12:18:06PM +0200, Johan Herland wrote:
quoted
quoted
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...
From: Johan Herland <hidden> Date: 2016-06-15 22:47:23
On Thursday 10 September 2009, Michael J Gruber wrote:
Johan Herland venit, vidit, dixit 10.09.2009 12:18:
quoted
On Thursday 10 September 2009, Michael J Gruber wrote:
quoted
Johannes Schindelin venit, vidit, dixit 10.09.2009 11:36:
quoted
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, [off-list ref]
www.herland.net
@@ -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
From: Michael J Gruber <hidden> Date: 2016-06-15 22:47:23
Johannes Schindelin venit, vidit, dixit 10.09.2009 15:35:
Hi,
On Thu, 10 Sep 2009, Johan Herland wrote:
quoted
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
From: Jeff King <hidden> Date: 2016-06-15 22:47:23
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.
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:47:23
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
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:47:23
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 <redacted>
---
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
@@ -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}'
@@ -0,0 +1,69 @@+#!/bin/sh++test_description='test <branch>@{upstream} syntax'++../test-lib.sh+++test_expect_success'setup''++test_commit1&&+gitcheckout-bside&&+test_commit2&&+gitcheckoutmaster&&+gitclone.clone&&+test_commit3&&+(cdclone&&+test_commit4&&+gitbranch--trackmy-sideorigin/side)++'++full_name(){+(cdclone&&+gitrev-parse--symbolic-full-name"$@")+}++commit_subject(){+(cdclone&&+gitshow-s--pretty=format:%s"$@")+}++test_expect_success'@{upstream} resolves to correct full name''+testrefs/remotes/origin/master="$(full_name@{upstream})"+'++test_expect_success'@{u} resolves to correct full name''+testrefs/remotes/origin/master="$(full_name@{u})"+'++test_expect_success'my-side@{upstream} resolves to correct full name''+testrefs/remotes/origin/side="$(full_namemy-side@{u})"+'++test_expect_success'my-side@{u} resolves to correct commit''+gitcheckoutside&&+test_commit5&&+(cdclone&&gitfetch)&&+test2="$(commit_subjectmy-side)"&&+test5="$(commit_subjectmy-side@{u})"+'++test_expect_success'not-tracking@{u} fails''+test_must_failfull_namenon-tracking@{u}&&+(cdclone&&gitcheckout--no-track-bnon-tracking)&&+test_must_failfull_namenon-tracking@{u}+'++test_expect_success'<branch>@{u}@{1} resolves correctly''+test_commit6&&+(cdclone&&gitfetch)&&+test5=$(commit_subjectmy-side@{u}@{1})+'++test_expect_success'% without specifying branch crashes on a detached HEAD''+gitcheckoutHEAD^0&&+test_must_failgitrev-parse@{u}+'++test_done
From: Jeff King <hidden> Date: 2016-06-15 22:47:23
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
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:47:23
Hi,
On Thu, 10 Sep 2009, Jeff King wrote:
I wrote:
quoted
+ 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