git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Taylor Blau <me@ttaylorr.com>
To: Jeff King <peff@peff.net>
Cc: Taylor Blau <me@ttaylorr.com>,
	git@vger.kernel.org, gitster@pobox.com, sunshine@sunshineco.com,
	sbeller@google.com
Subject: Re: [PATCH v3 3/4] transport.c: introduce core.alternateRefsCommand
Date: Fri, 28 Sep 2018 15:04:10 -0700	[thread overview]
Message-ID: <20180928220410.GA45367@syl> (raw)
In-Reply-To: <20180928052613.GC25850@sigill.intra.peff.net>

On Fri, Sep 28, 2018 at 01:26:13AM -0400, Jeff King wrote:
> On Thu, Sep 27, 2018 at 09:25:42PM -0700, Taylor Blau wrote:
>
> > Let the repository that has alternates configure this command to avoid
> > trusting the alternate to provide us a safe command to run in the shell.
> > To behave differently on each alternate (e.g., only list tags from
> > alternate A, only heads from B) provide the path of the alternate as the
> > first argument.
>
> Well, you also need to pass the path so it knows which repo to look at.
> Which I think is the primary reason we do it, but behaving differently
> for each alternate is another option.

Yeah. I think that the clearer argument is yours, so I'll amend my copy.
I am thinking of:

  To find the alternate, pass its absolute path as the first argument.

How does that sound?

> > +core.alternateRefsCommand::
> > +   When advertising tips of available history from an alternate, use the shell to
> > +   execute the specified command instead of linkgit:git-for-each-ref[1]. The
> > +   first argument is the absolute path of the alternate. Output must be of the
> > +   form: `%(objectname)`, where multiple tips are separated by newlines.
>
> I wonder if people may be confused about the %(objectname) syntax, since
> it's specific to for-each-ref.  Now that we've simplified the output
> format to a single value, perhaps we should define it more directly.
> E.g., like:
>
>   The output should contain one hex object id per line (i.e., the same
>   as produced by `git for-each-ref --format='%(objectname)'`).

I think that that's clearer, thanks. I applied it pretty much as you
suggested, but changed 'should' to 'must' and dropped the leading 'the'.

> Now that we've dropped the refname requirement from the output, it is
> more clear that this really does not have to be about refs at all.  In
> the most technical sense, what we really allow in the output is any
> object id X for which the alternate promises it has all objects
> reachable from X. Ref tips are a convenient and efficient way of
> providing that, but they are not the only possibility (and likewise, it
> is fine to omit duplicates or even tips that are ancestors of other
> tips).
>
> I think that's probably getting _too_ technical, though. It probably
> makes sense to just keep thinking of these as "what are the ref tips".

Yep, I agree completely.

> > +This is useful when a repository only wishes to advertise some of its
> > +alternate's references as ".have"'s. For example, to only advertise branch
>
> Maybe put ".have" into backticks for formatting?

Good idea, thanks. I took this locally as suggested.

> > +heads, configure `core.alternateRefsCommand` to the path of a script which runs
> > +`git --git-dir="$1" for-each-ref --format='%(objectname)' refs/heads`.
>
> Does that script actually work? Because of the way we invoke shell
> commands with arguments, I think we'd end up with:
>
>   git --git-dir="$1" for-each-ref --format='%(objectname)' refs/heads "$@"

I think that you're right...

> Possibly for-each-ref would ignore the extra path argument (thinking
> it's a ref pattern that just doesn't match), but it's definitely not
> what you intended. You'd have to write:
>
>   f() { git --git-dir=$1 ...etc; } f
>
> in the usual way. That's a minor pain, but it's what makes the more
> direct:
>
>   /my/script
>
> work.

...but this was what I was trying to get across with saying "...to the
path of a script which runs...", such that we would get the implicit
scoping that you make explicit in your example with "f() { ... }; f".

