{"thread":{"id":"63939","subject":"Minor Bug in git cat-file (git 2.50)?","startedAt":"2025-08-10T14:52:44Z","lastAt":"2025-08-11T19:10:13Z","messageCount":4,"participants":["Jon Forrest","Patrick Steinhardt","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"523885","messageId":"b37629c6-b730-45ce-b839-e782aafe238d@gmail.com","threadId":"63939","inReplyTo":null,"subject":"Minor Bug in git cat-file (git 2.50)?","fromName":"Jon Forrest","fromEmail":"nobozo@gmail.com","sentAt":"2025-08-10T14:52:42Z","receivedAt":"2025-08-10T14:52:44Z","isPatch":false,"sender":{"key":"nobozo@gmail.com","avatar":"https://gravatar.com/avatar/37c6a7b57f29b3f35c6a9016537907c52f15bbf98575617dc046bcec6bf06372?d=mp&s=160"},"body":"(Sorry if you see this more than once)\n\nI'm using 'git cat-file' to show the example. This is probably not a\ncommand-specific problem.\n\nThe problem is that using a deliberately ambiguous object ID produces\nsurprising output. This is a minor issue.\n\n% git --version\ngit version 2.50.GIT\n% uname -a\nLinux fedora 6.15.9-201.fc42.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Aug  2 \n11:37:34 UTC 2025 x86_64 GNU/Linux\n\n% git init\n\n# depending on where you run the test, might not be necessary\n% git config --global --add safe.directory /tmp\n\nInitialized empty Git repository in /tmp/.git/\n% echo a > a.txt\n% git add a.txt\n% git ls-files -s\n100644 78981922613b2afb6025042ff6bd878ac1994e85 0       a.txt\t\n% git cat-file -t 78981922613b2afb6025042ff6bd878ac1994e85\nblob\n\n# All is well so far.\n\n% pushd .git/objects/78\n% ls\n981922613b2afb6025042ff6bd878ac1994e85\n# create a new file with the same name as the file that already exists,\n# except change the final letter to something else.\n% cp 981922613b2afb6025042ff6bd878ac1994e85 \n981922613b2afb6025042ff6bd878ac1994e86\n% ls\n981922613b2afb6025042ff6bd878ac1994e85 \n981922613b2afb6025042ff6bd878ac1994e86\n% popd\n# use an ambiguous SHA1 prefix\n# why does the next command produce two identical hints, both of which\n# are incorrect?\n% git cat-file -t 78981922613b2afb6025042ff6bd878ac1994e8\nerror: short object ID 78981922613b2afb6025042ff6bd878ac1994e8 is \nambiguous  # this is correct\nhint: The candidates are:\nhint:   7898192 blob\nhint:   7898192 blob\nfatal: Not a valid object name 78981922613b2afb6025042ff6bd878ac1994e8\n# I would have expected:\nhint:   78981922613b2afb6025042ff6bd878ac1994e85 blob\nhint:   78981922613b2afb6025042ff6bd878ac1994e86 blob\n# using the supplied hint doesn't work, which is no surprise\n% git cat-file -t 7898192\nfatal: Not a valid object name 7898192\n\nCordially,\nJon Forrest\n\n\n\n"},{"id":"523915","messageId":"aJmvykqFbsBJR_xk@pks.im","threadId":"63939","inReplyTo":"b37629c6-b730-45ce-b839-e782aafe238d@gmail.com","subject":"Re: Minor Bug in git cat-file (git 2.50)?","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-08-11T08:54:34Z","receivedAt":"2025-08-11T08:54:40Z","isPatch":false,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Sun, Aug 10, 2025 at 07:52:42AM -0700, Jon Forrest wrote:\n> (Sorry if you see this more than once)\n> \n> I'm using 'git cat-file' to show the example. This is probably not a\n> command-specific problem.\n> \n> The problem is that using a deliberately ambiguous object ID produces\n> surprising output. This is a minor issue.\n> \n> % git --version\n> git version 2.50.GIT\n> % uname -a\n> Linux fedora 6.15.9-201.fc42.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Aug  2\n> 11:37:34 UTC 2025 x86_64 GNU/Linux\n> \n> % git init\n> \n> # depending on where you run the test, might not be necessary\n> % git config --global --add safe.directory /tmp\n> \n> Initialized empty Git repository in /tmp/.git/\n> % echo a > a.txt\n> % git add a.txt\n> % git ls-files -s\n> 100644 78981922613b2afb6025042ff6bd878ac1994e85 0       a.txt\t\n> % git cat-file -t 78981922613b2afb6025042ff6bd878ac1994e85\n> blob\n> \n> # All is well so far.\n> \n> % pushd .git/objects/78\n> % ls\n> 981922613b2afb6025042ff6bd878ac1994e85\n> # create a new file with the same name as the file that already exists,\n> # except change the final letter to something else.\n> % cp 981922613b2afb6025042ff6bd878ac1994e85\n> 981922613b2afb6025042ff6bd878ac1994e86\n> % ls\n> 981922613b2afb6025042ff6bd878ac1994e85\n> 981922613b2afb6025042ff6bd878ac1994e86\n> % popd\n> # use an ambiguous SHA1 prefix\n> # why does the next command produce two identical hints, both of which\n> # are incorrect?\n> % git cat-file -t 78981922613b2afb6025042ff6bd878ac1994e8\n> error: short object ID 78981922613b2afb6025042ff6bd878ac1994e8 is ambiguous\n> # this is correct\n> hint: The candidates are:\n> hint:   7898192 blob\n> hint:   7898192 blob\n> fatal: Not a valid object name 78981922613b2afb6025042ff6bd878ac1994e8\n> # I would have expected:\n> hint:   78981922613b2afb6025042ff6bd878ac1994e85 blob\n> hint:   78981922613b2afb6025042ff6bd878ac1994e86 blob\n> # using the supplied hint doesn't work, which is no surprise\n> % git cat-file -t 7898192\n> fatal: Not a valid object name 7898192\n\nHm. I think the problem here is that you intentfully corrupt the\nrepository by copying the blob to a different name. As the object\ncontents itself remain the same though, and as the object ID is computed\nby hashing the object, looking up that object would ultimately lead to\nthe original object ID.\n\nThe consequence is that `show_ambiguous_object()` becomes confused. It\n_looks_ like the object name is ambiguous, but it ultimately isn't\nbecause both names refer to the same underlying object. We then use\n`repo_find_unique_abbrev()` to shorten the printed object IDs that are\nprinted in the error message, but given that those are really the same\nobject we abbreviate them to the same shortened object ID.\n\nI'm not really sure that this is something that we need to fix -- the\nrepository is corrupt, and git-fsck(1) should tell you so. Did you hit\nany real world scenario where this has happened in the wild without\nintentfully corrupting the repository? Or given that you explicitly\nmention Git 2.50, has the behaviour changed recently?\n\nThanks!\n\nPatrick\n"},{"id":"523950","messageId":"xmqqtt2d51zr.fsf@gitster.g","threadId":"63939","inReplyTo":"b37629c6-b730-45ce-b839-e782aafe238d@gmail.com","subject":"Re: Minor Bug in git cat-file (git 2.50)?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-08-11T15:09:28Z","receivedAt":"2025-08-11T15:09:30Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jon Forrest <nobozo@gmail.com> writes:\n\n> % ls\n> 981922613b2afb6025042ff6bd878ac1994e85\n> 981922613b2afb6025042ff6bd878ac1994e86\n> % popd\n> # use an ambiguous SHA1 prefix\n> # why does the next command produce two identical hints, both of which\n> # are incorrect?\n> % git cat-file -t 78981922613b2afb6025042ff6bd878ac1994e8\n> error: short object ID 78981922613b2afb6025042ff6bd878ac1994e8 is\n> ambiguous  # this is correct\n> hint: The candidates are:\n> hint:   7898192 blob\n> hint:   7898192 blob\n> fatal: Not a valid object name 78981922613b2afb6025042ff6bd878ac1994e8\n> # I would have expected:\n> hint:   78981922613b2afb6025042ff6bd878ac1994e85 blob\n> hint:   78981922613b2afb6025042ff6bd878ac1994e86 blob\n> # using the supplied hint doesn't work, which is no surprise\n> % git cat-file -t 7898192\n> fatal: Not a valid object name 7898192\n\nFun.\n\nI do not think disambiguation code inspects object validity to\nfilter out invalid one when computing the shortened object name when\ngiving hints, so one of these two being a corrupt object should not\nhave anything to do with this outcome.\n\nPerhaps something like this would help?\n\n object-name.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git c/object-name.c w/object-name.c\nindex 11aa0e6afc..13e8a4e47d 100644\n--- c/object-name.c\n+++ w/object-name.c\n@@ -704,7 +704,7 @@ static int extend_abbrev_len(const struct object_id *oid, void *cb_data)\n \twhile (mad->hex[i] && mad->hex[i] == get_hex_char_from_oid(oid, i))\n \t\ti++;\n \n-\tif (i < GIT_MAX_RAWSZ && i >= mad->cur_len)\n+\tif (i < GIT_MAX_HEXSZ && i >= mad->cur_len)\n \t\tmad->cur_len = i + 1;\n \n \treturn 0;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"},{"id":"523963","messageId":"ee87e67e-7551-428c-843e-1a4f57548f9f@gmail.com","threadId":"63939","inReplyTo":"aJmvykqFbsBJR_xk@pks.im","subject":"Re: Minor Bug in git cat-file (git 2.50)?","fromName":"Jon Forrest","fromEmail":"nobozo@gmail.com","sentAt":"2025-08-11T19:10:11Z","receivedAt":"2025-08-11T19:10:13Z","isPatch":false,"sender":{"key":"nobozo@gmail.com","avatar":"https://gravatar.com/avatar/37c6a7b57f29b3f35c6a9016537907c52f15bbf98575617dc046bcec6bf06372?d=mp&s=160"},"body":"\n\nOn 8/11/25 1:54 AM, Patrick Steinhardt wrote:\n\nThanks to you and Junio for looking at this.\n\nI agree that this shouldn't be considered a high priority\nbug.\n\nDo you agree that the below should be what I see?\n\n>> # I would have expected:\n>> hint:   78981922613b2afb6025042ff6bd878ac1994e85 blob\n>> hint:   78981922613b2afb6025042ff6bd878ac1994e86 blob\n\nThe reason I'm doing this is because, just for fun, I'm\ntrying to implement the disambiguation code in Go, and\nI needed a test case.\n\n> Hm. I think the problem here is that you intentfully corrupt the\n> repository by copying the blob to a different name. \n\nI didn't intentionally corrupt the repository but I couldn't think\nof any other way to do what I needed to do.\n\nHow would you have done this?\n\n> I'm not really sure that this is something that we need to fix -- the\n> repository is corrupt, and git-fsck(1) should tell you so.\n\nHere's what git-fsck said:\n\n% git fsck\nChecking ref database: 100% (1/1), done.\nerror: ee1a0d672b283dc03c94a266647e505ad340dc29: hash-path mismatch, \nfound at: .git/objects/ee/1a0d672b283dc03c94a266647e505ad340dc30\nChecking object directories: 100% (256/256), done.\ndangling tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904\ndangling tree d4607c312181a2fdbb66e8accb5b006156b6b733\n\n> Did you hit any real world scenario where this has happened\n > in the wild without intentfully corrupting the repository?\n\nNo\n\n > Or given that you explicitly mention Git 2.50, has the behaviour\n > changed recently?\n\nI mentioned Git 2.50 because I wanted to write a useful bug report.\nI have no idea if the behavior has changed.\n\nThanks for your work.\n\nJon\n\n"}]}