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

From: Junio C Hamano <[email-masked]>
Date: Thu, 20 Jun 2024 09:57:43 -0700

Paul Millar <[email-masked]> writes:

> 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.