All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Cc: git@vger.kernel.org, Junio C Hamano <gitster@pobox.com>,
	Lars Hjemli <hjemli@gmail.com>,
	Christian Couder <christian.couder@gmail.com>,
	Carlos Rica <jasampler@gmail.com>,
	Samuel Tardieu <sam@rfc1149.net>,
	Tom Grennan <tmgrennan@gmail.com>
Subject: Re: [PATCH 6/8] ref-filter: Add --no-contains option to tag/branch/for-each-ref
Date: Mon, 20 Mar 2017 00:25:19 -0400	[thread overview]
Message-ID: <20170320042519.srtavoxhm3fln5mw@sigill.intra.peff.net> (raw)
In-Reply-To: <20170318103256.27141-7-avarab@gmail.com>

On Sat, Mar 18, 2017 at 10:32:54AM +0000, Ævar Arnfjörð Bjarmason wrote:

> Change the tag, branch & for-each-ref commands to have a --no-contains
> option in addition to their longstanding --contains options.
> 
> This allows for finding the last-good rollout tag given a known-bad
> <commit>. Given a hypothetically bad commit cf5c7253e0 the git version
> revert to can be found with this hacky two-liner:

s/revert to/to &/, I think.


> With this new --no-contains the same can be achieved with:
> [..]

The goal sounds good to me.

> In addition to those tests, add a test for "tag" which asserts that
> --no-contains won't find tree/blob tags, which is slightly
> unintuitive, but consistent with how --contains works & is documented.

Makes sense. In theory we could dig into commits to find trees and blobs
when the user gives us one. But I kind of doubt anybody really wants it,
and it's expensive to compute. For the simple cases, --points-at already
does the right thing.

[more on that below, though...]

> @@ -604,7 +606,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
>  	if (!delete && !rename && !edit_description && !new_upstream && !unset_upstream && argc == 0)
>  		list = 1;
>  
> -	if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE || filter.points_at.nr)
> +	if (filter.with_commit || filter.no_commit || filter.merge != REF_FILTER_MERGED_NONE || filter.points_at.nr)
>  		list = 1;

Could we wrap this long conditional?

> diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
> index df41fa0350..a11542c4fd 100644
> --- a/builtin/for-each-ref.c
> +++ b/builtin/for-each-ref.c
> @@ -9,7 +9,7 @@ static char const * const for_each_ref_usage[] = {
>  	N_("git for-each-ref [<options>] [<pattern>]"),
>  	N_("git for-each-ref [--points-at <object>]"),
>  	N_("git for-each-ref [(--merged | --no-merged) [<object>]]"),
> -	N_("git for-each-ref [--contains [<object>]]"),
> +	N_("git for-each-ref [(--contains | --no-contains) [<object>]]"),
>  	NULL

I'm not sure if this presentation implies that the two cannot be used
together. It copies "--merged/--no-merged", but I think those two
_can't_ be used together (it probably wouldn't be hard to make it work,
but if nobody cares it may not be worth spending time on).

I also wonder if we need to explicitly document that --contains and
--no-contains can be used together and don't cancel each other. The
other option is to pick a new name ("--omits" is the most concise one I
could think of; maybe that is preferable anyway because it avoids
negation).

> @@ -457,7 +459,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
>  	if (!cmdmode && !create_tag_object) {
>  		if (argc == 0)
>  			cmdmode = 'l';
> -		else if (filter.with_commit || filter.points_at.nr || filter.merge_commit || filter.lines != -1)
> +		else if (filter.with_commit || filter.no_commit || filter.points_at.nr || filter.merge_commit || filter.lines != -1)

Ditto here on the wrapping. There were a few other long lines, but I
won't point them all out.

> -		/* We perform the filtering for the '--contains' option */
> +		/* We perform the filtering for the '--contains' option... */
>  		if (filter->with_commit &&
> -		    !commit_contains(filter, commit, &ref_cbdata->contains_cache))
> +		    !commit_contains(filter, commit, filter->with_commit, &ref_cbdata->contains_cache))
> +			return 0;
> +		/* ...or for the `--no-contains' option */
> +		if (filter->no_commit &&
> +		    commit_contains(filter, commit, filter->no_commit, &ref_cbdata->no_contains_cache))
>  			return 0;

This looks nice and simple. Good.

> +# As the docs say, list tags which contain a specified *commit*. We
> +# don't recurse down to tags for trees or blobs pointed to by *those*
> +# commits.
> +test_expect_success 'Does --[no-]contains stop at commits? Yes!' '
> +	cd no-contains &&
> +	blob=$(git rev-parse v0.3:v0.3.t) &&
> +	tree=$(git rev-parse v0.3^{tree}) &&
> +	git tag tag-blob $blob &&
> +	git tag tag-tree $tree &&
> +	git tag --contains v0.3 >actual &&
> +	cat >expected <<-\EOF &&
> +	v0.3
> +	v0.4
> +	v0.5
> +	EOF
> +	test_cmp expected actual &&
> +	git tag --no-contains v0.3 >actual &&
> +	cat >expected <<-\EOF &&
> +	v0.1
> +	v0.2
> +	EOF
> +	test_cmp expected actual
> +'

The tests mostly look fine, but this one puzzled me. I guess we're
checking that tag-blob does not contain v0.3. But how could it?