Does that seem OK as-is after the additional context? I think that after
reading your response, it seems to be confusing, so perhaps it should be
changed...

> The other alternative is to pass $GIT_DIR in the environment on behalf
> of the program. Then writing:
>
>   git for-each-ref --format='%(objectname)' refs/heads
>
> would Just Work. But it's a bit subtle, since it is not immediately
> obvious that the command is meant to run in a different repository.

I think that we discussed this approach a bit off-list, and I had the
idea that it was too fragile to work in practice, and that it would be
too surprising for callers to suddenly be in a different world.

I say this not because it wouldn't make this particular scenario more
convenient, which it uncountably would, but because it would make other
scenarios _more_ complicated.

For example, if a caller uses an alternate reference backed, perhaps,
MySQL (or anything that _isn't_ Git), they're not going to want to have
these GIT_ environment variable set.

So, I think that the greatest common denominator between the two is to
pass the alternate's absolute path as the first argument.

> > diff --git a/t/t5410-receive-pack.sh b/t/t5410-receive-pack.sh
> > new file mode 100755
> > index 0000000000..503dde35a4
> > --- /dev/null
> > +++ b/t/t5410-receive-pack.sh
> > @@ -0,0 +1,49 @@
> > +#!/bin/sh
> > +
> > +test_description='git receive-pack test'
>
> The name of this test file and the description are pretty vague. Can we
> say something like "test handling of receive-pack with alternate-refs
> config"?

I left it intentionally vague, since I'd like for it to contain more
tests about 'git receive-pack'-specific things in the future.

I'm happy to change the name, though I wonder if we should change the
filename accordingly, and if so, to what.

> > +test_expect_success 'setup' '
> > +   test_commit one &&
> > +   git update-ref refs/heads/a HEAD &&
> > +   test_commit two &&
> > +   git update-ref refs/heads/b HEAD &&
> > +   test_commit three &&
> > +   git update-ref refs/heads/c HEAD &&
> > +   git clone --bare . fork &&
> > +   git clone fork pusher &&
> > +   (
> > +           cd fork &&
> > +           git update-ref --stdin <<-\EOF &&
> > +           delete refs/heads/a
> > +           delete refs/heads/b
> > +           delete refs/heads/c
> > +           delete refs/heads/master
> > +           delete refs/tags/one
> > +           delete refs/tags/two
> > +           delete refs/tags/three
> > +           EOF
> > +           echo "../../.git/objects" >objects/info/alternates
> > +   )
> > +'
>
> This setup is kind of convoluted. You're deleting those refs in the
> fork, I think, because we don't want them to suppress the duplicate
> .have lines from the alternate. Might it be easier to just create the
> .have lines we're interested in after the fact?
> I think we can also use "clone -s" to make the setup of the alternate a
> little simpler.
>
> I don't see the "pusher" repo being used for anything here. Leftover
> cruft from when you were using "git push" to test?
>
> So all together, perhaps something like:
>
>   # we have a fork which points back to us as an alternate
>   test_commit base &&
>   git clone -s . fork &&
>
>   # the alternate has two refs with new tips, in two separate hierarchies
>   git checkout -b public/branch master &&
>   test_commit public &&
>   git checkout -b private/branch master &&
>   test_commit private
>
> And then...
>
> > +test_expect_success 'with core.alternateRefsCommand' '
> > +   write_script fork/alternate-refs <<-\EOF &&
> > +           git --git-dir="$1" for-each-ref \
> > +                   --format="%(objectname)" \
> > +                   refs/heads/a \
> > +                   refs/heads/c
> > +   EOF
>
> ...this can just look for refs/heads/public/, and...
>
> > +   test_config -C fork core.alternateRefsCommand alternate-refs &&
> > +   git rev-parse a c >expect &&
>
> ...we verify that we saw public/branch but not private/branch.
>
> It's not that much shorter, but I had trouble understanding from the
> setup why we needed to delete all those refs (and why we cared about
> those tags in the first place).

I agree with all of this. It's certainly roughly the same length, but I
think that it makes it much easier to grok, and it addresses a comment
that Junio made in an earlier response to this thread. So, two wins for
the price of one :-).

