Programmatically print git revision and check for uncommitted changes

To ensure that my scientific analysis will be reproducible, I would like to programmatically check if there are any changes in the code base that have not been verified, and if not, print out what kind of fixation is used.

For example, if there are uncommitted changes, it should output

Warning: uncommitted changes made. This output may not be reproducible. 

Else, produce

 Current commit: d27ec73cf2f1df89cbccd41494f579e066bad6fe 

Ideally, he should use plumbing rather than porcelain.

+7
git
source share
2 answers

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 
+8
source share

Porcelain is used, but git diff --exit-code exits with 1 if there are differences with existing files, and 0 if there are no differences in existing files. Unfortunately, it does not scan files without a trace.

This answer is to get a hash for the current commit in Git? protects git rev-parse --verify HEAD to print the current commit.

+1
source share

All Articles