[7/7] is the meat. Sorry it's in such a messy state: I was having a
field day tracing what push is actually doing. Anyway, I wanted to
send out the series now to get early feedback.
In other news: why on earth is push doing _so_ much processing before
pushing? Is it written very badly, or am I missing something?
Thanks.
(based on rr/die-on-missing-upstream)
Ramkumar Ramachandra (7):
sha1_name: abstract upstream_mark() logic
sha1_name: factor out die_no_upstream()
sha1_name: remove upstream_mark()
remote: expose parse_push_refspec()
remote: expose get_ref_match()
sha1_name: prepare to introduce AT_KIND_PUSH
sha1_name: implement finding @{push}
remote.c | 4 +--
remote.h | 4 +++
sha1_name.c | 111 ++++++++++++++++++++++++++++++++++++++++++++----------------
3 files changed, 88 insertions(+), 31 deletions(-)
--
1.8.3.rc3.17.gd95ec6c.dirty
Currently interpret_branch_name() tries to parse various things, and
finally falls back to parsing <branch>@{u[pstream]}. It dies if the
input string contained an "@{u[pstream]}" but an upstream could not be
found. The logic can be generalized to check for any branch property
after branch_get(). In preparation for introducing more special @{...}
forms, factor out die_no_upstream().
Signed-off-by: Ramkumar Ramachandra <redacted>
---
sha1_name.c | 40 ++++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 18 deletions(-)
@@ -998,6 +998,24 @@ int get_sha1_mb(const char *name, unsigned char *sha1)returnst;}+staticvoiddie_no_upstream(structbranch*upstream,char*name){+/*+*UpstreamcanbeNULLonlyifcpreferstoHEADandHEAD+*pointstosomethingdifferentthanabranch.+*/+if(!upstream)+die(_("HEAD does not point to a branch"));+if(!upstream->merge||!upstream->merge[0]->dst){+if(!ref_exists(upstream->refname))+die(_("No such branch: '%s'"),name);+if(!upstream->merge)+die(_("No upstream configured for branch '%s'"),+upstream->name);+die(_("Upstream branch '%s' not stored as a remote-tracking branch"),+upstream->merge[0]->src);+}+}+/**Thisreadsshort-handsyntaxthatnotonlyevaluatestoacommit*objectname,butalsocanactasiftheenduserspelledthename
@@ -1059,24 +1077,10 @@ int interpret_branch_name(const char *name, struct strbuf *buf)return-1;len=cp+tmp_len-name;cp=xstrndup(name,cp-name);-upstream=branch_get(*cp?cp:NULL);-/*-*UpstreamcanbeNULLonlyifcpreferstoHEADandHEAD-*pointstosomethingdifferentthanabranch.-*/-if(!upstream)-die(_("HEAD does not point to a branch"));-if(!upstream->merge||!upstream->merge[0]->dst){-if(!ref_exists(upstream->refname))-die(_("No such branch: '%s'"),cp);-if(!upstream->merge)-die(_("No upstream configured for branch '%s'"),-upstream->name);-die(_("Upstream branch '%s' not stored as a remote-tracking branch"),-upstream->merge[0]->src);-}+branch=branch_get(*cp?cp:NULL);+die_no_upstream(branch,cp);free(cp);-cp=shorten_unambiguous_ref(upstream->merge[0]->dst,0);+cp=shorten_unambiguous_ref(branch->merge[0]->dst,0);strbuf_reset(buf);strbuf_addstr(buf,cp);free(cp);
Currently, the only non-numerical @{...} expression we support is
@{u[pstream]}. Since we're slowly growing git to support triangular
workflows, it might make sense to have a @{p[ush]} and various other
special @{...} expressions in the future. To prepare for this, abstract
out the upstream_mark() logic to accept any suffix, while preserving the
upstream_mark() interface.
Signed-off-by: Ramkumar Ramachandra <redacted>
---
sha1_name.c | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
Try this now: configure your current branch's pushremote to push to
"refs/heads/*:refs/heads/rr/*". Now, type 'git show @{p}'. Voila!
It currently only works when:
1. remote.<name>.push is explicitly specified.
2. There is a pattern to match (*).
Proof-of-concept only.
Signed-off-by: Ramkumar Ramachandra <redacted>
---
sha1_name.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
Introduce an AT_KIND_PUSH to be represented as "@{p[ush]}". Determine
it using branch.remote.push_refspec.
Signed-off-by: Ramkumar Ramachandra <redacted>
---
sha1_name.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
@@ -426,7 +426,8 @@ static inline int at_mark(const char *string, int len, int *kind)intkind;constchar*suffix[2];}at_form[]={-{AT_KIND_UPSTREAM,{"@{upstream}","@{u}"}}+{AT_KIND_UPSTREAM,{"@{upstream}","@{u}"}},+{AT_KIND_PUSH,{"@{push}","@{p}"}}};for(j=0;j<ARRAY_SIZE(at_form);j++){
The first caller get_sha1_basic() just wants to make sure that no
non-numerical @{...} form was matched, so that it can proceed with
processing numerical @{...} forms. Since we're going to introduce more
non-numerical @{...} forms, replace this upstream_mark() call with a
call to at_mark() passing NULL as the last argument; we don't care what
the kind is: all we need to know is if the return value is zero (parse
failure).
The second caller interpret_branch_name() will be expanded in the future
to handle all possible AT_KIND_* values. So, replace the
upstream_mark() call with an upstream_mark() call capturing at_kind and
using it in a switch statement to perform the appropriate action.
Signed-off-by: Ramkumar Ramachandra <redacted>
---
sha1_name.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
@@ -443,15 +443,6 @@ static inline int at_mark(const char *string, int len, int *kind)return0;}-staticinlineintupstream_mark(constchar*string,intlen)-{-intsuffix_len,kind;-suffix_len=at_mark(string,len,&kind);-if(suffix_len&&kind==AT_KIND_UPSTREAM)-returnsuffix_len;-return0;-}-staticintget_sha1_1(constchar*name,intlen,unsignedchar*sha1,unsignedlookup_flags);staticintget_sha1_basic(constchar*str,intlen,unsignedchar*sha1)
@@ -469,7 +460,7 @@ 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]=='{'){-if(!upstream_mark(str+at,len-at)){+if(!at_mark(str+at,len-at,NULL)){reflog_len=(len-1)-(at+2);len=at;}
@@ -1044,6 +1035,7 @@ int interpret_branch_name(const char *name, struct strbuf *buf)intnamelen=strlen(name);intlen=interpret_nth_prior_checkout(name,buf);inttmp_len;+intat_kind;if(!len)returnlen;/* syntax Ok, not enough switches */
From: Felipe Contreras <hidden> Date: 2016-06-15 22:57:25
On Thu, May 23, 2013 at 10:12 AM, Ramkumar Ramachandra
[off-list ref] wrote:
Introduce an AT_KIND_PUSH to be represented as "@{p[ush]}". Determine
it using branch.remote.push_refspec.
I think the semantics of this don't make any sense.
git push branch@{upstream}
Is very clear: push upstream of branch.
git push branch@{push}
Is not clear at all: push push of branch?
Is it a noun, or a verb?
I would expect branch@{X} to be 'the X of branch', and "the push of
branch" doesn't make sense. Whatever X ends up being, it should be a
noun.
--
Felipe Contreras
(I haven't caught up with git mails lately, but the @{special}
refactoring caught my eyes..)
On Thu, May 23, 2013 at 10:12 PM, Ramkumar Ramachandra
[off-list ref] wrote:
Try this now: configure your current branch's pushremote to push to
"refs/heads/*:refs/heads/rr/*". Now, type 'git show @{p}'. Voila!
Voila what? Why not avoid guessing game and describe what the patch is for?
Isn't this an abuse of extended sha-1 syntax? How can I combine this
with other @{}, ^, ~...?
I'm unsure what you mean. How can I be on branch master^1? Did you
read the cover-letter?
I did not expect @{p} to printf(). If it's part of get_sha1(), how can
it return an sha-1? And the cover letter said "7/7 is the meat". Not
very informative.
--
Duy
Then "show @{p}" should show the tip commit of rr/master, not the ref
name.
Yes, that is correct.
rev-parse (with an option, maybe) may be a better place for
this.
Er, no. I actually want things like diff @{p}..HEAD. I want it to be
a first-class revision, just like @{u}.
I did not expect @{p} to printf(). If it's part of get_sha1(), how can
it return an sha-1? And the cover letter said "7/7 is the meat". Not
very informative.
I also said sorry for the horrible mess ;)
Yes, it's obviously not supposed to print and die() with a "Done!":
this was a development session, and I hit send-email as soon as I got
the right output. It's supposed to behave exactly like @{u} (failing
to resolve occasionally).