{"thread":{"id":"61654","subject":"bug with git describe --dirty --broken","startedAt":"2024-06-20T11:24:12Z","lastAt":"2024-06-21T17:31:44Z","messageCount":4,"participants":["Paul Millar","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"497397","messageId":"0fd230f6-a5c5-463d-8584-651ceff3cf99@desy.de","threadId":"61654","inReplyTo":null,"subject":"bug with git describe --dirty --broken","fromName":"Paul Millar","fromEmail":"paul.millar@desy.de","sentAt":"2024-06-20T11:14:24Z","receivedAt":"2024-06-20T11:24:12Z","isPatch":false,"sender":{"key":"paul.millar@desy.de","avatar":null},"body":"Thank you for filling out a Git bug report!\nPlease answer the following questions to help us understand your issue.\n\nWhat did you do before the bug happened? (Steps to reproduce your issue)\n\nmkdir test-container\ncd test-container\ncat >Dockerfile <<EOF\nFROM docker.io/debian:bookworm-slim\nWORKDIR /work\nRUN apt-get update && apt-get -y install git\nEOF\npodman build -t test-image .\n\nmkdir test-repo\ncd test-repo\ngit init echo \"Hello, world\" > README\ngit add README\ngit commit -m \"Initial commit\" README\ngit tag v1.0.0\n\ngit describe --tags --dirty --broken\n\npodman run -v `pwd`:/work --rm -it --entrypoint '[\"/usr/bin/git\",\n    \"describe\", \"--tags\", \"--dirty\", \"--broken\"]' test-image\n\n\nWhat did you expect to happen? (Expected behavior)\n\nI expect git, when running in the container, to identify that the repo \nis clean.\n\nWhat happened instead? (Actual behavior)\n\nWhen run within the container, git identifies the repo as dirty.  The \n'podman run' command returns\n\nv1.0.0-dirty\n\n\nWhat's different between what you expected and what actually happened?\n\nThe 'git' command is running within the container.\n\nAnything else you want to add:\n\nI believe the problem comes from two parts.\n\nFirst, when running within the container, the files seemed to be owned \nby user root.\n\n\n12:51 $ ls -l\ntotal 4\n-rw-r--r-- 1 paul paul 13 Jun 20 12:45 README\n\n\n12:49 $ podman run -v `pwd`:/work --rm -it --entrypoint '[\"ls\", \"-l\"]' \ntest-imag\ne\ntotal 4\n-rw-r--r-- 1 root root 13 Jun 20 10:45 README\n\n\nThis results in an inconsistency between the ownership information \ncontained within the .git/index file and the ownership information on \nthe filesystem when git is run within the container.\n\nSecond, when 'git describe' is run with the '--broken' flag then the \n'.git/index' file is not updated.  The ownership inconsistency then \ntriggers git's belief that the repo is dirty.\n\nIf the '--broken' flag is remove from the 'git describe' command then \nrunning the command directly and from the container give the same output.\n\n12:51 $ git describe --tags --dirty\nv1.0.0\n\n12:55 $ podman run -v `pwd`:/work --rm -it --entrypoint '[\"/usr/bin/git\",\n    \"describe\", \"--tags\", \"--dirty\"]' test-image\nv1.0.0\n\nIn this case, running the 'git describe' command (both in the container \nand directly) will update the '.git/index' file, and the correct output \nis presented.\n\n\nPlease review the rest of the bug report below.\nYou can delete any lines you don't wish to share.\n\n\n[System Info]\ngit version:\ngit version 2.39.2\ncpu: x86_64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nuname: Linux 6.1.0-21-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 \n(2024-05-03)\nx86_64\ncompiler info: gnuc: 12.2\nlibc info: glibc: 2.36\n$SHELL (typically, interactive shell): /bin/bash\n\n\n[Enabled Hooks]\nnot run from a git repository - no hooks to show\n\n\n"},{"id":"497413","messageId":"xmqqwmmjwnzs.fsf@gitster.g","threadId":"61654","inReplyTo":"0fd230f6-a5c5-463d-8584-651ceff3cf99@desy.de","subject":"Re: bug with git describe --dirty --broken","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-20T16:57:43Z","receivedAt":"2024-06-20T16:57:46Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Paul Millar <paul.millar@desy.de> writes:\n\n> When run within the container, git identifies the repo as dirty.  The\n> 'podman run' command returns\n>\n> v1.0.0-dirty\n>\n> Anything else you want to add:\n>\n> I believe the problem comes from two parts.\n>\n> First, when running within the container, the files seemed to be owned\n> by user root.\n> ...\n> This results in an inconsistency between the ownership information\n> contained within the .git/index file and the ownership information on\n> the filesystem when git is run within the container.\n\nIndeed.  You are running git in two separate environments with\ninconsistent worldview.  As many attributes of each file (like the\nlast modified timestamp and who owns the file) are recorded in the\nindex for files that were verified to be unmodified (this is done so\nthat by doing lstat() on a path and comparing the result with the\ninformation saved in the index, we can notice that the path was\nmodified without actually opening the file and looking at the\ncontents), after doing something (like \"git diff\") that causes this\ninformation updated while the files appear to be owned by you,\nswitching to the alternate world where the files appear to be owned\nby root and asking \"are these files modified?\", Git will trust what\nis in the index and report \"the index says they are owned by you but\nlstat() says otherwise; you must have modified them\".\n\nThe way we deal with such false positives is to \"refresh the index\".\n\nAnd it is done in \"git describe --dirty\" codepath, but not\n\"--broken\" codepath, which is the cause of the issue you discovered.\n\nThere is code snippet in builtin/describe.c that does:\n\n\tif (broken) {\n\t\trun 'git diff-index' in a subprocess\n\t\tuse the result from 'diff-index' unless the command\n\t\taborted\n\t} else if (dirty) {\n\t\trefresh the index\n\t\trun the equivalent of 'diff-index' in-core\n\t\tuse the result; if the in-core diff-index aborts,\n\t\tyou are dead already.\n\t}\n\nI _think_ the \"broken\" codepath should be taught to also run \"git\nupdate-index --refresh\" before it runs \"git diff-index\" (both in\ntheir own subprocesses, or run in the same subprocess sequencially,\nas if \"git update-index --refresh && git diff-index\" were run), and\nyour problem may disappear.\n\nThanks.\n"},{"id":"497492","messageId":"c4f5ae01-97fe-4e3a-94e2-72da75b9df83@desy.de","threadId":"61654","inReplyTo":"xmqqwmmjwnzs.fsf@gitster.g","subject":"Re: bug with git describe --dirty --broken","fromName":"Paul Millar","fromEmail":"paul.millar@desy.de","sentAt":"2024-06-21T12:07:26Z","receivedAt":"2024-06-21T12:07:36Z","isPatch":false,"sender":{"key":"paul.millar@desy.de","avatar":null},"body":"Hi Junio,\n\nThanks for your quick reply.\n\n> \tif (broken) {\n> \t\trun 'git diff-index' in a subprocess\n> \t\tuse the result from 'diff-index' unless the command\n> \t\taborted\n> \t} else if (dirty) {\n> \t\trefresh the index\n> \t\trun the equivalent of 'diff-index' in-core\n> \t\tuse the result; if the in-core diff-index aborts,\n> \t\tyou are dead already.\n> \t}\n\nGreat.\n\nThis matches my intuition from investigating this problem: the --broken \nflag triggers a different code-path.  However, it's good to have this \nconfirmed.\n\n> I _think_ the \"broken\" codepath should be taught to also run \"git\n> update-index --refresh\" before it runs \"git diff-index\" (both in\n> their own subprocesses, or run in the same subprocess sequencially,\n> as if \"git update-index --refresh && git diff-index\" were run), and\n> your problem may disappear.\n\nFor what it's worth, I agree.\n\nAlso, just to mention it, fixing this problem isn't a priority (at \nleast, not for me).  Simply removing the --broken flag resolves the \nproblem and I can live without this functionality.\n\nCheers,\nPaul.\n\n"},{"id":"497507","messageId":"xmqqmsnemccl.fsf@gitster.g","threadId":"61654","inReplyTo":"c4f5ae01-97fe-4e3a-94e2-72da75b9df83@desy.de","subject":"Re: bug with git describe --dirty --broken","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-06-21T17:31:38Z","receivedAt":"2024-06-21T17:31:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Paul Millar <paul.millar@desy.de> writes:\n\n> Hi Junio,\n>\n> Thanks for your quick reply.\n>\n>> \tif (broken) {\n>> \t\trun 'git diff-index' in a subprocess\n>> \t\tuse the result from 'diff-index' unless the command\n>> \t\taborted\n>> \t} else if (dirty) {\n>> \t\trefresh the index\n>> \t\trun the equivalent of 'diff-index' in-core\n>> \t\tuse the result; if the in-core diff-index aborts,\n>> \t\tyou are dead already.\n>> \t}\n>\n> Great.\n>\n> This matches my intuition from investigating this problem: the\n> --broken flag triggers a different code-path.  However, it's good to\n> have this confirmed.\n>\n>> I _think_ the \"broken\" codepath should be taught to also run \"git\n>> update-index --refresh\" before it runs \"git diff-index\" (both in\n>> their own subprocesses, or run in the same subprocess sequencially,\n>> as if \"git update-index --refresh && git diff-index\" were run), and\n>> your problem may disappear.\n>\n> For what it's worth, I agree.\n>\n> Also, just to mention it, fixing this problem isn't a priority (at\n> least, not for me).  Simply removing the --broken flag resolves the\n> problem and I can live without this functionality.\n\nThanks.  Let's mark it with #leftoverbits so that people who are\nbored and looking for small and isolated things to do can work on it\non their ample spare time ;-)\n"}]}