Skip to content

Instantly share code, notes, and snippets.

@DanielleSucher
Forked from aprescott/gist:5683945
Last active December 17, 2015 22:59
Show Gist options
  • Save DanielleSucher/5686074 to your computer and use it in GitHub Desktop.
Save DanielleSucher/5686074 to your computer and use it in GitHub Desktop.
Bash script to find all single-character commits in a git repository
first_commit=$(git log --pretty=format:%H | tail -1)
git rev-list --all --no-merges |
while read commit; do
if [ $commit == $first_commit ]; then break; fi;
IFS_backup=$IFS
IFS=$'\n'
diff_lines=( $(git diff --numstat --minimal -U0 --word-diff=porcelain $commit^ $commit | grep -E '^(\+[^+]|-[^-]).*$') )
IFS=$IFS_backup
character_count_diff=$(expr ${#diff_lines[0]} - ${#diff_lines[1]})
if [ ${#diff_lines[@]} -eq 2 ] && [ ${character_count_diff#-} -lt 2 ]; then
for (( i=1; i<${#diff_lines[0]}; i++ )); do
character=${diff_lines[0]:$i:1}
if [ "$character" = "${diff_lines[1]:$i:1}" ]; then continue; fi;
next_index=$(expr $i + 1)
single_subtraction=$(expr "${diff_lines[0]:$i}" = "${diff_lines[1]:$next_index}")
single_addition=$(expr "${diff_lines[1]:$i}" = "${diff_lines[0]:$next_index}")
# $single_substitution needs 'x's for cases where (for example) the diff is '-300 +60'
# and '00' and '000' would otherwise end up being compared as numbers and deemed equal
single_substitution=$(expr "x${diff_lines[0]:$next_index}" = "x${diff_lines[1]:$next_index}")
if [ $single_subtraction -eq 1 ] || [ $single_addition -eq 1 ] || [ $single_substitution -eq 1 ]; then
echo "$(git log --pretty=oneline $commit^...$commit)"
echo "$(git diff --minimal $commit^ $commit)"
echo ''
echo ''
fi;
break
done
fi;
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment