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: git@vger.kernel.org
Subject: Re: [PATCH] index-pack: downgrade twice-resolved REF_DELTA to die()
Date: Mon, 3 Feb 2020 09:53:10 -0800	[thread overview]
Message-ID: <20200203175310.GA54832@syl.local> (raw)
In-Reply-To: <20200203144055.GA4170731@coredump.intra.peff.net>

On Mon, Feb 03, 2020 at 09:40:55AM -0500, Jeff King wrote:
> When we're resolving a REF_DELTA, we compare-and-swap its type from
> REF_DELTA to whatever real type the base object has, as discussed in
> ab791dd138 (index-pack: fix race condition with duplicate bases,
> 2014-08-29). If the old type wasn't a REF_DELTA, we consider that a
> BUG(). But as discussed in that commit, we might see this case whenever
> we try to resolve an object twice, which may happen because we have
> multiple copies of the base object.
>
> So this isn't a bug at all, but rather a sign that the input pack is
> broken. And indeed, this case is triggered already in t5309.5 and
> t5309.6, which create packs with delta cycles and duplicate bases. But
> we never noticed because those tests are marked expect_failure.
>
> Those tests were added by b2ef3d9ebb (test index-pack on packs with
> recoverable delta cycles, 2013-08-23), which was leaving the door open
> for cases that we theoretically _could_ handle. And when we see an
> already-resolved object like this, in theory we could keep going after
> confirming that the previously resolved child->real_type matches
> base->obj->real_type. But:
>
>   - enforcing the "only resolve once" rule here saves us from an
>     infinite loop in other parts of the code. If we keep going, then the
>     delta cycle in t5309.5 causes us to loop infinitely, as
>     find_ref_delta_children() doesn't realize which objects have already
>     been resolved. So there would be more changes needed to make this
>     case work, and in the meantime we'd be worse off.
>
>   - any pack that triggers this is broken anyway. It either has a
>     duplicate base object, or it has a cycle which causes us to bring in
>     a duplicate via --fix-thin. In either case, we'd end up rejecting
>     the pack in write_idx_file(), which also detects duplicates.
>
> So the tests have little value in documenting what we _could_ be doing
> (and have been neglected for 6+ years). Let's switch them to confirming
> that we handle this case cleanly (and switch out the BUG() for a more
> informative die() so that we do so).
>
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> Noticed while running the tests in an environment that complains about
> SIGABRT deaths. Arguably the test suite should be looking for these even
> in test_expect_failure, but it would be a little convoluted to do so
> (e.g., teaching BUG() to write to a marker file, and then checking the
> file). And I think we're better off phrasing things as much as possible
> as expect_success anyway.
>
>  builtin/index-pack.c         | 4 +++-
>  t/t5309-pack-delta-cycles.sh | 8 ++++----
>  2 files changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/builtin/index-pack.c b/builtin/index-pack.c
> index 60a5591039..41a7c11c8e 100644
> --- a/builtin/index-pack.c
> +++ b/builtin/index-pack.c
> @@ -1003,7 +1003,9 @@ static struct base_data *find_unresolved_deltas_1(struct base_data *base,
>
>  		if (!compare_and_swap_type(&child->real_type, OBJ_REF_DELTA,
>  					   base->obj->real_type))
> -			BUG("child->real_type != OBJ_REF_DELTA");
> +			die("REF_DELTA at offset %"PRIuMAX" already resolved (duplicate base %s?)",
> +			    (uintmax_t)child->idx.offset,
> +			    oid_to_hex(&base->obj->idx.oid));

This error message is informative, and matches what you described in the
patch message.

>  		resolve_delta(child, base, result);
>  		if (base->ref_first == base->ref_last && base->ofs_last == -1)
> diff --git a/t/t5309-pack-delta-cycles.sh b/t/t5309-pack-delta-cycles.sh
> index 491556dad9..6c209ad45c 100755
> --- a/t/t5309-pack-delta-cycles.sh
> +++ b/t/t5309-pack-delta-cycles.sh
> @@ -62,13 +62,13 @@ test_expect_success 'index-pack detects REF_DELTA cycles' '
>  	test_must_fail git index-pack --fix-thin --stdin <cycle.pack
>  '
>
> -test_expect_failure 'failover to an object in another pack' '
> +test_expect_success 'failover to an object in another pack' '
>  	clear_packs &&
>  	git index-pack --stdin <ab.pack &&
> -	git index-pack --stdin --fix-thin <cycle.pack
> +	test_must_fail git index-pack --stdin --fix-thin <cycle.pack
>  '
>
> -test_expect_failure 'failover to a duplicate object in the same pack' '
> +test_expect_success 'failover to a duplicate object in the same pack' '
>  	clear_packs &&
>  	{
>  		pack_header 3 &&
> @@ -77,7 +77,7 @@ test_expect_failure 'failover to a duplicate object in the same pack' '
>  		pack_obj $A
>  	} >recoverable.pack &&
>  	pack_trailer recoverable.pack &&
> -	git index-pack --fix-thin --stdin <recoverable.pack
> +	test_must_fail git index-pack --fix-thin --stdin <recoverable.pack
>  '

And these hunks all make sense, too.

>  test_done
> --
> 2.25.0.541.gdfd61ebb85

This looks great, thanks :-)

  Reviewed-by: Taylor Blau <me@ttaylorr.com>

Thanks,
Taylor

      reply	other threads:[~2020-02-03 17:53 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-31 23:24 [PATCH] doc: add documentation for git log --no-follow Étienne Servais
2020-02-01 11:16 ` Jeff King
2020-02-03 20:27   ` Étienne Servais
2020-02-03 14:40 ` [PATCH] index-pack: downgrade twice-resolved REF_DELTA to die() Jeff King
2020-02-03 17:53   ` Taylor Blau [this message]

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=20200203175310.GA54832@syl.local \
    --to=me@ttaylorr.com \
    --cc=git@vger.kernel.org \
    --cc=peff@peff.net \
    /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).