{"thread":{"id":"56780","subject":"Unexpected cat-file --batch-check output","startedAt":"2021-10-25T19:02:52Z","lastAt":"2021-10-27T08:08:16Z","messageCount":6,"participants":["Bryan Turner","Jeff King","Johannes Sixt"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"439580","messageId":"CAGyf7-HFGgkXsA-MXBOdiogDid+=F8jmqw0zxwQoUzha-jc1Hw@mail.gmail.com","threadId":"56780","inReplyTo":null,"subject":"Unexpected cat-file --batch-check output","fromName":"Bryan Turner","fromEmail":"bturner@atlassian.com","sentAt":"2021-10-25T19:02:38Z","receivedAt":"2021-10-25T19:02:52Z","isPatch":false,"sender":{"key":"bturner@atlassian.com","avatar":"https://gravatar.com/avatar/16bcf3167981c1ef7c804e502642366d888a35b0d0b0a4ca01fdc442aa1acb1e?d=mp&s=160"},"body":"I'm working with some users trying to reconcile an odd mismatch\nobserved in some Git output.\n\nRunning an ls-tree for a branch and path, limited to a single pattern\nwithin, shows this:\n/usr/bin/git ls-tree -z refs/heads/develop:path/to/parent – file\n100644 blob 4c8d566ed80a1554a059b97f7cd533a55bbd2ea8    file\n\nIf we then run cat-file --batch-check, though, we see this:\necho 'refs/heads/develop\nrefs/heads/develop:path/to/parent/file' | /usr/bin/git cat-file --batch-check\n28a05ce2e3079afcb32e4f1777b42971d7933a91 commit 259\ncc10f4b278086325aab2f95df97c807c7c6cd75e commit 330\n\nThere's a newline after the branch name, inside the single quotes,\nfollowed by the same branch name plus the full path. In this output,\nit comes back as a commit, though. Both commands were run with\nrefs/heads/develop at the same commit. I've checked for a .gitmodules\nfile and while they _do_ have submodules, they're at different,\nnon-intersecting paths to the one in question here.\n\nI can't share the actual repository (I don't have access to it\nmyself), but I'm hoping someone might have some ideas. I've never seen\nthis sort of mismatch before; for every path in the repositories I do\nhave access to that I've tried this for, the cat-file --batch-check\nalways shows \"commit\" (or \"tag\") for the ref, and then \"blob\" for the\nref+path. Submodules were the only thing I could think of, but that\ndoesn't appear to be the case. Could it be a subtree instead? How\nwould I check?\n\nThanks in advance for any ideas; I appreciate any help.\nBryan Turner\n"},{"id":"439582","messageId":"YXcC8jQbFsaqYN2M@coredump.intra.peff.net","threadId":"56780","inReplyTo":"CAGyf7-HFGgkXsA-MXBOdiogDid+=F8jmqw0zxwQoUzha-jc1Hw@mail.gmail.com","subject":"Re: Unexpected cat-file --batch-check output","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2021-10-25T19:18:10Z","receivedAt":"2021-10-25T19:19:28Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Oct 25, 2021 at 12:02:38PM -0700, Bryan Turner wrote:\n\n> I'm working with some users trying to reconcile an odd mismatch\n> observed in some Git output.\n> \n> Running an ls-tree for a branch and path, limited to a single pattern\n> within, shows this:\n> /usr/bin/git ls-tree -z refs/heads/develop:path/to/parent – file\n> 100644 blob 4c8d566ed80a1554a059b97f7cd533a55bbd2ea8    file\n> \n> If we then run cat-file --batch-check, though, we see this:\n> echo 'refs/heads/develop\n> refs/heads/develop:path/to/parent/file' | /usr/bin/git cat-file --batch-check\n> 28a05ce2e3079afcb32e4f1777b42971d7933a91 commit 259\n> cc10f4b278086325aab2f95df97c807c7c6cd75e commit 330\n\nThat's definitely odd. Some things I'd try:\n\n  - do other versions of cat-file behave differently (i.e., is it a\n    regression)?\n\n  - what does \"git rev-parse refs/heads/develop:path/to/parent/file\"\n    say? If it comes up with 4c8d566ed80, then the problem is cat-file\n    specific. If not, then it's a problem in the name resolution\n    routines.\n\n  - likewise, what does \"git cat-file -t cc10f4b27808\" say? I'd expect\n    it to really be a commit (a bug in batch-check's formatting routines\n    could show the wrong object, but I'd expect the oid to at least\n    match what ls-tree showed).\n\n  - Is there anything odd about the tree? E.g., duplicate entries, out\n    of order entries, etc? Examining \"ls-tree\" output might help, but\n    \"git fsck\" should also note any irregularities.\n\nAfter that, I'd probably start running \"cat-file --batch-check\" through\na debugger. I know you said you don't have access to the repository, but\nperhaps whoever does might be willing to run it through \"fast-export\n--anonymize\" and see if the bug persists?\n\n-Peff\n"},{"id":"439601","messageId":"CAGyf7-Gge72Cr39pEci8CNBiVWDO2O5MesrFRqafE-_ibHfR0g@mail.gmail.com","threadId":"56780","inReplyTo":"YXcC8jQbFsaqYN2M@coredump.intra.peff.net","subject":"Re: Unexpected cat-file --batch-check output","fromName":"Bryan Turner","fromEmail":"bturner@atlassian.com","sentAt":"2021-10-25T21:48:13Z","receivedAt":"2021-10-25T21:48:26Z","isPatch":false,"sender":{"key":"bturner@atlassian.com","avatar":"https://gravatar.com/avatar/16bcf3167981c1ef7c804e502642366d888a35b0d0b0a4ca01fdc442aa1acb1e?d=mp&s=160"},"body":"On Mon, Oct 25, 2021 at 12:18 PM Jeff King <peff@peff.net> wrote:\n>\n> On Mon, Oct 25, 2021 at 12:02:38PM -0700, Bryan Turner wrote:\n>\n> > I'm working with some users trying to reconcile an odd mismatch\n> > observed in some Git output.\n> >\n> > Running an ls-tree for a branch and path, limited to a single pattern\n> > within, shows this:\n> > /usr/bin/git ls-tree -z refs/heads/develop:path/to/parent – file\n> > 100644 blob 4c8d566ed80a1554a059b97f7cd533a55bbd2ea8    file\n> >\n> > If we then run cat-file --batch-check, though, we see this:\n> > echo 'refs/heads/develop\n> > refs/heads/develop:path/to/parent/file' | /usr/bin/git cat-file --batch-check\n> > 28a05ce2e3079afcb32e4f1777b42971d7933a91 commit 259\n> > cc10f4b278086325aab2f95df97c807c7c6cd75e commit 330\n>\n> That's definitely odd. Some things I'd try:\n>\n>   - do other versions of cat-file behave differently (i.e., is it a\n>     regression)?\n>\n>   - what does \"git rev-parse refs/heads/develop:path/to/parent/file\"\n>     say? If it comes up with 4c8d566ed80, then the problem is cat-file\n>     specific. If not, then it's a problem in the name resolution\n>     routines.\n>\n>   - likewise, what does \"git cat-file -t cc10f4b27808\" say? I'd expect\n>     it to really be a commit (a bug in batch-check's formatting routines\n>     could show the wrong object, but I'd expect the oid to at least\n>     match what ls-tree showed).\n\nI don't have that specific data, but one thing I do know is that\ncat-file -p prints commit contents:\n\n/usr/bin/git cat-file -p refs/heads/develop:path/to/parent/file\ntree c378146c918c05794e5fb1d1f6986c81ca866326\nparent 6cb6016c78c4c963311ca82fc53764141b0d3bdd\nauthor ...\ncommitter ...\n\n<Commit message starts here>\n\nOne other observation. I threw\ncc10f4b278086325aab2f95df97c807c7c6cd75e into Github's search, on a\nlark, since so much open source is there, and it actually finds that\ncommit in multiple repositories[1][2][3]\n\n[1] https://github.com/bitcoin-sv/bitcoin-sv/commit/cc10f4b278086325aab2f95df97c807c7c6cd75e\n[2] https://github.com/fakecoinbase/bitcoin-svslashbitcoin-sv/commit/cc10f4b278086325aab2f95df97c807c7c6cd75e\n[3] https://github.com/TuringBitchain/TuringBitchain/commit/cc10f4b278086325aab2f95df97c807c7c6cd75e\n\nNone of those repositories has a branch named \"develop\", and the\n\"file\" I've obscured here is not present in any of them, so while\nthere is clearly some ancestry in this repository with open source\nroots, it's evolved since then. Experimenting with some of the\n\"nearby\" files that are present in those public repositories, I have\nnot been able to reproduce the issue in any of them.\n\n>\n>   - Is there anything odd about the tree? E.g., duplicate entries, out\n>     of order entries, etc? Examining \"ls-tree\" output might help, but\n>     \"git fsck\" should also note any irregularities.\n\nI've sent some further commands, based on your suggestions, to the users.\n\n>\n> After that, I'd probably start running \"cat-file --batch-check\" through\n> a debugger. I know you said you don't have access to the repository, but\n> perhaps whoever does might be willing to run it through \"fast-export\n> --anonymize\" and see if the bug persists?\n\nfast-export --anonymize might be a way forward. Thanks for suggesting\nit (I always forget about it); I've mentioned it to the users.\n\nThanks Jeff; I appreciate your time/insights!\n\nBest regards,\nBryan Turner\n"},{"id":"439702","messageId":"CAGyf7-Gaphb9q=4cyT0BQa7oYGKXQQsU-XfqvoxfDyijehJO3Q@mail.gmail.com","threadId":"56780","inReplyTo":"YXcC8jQbFsaqYN2M@coredump.intra.peff.net","subject":"Re: Unexpected cat-file --batch-check output","fromName":"Bryan Turner","fromEmail":"bturner@atlassian.com","sentAt":"2021-10-26T23:58:49Z","receivedAt":"2021-10-26T23:59:06Z","isPatch":false,"sender":{"key":"bturner@atlassian.com","avatar":"https://gravatar.com/avatar/16bcf3167981c1ef7c804e502642366d888a35b0d0b0a4ca01fdc442aa1acb1e?d=mp&s=160"},"body":"A few quick updates to some of the questions:\n\nOn Mon, Oct 25, 2021 at 12:18 PM Jeff King <peff@peff.net> wrote:\n>\n> On Mon, Oct 25, 2021 at 12:02:38PM -0700, Bryan Turner wrote:\n>\n> > I'm working with some users trying to reconcile an odd mismatch\n> > observed in some Git output.\n> >\n> > Running an ls-tree for a branch and path, limited to a single pattern\n> > within, shows this:\n> > /usr/bin/git ls-tree -z refs/heads/develop:path/to/parent – file\n> > 100644 blob 4c8d566ed80a1554a059b97f7cd533a55bbd2ea8    file\n> >\n> > If we then run cat-file --batch-check, though, we see this:\n> > echo 'refs/heads/develop\n> > refs/heads/develop:path/to/parent/file' | /usr/bin/git cat-file --batch-check\n> > 28a05ce2e3079afcb32e4f1777b42971d7933a91 commit 259\n> > cc10f4b278086325aab2f95df97c807c7c6cd75e commit 330\n>\n> That's definitely odd. Some things I'd try:\n>\n>   - do other versions of cat-file behave differently (i.e., is it a\n>     regression)?\n\nThey're using Git 2.32 built from source on Ubuntu 20.04. I may see if\nthey can reinstall the 2.25.1 from focal's standard repositories and\nsee if it reproduces the issue. That said, they may not be\nable/willing to do it.\n\n>\n>   - what does \"git rev-parse refs/heads/develop:path/to/parent/file\"\n>     say? If it comes up with 4c8d566ed80, then the problem is cat-file\n>     specific. If not, then it's a problem in the name resolution\n>     routines.\n\n$ /usr/bin/git rev-parse refs/heads/develop\n28a05ce2e3079afcb32e4f1777b42971d7933a91\n$ /usr/bin/git rev-parse refs/heads/develop:path/to/parent/file\ncc10f4b278086325aab2f95df97c807c7c6cd75e\n\nSo it looks like rev-parse and cat-file --batch-check both exhibit the\nsame behavior.\n\nI also had them expand their cat-file --batch-check to include another\nfile in the same \"path/to/parent\" directory:\n$ echo 'refs/heads/develop\nrefs/heads/develop:path/to/parent/sibling\nrefs/heads/develop:path/to/parent/file' | /usr/bin/git cat-file --batch-check\n28a05ce2e3079afcb32e4f1777b42971d7933a91 commit 259\n2bfe7b4b7c7cdeb9653801d99b65dfefe5780dda blob 897\ncc10f4b278086325aab2f95df97c807c7c6cd75e commit 330\n\nSo the \"sibling\" file in the same directory comes out as a \"blob\", as expected.\n\nThey also ran an ls-tree for the directory without any globs:\n# /usr/bin/git ls-tree refs/heads/develop:path/to/parent\n100644 blob 2bfe7b4b7c7cdeb9653801d99b65dfefe5780dda    sibling\n100644 blob 4c8d566ed80a1554a059b97f7cd533a55bbd2ea8    file\n\nFor \"sibling\" the blob's ID matches what cat-file --batch-check shows,\nas I'd expect. There are several other tree entries, one \"tree\" and\nthe rest \"blob\", that I've omitted for brevity. All of their modes\nlook normal.\n\nI also had them check ls-tree for some parent levels:\n$ /usr/bin/git ls-tree refs/heads/develop:path -- to\n040000 tree 5244cd18e3d9de9002bdfcd18e173ca55c035084    to\n$ /usr/bin/git ls-tree refs/heads/develop:path/to -- parent\n040000 tree 2847dc49d79e8d66040047a9dd61376115bf8829    parent\n\nNothing out of the ordinary to my eye.\n\n>\n>   - likewise, what does \"git cat-file -t cc10f4b27808\" say? I'd expect\n>     it to really be a commit (a bug in batch-check's formatting routines\n>     could show the wrong object, but I'd expect the oid to at least\n>     match what ls-tree showed).\n\n$ /usr/bin/git cat-file -t cc10f4b278086325aab2f95df97c807c7c6cd75e\ncommit\n\n>\n>   - Is there anything odd about the tree? E.g., duplicate entries, out\n>     of order entries, etc? Examining \"ls-tree\" output might help, but\n>     \"git fsck\" should also note any irregularities.\n\n$ /usr/bin/git fsck --no-dangling\nChecking object directories: 100% (256/256), done.\nChecking object directories: 100% (256/256), done.\nChecking objects: 100% (122888/122888), done.\n\nThere's one alternate. No warnings, though.\n\n>\n> After that, I'd probably start running \"cat-file --batch-check\" through\n> a debugger. I know you said you don't have access to the repository, but\n> perhaps whoever does might be willing to run it through \"fast-export\n> --anonymize\" and see if the bug persists?\n\nI've asked them to double-check whether they can provide me with the\nrepository, or with an anonymized copy. At this point, it feels like\nthere's not a lot more I can do/check without access to data that\nreproduces the issue so I can attach a debugger.\n\nThanks again,\nBryan\n"},{"id":"439704","messageId":"YXirLGXsKj01uNGv@coredump.intra.peff.net","threadId":"56780","inReplyTo":"CAGyf7-Gaphb9q=4cyT0BQa7oYGKXQQsU-XfqvoxfDyijehJO3Q@mail.gmail.com","subject":"Re: Unexpected cat-file --batch-check output","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2021-10-27T01:28:12Z","receivedAt":"2021-10-27T01:28:16Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Oct 26, 2021 at 04:58:49PM -0700, Bryan Turner wrote:\n\n> >   - what does \"git rev-parse refs/heads/develop:path/to/parent/file\"\n> >     say? If it comes up with 4c8d566ed80, then the problem is cat-file\n> >     specific. If not, then it's a problem in the name resolution\n> >     routines.\n> \n> $ /usr/bin/git rev-parse refs/heads/develop\n> 28a05ce2e3079afcb32e4f1777b42971d7933a91\n> $ /usr/bin/git rev-parse refs/heads/develop:path/to/parent/file\n> cc10f4b278086325aab2f95df97c807c7c6cd75e\n> \n> So it looks like rev-parse and cat-file --batch-check both exhibit the\n> same behavior.\n\nOK, that's not too surprising, since they're using the same routines\nunder the hood. But that does imply that the problem is in the get_oid()\nfamily, which is what's doing that name to oid lookup.\n\nI don't recall us ever having a bug of this nature in the history of\nGit, nor do I think this code would have changed recently. But of course\nthere's a first time for everything.\n\nThe parser there isn't exactly left-to-right, so perhaps this particular\nname is stimulating some corner case. I imagine the answer is \"no\", or\nyou'd have said so already, but are there any unusual characters in the\nfilename path? Colons, curly braces, etc?\n\n> I also had them expand their cat-file --batch-check to include another\n> file in the same \"path/to/parent\" directory:\n> $ echo 'refs/heads/develop\n> refs/heads/develop:path/to/parent/sibling\n> refs/heads/develop:path/to/parent/file' | /usr/bin/git cat-file --batch-check\n> 28a05ce2e3079afcb32e4f1777b42971d7933a91 commit 259\n> 2bfe7b4b7c7cdeb9653801d99b65dfefe5780dda blob 897\n> cc10f4b278086325aab2f95df97c807c7c6cd75e commit 330\n> \n> So the \"sibling\" file in the same directory comes out as a \"blob\", as expected.\n\nInteresting. That again points to their being something funny either\nwith this filename, or perhaps with the tree that contains it.\n\n> >   - likewise, what does \"git cat-file -t cc10f4b27808\" say? I'd expect\n> >     it to really be a commit (a bug in batch-check's formatting routines\n> >     could show the wrong object, but I'd expect the oid to at least\n> >     match what ls-tree showed).\n> \n> $ /usr/bin/git cat-file -t cc10f4b278086325aab2f95df97c807c7c6cd75e\n> commit\n\nThat's not too surprising. I did wonder if refs/replace or something\ncould be at work here, but I think in that case we'd still report the\nexpected oid. At any rate, we can probably rule that out as rev-parse is\nreturning the same unexpected oid, which means the problem is during the\nname resolution (and we shouldn't respect refs/replace there at all; we\nwould respect it while reading the outer tree, but then so would your\nls-tree, etc).\n\n> I've asked them to double-check whether they can provide me with the\n> repository, or with an anonymized copy. At this point, it feels like\n> there's not a lot more I can do/check without access to data that\n> reproduces the issue so I can attach a debugger.\n\nAnother possibility, if they would run a custom Git on their end, is to\nprovide them with a patch that cranks up the debugging output from\nget_oid_with_context_1(). Though I feel like it's hard to know where to\nsprinkle printf()s until we know where things go wrong. Is it\nmisinterpreting the name, and not realizing it's a tree:path name? Or is\nget_tree_entry() at fault? That kind of thing is much easier to figure\nout interactively in a debugger.\n\n-Peff\n"},{"id":"439727","messageId":"ad21b3f5-d352-64f4-0dd2-5ad1e839193a@kdbg.org","threadId":"56780","inReplyTo":"CAGyf7-Gaphb9q=4cyT0BQa7oYGKXQQsU-XfqvoxfDyijehJO3Q@mail.gmail.com","subject":"Re: Unexpected cat-file --batch-check output","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2021-10-27T08:08:11Z","receivedAt":"2021-10-27T08:08:16Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 27.10.21 um 01:58 schrieb Bryan Turner:\n> $ /usr/bin/git rev-parse refs/heads/develop\n> 28a05ce2e3079afcb32e4f1777b42971d7933a91\n> $ /usr/bin/git rev-parse refs/heads/develop:path/to/parent/file\n> cc10f4b278086325aab2f95df97c807c7c6cd75e\n> \n> So it looks like rev-parse and cat-file --batch-check both exhibit the\n> same behavior.\n> \n> I also had them expand their cat-file --batch-check to include another\n> file in the same \"path/to/parent\" directory:\n> $ echo 'refs/heads/develop\n> refs/heads/develop:path/to/parent/sibling\n> refs/heads/develop:path/to/parent/file' | /usr/bin/git cat-file --batch-check\n> 28a05ce2e3079afcb32e4f1777b42971d7933a91 commit 259\n> 2bfe7b4b7c7cdeb9653801d99b65dfefe5780dda blob 897\n> cc10f4b278086325aab2f95df97c807c7c6cd75e commit 330\n> \n> So the \"sibling\" file in the same directory comes out as a \"blob\", as expected.\n> \n> They also ran an ls-tree for the directory without any globs:\n> # /usr/bin/git ls-tree refs/heads/develop:path/to/parent\n> 100644 blob 2bfe7b4b7c7cdeb9653801d99b65dfefe5780dda    sibling\n> 100644 blob 4c8d566ed80a1554a059b97f7cd533a55bbd2ea8    file\n\nJust a shot in the dark: what happens when you use /usr/bin/git\n--no-replace-objects?\n\n-- Hannes\n"}]}