2 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3 # If clang_format_diff.py command is not specfied, we assume we are able to
4 # access directly without any path.
8 echo "format-diff.sh [OPTIONS]"
10 echo "-h: print this message."
13 while getopts ':ch' OPTION
; do
29 REPO_ROOT
="$(git rev-parse --show-toplevel)"
31 if [ "$CLANG_FORMAT_DIFF" ]; then
32 echo "Note: CLANG_FORMAT_DIFF='$CLANG_FORMAT_DIFF'"
33 # Dry run to confirm dependencies like argparse
34 if $CLANG_FORMAT_DIFF --help >/dev
/null
< /dev
/null
; then
40 # First try directly executing the possibilities
41 if clang-format-diff.py
--help &> /dev
/null
< /dev
/null
; then
42 CLANG_FORMAT_DIFF
=clang-format-diff.py
43 elif $REPO_ROOT/clang-format-diff.py
--help &> /dev
/null
< /dev
/null
; then
44 CLANG_FORMAT_DIFF
=$REPO_ROOT/clang-format-diff.py
46 # This probably means we need to directly invoke the interpreter.
47 # But first find clang-format-diff.py
48 if [ -f "$REPO_ROOT/clang-format-diff.py" ]; then
49 CFD_PATH
="$REPO_ROOT/clang-format-diff.py"
50 elif which clang-format-diff.py
&> /dev
/null
; then
51 CFD_PATH
="$(which clang-format-diff.py)"
53 echo "You didn't have clang-format-diff.py and/or clang-format available in your computer!"
54 echo "You can download clang-format-diff.py by running: "
55 echo " curl --location https://tinyurl.com/y2kvokof -o ${REPO_ROOT}/clang-format-diff.py"
56 echo "You can download clang-format by running:"
57 echo " brew install clang-format"
59 echo " apt install clang-format"
60 echo " This might work too:"
61 echo " yum install git-clang-format"
62 echo "Then make sure clang-format is available and executable from \$PATH:"
63 echo " clang-format --version"
66 # Check argparse pre-req on interpreter, or it will fail
67 if echo import argparse |
${PYTHON:-python3}; then
70 echo "To run clang-format-diff.py, we'll need the library "argparse
" to be"
71 echo "installed. You can try either of the follow ways to install it:"
72 echo " 1. Manually download argparse: https://pypi.python.org/pypi/argparse"
73 echo " 2. easy_install argparse (if you have easy_install)"
74 echo " 3. pip install argparse (if you have pip)"
77 # Unfortunately, some machines have a Python2 clang-format-diff.py
78 # installed but only a Python3 interpreter installed. Unfortunately,
79 # automatic 2to3 migration is insufficient, so suggest downloading latest.
80 if grep -q "print '" "$CFD_PATH" && \
81 ${PYTHON:-python3} --version |
grep -q 'ython 3'; then
82 echo "You have clang-format-diff.py for Python 2 but are using a Python 3"
83 echo "interpreter (${PYTHON:-python3})."
84 echo "You can download clang-format-diff.py for Python 3 by running: "
85 echo " curl --location https://tinyurl.com/y2kvokof -o ${REPO_ROOT}/clang-format-diff.py"
88 CLANG_FORMAT_DIFF
="${PYTHON:-python3} $CFD_PATH"
89 # This had better work after all those checks
90 if $CLANG_FORMAT_DIFF --help >/dev
/null
< /dev
/null
; then
98 # TODO(kailiu) following work is not complete since we still need to figure
99 # out how to add the modified files done pre-commit hook to git's commit index.
101 # Check if this script has already been added to pre-commit hook.
102 # Will suggest user to add this script to pre-commit hook if their pre-commit
104 # PRE_COMMIT_SCRIPT_PATH="`git rev-parse --show-toplevel`/.git/hooks/pre-commit"
105 # if ! ls $PRE_COMMIT_SCRIPT_PATH &> /dev/null
107 # echo "Would you like to add this script to pre-commit hook, which will do "
108 # echo -n "the format check for all the affected lines before you check in (y/n):"
110 # if [ "$add_to_hook" == "y" ]
112 # ln -s `git rev-parse --show-toplevel`/build_tools/format-diff.sh $PRE_COMMIT_SCRIPT_PATH
117 uncommitted_code
=`git diff HEAD`
119 # If there's no uncommitted changes, we assume user are doing post-commit
120 # format check, in which case we'll try to check the modified lines vs. the
121 # facebook/rocksdb.git master branch. Otherwise, we'll check format of the
122 # uncommitted code only.
123 if [ -z "$uncommitted_code" ]
125 # Attempt to get name of facebook/rocksdb.git remote.
126 [ "$FORMAT_REMOTE" ] || FORMAT_REMOTE
="$(git remote -v | grep 'facebook/rocksdb.git' | head -n 1 | cut -f 1)"
127 # Fall back on 'origin' if that fails
128 [ "$FORMAT_REMOTE" ] || FORMAT_REMOTE
=origin
129 # Use master branch from that remote
130 [ "$FORMAT_UPSTREAM" ] || FORMAT_UPSTREAM
="$FORMAT_REMOTE/master"
131 # Get the common ancestor with that remote branch. Everything after that
132 # common ancestor would be considered the contents of a pull request, so
133 # should be relevant for formatting fixes.
134 FORMAT_UPSTREAM_MERGE_BASE
="$(git merge-base "$FORMAT_UPSTREAM" HEAD)"
135 # Get the differences
136 diffs
=$
(git
diff -U0 "$FORMAT_UPSTREAM_MERGE_BASE" |
$CLANG_FORMAT_DIFF -p 1)
138 # Check the format of uncommitted lines,
139 diffs
=$
(git
diff -U0 HEAD |
$CLANG_FORMAT_DIFF -p 1)
144 echo "Nothing needs to be reformatted!"
148 echo "Your change has unformatted code. Please run make format!"
149 if [ $VERBOSE_CHECK ]; then
150 clang-format
--version
156 # Highlight the insertion/deletion from the clang-format-diff.py's output
158 COLOR_RED
="\033[0;31m"
159 COLOR_GREEN
="\033[0;32m"
161 echo -e "Detect lines that doesn't follow the format rules:\r"
162 # Add the color to the diff. lines added will be green; lines removed will be red.
164 sed -e "s/\(^-.*$\)/`echo -e \"$COLOR_RED\1$COLOR_END\"`/" |
165 sed -e "s/\(^+.*$\)/`echo -e \"$COLOR_GREEN\1$COLOR_END\"`/"
167 if [[ "$OPT" == *"-DTRAVIS"* ]]
172 echo -e "Would you like to fix the format automatically (y/n): \c"
174 # Make sure under any mode, we can read user input.
178 if [ "$to_fix" != "y" ]
183 # Do in-place format adjustment.
184 if [ -z "$uncommitted_code" ]
186 git
diff -U0 "$FORMAT_UPSTREAM_MERGE_BASE" |
$CLANG_FORMAT_DIFF -i -p 1
188 git
diff -U0 HEAD |
$CLANG_FORMAT_DIFF -i -p 1
190 echo "Files reformatted!"
192 # Amend to last commit if user do the post-commit format check
193 if [ -z "$uncommitted_code" ]; then
194 echo -e "Would you like to amend the changes to last commit (`git log HEAD --oneline | head -1`)? (y/n): \c"
197 if [ "$to_amend" == "y" ]
199 git commit
-a --amend --reuse-message HEAD
200 echo "Amended to last commit"