Skip to content
Snippets Groups Projects
pre-commit 1.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/usr/bin/sh
    #
    # Format *.cpp|*.c|*.cc|*.h|*.hpp files with clang-format.
    # Called by "git commit" with no arguments.  The hook should
    # exit with non-zero status after issuing an appropriate message if
    # it wants to stop the commit.
    
    if git rev-parse --verify HEAD >/dev/null 2>&1
    then
        against=HEAD
    else
        # Initial commit: diff against an empty tree object
        against=$(git hash-object -t tree /dev/null)
    fi
    
    # Redirect output to stderr.
    exec 1>&2
    
    # Find all changed C/C++ files
    diff_source_files=$(git diff --cached --name-only --diff-filter=AM $against \
    					-- '*.c' '*.cc' '*.cpp' '*.h' '*.hpp')
    # Only perform clang-format when changed source files exist
    if [[ ! -z $diff_source_files ]]; then
    	echo "[clang-format] Reformatting the following files: "
    	echo $diff_source_files
    	clang-format --style=file -i $diff_source_files
    	echo "[clang-format] Adding reformatted files."
    	git add $diff_source_files
    	# Commit can become empty after this; reject commit in that case.
    	diff_after_format=$(git diff --cached $against)
    	if [[ -z $diff_after_format ]]; then
    		echo "[clang-format] Commit is empty after formatting; rejected."
    		exit 1
    	fi
    else
    	echo "[clang-format] No C/C++ source files modified in the commit."
    fi