I want to know which files (perhaps Fortran source files) in a directory have never been committed to git, which ones differ from the last commit, and which ones are the same as their last commit. You can get such information with git commands, but files with a certain status are listed on successive lines. Running `bash gitc.sh *.f90` gives compact output such as
NEW garch_ged.f90 garch_laplace.f90 garch_logis.f90 garch_t.f90 temp.f90 temp_garch.f90 temp_xgarch_sim.f90 tests.f90 tests_mix.f90 tfit.f90 xchar.f90 xcumsum.f90 xenv.f90 xmean_median.f90 xprint_real.f90 xqsort.f90 xrandom.f90 xread_vec.f90 xrep.f90 xreplace.f90 xtest_mssk.f90 xutil.f90 xwindows.f90 xxenv.f90 xxprint_real.f90
DIFFERENT constants.f90 gnuplot.f90 interpret.f90 mat.f90 qsort.f90 random.f90 util.f90 xfit_t.f90 xgarch_sim.f90 xgarch_sim_nonnormal.f90 xtest_dist.f90
SAME calc.f90 garch.f90 kind.f90 stats.f90 xcalc.f90 xinterpret.f90 xnoise.f90
Here is the script. A version that uses Windows CMD is here.
#!/usr/bin/env bash
# gitc.sh: group files (current directory only) into NEW (not in HEAD), DIFFERENT (changed vs HEAD), and SAME (matches HEAD).
# usage:
# ./gitc.sh # all files in current directory
# ./gitc.sh '*.f90' # glob in current directory
# ./gitc.sh file1 file2 ...
set -euo pipefail
new=()
diff=()
same=()
files=()
# build file list (ignore subdirectories)
if (($# == 0)); then
shopt -s nullglob dotglob
for f in *; do
[[ -f $f ]] && files+=("$f")
done
shopt -u dotglob
elif (($# == 1)); then
shopt -s nullglob
for f in $1; do
f=${f//\\//} # windows slashes -> /
f=${f#./}
[[ $f == */* ]] && continue
[[ -f $f ]] && files+=("$f")
done
else
for f in "$@"; do
f=${f//\\//}
f=${f#./}
[[ $f == */* ]] && continue
[[ -f $f ]] && files+=("$f")
done
fi
((${#files[@]})) || exit 1
for f in "${files[@]}"; do
# NEW if not present in HEAD
if ! git cat-file -e "HEAD:$f" 2>/dev/null; then
new+=("$f")
else
if git diff --quiet HEAD -- "$f" 2>/dev/null; then
same+=("$f")
else
diff+=("$f")
fi
fi
done
if ((${#new[@]})); then
printf 'NEW'
printf ' %s' "${new[@]}"
printf '\n'
fi
if ((${#diff[@]})); then
printf 'DIFFERENT'
printf ' %s' "${diff[@]}"
printf '\n'
fi
if ((${#same[@]})); then
printf 'SAME'
printf ' %s' "${same[@]}"
printf '\n'
fi