I had to make a couple of other changes that you didn't recommend:

  - Since we used to create fork with 'git clone --bare', the path of
    `core.alternateRefsCommand` grew an extra `../`, since we have to
    also traverse _out_ of the .git directory in a non-bare repository.

    Instead of this, I opted for both, with 'git clone -s --bare .
    fork', which means we don't have to check out a working copy, and we
    can avoid changing the line mentioned above.

  - Another thing that I had to decide on was what to give as a prefix
    for the test exercising 'core.alternateRefsPrefixes', which I
    decided to use 'refs/heads/private' for, which makes sure that we're
    seeing something different than 'core.alternateRefsCommand'.

The diff is kind of long (so I'm avoiding sending it here), but I think
that it's mostly self-explanatory from what you recommended to me and
what I said above.

> > diff --git a/transport.c b/transport.c
> > index 2825debac5..e271b66603 100644
> > --- a/transport.c
> > +++ b/transport.c
> > @@ -1328,10 +1328,21 @@ char *transport_anonymize_url(const char *url)
> >  static void fill_alternate_refs_command(struct child_process *cmd,
> >                                     const char *repo_path)
>
> The code change itself looks good to me.

Thanks for your review, as always.

I'll wait until Monday to re-roll, just to make sure that there isn't
any new feedback between now and then.

Thanks,
Taylor

  reply	other threads:[~2018-09-28 22:04 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-20 18:04 [PATCH 0/3] Filter alternate references Taylor Blau
2018-09-20 18:04 ` [PATCH 1/3] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-09-20 18:04 ` [PATCH 2/3] transport.c: introduce core.alternateRefsCommand Taylor Blau
2018-09-20 19:37   ` Jeff King
2018-09-20 20:00     ` Taylor Blau
2018-09-20 20:06       ` Jeff King
2018-09-21 16:39   ` Junio C Hamano
2018-09-21 17:48     ` Taylor Blau
2018-09-21 17:57       ` Taylor Blau
2018-09-21 19:59         ` Junio C Hamano
2018-09-26  0:56           ` Taylor Blau
2018-09-20 18:04 ` [PATCH 3/3] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-09-20 19:47   ` Jeff King
2018-09-20 20:12     ` Taylor Blau
2018-09-21  7:19   ` Eric Sunshine
2018-09-21 14:07     ` Taylor Blau
2018-09-21 16:45       ` Junio C Hamano
2018-09-21 17:49         ` Taylor Blau
2018-09-21 16:40     ` Junio C Hamano
2018-09-20 18:35 ` [PATCH 0/3] Filter alternate references Stefan Beller
2018-09-20 18:56   ` Taylor Blau
2018-09-20 19:27   ` Jeff King
2018-09-20 19:21 ` Jeff King
2018-09-21 18:47 ` [PATCH v2 " Taylor Blau
2018-09-21 18:47   ` [PATCH v2 1/3] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-09-21 18:47   ` [PATCH v2 2/3] transport.c: introduce core.alternateRefsCommand Taylor Blau
2018-09-21 20:18     ` Eric Sunshine
2018-09-26  0:59       ` Taylor Blau
2018-09-21 21:09     ` Junio C Hamano
2018-09-21 22:13       ` Jeff King
2018-09-21 22:23         ` Junio C Hamano
2018-09-21 22:27           ` Jeff King
2018-09-26  1:06       ` Taylor Blau
2018-09-26  3:21         ` Jeff King
2018-09-21 21:10     ` Eric Sunshine
2018-09-22 18:02     ` brian m. carlson
2018-09-22 19:52       ` Jeff King
2018-09-23 14:53         ` brian m. carlson
2018-09-26  1:09         ` Taylor Blau
2018-09-26  3:33           ` Jeff King
2018-09-26 13:39             ` Taylor Blau
2018-09-26 18:38               ` Jeff King
2018-09-28  2:39                 ` Taylor Blau
2018-09-21 18:47   ` [PATCH v2 3/3] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-09-21 21:14     ` Junio C Hamano
2018-09-21 21:37       ` Jeff King
2018-09-21 22:06         ` Junio C Hamano
2018-09-21 22:18           ` Jeff King
2018-09-21 22:23             ` Stefan Beller
2018-09-24 15:17             ` Junio C Hamano
2018-09-24 18:10               ` Jeff King
2018-09-24 20:32                 ` Junio C Hamano
2018-09-24 20:50                   ` Jeff King
2018-09-24 21:01                     ` Jeff King
2018-09-24 21:55                     ` Junio C Hamano
2018-09-24 23:14                       ` Jeff King
2018-09-25 17:41                         ` Junio C Hamano
2018-09-25 22:46                           ` Taylor Blau
2018-09-25 23:56                             ` Junio C Hamano
2018-09-26  1:18                               ` Taylor Blau
2018-09-26  3:16                               ` Jeff King
2018-09-28  4:25 ` [PATCH v3 0/4] Filter alternate references Taylor Blau
2018-09-28  4:25   ` [PATCH v3 1/4] transport: drop refnames from for_each_alternate_ref Jeff King
2018-09-28  4:58     ` Jeff King
2018-09-28 14:21       ` Taylor Blau
2018-09-28  4:25   ` [PATCH v3 2/4] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-09-28  4:59     ` Jeff King
2018-09-28  4:25   ` [PATCH v3 3/4] transport.c: introduce core.alternateRefsCommand Taylor Blau
2018-09-28  5:26     ` Jeff King
2018-09-28 22:04       ` Taylor Blau [this message]
2018-09-29  7:31         ` Jeff King
2018-10-02  1:56           ` Taylor Blau
2018-09-28  4:25   ` [PATCH v3 4/4] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-09-28  5:30     ` Jeff King
2018-09-28 22:05       ` Taylor Blau
2018-09-29  7:34         ` Jeff King
2018-10-02  1:57           ` Taylor Blau
2018-10-02  2:00             ` Taylor Blau
2018-10-02  2:23 ` [PATCH v4 0/4] Filter alternate references Taylor Blau
2018-10-02  2:23   ` [PATCH v4 1/4] transport: drop refnames from for_each_alternate_ref Taylor Blau
2018-10-02  2:23   ` [PATCH v4 2/4] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-10-02  2:23   ` [PATCH v4 3/4] transport.c: introduce core.alternateRefsCommand Taylor Blau
2018-10-02 23:40     ` Jeff King
2018-10-04  2:17       ` Taylor Blau
2018-10-02  2:24   ` [PATCH v4 4/4] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-10-02 15:13     ` Ramsay Jones
2018-10-02 23:28       ` Taylor Blau
2018-10-08 18:09 ` [PATCH v5 0/4] Filter alternate references Taylor Blau
2018-10-08 18:09   ` [PATCH v5 1/4] transport: drop refnames from for_each_alternate_ref Taylor Blau
2018-10-08 18:09   ` [PATCH v5 2/4] transport.c: extract 'fill_alternate_refs_command' Taylor Blau
2018-10-08 18:09   ` [PATCH v5 3/4] transport.c: introduce core.alternateRefsCommand Taylor Blau
2018-10-08 18:09   ` [PATCH v5 4/4] transport.c: introduce core.alternateRefsPrefixes Taylor Blau
2018-10-09  3:09   ` [PATCH v5 0/4] Filter alternate references Jeff King
2018-10-09 14:49     ` Taylor Blau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180928220410.GA45367@syl \
    --to=me@ttaylorr.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    --cc=sbeller@google.com \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).