From: Junio C Hamano <hidden> Date: 2016-06-15 22:48:00
Jeff King [off-list ref] writes:
Hmm. If we had the oft-discussed-but-never-agreed-upon shorthand for
"the upstream of" then we wouldn't need a special merge option. You
could just do:
git merge %HEAD ;# (or git merge %, IIRC the proposal correctly)
I don't think "whatever _HEAD_ tracks" makes sense at the semantic level
(i.e. you don't do "branch.HEAD.merge") but a syntax for "whatever the
named _branch_ tracks" with "if a branch is not named, the current branch
is implied" (i.e. the one in parentheses) would.
It is an entirely different matter what the special syntax to trigger that
"upstream-ness" should be. I vaguely recall @{upstream} or @{u} were the
concensus?
From: Jeff King <hidden> Date: 2016-06-15 22:48:00
On Tue, Jan 12, 2010 at 10:11:26AM -0800, Junio C Hamano wrote:
Jeff King [off-list ref] writes:
quoted
Hmm. If we had the oft-discussed-but-never-agreed-upon shorthand for
"the upstream of" then we wouldn't need a special merge option. You
could just do:
git merge %HEAD ;# (or git merge %, IIRC the proposal correctly)
I don't think "whatever _HEAD_ tracks" makes sense at the semantic level
(i.e. you don't do "branch.HEAD.merge") but a syntax for "whatever the
named _branch_ tracks" with "if a branch is not named, the current branch
is implied" (i.e. the one in parentheses) would.
The patch that Dscho provided would actually convert HEAD@{upstream}
into the upstream of whatever HEAD pointed at. Which I think makes
sense. We don't do it for reflogs, but that is because it is useful to
distinguish between the reflog for a symref and the thing it points to.
But since one would presumably not make such a configuration for a
symref, that distinction is not useful.
It is an entirely different matter what the special syntax to trigger that
"upstream-ness" should be. I vaguely recall @{upstream} or @{u} were the
concensus?
Ah, right. I remembered hating "%" even as I typed it, but I had
forgotten about the followup discussion. Looking at it again, I note:
1. The last posted patch still has a misplaced free() (patch below),
but I think otherwise is not buggy.
2. We don't complain on "git show @{usptream}" and we probably should.
I remember there being some complications because the contents of
@{} were passed to approxidate, but I think we can get around that
by letting approxidate complain if _nothing_ in the date was
useful. So "git show @{2.weeks.and.7.hot.dogs.ago}" would still
work, but "git show @{totally.bogus.input}" would complain.
3. I have actually been running with Dscho's patch for the last couple
of months, and I don't remember using it once. So perhaps it is not
as useful as I might have thought. :)
Anyway, fixup patch is below. I don't expect you to pick up the topic or
anything, but since I went to the trouble to find the bug once upon a
time, I thought I would post the fix for anybody who does want to pick
it up.
From: Junio C Hamano <hidden> Date: 2016-06-15 22:48:00
Jeff King [off-list ref] writes:
Ah, right. I remembered hating "%" even as I typed it, but I had
forgotten about the followup discussion. Looking at it again, I note:
1. The last posted patch still has a misplaced free() (patch below),
but I think otherwise is not buggy.
2. We don't complain on "git show @{usptream}" and we probably should.
I remember there being some complications because the contents of
@{} were passed to approxidate, but I think we can get around that
by letting approxidate complain if _nothing_ in the date was
useful. So "git show @{2.weeks.and.7.hot.dogs.ago}" would still
work, but "git show @{totally.bogus.input}" would complain.
3. I have actually been running with Dscho's patch for the last couple
of months, and I don't remember using it once. So perhaps it is not
as useful as I might have thought. :)
I presume we are discussing this patch?
http://article.gmane.org/gmane.comp.version-control.git/128121
I'll squash the free() fix; thanks.
I wondered why it doesn't hook into interpret_branch_name(), and instead
adds itself to the static substitute_branch_name(); it forbids the use of
the syntax from by callers of strbuf_branchname().
I agree with your point #2 above.
Regarding your point #3, I don't think the notation should be that useful
if your workflow is sane. The original use case that triggered the
resurrection of the patch went like this:
git fetch &&
for local in my set of local branches
do
git checkout $local &&
git merge $local@{upstream} || {
echo failed to merge on $local
break
}
done
and the new notation might look useful in the scenario. But the thing is,
constantly merging with the other side, even if you haven't added anything
of value since you merged from there last time, is a bad practice to begin
with. I added one use case that is sane _and_ will be helped by the new
notation to the rewritten version of Dscho's patch (below).
Just to refresh our memory from the old thread and make sure we are
discussing the same patch, here is what I am planning to queue. The log
message and documentation are somewhat updated to avoid the word "track"
because it seems that everybody gets confused and starts talking different
things whenever that word is used. For the same reason, the test script
was renamed.
In this set-up, for example:
[remote "filfre"]
url = ...
fetch = +refs/heads/nitfol:refs/heads/rezrov
[branch "frotz"]
remote = filfre
merge = refs/heads/nitfol
some people say rezrov tracks nitfol from filfre but Dscho's patch says
frotz tracks nitfol from filfre. They _may_ both track, but they "track"
the other in a quite differently way, so the word has become meaningless.
I've been trying to be careful and used different words to disambiguate
whenever I had to talk about these concepts:
- The purpose of rezrov is to keep a tab on the progress of the nitfol
branch at the remote end. We say rezrov is a remote tracking branch
for nitfol from filfre.
- On the other hand, we have branch frotz that forked from nitfol that
came from filfre. It builds on top of that history by occasionally
merging with it at key points in the history. So we say frotz builds
on top of nitfol from filfre. We also say nitfol at filfre is the
upstream of frotz.
-- >8 --
Date: Thu, 10 Sep 2009 17:25:57 +0200
Subject: [PATCH] Introduce <branch>@{upstream} notation
A new notation '<branch>@{upstream}' refers to the branch <branch> is set
to build on top of. Missing <branch> (i.e. '@{upstream}') defaults to the
current branch.
This allows you to run, for example,
for l in list of local branches
do
git log --oneline --left-right $l...$l@{upstream}
done
to inspect each of the local branches you are interested in for the
divergence from its upstream.
Signed-off-by: Johannes Schindelin <redacted>
Signed-off-by: Junio C Hamano <redacted>
---
Documentation/git-rev-parse.txt | 4 ++
sha1_name.c | 39 ++++++++++++++++++++--
t/t1506-rev-parse-upstream.sh | 69 +++++++++++++++++++++++++++++++++++++++
3 files changed, 109 insertions(+), 3 deletions(-)
create mode 100755 t/t1506-rev-parse-upstream.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 'ref@{u}') refers to+ the branch the ref is set to build on top of. Missing ref defaults+ to 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'@{u} without specifying branch fails on a detached HEAD''+gitcheckoutHEAD^0&&+test_must_failgitrev-parse@{u}+'++test_done
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:48:00
Hi,
On Tue, 12 Jan 2010, Junio C Hamano wrote:
I wondered why it doesn't hook into interpret_branch_name(), and instead
adds itself to the static substitute_branch_name(); it forbids the use
of the syntax from by callers of strbuf_branchname().
I _think_ it was to allow something like
git log -g @{u}
but frankly, this is so long ago, I do not remember, I reconstructed this
reasoning as being the most likely.
Ciao,
Dscho
From: Junio C Hamano <hidden> Date: 2016-06-15 22:48:04
Earlier I wondered if the approach Dscho's patch takes to teach the new
@{upstream} syntax to substitute_branch_name() (hence dwim_ref()) without
teaching it to interpret_branch_name() (hence strbuf_branchname()) was a
bad idea. I thought about this a bit more; there are some downsides for
not doing so.
The first patch adds a handful of tests that show why strbuf_branchname()
callers may also want to learn about the new syntax. The second patch
moves the logic to interpret_branch_name() to make them happier.
The name of the key function was changed from tracked_suffix() to
upstream_mark(), not only because the syntax talks about @{upstream}, but
because the parsing needs to recognize the @{u}/@{upstream} mark at the
beginning of the given string (that is a suffix to some other string), and
strip it (the earlier code wanted @{u} to be at the very end but the
callers need to have it at the beginning).
Junio C Hamano (2):
t1506: more test for @{upstream} syntax
Teach @{upstream} syntax to strbuf_branchanme()
sha1_name.c | 116 ++++++++++++++++++++++++++---------------
t/t1506-rev-parse-upstream.sh | 41 ++++++++++++++
2 files changed, 115 insertions(+), 42 deletions(-)
From: Junio C Hamano <hidden> Date: 2016-06-15 22:48:04
This adds a few more tests that exercises @{upstream} syntax by commands
that operate differently when they are given branch name as opposed to a
refname (i.e. where "master" and "refs/heads/master" makes a difference).
Signed-off-by: Junio C Hamano <redacted>
---
t/t1506-rev-parse-upstream.sh | 41 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 41 insertions(+), 0 deletions(-)
@@ -66,4 +66,45 @@ test_expect_success '@{u} without specifying branch fails on a detached HEAD' 'test_must_failgitrev-parse@{u}'+test_expect_success'checkout -b new my-side@{u} forks from the same''+(+cdclone&&+gitcheckout-bnewmy-side@{u}&&+gitrev-parse--symbolic-full-namemy-side@{u}>expect&&+gitrev-parse--symbolic-full-namenew@{u}>actual&&+test_cmpexpectactual+)+'++test_expect_failure'merge my-side@{u} records the correct name''+(+sq="'\''"&&+cdclone||exit+gitcheckoutmaster||exit+gitbranch-Dnew;# can fail but is ok+gitbranch-tnewmy-side@{u}&&+gitmerge-soursnew@{u}&&+gitshow-s--pretty=format:%s>actual&&+echo"Merge remote branch ${sq}origin/side${sq}">expect&&+test_cmpexpectactual+)+'++test_expect_failure'branch -d other@{u}''+gitcheckout-t-bothermaster&&+gitbranch-d@{u}&&+gitfor-each-refrefs/heads/master>actual&&+>expect&&+test_cmpexpectactual+'++test_expect_failure'checkout other@{u}''+gitbranch-fmasterHEAD&&+gitcheckout-t-banothermaster&&+gitcheckout@{u}&&+gitsymbolic-refHEAD>actual&&+echorefs/heads/master>expect&&+test_cmpexpectactual+'+ test_done
From: Junio C Hamano <hidden> Date: 2016-06-15 22:48:04
This teaches @{upstream} syntax to interpret_branch_name(), instead
of dwim_ref() machinery.
There are places in git UI that behaves differently when you give a local
branch name and when you give an extended SHA-1 expression that evaluates
to the commit object name at the tip of the branch. The intent is that
the special syntax such as @{-1} can stand in as if the user spelled the
name of the branch in such places.
The name of the branch "frotz" to switch to ("git checkout frotz"), and
the name of the branch "nitfol" to fork a new branch "frotz" from ("git
checkout -b frotz nitfol"), are examples of such places. These places
take only the name of the branch (e.g. "frotz"), and they are supposed to
act differently to an equivalent refname (e.g. "refs/heads/frotz"), so
hooking the @{upstream} and @{-N} syntax to dwim_ref() is insufficient
when we want to deal with cases a local branch is forked from another
local branch and use "forked@{upstream}" to name the forkee branch.
The "upstream" syntax "forked@{u}" is to specify the ref that "forked" is
configured to merge with, and most often the forkee is a remote tracking
branch, not a local branch. We cannot simply return a local branch name,
but that does not necessarily mean we have to returns the full refname
(e.g. refs/remotes/origin/frotz, when returning origin/frotz is enough).
This update calls shorten_unambiguous_ref() to do so.
Signed-off-by: Junio C Hamano <redacted>
---
sha1_name.c | 116 ++++++++++++++++++++++++++---------------
t/t1506-rev-parse-upstream.sh | 6 +-
2 files changed, 77 insertions(+), 45 deletions(-)
@@ -828,6 +806,60 @@ release_return:}/*+*Thisreadsshort-handsyntaxthatnotonlyevaluatestoacommit+*objectname,butalsocanactasiftheenduserspelledthename+*ofthebranchfromthecommandline.+*+*-"@{-N}"findsthenameoftheNthpreviousbranchwewereon,and+*placesthenameofthebranchinthegivenbufandreturnsthe+*numberofcharactersparsedifsuccessful.+*+*-"<branch>@{upstream}"findsthenameoftheotherrefthat+*<branch>isconfiguredtomergewith(missing<branch>defaults+*tothecurrentbranch),andplacesthenameofthebranchinthe+*givenbufandreturnsthenumberofcharactersparsedif+*successful.+*+*Iftheinputisnotoftheacceptedformat,itreturnsanegative+*numbertosignalanerror.+*+*IftheinputwasokbuttherearenotNbranchswitchesinthe+*reflog,itreturns0.+*/+intinterpret_branch_name(constchar*name,structstrbuf*buf)+{+char*cp;+structbranch*upstream;+intnamelen=strlen(name);+intlen=interpret_nth_prior_checkout(name,buf);+inttmp_len;++if(!len)+returnlen;/* syntax Ok, not enough switches */+if(0<len)+returnlen;/* consumed from the front */+cp=strchr(name,'@');+if(!cp)+return-1;+tmp_len=upstream_mark(cp,namelen-(cp-name));+if(!tmp_len)+return-1;+len=cp+tmp_len-name;+cp=xstrndup(name,cp-name);+upstream=branch_get(*cp?cp:NULL);+if(!upstream+||!upstream->merge+||!upstream->merge[0]->dst)+returnerror("No upstream branch found for '%s'",cp);+free(cp);+cp=shorten_unambiguous_ref(upstream->merge[0]->dst,0);+strbuf_reset(buf);+strbuf_addstr(buf,cp);+free(cp);+returnlen;+}++/**Thisislike"get_sha1_basic()",exceptitallows"sha1 expressions",*notably"xyz^"for"parent of xyz"*/
@@ -76,7 +76,7 @@ test_expect_success 'checkout -b new my-side@{u} forks from the same' ')'-test_expect_failure'merge my-side@{u} records the correct name''+test_expect_success'merge my-side@{u} records the correct name''(sq="'\''"&&cdclone||exit
@@ -90,7 +90,7 @@ test_expect_failure 'merge my-side@{u} records the correct name' ')'-test_expect_failure'branch -d other@{u}''+test_expect_success'branch -d other@{u}''gitcheckout-t-bothermaster&&gitbranch-d@{u}&&gitfor-each-refrefs/heads/master>actual&&
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:48:04
Hi,
On Wed, 20 Jan 2010, Junio C Hamano wrote:
Earlier I wondered if the approach Dscho's patch takes to teach the new
@{upstream} syntax to substitute_branch_name() (hence dwim_ref()) without
teaching it to interpret_branch_name() (hence strbuf_branchname()) was a
bad idea. I thought about this a bit more; there are some downsides for
not doing so.
The first patch adds a handful of tests that show why strbuf_branchname()
callers may also want to learn about the new syntax. The second patch
moves the logic to interpret_branch_name() to make them happier.
From: Jeff King <hidden> Date: 2016-06-15 22:48:06
On Wed, Jan 20, 2010 at 01:38:41AM -0800, Junio C Hamano wrote:
This adds a few more tests that exercises @{upstream} syntax by commands
that operate differently when they are given branch name as opposed to a
refname (i.e. where "master" and "refs/heads/master" makes a difference).
Overall this looks good, but there are a few minor defects. I haven't
had a chance to fix them yet, but here are tests showing them. I hope to
get to them pre-1.7.0, but please feel free to take a crack at them if
you want.
The first one is that @{usptream} silently becomes @{0}. I think
we need to double-check whether approxidate found absolutely nothing,
and complain if that is the case.
@@ -0,0 +1,41 @@+#!/bin/sh++test_description='various @{whatever} syntax tests'+../test-lib.sh++test_expect_success'setup''+test_commitone&&+test_committwo+'++check_at(){+echo"$2">expect&&+gitlog-1--format=%s"$1">actual&&+test_cmpexpectactual+}++test_expect_success'@{0} shows current''+check_at@{0}two+'++test_expect_success'@{1} shows old''+check_at@{1}one+'++test_expect_success'@{now} shows current''+check_at@{now}two+'++test_expect_success'@{30.years.ago} shows old''+check_at@{30.years.ago}one+'++test_expect_success'silly approxidates work''+check_at@{3.hot.dogs.and.30.years.ago}one+'++test_expect_failure'complain about total nonsense''+test_must_failgitlog-1--format=%s@{utter.bogosity}+'++test_done
The second one is that "log -g branch@{u}" shows the correct commits
(from the upstream of "branch"), but displays the incorrect reflog
information (it shows information for "branch", not for its upstream).