Hi! Timo Funke wrote: > podman run --rm -it -v `pwd`:/git:z --entrypoint sh docker.io/alpine > > container# apk add git > > container# cd /git > > container# git diff-index --quiet HEAD -- ; echo $? > 1 > > container# git diff-index --quiet HEAD -- ; echo $? > 1 > > container# git status > On branch master > nothing to commit, working tree clean > > container# git diff-index --quiet HEAD -- ; echo $? > 0 > > > What did you expect to happen? (Expected behavior) > `git diff-index --quiet HEAD -- ; echo $?` should return `0` > even without executing `git status`. > > What happened instead? (Actual behavior) > Without executing `git status` `git diff-index --quiet HEAD -- ; echo $?` > will repeatedly print `1`. > > What's different between what you expected and what actually happened? > It is odd that `git diff-index --quiet HEAD -- ; echo $?` prints > different results depending on whether `git status` was executed. I love this example. Thanks for writing. I checked "git help diff-index" to see whether it describes this pitfall, and I didn't see an explanation. So at the very least you have uncovered a documentation bug. The difference between diff-index and status here is a difference between "porcelain" (user-facing) commands and "plumbing" (script-facing) commands. In Git's index file there is stat(2) information for each file; if that stat(2) information matches the corresponding file in the working directory then we know it hasn't been modified relative to what is in the index. If the stat(2) information differs from the working copy, on the other hand, the behavior depends on whether the command being run is porcelain or plumbing: - plumbing commands assume that the script author has run "git update-index --refresh -q" first to update the stat(2) information if the file hasn't changed. This allows efficient scripts to refresh the index once and then run multiple commands that rely on the result of that: git update-index --refresh -q || : for rev in "${revs[@]}" do if git diff-index --quiet "$rev" -- then ... do something ... fi done - porcelain commands such as "git status" implicitly refresh the index before doing anything else. This allows them to produce the expected result even if the repository is a copy made using "cp -a" or has been transferred across machines on a USB stick. Some places I expected to find an explanation of this: - documentation for the "git diff-index" command ("git help diff-index"). It does not mention this behavior. - documentation for the "git diff" command ("git help diff"). It also doesn't mention this. That's particularly surprising because it would be a great place to document the diff.autoRefreshIndex setting that affects this behavior of the "git diff" command (described in Documentation/config/diff.txt). - the Git user manual (Documentation/user-manual.txt). It describes "git update-index --refresh" but very briefly. It doesn't describe the above scripting pattern. - Git's command-line conventions ("git help cli"). No mention. - overview of plumbing and porcelain commands ("man git"). No mention. - the Git scripting manual ("git help core-tutorial"). It describes "git update-index --refresh" after a "cp -a" but not its use in scripts. - the history of Git's contrib/examples/. This contains many examples of the above scripting pattern but is not very discoverable. So there are many opportunities for someone to document this better. If you'd be interested in pursuing that, I'd be happy to provide some pointers. Thanks, Jonathan