Skip to content

Instantly share code, notes, and snippets.

@CDanU
Last active May 20, 2017 19:09
Show Gist options
  • Save CDanU/15601f1761543cd1b8a73e4613bfa283 to your computer and use it in GitHub Desktop.
Save CDanU/15601f1761543cd1b8a73e4613bfa283 to your computer and use it in GitHub Desktop.
Uncrustify Hooks
#!/bin/sh
# ------------------------------------------------------------------------------
# GPLv2
# Copyright (c) 2017, Daniel Chumak
# All rights reserved.
# ------------------------------------------------------------------------------
post="`pwd`/.uncr_5ca35"
# ------------------------------------------------------------------------------
CYA='\033[0;36m'
RED='\033[0;31m'
NC='\033[0m' # No Color
iecho () {
printf "${CYA}$1${NC}\n"
}
eecho () {
>&2 printf "${RED}$1${NC}\n"
}
# ------------------------------------------------------------------------------
iecho "Executing script: $0"
# exit if no post_file was generated by the pre-commit script
if [ ! -f "$post" ]; then
exit 0
fi
# remove the post file
rm "$post"
# restore stashed changed
git stash pop
RET=$?
iecho "Git stash pop END"
if [ "$RET" -ne 0 ]; then
# output of 'git ls-files -u' should be empty, if not there is a merge conflict
MERGE_CONFLICT=`git ls-files -u`
if [ ! -z "$MERGE_CONFLICT" ]; then
iecho "merge conflict detected"
# the conflict will be solved by completely restoring the stash
git checkout --theirs .
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - 'git checkout --theirs .' failed"
exit $RET
fi
git reset
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - 'git reset' failed"
exit $RET
fi
git stash drop
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - 'git stash drop' failed"
exit $RET
fi
iecho "merge conflict solved"
else
# some other error happened - stash is not dropped
eecho "$RET - Problems occurred while running 'git stash pop'"
exit $RET
fi
fi
exit 0
#!/bin/sh
# ------------------------------------------------------------------------------
# BSD 2-clause
# Copyright (c) 2015, David Martin
# All rights reserved.
# ------------------------------------------------------------------------------
# GPLv2
# Copyright (c) 2017, Daniel Chumak
# All rights reserved.
# ------------------------------------------------------------------------------
CFG="forUncrustifySources.cfg"
#BIN="./build/Debug/uncrustify.exe"
BIN="./build/uncrustify"
patch_file="`pwd`/.uncr_4ca35.patch"
post_file="`pwd`/.uncr_5ca35"
# ------------------------------------------------------------------------------
RED='\033[0;31m'
GRE='\033[0;32m'
CYA='\033[0;36m'
NC='\033[0m' # No Color
eecho () {
>&2 printf "${RED}$1${NC}\n"
}
wecho () {
printf "${RED}$1${NC}\n"
}
iecho () {
printf "${CYA}$1${NC}\n"
}
oecho () {
printf "${GRE}$1${NC}\n"
}
save_stash () {
# check if there are unstaged files to stash, 0 = no unstaged files
git diff-files --quiet
NEED_STASH=$?
if [ "$NEED_STASH" -eq 0 ]; then
return 1
fi
# check if stash count > 0
# --> if refs/stash is not a valid ref than there are no stashes
git show-ref --verify refs/stash --quiet
HAS_STASH=$?
pre_stash_hash=""
# if count != 0 save pre_stash_hash
if [ "$HAS_STASH" -eq 0 ]; then
pre_stash_hash=`git rev-parse --verify -q refs/stash`
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - Faild to get stash hash"
exit $RET
fi
fi
# stash unstaged and untracked files in the src dir
git stash -k -u
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - Faild to execute git stash"
exit $RET
fi
# check again if stash count > 0, it should be, if not abort
git show-ref --verify refs/stash &> /dev/null
HAS_STASH=$?
if [ "$HAS_STASH" -ne 0 ]; then
eecho "$RET - No stash ref found"
exit $RET
fi
# check if pre_stash_hash != post_stash_hash,
# if not than there was nothing to stash
post_stash_hash=`git rev-parse --verify -q refs/stash`
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - Faild to get stash hash"
exit $RET
fi
if [ "$pre_stash_hash" != "$post_stash_hash" ]; then
iecho "Git stash END"
return 0
fi
return 1
}
pop_stash ()
{
if [ $1 -eq 0 ]; then
git stash pop
iecho "Git stash pop END"
rm "$post_file"
fi
}
# ------------------------------------------------------------------------------
iecho "Executing script: $0"
# make sure the config file and executable are correctly set
if [ ! -f "$CFG" ] ; then
eecho "Config file not found: $CFG"
exit 2
fi
if [ ! -f "$BIN" ] ; then
eecho "Uncrustify executable not found: $BIN"
exit 3
fi
# remove old patch_file & post_file
rm $patch_file
rm $post_file
# stash uncommitted changes
save_stash
stash_flag=$?
if [ "$stash_flag" -eq 0 ]; then
# create $post_file so that the post-commit script will restore the
# stashed changes
touch $post_file
# return stash on failure
trap pop_stash 1 2 3 9 15
fi
# get all source files that deviate from the upstream branch
git diff -z --name-only origin/master src/* \
| grep ".*\.\(cpp\|c\|h\)" --text \
| while read -r -d '' file_path; do
# escape special characters in the source filename:
# - '\': backslash needs to be escaped
# - '*': used as matching string => '*' would mean expansion
# (curiously, '?' must not be escaped)
# - '[': used as matching string => '[' would mean start of set
# - '|': used as sed split char instead of '/', so it needs to be escaped
# in the filename
# printf %s particularly important if the filename contains the % character
file_escaped_source=`printf "%s" "$file_path" | sed -e 's/[\*[| ]/\\&/g'`
echo "file_escaped_source $file_escaped_source"
# escape special characters in the target filename:
# phase 1 (characters escaped in the output diff):
# - '\': backslash needs to be escaped in the output diff
# - '"': quote needs to be escaped in the output diff if present inside
# of the filename, as it used to bracket the entire filename part
# phase 2 (characters escaped in the match replacement):
# - '\': backslash needs to be escaped again for sed itself
# (i.e. double escaping after phase 1)
# - '&': would expand to matched string
# - '|': used as sed split char instead of '/'
# printf %s particularly important if the filename contains the % character
file_escaped_target=`printf "%s" "$file_path" \
| sed -e 's/[\" ]/\\&/g' -e 's/[\&|]/\\&/g'`
echo "file_escaped_target: $file_escaped_target"
# uncrustify our sourcefile, create a patch with diff and append it
# to $patch_file
#
# The sed call is necessary to transform the patch from
# --- $file_pathile timestamp
# +++ - timestamp
# to both lines working on the same file and having a a/ and b/ prefix.
"$BIN" -c "$CFG" -f "$file_path" | \
diff -u -- "$file_path" - | \
sed -e "1s|--- $file_pathile_escaped_source|--- \"a/$file_pathile_escaped_target\"|" \
-e "2s|+++ -|+++ \"b/$file_escaped_target\"|" \
>> "$patch_file"
done
# if no patch has been generated everything is ok
if [ ! -s "$patch_file" ] ; then
pop_stash $stash_flag
exit 0
fi
# a patch has been created, show diff, show options
eecho "Aborting commit."
echo
echo "The following differences were found between the code to commit "
echo "and the uncrustify rules:"
echo
if [ `which grc 2> /dev/null` ]; then
cat "$patch_file" | grcat conf.diff
elif [ `which colordiff 2> /dev/null` ]; then
cat "$patch_file" | colordiff
elif [ `which diff-highlight 2> /dev/null` ]; then
cat "$patch_file" | diff-highlight
elif [ -f "/usr/share/git/diff-highlight/diff-highlight" ]; then
# seems to be missing in my ptah, so try again with hardcoded path
cat "$patch_file" | /usr/share/git/diff-highlight/diff-highlight
else
cat "$patch_file"
fi
user_option=0
RET=1
echo -en "\n\
Options ========================================================================\n\
[0]: abort\n\
1 : apply & commit\n\
2 : ignore & continue\n\
================================================================================\n\
Input option: "
read user_option </dev/tty
if [ "$user_option" = "1" ]; then
iecho " apply & commit"
git apply "$patch_file" --ignore-whitespace --inaccurate-eof -v --recount
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - Failed to apply patch"
eecho "Aborting commit."
else
echo "changes: `git diff --name-only origin/master src/*`"
git diff -z --name-only origin/master src/* \
| grep ".*\.\(cpp\|c\|h\)" --text \
| while read -r -d '' file_path; do
echo "git add: $file_path"
git add "$file_path"
done
fi
elif [ "$user_option" = "2" ]; then
wecho " ignore & continue"
RET=0
else
oecho " abort"
echo -en "\n\n\
You can apply the diff manually with: \n\
git apply $patch_file\n"
RET=1
fi
if [ "$RET" -ne 0 ]; then
pop_stash $stash_flag;
fi
exit $RET
#!/bin/sh
# ------------------------------------------------------------------------------
# GPLv2
# Copyright (c) 2017, Daniel Chumak
# All rights reserved.
# ------------------------------------------------------------------------------
RED='\033[0;31m'
GRE='\033[0;32m'
BLU='\033[0;34m'
NC='\033[0m' # No Color
eecho () {
>&2 printf "${RED}$1${NC}\n"
}
wecho () {
printf "${RED}$1${NC}\n"
}
iecho () {
printf "${BLU}$1${NC}\n"
}
oecho () {
printf "${GRE}$1${NC}\n"
}
save_stash () {
# check if there are unstaged files to stash, 0 = no unstaged files
git diff-files --quiet
NEED_STASH=$?
if [ "$NEED_STASH" -eq 0 ]; then
return 1
fi
# check if stash count > 0
# --> if refs/stash is not a valid ref than there are no stashes
git show-ref --verify refs/stash --quiet
HAS_STASH=$?
pre_stash_hash=""
# if count != 0 save pre_stash_hash
if [ "$HAS_STASH" -eq 0 ]; then
pre_stash_hash=`git rev-parse --verify -q refs/stash`
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - Faild to get stash hash"
exit $RET
fi
fi
git stash
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - Faild to execute git stash"
exit $RET
fi
# check again if stash count > 0, it should be, if not abort
git show-ref --verify refs/stash &> /dev/null
HAS_STASH=$?
if [ "$HAS_STASH" -ne 0 ]; then
eecho "$RET - No stash ref found"
exit $RET
fi
# check if pre_stash_hash != post_stash_hash,
# if not than there was nothing to stash
post_stash_hash=`git rev-parse --verify -q refs/stash`
RET=$?
if [ "$RET" -ne 0 ]; then
eecho "$RET - Faild to get stash hash"
exit $RET
fi
if [ "$pre_stash_hash" != "$post_stash_hash" ]; then
iecho "Git stash END"
return 0
fi
return 1
}
# ------------------------------------------------------------------------------
iecho "Executing script: $0"
save_stash
stash_flag=$?
./scripts/Test_more_Options.sh
RET=$?
if [ "$stash_flag" -eq 0 ]; then
git stash pop &> /dev/null && iecho "Git stash pop"
fi
if [ "$RET" -eq 0 ]; then
exit $RET
fi
echo -en "\n\
Options ========================================================================\n\
[y|0]: Abort - default \n\
n|1 : Ignore & continue \n\
================================================================================\n\
Abort? "
user_option="y"
read user_option </dev/tty
if [ "$user_option" = "1" ] || [ "$user_option" = "n" ] || [ "$user_option" = "N" ]; then
wecho " Ignore & continue"
RET=0
else
oecho " Abort"
RET=1
fi
exit $RET
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment