Re: [PATCH v2 2/2] remote.c: fix handling of %(push:remoteref)
- From
- Damien Robert <damien.olivier.robert@gmail.com>
- Date
- Mar 3, 2020, 22:24 UTC
- Message-ID
- <20200303222423.wfbjuuwp3263qesv@doriath>
- In-Reply-To
- <xmqqtv358fkk.fsf@gitster-ct.c.googlers.com>
From Junio C Hamano, Tue 03 Mar 2020 at 10:21:31 (-0800) :
> Mental note: this function was moved down, the main part of the > logic extracted to a new branch_get_push_remoteref() helper, which > in addition got extended.
Exactly.
> That's a fairly expensive way to write > if (remote->push.nr) > return apply_refspecs(&remote->push, branch->refname); > one-liner.
You anticipated the question I asked afterwards :)
Show 11 quoted lines
> > + case PUSH_DEFAULT_UPSTREAM:
> > + {
> > + if (!branch || !branch->merge ||
> > + !branch->merge[0] || !branch->merge[0]->dst)
> > + return NULL;
> > +
> > + return branch->merge[0]->src;
> > + }
>
> This is strangely indented and somewhat unreadable. Why isn't this
> more like:Sorry I missed the indentation for the return NULL.
Show 8 quoted lines
> case PUSH_DEFAULT_UPSTREAM: > if (branch && branch->merge && branch->merge[0] && > branch->merge[0]->dst) > return branch->merge[0]->src; > break; > > and have "return NULL" after the switch() statement before we leave > the function?
We could, I agree this is more readable. If we return NULL after the switch, we need to put the
> > + BUG("unhandled push situation")in a default clause a you say.
The reason I wrote the code as above is to be as close as possible to `branch_get_push_1`. If we make the changes you suggest, I'll probably need a preliminary patch to change `branch_get_push_1` accordingly.
Show 20 quoted lines
> > + case PUSH_DEFAULT_UNSPECIFIED:
> > + case PUSH_DEFAULT_SIMPLE:
> > + {
> > + const char *up, *cur;
> > +
> > + up = branch_get_upstream(branch, NULL);
> > + if (!up)
> > + return NULL;
> > + cur = tracking_for_push_dest(remote, branch->refname, NULL);
> > + if (!cur)
> > + return NULL;
> > + if (strcmp(cur, up))
> > + return NULL;
>
> This is probably not all that performance critical, so
> up = branch_get_upstream(branch, NULL);
> current = tracking_for_push_dest(remote, branch->refname, NULL);
> if (!up || !current || strcmp(current, up))
> return NULL;
> might be easier to follow.I don't mind but likewise in this case we should probably change branch_get_push_1 too.
> By the way, I have a bit higher-level question. > > All of the above logic that decides what should happen in "git push" > MUST have existing code we already use to implement "git push", no?
Yes.
> Why do we need to reinvent it here, instead of reusing the existing > code? Is it because the interface into the functions that implement > the existing logic is very different from what this function wants?
Mostly yes. The logic of git push is to massage the refspecs directly, for instance: case PUSH_DEFAULT_MATCHING: refspec_append(&rs, ":"); case PUSH_DEFAULT_CURRENT: ... strbuf_addf(&refspec, "%s:%s", branch->refname, branch->refname); case PUSH_DEFAULT_UPSTREAM: ... strbuf_addf(&refspec, "%s:%s", branch->refname, branch->merge[0]->src);
And the error messages are also not the same, and to give a good error message we need to parse the different cases.
It may be possible to refactorize all this, but not in an obvious way and it would be a lot more work than this patch series.
-- Damien Robert http://www.normalesup.org/~robert/pro