diff mbox series

[3/5] commit-graph: validate layers for generation data

Message ID d554fa306601c9e5e0e804d10b7a73b6eece6b04.1612199707.git.gitgitgadget@gmail.com (mailing list archive)
State Superseded
Headers show
Series Generation Number v2: Fix a tricky split graph bug | expand

Commit Message

Derrick Stolee Feb. 1, 2021, 5:15 p.m. UTC
From: Derrick Stolee <dstolee@microsoft.com>

We need to be extra careful that we don't use corrected
commit dates from any layer of a commit-graph chain if there is a
single commit-graph file that is missing the generation_data chunk.
Update validate_mixed_generation_chain() to correctly update each
layer to ignore the generation_data chunk in this case. It now also
returns 1 if all layers have a generation_data chunk. This return
value will be used in the next change.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
 commit-graph.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

Comments

Taylor Blau Feb. 1, 2021, 5:39 p.m. UTC | #1
On Mon, Feb 01, 2021 at 05:15:05PM +0000, Derrick Stolee via GitGitGadget wrote:
> diff --git a/commit-graph.c b/commit-graph.c
> index edbb3a0f2cc..13992137dd0 100644
> --- a/commit-graph.c
> +++ b/commit-graph.c
> @@ -614,19 +614,26 @@ static struct commit_graph *load_commit_graph_chain(struct repository *r,
>  	return graph_chain;
>  }
>
> -static void validate_mixed_generation_chain(struct commit_graph *g)
> +/*
> + * returns 1 if and only if all graphs in the chain have
> + * corrected commit dates stored in the generation_data chunk.
> + */
> +static int validate_mixed_generation_chain(struct commit_graph *g)

Thanks for the comment. It does make me wonder if the function name
needs updating, though. I'm having some trouble coming up with a better
alternative, though, so maybe it's fine...

>  {
> -	int read_generation_data;
> +	int read_generation_data = 1;

OK, we might not ever enter the while loops below, so this needs
initializing.

> +	struct commit_graph *p = g;
>
> -	if (!g)
> -		return;
> -
> -	read_generation_data = !!g->chunk_generation_data;
> +	while (read_generation_data && p) {
> +		read_generation_data = p->read_generation_data;
> +		p = p->base_graph;
> +	}

This could probably be guarded with an 'if !read_generation_data', since
if the previous while loop always read '1' from
'p->read_generation_data', then nothing needs updating, no?

(If you do make this change, please don't add '!read_generation_data' to
the while expression, since it isn't a property of the loop.)

>  	while (g) {
>  		g->read_generation_data = read_generation_data;
>  		g = g->base_graph;
>  	}
> +
> +	return read_generation_data;
>  }
>
>  struct commit_graph *read_commit_graph_one(struct repository *r,
> --
> gitgitgadget
>

Thanks,
Taylor
Derrick Stolee Feb. 1, 2021, 6:10 p.m. UTC | #2
On 2/1/2021 12:39 PM, Taylor Blau wrote:
> On Mon, Feb 01, 2021 at 05:15:05PM +0000, Derrick Stolee via GitGitGadget wrote:
>> +	struct commit_graph *p = g;
>>
>> -	if (!g)
>> -		return;
>> -
>> -	read_generation_data = !!g->chunk_generation_data;
>> +	while (read_generation_data && p) {
>> +		read_generation_data = p->read_generation_data;
>> +		p = p->base_graph;
>> +	}
> 
> This could probably be guarded with an 'if !read_generation_data', since
> if the previous while loop always read '1' from
> 'p->read_generation_data', then nothing needs updating, no?
> 
> (If you do make this change, please don't add '!read_generation_data' to
> the while expression, since it isn't a property of the loop.)

True, we could do that. It's enough to add

	if (read_generation_data)
		return 1;

>>  	while (g) {
>>  		g->read_generation_data = read_generation_data;
>>  		g = g->base_graph;
>>  	}
>> +
>> +	return read_generation_data;

then this becomes

	return 0;

Thanks,
-Stolee
diff mbox series

Patch

diff --git a/commit-graph.c b/commit-graph.c
index edbb3a0f2cc..13992137dd0 100644
--- a/commit-graph.c
+++ b/commit-graph.c
@@ -614,19 +614,26 @@  static struct commit_graph *load_commit_graph_chain(struct repository *r,
 	return graph_chain;
 }
 
-static void validate_mixed_generation_chain(struct commit_graph *g)
+/*
+ * returns 1 if and only if all graphs in the chain have
+ * corrected commit dates stored in the generation_data chunk.
+ */
+static int validate_mixed_generation_chain(struct commit_graph *g)
 {
-	int read_generation_data;
+	int read_generation_data = 1;
+	struct commit_graph *p = g;
 
-	if (!g)
-		return;
-
-	read_generation_data = !!g->chunk_generation_data;
+	while (read_generation_data && p) {
+		read_generation_data = p->read_generation_data;
+		p = p->base_graph;
+	}
 
 	while (g) {
 		g->read_generation_data = read_generation_data;
 		g = g->base_graph;
 	}
+
+	return read_generation_data;
 }
 
 struct commit_graph *read_commit_graph_one(struct repository *r,