threads / bug / 61654

bug with git describe --dirty --broken

Subject: bug with git describe --dirty --broken

## tl;dr

4 messages between Jun 20, 2024 and Jun 21, 2024.

replies: 3people: 2as markdown or json

Paul Millar· Jun 20, 2024, 11:14 UTC · lore

Thank you for filling out a Git bug report! Please answer the following questions to help us understand your issue.

What did you do before the bug happened? (Steps to reproduce your issue)

mkdir test-container cd test-container cat >Dockerfile <<EOF FROM docker.io/debian:bookworm-slim WORKDIR /work RUN apt-get update && apt-get -y install git EOF podman build -t test-image .

mkdir test-repo cd test-repo git init echo "Hello, world" > README git add README git commit -m "Initial commit" README git tag v1.0.0

git describe --tags --dirty --broken
podman run -v `pwd`:/work --rm -it --entrypoint '["/usr/bin/git",
    "describe", "--tags", "--dirty", "--broken"]' test-image
What did you expect to happen? (Expected behavior)

I expect git, when running in the container, to identify that the repo is clean.

What happened instead? (Actual behavior)

When run within the container, git identifies the repo as dirty.  The 'podman run' command returns

v1.0.0-dirty
What's different between what you expected and what actually happened?
The 'git' command is running within the container.
Anything else you want to add:
I believe the problem comes from two parts.

First, when running within the container, the files seemed to be owned by user root.

12:51 $ ls -l total 4 -rw-r--r-- 1 paul paul 13 Jun 20 12:45 README

12:49 $ podman run -v `pwd`:/work --rm -it --entrypoint '["ls", "-l"]' test-imag e total 4 -rw-r--r-- 1 root root 13 Jun 20 10:45 README

This results in an inconsistency between the ownership information contained within the .git/index file and the ownership information on the filesystem when git is run within the container.

Second, when 'git describe' is run with the '--broken' flag then the '.git/index' file is not updated.  The ownership inconsistency then triggers git's belief that the repo is dirty.

If the '--broken' flag is remove from the 'git describe' command then running the command directly and from the container give the same output.

12:51 $ git describe --tags --dirty v1.0.0

12:55 $ podman run -v `pwd`:/work --rm -it --entrypoint '["/usr/bin/git",
    "describe", "--tags", "--dirty"]' test-image
v1.0.0

In this case, running the 'git describe' command (both in the container and directly) will update the '.git/index' file, and the correct output is presented.

Please review the rest of the bug report below. You can delete any lines you don't wish to share.

[System Info] git version: git version 2.39.2 cpu: x86_64 no commit associated with this build sizeof-long: 8 sizeof-size_t: 8 shell-path: /bin/sh uname: Linux 6.1.0-21-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 (2024-05-03) x86_64 compiler info: gnuc: 12.2 libc info: glibc: 2.36 $SHELL (typically, interactive shell): /bin/bash

[Enabled Hooks] not run from a git repository - no hooks to show

Junio C Hamano· Jun 20, 2024, 16:57 UTC · re: Paul Millar · lore

Re: bug with git describe --dirty --broken

Paul Millar <paul.millar@desy.de> writes:
Show 15 quoted lines
> When run within the container, git identifies the repo as dirty.  The
> 'podman run' command returns
>
> v1.0.0-dirty
>
> Anything else you want to add:
>
> I believe the problem comes from two parts.
>
> First, when running within the container, the files seemed to be owned
> by user root.
> ...
> This results in an inconsistency between the ownership information
> contained within the .git/index file and the ownership information on
> the filesystem when git is run within the container.

Indeed. You are running git in two separate environments with inconsistent worldview. As many attributes of each file (like the last modified timestamp and who owns the file) are recorded in the index for files that were verified to be unmodified (this is done so that by doing lstat() on a path and comparing the result with the information saved in the index, we can notice that the path was modified without actually opening the file and looking at the contents), after doing something (like "git diff") that causes this information updated while the files appear to be owned by you, switching to the alternate world where the files appear to be owned by root and asking "are these files modified?", Git will trust what is in the index and report "the index says they are owned by you but lstat() says otherwise; you must have modified them".

The way we deal with such false positives is to "refresh the index".

And it is done in "git describe --dirty" codepath, but not "--broken" codepath, which is the cause of the issue you discovered.

There is code snippet in builtin/describe.c that does:
	if (broken) {
		run 'git diff-index' in a subprocess
		use the result from 'diff-index' unless the command
		aborted
	} else if (dirty) {
		refresh the index
		run the equivalent of 'diff-index' in-core
		use the result; if the in-core diff-index aborts,
		you are dead already.
	}

I _think_ the "broken" codepath should be taught to also run "git update-index --refresh" before it runs "git diff-index" (both in their own subprocesses, or run in the same subprocess sequencially, as if "git update-index --refresh && git diff-index" were run), and your problem may disappear.

Thanks.
Paul Millar· Jun 21, 2024, 12:07 UTC · re: Junio C Hamano · lore

Re: bug with git describe --dirty --broken

Hi Junio,
Thanks for your quick reply.
Show 10 quoted lines
> 	if (broken) {
> 		run 'git diff-index' in a subprocess
> 		use the result from 'diff-index' unless the command
> 		aborted
> 	} else if (dirty) {
> 		refresh the index
> 		run the equivalent of 'diff-index' in-core
> 		use the result; if the in-core diff-index aborts,
> 		you are dead already.
> 	}
Great.

This matches my intuition from investigating this problem: the --broken flag triggers a different code-path.  However, it's good to have this confirmed.

Show 5 quoted lines
> I _think_ the "broken" codepath should be taught to also run "git
> update-index --refresh" before it runs "git diff-index" (both in
> their own subprocesses, or run in the same subprocess sequencially,
> as if "git update-index --refresh && git diff-index" were run), and
> your problem may disappear.
For what it's worth, I agree.

Also, just to mention it, fixing this problem isn't a priority (at least, not for me).  Simply removing the --broken flag resolves the problem and I can live without this functionality.

Cheers, Paul.

Junio C Hamano· Jun 21, 2024, 17:31 UTC · re: Paul Millar · lore

Re: bug with git describe --dirty --broken

Paul Millar <paul.millar@desy.de> writes:
Show 32 quoted lines
> Hi Junio,
>
> Thanks for your quick reply.
>
>> 	if (broken) {
>> 		run 'git diff-index' in a subprocess
>> 		use the result from 'diff-index' unless the command
>> 		aborted
>> 	} else if (dirty) {
>> 		refresh the index
>> 		run the equivalent of 'diff-index' in-core
>> 		use the result; if the in-core diff-index aborts,
>> 		you are dead already.
>> 	}
>
> Great.
>
> This matches my intuition from investigating this problem: the
> --broken flag triggers a different code-path.  However, it's good to
> have this confirmed.
>
>> I _think_ the "broken" codepath should be taught to also run "git
>> update-index --refresh" before it runs "git diff-index" (both in
>> their own subprocesses, or run in the same subprocess sequencially,
>> as if "git update-index --refresh && git diff-index" were run), and
>> your problem may disappear.
>
> For what it's worth, I agree.
>
> Also, just to mention it, fixing this problem isn't a priority (at
> least, not for me).  Simply removing the --broken flag resolves the
> problem and I can live without this functionality.

Thanks. Let's mark it with #leftoverbits so that people who are bored and looking for small and isolated things to do can work on it on their ample spare time ;-)

← back to recent threads