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

Re: Fetching upstream remote fails if repo was a blobless clone

From
Jeff King <peff@peff.net>
Date
Aug 2, 2025, 19:55 UTC
Message-ID
<20250802195518.GA1800293@coredump.intra.peff.net>
In-Reply-To
<20250802193110.GA1774743@coredump.intra.peff.net>
On Sat, Aug 02, 2025 at 03:31:11PM -0400, Jeff King wrote:
Show 28 quoted lines
> Doing this:
> 
> diff --git a/builtin/index-pack.c b/builtin/index-pack.c
> index 0a5c8a1ac8..e01cf7238b 100644
> --- a/builtin/index-pack.c
> +++ b/builtin/index-pack.c
> @@ -262,9 +262,14 @@ static unsigned check_object(struct object *obj)
>  		unsigned long size;
>  		int type = odb_read_object_info(the_repository->objects,
>  						&obj->oid, &size);
> -		if (type <= 0)
> +		if (type <= 0) {
> +			if (is_promisor_object(the_repository, &obj->oid)) {
> +				obj->flags |= FLAG_CHECKED;
> +				return 1;
> +			}
>  			die(_("did not receive expected object %s"),
>  			      oid_to_hex(&obj->oid));
> +		}
>  		if (type != obj->type)
>  			die(_("object %s: expected type %s, found %s"),
>  			    oid_to_hex(&obj->oid),
> 
> makes the problem go away. But I feel like I'm probably missing
> something (and that function is rather expensive to run, though maybe
> not so bad if the alternative is crashing).
> 
> +cc Jonathan Tan as the author of the code comment above for any wisdom.

And here is a minimal reproduction that doesn't depend on any other repositories:

-- >8 --
# Server has two commits, with two blobs for file, old and new.
git init server
(
	cd server
	echo old >file
	git add .
	git commit -m old
	echo new >file
	git commit -am new
	git config uploadpack.allowfilter true
)
# The fork has built a new tree which mentions the old file.
git clone server fork
(
	cd fork
	git reset --hard HEAD^
	echo content >unrelated
	git add .
	git commit -m unrelated
)

# After our partial clone, we have the new blob (because we faulted it in to # checkout), but not the old one (because it is buried in history). git clone --no-local --filter=blob:none server repo cd repo

# This will get the tree at the tip of the fork repo, which mentions old. When # we fsck that tree, we'll see that it mentions the old blob, and expect to # find it. But we won't due to the partial clone (though we could get it if we # wanted from the server repo). git -c transfer.fsckObjects=true fetch ../fork -- >8 --

That fails with stock git now, like this:
  fatal: did not receive expected object 3367afdbbf91e638efe983616377c60477cc6612
  fatal: index-pack failed
but succeeds with the patch above.
-Peff
Previous: Jeff King
Message 6 of 6 in “Fetching upstream remote fails if repo was a blobless clone”
  1. Justin SuAug 1, 2025
  2. Jeff KingAug 2, 2025
  3. Justin SuAug 2, 2025
  4. Justin SuAug 2, 2025
  5. Jeff KingAug 2, 2025
  6. Jeff KingAug 2, 2025

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.