From: Taylor Blau <me@ttaylorr.com>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org, Derrick Stolee <derrickstolee@github.com>
Subject: Re: [RFC/PATCH] commit-graph: verify swapped zero/non-zero generation cases
Date: Thu, 10 Aug 2023 13:44:49 -0400 [thread overview]
Message-ID: <ZNUiEXF5CP6WMk9A@nand.local> (raw)
In-Reply-To: <ZNUJq2nFEDHwrF0U@nand.local>
On Thu, Aug 10, 2023 at 12:00:43PM -0400, Taylor Blau wrote:
> > There's a matching GENERATION_NUMBER_EXISTS value, which in theory would
> > be used to find the case that we see the entries in the opposite order:
> >
> > 1. When we see an entry with a non-zero generation, we set the
> > generation_zero flag to GENERATION_NUMBER_EXISTS.
> >
> > 2. When we later see an entry with a zero generation, we complain if
> > the flag is GENERATION_NUMBER_EXISTS.
> >
> > But that doesn't work; step 2 is implemented, but there is no step 1. We
> > never use NUMBER_EXISTS at all, and Coverity rightly complains that step
> > 2 is dead code.
>
> So I think the missing part is setting GENERATION_NUMBER_EXISTS when we
> have a non-zero generation number from the commit-graph, but have
> generation_zero set to GENERATION_ZERO_EXISTS (IOW, we have seen at
> least one commit with generation number 0).
>
> --- 8< ---
> diff --git a/commit-graph.c b/commit-graph.c
> index 0aa1640d15..935bc15440 100644
> --- a/commit-graph.c
> +++ b/commit-graph.c
> @@ -2676,9 +2676,11 @@ static int verify_one_commit_graph(struct repository *r,
> graph_report(_("commit-graph has generation number zero for commit %s, but non-zero elsewhere"),
> oid_to_hex(&cur_oid));
> generation_zero = GENERATION_ZERO_EXISTS;
> - } else if (generation_zero == GENERATION_ZERO_EXISTS)
> + } else if (generation_zero == GENERATION_ZERO_EXISTS) {
> graph_report(_("commit-graph has non-zero generation number for commit %s, but zero elsewhere"),
> oid_to_hex(&cur_oid));
> + generation_zero = GENERATION_NUMBER_EXISTS;
> + }
>
> if (generation_zero == GENERATION_ZERO_EXISTS)
> continue;
> --- >8 ---
OK, I investigated this a little bit more and now I think I understand
fully what's going on here.
There are a couple of things wrong with the diff that I posted above.
First, it has a logic error that we should set GENERATION_NUMBER_EXISTS
when we have a non-zero generation number from the graph, regardless of
whether or not GENERATION_ZERO_EXISTS is set (like how it is done in
your patch).
But more importantly, we'll never end up in the first arm of that
conditional as-is (the one that fires for when we see a generation
number of zero) as a consequence of 2ee11f7261 (commit-graph: return
generation from memory, 2023-03-20), which only returns non-zero
generation numbers (or GENERATION_NUMBER_INFINITY, which is also
non-zero).
I think you want something like `commit_graph_generation()` that returns
whatever is in `data->generation` regardless of whether or not it is
zero valued. You'd then want to use that function instead of calling
commit_graph_generation() directly.
> > So I kind of wonder if there's something I'm not getting here. Coverity
> > is definitely right that our "step 2" is dead code (because we never set
> > NUMBER_EXISTS). But I'm not sure if we should be deleting it, or trying
> > to fix an underlying bug.
>
> I think that above is correct in that we should be fixing an underlying
> bug. But the fact that this isn't caught by our existing tests indicates
> that there is a gap in coverage. Let me see if I can find a test case
> that highlights this bug...
Doing the above allows me to write these two tests on top of your patch,
which both pass:
--- &< ---
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index 4df76173a8..8e96471b34 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -450,14 +450,15 @@ GRAPH_BYTE_FANOUT2=$(($GRAPH_FANOUT_OFFSET + 4 * 255))
GRAPH_OID_LOOKUP_OFFSET=$(($GRAPH_FANOUT_OFFSET + 4 * 256))
GRAPH_BYTE_OID_LOOKUP_ORDER=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * 8))
GRAPH_BYTE_OID_LOOKUP_MISSING=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * 4 + 10))
+GRAPH_COMMIT_DATA_WIDTH=$(($HASH_LEN + 16))
GRAPH_COMMIT_DATA_OFFSET=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * $NUM_COMMITS))
GRAPH_BYTE_COMMIT_TREE=$GRAPH_COMMIT_DATA_OFFSET
GRAPH_BYTE_COMMIT_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN))
GRAPH_BYTE_COMMIT_EXTRA_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 4))
GRAPH_BYTE_COMMIT_WRONG_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 3))
GRAPH_BYTE_COMMIT_GENERATION=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 11))
+GRAPH_BYTE_COMMIT_GENERATION_LAST=$(($GRAPH_BYTE_COMMIT_GENERATION + $(($NUM_COMMITS - 1)) * $GRAPH_COMMIT_DATA_WIDTH))
GRAPH_BYTE_COMMIT_DATE=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 12))
-GRAPH_COMMIT_DATA_WIDTH=$(($HASH_LEN + 16))
GRAPH_OCTOPUS_DATA_OFFSET=$(($GRAPH_COMMIT_DATA_OFFSET + \
$GRAPH_COMMIT_DATA_WIDTH * $NUM_COMMITS))
GRAPH_BYTE_OCTOPUS=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4))
@@ -596,11 +597,6 @@ test_expect_success 'detect incorrect generation number' '
"generation for commit"
'
-test_expect_success 'detect incorrect generation number' '
- corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION "\01" \
- "commit-graph generation for commit"
-'
-
test_expect_success 'detect incorrect commit date' '
corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_DATE "\01" \
"commit date"
@@ -622,6 +618,16 @@ test_expect_success 'detect incorrect chunk count' '
$GRAPH_CHUNK_LOOKUP_OFFSET
'
+test_expect_success 'detect mixed generation numbers (non-zero to zero)' '
+ corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION_LAST "\0\0\0\0" \
+ "but non-zero elsewhere"
+'
+
+test_expect_success 'detect mixed generation numbers (zero to non-zero)' '
+ corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION "\0\0\0\0" \
+ "but zero elsewhere"
+'
+
test_expect_success 'git fsck (checks commit-graph when config set to true)' '
git -C full fsck &&
corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \
--- >8 ---
Note that we remove the duplicate "detect incorrect generation number"
test, which was originally introduced in 1373e547f7 (commit-graph:
verify generation number, 2018-06-27), but was modified in 2ee11f7261.
That test is replaced by the latter "non-zero to zero" variant.
Thanks,
Taylor
next prev parent reply other threads:[~2023-08-10 17:44 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-08 19:15 [RFC/PATCH] commit-graph: verify swapped zero/non-zero generation cases Jeff King
2023-08-10 16:00 ` Taylor Blau
2023-08-10 17:44 ` Taylor Blau [this message]
2023-08-10 20:37 ` [PATCH 0/4] commit-graph: fsck zero/non-zero generation number fixes Taylor Blau
2023-08-10 20:37 ` [PATCH 1/4] commit-graph: introduce `commit_graph_generation_from_graph()` Taylor Blau
2023-08-10 20:37 ` [PATCH 2/4] commit-graph: verify swapped zero/non-zero generation cases Taylor Blau
2023-08-10 21:36 ` Junio C Hamano
2023-08-11 15:01 ` Jeff King
2023-08-11 17:08 ` Taylor Blau
2023-08-10 20:37 ` [PATCH 3/4] t/t5318-commit-graph.sh: test generation zero transitions during fsck Taylor Blau
2023-08-10 20:37 ` [PATCH 4/4] commit-graph: invert negated conditional Taylor Blau
2023-08-11 15:02 ` [PATCH 0/4] commit-graph: fsck zero/non-zero generation number fixes Jeff King
2023-08-11 17:05 ` [PATCH v2 0/5] " Taylor Blau
2023-08-11 17:05 ` [PATCH v2 1/5] commit-graph: introduce `commit_graph_generation_from_graph()` Taylor Blau
2023-08-11 17:05 ` [PATCH v2 2/5] commit-graph: verify swapped zero/non-zero generation cases Taylor Blau
2023-08-11 17:05 ` [PATCH v2 3/5] t/t5318-commit-graph.sh: test generation zero transitions during fsck Taylor Blau
2023-08-11 17:05 ` [PATCH v2 4/5] commit-graph: invert negated conditional, extract to function Taylor Blau
2023-08-11 17:05 ` [PATCH v2 5/5] commit-graph: avoid repeated mixed generation number warnings Taylor Blau
2023-08-11 17:58 ` [PATCH v2 0/5] commit-graph: fsck zero/non-zero generation number fixes Jeff King
2023-08-11 19:28 ` Junio C Hamano
2023-08-17 19:51 ` Jeff King
2023-08-21 21:25 ` Taylor Blau
2023-08-21 21:34 ` [PATCH v3 0/4] " Taylor Blau
2023-08-21 21:34 ` [PATCH v3 1/4] commit-graph: introduce `commit_graph_generation_from_graph()` Taylor Blau
2023-08-21 21:34 ` [PATCH v3 2/4] commit-graph: verify swapped zero/non-zero generation cases Taylor Blau
2023-08-21 21:34 ` [PATCH v3 3/4] t/t5318-commit-graph.sh: test generation zero transitions during fsck Taylor Blau
2023-08-21 21:34 ` [PATCH v3 4/4] commit-graph: commit-graph: avoid repeated mixed generation number warnings Taylor Blau
2023-08-21 21:55 ` [PATCH v3 0/4] commit-graph: fsck zero/non-zero generation number fixes Jeff King
2023-08-21 23:22 ` Junio C Hamano
2023-08-23 19:59 ` 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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZNUiEXF5CP6WMk9A@nand.local \
--to=me@ttaylorr.com \
--cc=derrickstolee@github.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.
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.