The Git bits you need are diff-index , rev-parse --verify and possibly rev-parse --show-cdup with ls-files --others .
The next shell program uses Git plumbing commands, has custom processing without tracking / ignoring, and is pretty cautious about all possible cases of errors.
#!/bin/sh # warn-unclean: print a warning if the working tree and index are not clean # For utmost strictness, set check_untracked=yes and check_ignored=yes. # When both are 'yes', verify that working tree and index are identical to HEAD. # When only check_untracked is yes, extra ignored files are allowed. # When neither is yes, extra untracked files and ignored files are allowed. check_untracked=yes check_ignored=yes warn() { echo 'Warning: '"$*" \ 'This output may not be reproducible.' } # Compare HEAD to index and/or working tree versions of tracked files git diff-index --quiet HEAD case $? in 0) if test "$check_untracked" != yes; then clean=yes else # Still need to check for untracked files or_ignored='' exclude=--exclude-standard if test "$check_ignored" = yes; then or_ignored=' or ignored' exclude='' fi ( # Move to top level of working tree if up="$(git rev-parse --show-cdup)"; then test -n "$up" && cd "$up" else echo 'error running "git rev-parse --show-cdup"' exit 129 fi # Check for untracked files git ls-files --others $exclude --error-unmatch . >/dev/null 2>&1 case $? in 0) # some untracked/ignored file is present warn 'some untracked'"$or_ignored"' file is present.' exit 1 ;; 1) # no untracked files exit 0 ;; *) echo 'error running "git diff-index"!' exit 129 ;; esac ) case $? in 0) clean=yes ;; 1) clean=no ;; *) exit $? ;; esac fi test "$clean" = yes && if c="$(git rev-parse --verify HEAD)"; then echo 'Current commit: '"$c" else echo 'error running "git rev-parse --verify"!' fi ;; 1) warn 'some tracked file has an uncommitted change.' ;; *) echo 'error running "git diff-index"!' exit 129 ;; esac
You can sprinkle another exit if you want its exit code to be meaningful in all cases.
If you do not care about all error handling or processing without a trace / ignoring, then maybe short enough:
if git diff-index --quiet; then printf 'Current commit: %s\n' "$(git rev-parse --verify HEAD) else echo 'Warning: …' fi
You can also check non-verified files (which can be changed for ignored ones, etc.), without error handling:
git ls-files --others --exclude-standard --error-unmatch \ "./$(git rev-parse --show-cdup)" >/dev/null 2>&1
Chris johnsen
source share