Skip to content

Commit fccf5fc

Browse files
committed
Auto-format on commit
1 parent 63a73a6 commit fccf5fc

3 files changed

Lines changed: 70 additions & 0 deletions

File tree

‎configure‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
3+
# Activates git_hooks directory
4+
git config core.hooksPath git_hooks
6.36 MB
Binary file not shown.

‎git_hooks/pre-commit‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/bin/bash
2+
# Auto format changed java files using google-java-format.
3+
# To install, copy this file into $repo/.git/hooks and remove the .sh extension.
4+
# Download the google-java-format JAR from
5+
# https://github.com/google/google-java-format
6+
# A more mature implementation of this would be a plugin for Yelp's pre-commit library:
7+
# http://pre-commit.com/
8+
echo "Running auto-formatter for any changed Java files"
9+
echo "(formatting changes will be automatically added to your commit)"
10+
11+
# Grab root directory to help with creating an absolute path for changed files.
12+
root_dir="$(git rev-parse --show-toplevel)"
13+
[ -d "${root_dir}" ] || exit 1
14+
15+
# TODO add your path here.
16+
jar_base_dir="git_hooks/"
17+
18+
# To avoid any unexpected behavior, we need to "stash" any unstaged changes.
19+
# We could use "git stash" but the situation gets complicated because we
20+
# need to make additional changes with the formatter.
21+
# Here's how we could do this if we didn't need to make additional changes:
22+
# http://stackoverflow.com/a/20480591
23+
# But since we do, we follow the same general pattern as the "pre-commit" lib:
24+
# https://github.com/pre-commit/pre-commit/blob/master/pre_commit/staged_files_only.py#L15
25+
# Basically we just diff the unstaged changes, store the patch, and apply it later.
26+
# In the future, we should consider migrating to using that library.
27+
staged_changes_diff=$(mktemp -t format_patch)
28+
git diff --ignore-submodules --binary --exit-code --no-color > $staged_changes_diff
29+
if [ $? -eq 1 ]; then
30+
echo "Found unstaged changes, storing in ${staged_changes_diff}"
31+
echo "Clearing unstaged changes for formatting, will restore after formatting."
32+
git checkout -- ${root_dir}
33+
stored_staged_changes=true
34+
else
35+
stored_staged_changes=false
36+
fi
37+
38+
formatter_jar="${root_dir}/${jar_base_dir}/google-java-format-1.3-all-deps.jar"
39+
formatter_cmd="java -jar ${formatter_jar}"
40+
# Format file in-place and use 4-space style (AOSP).
41+
formatter_args="--replace --aosp"
42+
43+
# filter=ACMR shows only added, changed, modified, or renamed files.
44+
# Get only java files and prepend the root directory to make the paths absolute.
45+
changed_java_files=($(git diff --cached --name-only --diff-filter=ACMR \
46+
| grep ".*java$" \
47+
| sed "s:^:${root_dir}/:"))
48+
# If we have changed java files, format them!
49+
if [ ${#changed_java_files[@]} -gt 0 ]; then
50+
# Do the formatting, stage the changes, and print out which files were changed.
51+
eval ${formatter_cmd} ${formatter_args} "${changed_java_files[@]}"
52+
git add "${changed_java_files[@]}"
53+
echo "${changed_java_files[@]}" | xargs basename | sed "s/^/ Formatting: /"
54+
fi
55+
56+
echo "Finished formatting."
57+
58+
if $stored_staged_changes ; then
59+
echo "Restoring unstaged changes"
60+
git apply "${staged_changes_diff}"
61+
62+
if [ $? -eq 1 ]; then
63+
echo "Shoot! We failed to re-apply your unstaged changes."
64+
echo "The patch for these changes is preserved at ${staged_changes_diff}"
65+
fi
66+
fi

0 commit comments

Comments
 (0)