The more interesting test to me is:

  git tag --contains $blob

which should barf on a non-commit.

For the --no-contains side, you could argue that the blob-tag doesn't
contain the commit, and it should be listed. But it looks like we just
drop all non-commit tags completely as soon as we start to do a
contains/not-contains traversal.

I think the more relevant comparison is "--no-merged", and it behaves
the same way as your new --no-contains. I don't think I saw this
subtlety in the documentation, though. It might be worth mentioning
(unless I just missed it).

-Peff

  reply	other threads:[~2017-03-20  4:25 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-18 10:32 [PATCH 0/8] Various changes to the "tag" command Ævar Arnfjörð Bjarmason
2017-03-18 10:32 ` [PATCH 1/8] tag: Remove a TODO item from the test suite Ævar Arnfjörð Bjarmason
2017-03-18 18:14   ` Junio C Hamano
2017-03-18 18:42     ` [PATCH 0/2] doc/SubmittingPatches: A couple of minor improvements Ævar Arnfjörð Bjarmason
2017-03-18 18:42     ` [PATCH 1/2] doc/SubmittingPatches: clarify the casing convention for "area: change..." Ævar Arnfjörð Bjarmason
2017-03-18 19:04       ` Junio C Hamano
2017-03-18 19:16         ` Ævar Arnfjörð Bjarmason
2017-03-18 20:07           ` Junio C Hamano
2017-03-18 18:42     ` [PATCH 2/2] doc/SubmittingPatches: show how to get a CLI commit summary Ævar Arnfjörð Bjarmason
2017-03-18 19:07       ` Junio C Hamano
2017-03-21 14:21         ` [PATCH v2 0/2] A couple of minor improvements Ævar Arnfjörð Bjarmason
2017-03-21 14:21         ` [PATCH v2 1/2] doc/SubmittingPatches: clarify the casing convention for "area: change..." Ævar Arnfjörð Bjarmason
2017-03-21 14:21         ` [PATCH v2 2/2] doc/SubmittingPatches: show how to get a CLI commit summary Ævar Arnfjörð Bjarmason
2017-03-21 15:51           ` SZEDER Gábor
2017-03-21 17:58             ` Junio C Hamano
2017-03-21 18:47               ` Ævar Arnfjörð Bjarmason
2017-03-21 20:01               ` SZEDER Gábor
2017-03-21 20:13                 ` Junio C Hamano
2017-03-19  0:48   ` [PATCH 1/8] tag: Remove a TODO item from the test suite Jakub Narębski
2017-03-19  6:43     ` Ævar Arnfjörð Bjarmason
2017-03-18 10:32 ` [PATCH 2/8] tag: Refactor the options handling code to be less bizarro Ævar Arnfjörð Bjarmason
2017-03-18 18:35   ` Junio C Hamano
2017-03-18 19:13     ` Ævar Arnfjörð Bjarmason
2017-03-18 19:27       ` Junio C Hamano
2017-03-18 20:00         ` Ævar Arnfjörð Bjarmason
2017-03-18 10:32 ` [PATCH 3/8] tag: Change misleading --list <pattern> documentation Ævar Arnfjörð Bjarmason
2017-03-18 18:43   ` Junio C Hamano
2017-03-18 19:49     ` Ævar Arnfjörð Bjarmason
2017-03-20  3:44     ` Jeff King
2017-03-20 15:55       ` Junio C Hamano
2017-03-20 17:07         ` Junio C Hamano
2017-03-20 16:09       ` Ævar Arnfjörð Bjarmason
2017-03-20 16:11         ` Jeff King
2017-03-18 10:32 ` [PATCH 4/8] tag: Implicitly supply --list given another list-like option Ævar Arnfjörð Bjarmason
2017-03-20  3:55   ` Jeff King
2017-03-20  9:16     ` Ævar Arnfjörð Bjarmason
2017-03-18 10:32 ` [PATCH 5/8] tag: Implicitly supply --list given the -n option Ævar Arnfjörð Bjarmason
2017-03-20  4:02   ` Jeff King
2017-03-18 10:32 ` [PATCH 6/8] ref-filter: Add --no-contains option to tag/branch/for-each-ref Ævar Arnfjörð Bjarmason
2017-03-20  4:25   ` Jeff King [this message]
2017-03-20  9:32     ` Ævar Arnfjörð Bjarmason
2017-03-20 19:52       ` Jeff King
2017-03-20 20:04         ` Ævar Arnfjörð Bjarmason
2017-03-18 10:32 ` [PATCH 7/8] tag: Add tests for --with and --without Ævar Arnfjörð Bjarmason
2017-03-18 10:32 ` [PATCH 8/8] tag: Change --point-at to default to HEAD Ævar Arnfjörð Bjarmason
2017-03-18 18:54   ` Junio C Hamano
2017-03-18 19:52     ` Ævar Arnfjörð Bjarmason
2017-03-20  4:26 ` [PATCH 0/8] Various changes to the "tag" command Jeff King
2017-03-20 15:57   ` Junio C Hamano

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

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

  git send-email \
    --in-reply-to=20170320042519.srtavoxhm3fln5mw@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=avarab@gmail.com \
    --cc=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=hjemli@gmail.com \
    --cc=jasampler@gmail.com \
    --cc=sam@rfc1149.net \
    --cc=tmgrennan@gmail.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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.