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

Re: [PATCH v2 2/2] shallow.c: use '{commit,rollback}_shallow_file'

From
Taylor Blau <me@ttaylorr.com>
Date
Jun 3, 2020, 04:52 UTC
Message-ID
<20200603045248.GA20266@syl.local>
In-Reply-To
<20200603034213.GB253041@google.com>
Hi Jonathan,
On Tue, Jun 02, 2020 at 08:42:13PM -0700, Jonathan Nieder wrote:
Show 44 quoted lines
> Hi,
>
> Taylor Blau wrote:
>
> > Signed-off-by: Taylor Blau <me@ttaylorr.com>
> > ---
> >  builtin/receive-pack.c   |  4 ++--
> >  commit.h                 |  2 ++
> >  fetch-pack.c             | 10 +++++-----
> >  shallow.c                | 30 +++++++++++++++++++++---------
> >  t/t5537-fetch-shallow.sh | 29 +++++++++++++++++++++++++++++
> >  5 files changed, 59 insertions(+), 16 deletions(-)
>
> I haven't investigated the cause yet, but I've run into an interesting
> bug that bisects to this commit.  Jay Conrod (cc-ed) reports:
>
> | I believe this is also the cause of Go toolchain test failures we've
> | been seeing. Go uses git to fetch dependencies.
> |
> | The problem we're seeing can be reproduced with the script below. It
> | should print "success". Instead, the git merge-base command fails
> | because the commit 7303f77963648d5f1ec5e55eccfad8e14035866c
> | (origin/master) has no history.
>
> -- 8< --
> #!/bin/bash
>
> set -euxo pipefail
> if [ -d legacytest ]; then
>   echo "legacytest directory already exists" >&2
>   exit 1
> fi
> mkdir legacytest
> cd legacytest
> git init --bare
> git config protocol.version 2
> git config fetch.writeCommitGraph true
> git remote add origin -- https://github.com/rsc/legacytest
> git fetch -f --depth=1 origin refs/heads/master:refs/heads/master
> git fetch -f origin 'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*'
> git fetch --unshallow -f origin
> git merge-base --is-ancestor -- v2.0.0 7303f77963648d5f1ec5e55eccfad8e14035866c
> echo success
> -- >8 --

Thanks to you and Jay for the report and reproduction script. Indeed, I can reproduce this on the tip of master (which is equivalent to v2.27.0 at the time of writing).

> The fetch.writeCommitGraph part is interesting.  When does a commit
> graph file get written in this sequence of operations?  In an
> unshallow operation, does the usual guard against writing a commit
> graph in a shallow repo get missed?

The last 'git fetch' is the one that writes the commit-graph. You can verify this by sticking a 'ls objects/info' after each 'git' invocation in your script.

Here's where things get weird, though. Prior to this patch, Git would pick up that the repository is shallow before unshallowing, but never invalidate this fact after unshallowing. That means that once we got to 'write_commit_graph', we'd exit immediately since it appears as if the repository is shallow.

In this patch, we don't do that anymore, since we rightly unset the fact that we are (were) shallow.

In a debugger, I ran your script and a 'git commit-graph write --split --reachable' side-by-side, and found an interesting discrepancy: some commits (loaded from 'copy_oids_to_commits') *don't* have their parents set when invoked from 'git fetch', but *do* when invoked as 'git commit-graph write ...'.

I'm not an expert in the object cache, but my hunch is that when we fetch these objects they're marked as parsed without having loaded their parents. When we load them again via 'lookup_object', we get objects that look parsed, but don't have parents where they otherwise should.

I'm going to CC Stolee to see if he has any thoughts on how to handle this and/or if my idea is on the right track.

Show 9 quoted lines
> "rm -fr objects/info/commit-graphs" recovers the full history in the
> repo, so this is not a case of writing the wrong shallows --- it's
> only a commit graph issue.
>
> I'll take a closer look, but thought I'd give others a chance to look
> to in case there's something obvious. :)
>
> Thanks,
> Jonathan

Thanks, Taylor

Previous: Jonathan NiederNext: Taylor Blau
Message 23 of 32 in “shallow.c: use 'reset_repository_shallow' when appropriate”
  1. shallow.c: use 'reset_repository_shallow' when appropriateTaylor Blau, Apr 21, 2020
  2. Junio C HamanoApr 21, 2020
  3. Taylor BlauApr 21, 2020
  4. Junio C HamanoApr 21, 2020
  5. Taylor BlauApr 21, 2020
  6. Junio C HamanoApr 21, 2020
  7. Jonathan TanApr 22, 2020
  8. Jonathan TanApr 22, 2020
  9. Junio C HamanoApr 22, 2020
  10. Taylor BlauApr 23, 2020
  11. 0/2 shallow.c: reset shallow-ness after updatingTaylor Blau, Apr 23, 2020
  12. 1/2 t5537: use test_write_lines, indented heredocs for readabilityTaylor Blau, Apr 23, 2020
  13. Jonathan NiederApr 23, 2020
  14. Taylor BlauApr 24, 2020
  15. Jonathan NiederApr 24, 2020
  16. Junio C HamanoApr 24, 2020
  17. 2/2 shallow.c: use '{commit,rollback}_shallow_file'Taylor Blau, Apr 23, 2020
  18. Jonathan NiederApr 23, 2020
  19. Jonathan TanApr 23, 2020
  20. Junio C HamanoApr 23, 2020
  21. Taylor BlauApr 24, 2020
  22. Jonathan NiederJun 3, 2020
  23. Taylor BlauJun 3, 2020
  24. Taylor BlauJun 3, 2020
  25. Derrick StoleeJun 3, 2020
  26. Taylor BlauJun 3, 2020
  27. Jonathan NiederJun 3, 2020
  28. Jonathan NiederJun 3, 2020
  29. Taylor BlauJun 3, 2020
  30. Jonathan NiederJun 3, 2020
  31. Taylor BlauJun 4, 2020
  32. Junio C HamanoApr 23, 2020

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.