Subject: Re: git clone with --dissociate sometimes fails to check out target commit

From: Rasmus Villemoes <[email-masked]>
Date: Mon, 04 May 2026 13:36:46 +0200

On Mon, May 04 2026, Jeff King <[email-masked]> wrote:

> On Mon, May 04, 2026 at 10:20:32AM +0200, Rasmus Villemoes wrote:
>
>> Are we using --dissociate wrongly, or are we perhaps not maintaining
>> those local mirror repos properly? They are essentially just created
>> with 'git clone --mirror', with 'git remote update' run periodically.
>> 
>> Naively, I'd expect the effects of --dissociate to only happen after
>> everything else the clone command does has been done, but it seems that
>> the ties to the reference repo are cut too soon.
>
> No, you're using it correctly. The dissociate step should copy all of
> the shared objects into the new repo, so it shouldn't matter whether we
> do it before or after checkout. The objects are there either way.
>
[snip]
>
> It's kind of ugly, but I think may be the least-bad solution. See that
> earlier thread for more discussion of alternatives.
>
> In the meantime, doing your dissociate clone with:
>
>   git -c core.commitGraph=false clone ...
>
> should work around the problem.

Thanks for the extremely fast reply, analysis, patch and workaround!

I can confirm that the commit graph disabling workaround works on both
the Debian and Arch machines.

I can also confirm that the patch applied on top of v2.54.0 works,
although the build does throw this warning:

commit.c: In function ‘get_commit_tree_oid’:                                                                                                                                                                          
commit.c:481:66: warning: passing argument 2 of ‘repo_get_commit_tree’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]                                                                   
  481 |         struct tree *tree = repo_get_commit_tree(the_repository, commit);                                                                                                                                     
      |                                                                  ^~~~~~                                                                                                                                       
commit.c:459:50: note: expected ‘struct commit *’ but argument is of type ‘const struct commit *’                                                                                                                     
  459 |                                   struct commit *commit)                                                                                                                                                      
      |                                   ~~~~~~~~~~~~~~~^~~~~~                                                          

Thanks again,
Rasmus