git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v4 2/2] shallow: handling fetch relative-deepen

From
Samo Pogačnik <samo_pogacnik@t-2.net>
Date
Feb 13, 2026, 20:48 UTC
Message-ID
<0331ea3cef47b56ab920756fd66449e572667fee.camel@t-2.net>
In-Reply-To
<aYyGTmS6fEb2QfBU@pks.im>
On Wed, 2026-02-11 at 14:38 +0100, Patrick Steinhardt wrote:
Show 24 quoted lines
> On Fri, Jan 16, 2026 at 10:31:01PM +0000, Samo Pogačnik via GitGitGadget
> wrote:
> > diff --git a/shallow.c b/shallow.c
> > index 497a25836b..1a32808865 100644
> > --- a/shallow.c
> > +++ b/shallow.c
> > @@ -130,11 +130,12 @@ static void free_depth_in_slab(int **ptr)
> >  {
> >  	FREE_AND_NULL(*ptr);
> >  }
> > -struct commit_list *get_shallow_commits(struct object_array *heads, int
> > depth,
> > -		int shallow_flag, int not_shallow_flag)
> > +struct commit_list *get_shallow_commits(struct object_array *heads,
> > +					struct object_array *shallows, int
> > *deepen_relative,
> > +					int depth, int shallow_flag, int
> > not_shallow_flag)
> >  {
> > -	size_t i = 0;
> > -	int cur_depth = 0;
> > +	size_t i = 0, j;
> 
> We can declare `j` in the loop itself, as it's not used anywhere else.
Yes, sure.
Show 24 quoted lines
> 
> > @@ -168,16 +169,30 @@ struct commit_list *get_shallow_commits(struct
> > object_array *heads, int depth,
> >  		}
> >  		parse_commit_or_die(commit);
> >  		cur_depth++;
> > -		if ((depth != INFINITE_DEPTH && cur_depth >= depth) ||
> > -		    (is_repository_shallow(the_repository) && !commit-
> > >parents &&
> > -		     (graft = lookup_commit_graft(the_repository, &commit-
> > >object.oid)) != NULL &&
> > -		     graft->nr_parent < 0)) {
> > -			commit_list_insert(commit, &result);
> > -			commit->object.flags |= shallow_flag;
> > -			commit = NULL;
> > -			continue;
> > +		if (shallows) {
> > +			for (j = 0; j < shallows->nr; j++)
> > +				if (oideq(&commit->object.oid, &shallows-
> > >objects[j].item->oid))
> > +					if ((!cur_depth_shallow) ||
> > (cur_depth < cur_depth_shallow))
> 
> The additional braces around the respective conditions are not needed.
Of course.
Show 27 quoted lines
> 
> > +						cur_depth_shallow =
> > cur_depth;
> > +
> > +			if ((is_repository_shallow(the_repository) &&
> > !commit->parents &&
> > +			     (graft = lookup_commit_graft(the_repository,
> > &commit->object.oid)) != NULL &&
> > +			     graft->nr_parent < 0)) {
> > +				commit = NULL;
> > +				continue;
> > +			}
> 
> This block here is almost the same as the one below. But there's some
> confusing parts:
> 
>   - Why don't we update `result` at all?
> 
>   - Why don't we set the `shallow_flag`?
> 
>   - Why don't we have to check for the passed-in depth?
> 
> All of these parts feel somewhat surprising to me, as the function now
> behaves so wildly different depending on whether or not `shallows` was
> passed.
> 
> I guess this is because we really only care about `cur_depth_shallow`?

Exactly, i merged the two functions with almost the same algorithm producing different results depending on additional input parameter shallows. When shallows passed only current maximum absolute depth is returned in the extra output parameter deepen_relative (if provided) and nothing else is done. The passed-in depth is not checked as it is irrelevant for this depth-measuring scenario.

Show 16 quoted lines
> 
> > diff --git a/upload-pack.c b/upload-pack.c
> > index 2d2b70cbf2..4232eef34f 100644
> > --- a/upload-pack.c
> > +++ b/upload-pack.c
> > @@ -704,54 +704,11 @@ error:
> >  	return -1;
> >  }
> >  
> > -static int get_reachable_list(struct upload_pack_data *data,
> > -			      struct object_array *reachable)
> > +static void get_shallows_depth(struct upload_pack_data *data)
> 
> I think this function is rather pointless, as there is only a single
> caller and we only end up forwarding to `get_shallow_commits()`. Let's
> inline it.

True, i suppose you ment inline the function code instead of function call and not making the function inline?

Show 40 quoted lines
> 
> > @@ -881,29 +838,14 @@ static void deepen(struct upload_pack_data *data, int
> > depth)
> >  			struct object *object = data-
> > >shallows.objects[i].item;
> >  			object->flags |= NOT_SHALLOW;
> >  		}
> > -	} else if (data->deepen_relative) {
> > -		struct object_array reachable_shallows = OBJECT_ARRAY_INIT;
> > -		struct commit_list *result;
> > -
> > -		/*
> > -		 * Checking for reachable shallows requires that our refs
> > be
> > -		 * marked with OUR_REF.
> > -		 */
> > -
> > 		refs_head_ref_namespaced(get_main_ref_store(the_repository),
> > -					 check_ref, data);
> > -		for_each_namespaced_ref_1(check_ref, data);
> > -
> > -		get_reachable_list(data, &reachable_shallows);
> > -		result = get_shallow_commits(&reachable_shallows,
> > -					     depth + 1,
> > -					     SHALLOW, NOT_SHALLOW);
> > -		send_shallow(data, result);
> > -		free_commit_list(result);
> > -		object_array_clear(&reachable_shallows);
> >  	} else {
> >  		struct commit_list *result;
> >  
> > -		result = get_shallow_commits(&data->want_obj, depth,
> > +		if (data->deepen_relative)
> > +			get_shallows_depth(data);
> 
> Okay, so here we now essentially call `get_shallow_commits()` twice. The
> first time we compute `data->deepen_relative`, only to then pass it back
> to `get_shallow_commits()` a second time. That feels quite strange to
> me. Can't we have `get_shallow_commits()` handle this for us directly in
> a single call?

Nicely put, i just wasn't (and still am not) confident enough to change code in a way that would potentially affect any other scenarios than fetching relative- deepen.

Thank you very much for the review and i'll try to address all your review points in the next patch version.

Best regards, Samo
Previous: Patrick SteinhardtNext: Samo Pogačnik
Message 21 of 27 in “shallow: handling fetch relative-deepen”
  1. 0/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Dec 9, 2025
  2. 1/2 shallow: free local object_array allocationsSamo Pogačnik via GitGitGadget, Dec 9, 2025
  3. Patrick SteinhardtJan 6, 2026
  4. Samo PogačnikJan 9, 2026
  5. Patrick SteinhardtJan 9, 2026
  6. 2/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Dec 9, 2025
  7. Patrick SteinhardtJan 6, 2026
  8. Samo PogačnikJan 9, 2026
  9. 0/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Jan 9, 2026
  10. 1/2 shallow: free local object_array allocationsSamo Pogačnik via GitGitGadget, Jan 9, 2026
  11. 2/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Jan 9, 2026
  12. Junio C HamanoJan 10, 2026
  13. 0/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Jan 10, 2026
  14. 1/2 shallow: free local object_array allocationsSamo Pogačnik via GitGitGadget, Jan 10, 2026
  15. 2/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Jan 10, 2026
  16. Kristoffer HaugsbakkJan 15, 2026
  17. 0/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Jan 16, 2026
  18. 1/2 shallow: free local object_array allocationsSamo Pogačnik via GitGitGadget, Jan 16, 2026
  19. 2/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Jan 16, 2026
  20. Patrick SteinhardtFeb 11, 2026
  21. Samo PogačnikFeb 13, 2026
  22. Samo PogačnikFeb 14, 2026
  23. Samo PogačnikFeb 15, 2026
  24. 0/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Feb 15, 2026
  25. 1/2 shallow: free local object_array allocationsSamo Pogačnik via GitGitGadget, Feb 15, 2026
  26. 2/2 shallow: handling fetch relative-deepenSamo Pogačnik via GitGitGadget, Feb 15, 2026
  27. Junio C HamanoFeb 20, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.