diff options
author | Brad King <brad.king@kitware.com> | 2010-05-20 11:42:57 -0400 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2010-05-20 11:42:57 -0400 |
commit | 7827726e88c2a4cacdda5cd09e6907925cd30f2f (patch) | |
tree | 024b3514c44c8f2d9aa3c7aafa32f43f50d33235 | |
parent | 7cd6238240d440f0a69a0f4e8eecc3b2a23a1973 (diff) | |
download | cmake-7827726e88c2a4cacdda5cd09e6907925cd30f2f.tar.gz |
pre-commit: Check file modes
Check new files and files whose mode changes to verify that each file
mode matches the content of the file. The mode of a file must be
executable if and only if the file looks executable (name ends in a
Windows executable extension or content starts with a shebang line).
-rwxr-xr-x | pre-commit | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/pre-commit b/pre-commit index 14e03ab593..00dc8486ef 100755 --- a/pre-commit +++ b/pre-commit @@ -49,9 +49,11 @@ if test "$(git diff --cached --name-only --diff-filter=A -z $against | '"$(git diff --cached --name-only --diff-filter=A $against)" fi +#----------------------------------------------------------------------------- # Builtin whitespace checks. bad=$(git diff-index --check --cached $against --) || die "$bad" +#----------------------------------------------------------------------------- # Reject leading TABs. check_tab() { git diff-index -p --cached $against -- "$1" | @@ -78,3 +80,40 @@ done) test -z "$bad" || die 'Leading TABs added in '"$bad"' Convert them to spaces (2 per TAB) before commit.' + +#----------------------------------------------------------------------------- +# Check file modes. +looks_executable() { + case "$1" in + *.bat) return 0 ;; + *.cmd) return 0 ;; + *.exe) return 0 ;; + *.com) return 0 ;; + esac + git cat-file blob "$2" | head -1 | grep "^#!/" > /dev/null +} +mode_not_exe () { + echo "The file '$file' has looks executable but does not have an executable mode." +} +mode_bad_exe () { + echo "The file '$file' has executable mode but does not look executable." +} +mode_non_file () { + echo "The path '$file' has a non-file mode." +} +check_mode() { + case "$dst_mode" in + 100755) looks_executable "$file" "$dst_obj" || mode_bad_exe ;; + 100644) looks_executable "$file" "$dst_obj" && mode_not_exe ;; + 160000) ;; + *) mode_non_file ;; + esac +} +bad=$(git diff-index --cached $against -- | +sed -n '/^:[^:]/ {s/^://;p;}' | +while read src_mode dst_mode src_obj dst_obj status file; do + if test "$src_mode" != "$dst_mode" -a "$dst_mode" != "000000"; then + check_mode + fi +done) +test -z "$bad" || die "$bad" |