summaryrefslogtreecommitdiff
path: root/git-hooks
diff options
context:
space:
mode:
authorNorbert Thiebaud <nthiebaud@gmail.com>2011-06-22 01:42:01 -0500
committerNorbert Thiebaud <nthiebaud@gmail.com>2011-06-22 01:42:47 -0500
commit41f9319cda0abb94e865e069ec49f848285a29ad (patch)
tree1c6d2e2761bcc2e041f96c077a4e7e9ffaca9281 /git-hooks
parent3fb73be520950039b5a88d95057bc705bef147bb (diff)
fixing trailing whitespaces in pre-commit hook is broken.
The pre-commit hook had code that was trying to detect and _fix_ trailing whitespaces. this code was broken. If you try to do a partial commit on a file and the part your are partially commiting contain offending lines, the process to try to fix them drop the rest of the changes. In general it is very dangerous to try to be cute in a pre-commit hook a pre-commit hook you tell you something is wrong, and preferably were it think that it is wrong... but should not attempt to 'fix' things silently. So I did not try to 'fix' that code. Instead I replaced it by a straight forward 'detection-only', lifted from the linux-kernel's git hook.
Diffstat (limited to 'git-hooks')
-rwxr-xr-xgit-hooks/pre-commit142
1 files changed, 53 insertions, 89 deletions
diff --git a/git-hooks/pre-commit b/git-hooks/pre-commit
index f71ad6f98214..bae5ff99bf94 100755
--- a/git-hooks/pre-commit
+++ b/git-hooks/pre-commit
@@ -12,96 +12,60 @@ use Cwd;
$ENV{LC_ALL} = "C";
-# attempt to fix whitespace in one file
-# $1 - file to fix
-# $2 - list of lines containing whitespace errors
-sub fix_whitespace($$) {
- my ( $file, $lines ) = @_;
-
- open( IN, "$file" ) || die "Cannot open $file for reading";
- my ( $out, $tmpfile ) = mkstemp( "/tmp/whitespace-fixing-XXXXXX" );
-
- my $changed = 0;
- my $line_no = 1;
- while ( my $line = <IN> ) {
- if ( $lines->{$line_no} && $line =~ /^(.*[^ \t])[ \t]+$/ ) {
- $changed = 1;
- print $out "$1\n";
- }
- elsif ( $lines->{$line_no} && $line =~ /^[ \t]+$/ ) {
- $changed = 1;
- print $out "\n";
- }
- else {
- print $out $line;
- }
- ++$line_no;
- }
- close( $out );
- close( IN );
-
- if ( $changed )
- {
- move( $tmpfile, $file ) or die "Cannot move '$tmpfile' to '$file'";
-
- system( "git add $file" );
- print "Fixed whitespace in '$file'\n";
- }
-}
-
-# go through the patch and collect lines to fix
-sub check_and_fix_whitespace($)
+sub check_whitespaces($)
{
- my ( $head ) = @_;
-
- my $file = "";
- my %lines = ();
- my $line_no = 0;
- my $line_max = -1;
-
- my $stash = "";
-
- # any not staged changes to stash away?
- system( "git update-index -q --refresh" );
- if ( `git diff --name-only --` ) {
- my $fd;
- ( $fd, $stash ) = mkstemp( "/tmp/unstaged-changes-XXXXXX" );
- close( $fd );
-
- # this will keep the staged changes
- system( "git diff > $stash" );
- system( "git checkout ." );
+ my ($h) = @_;
+
+ my $found_bad = 0;
+ my $filename;
+ my $reported_filename = "";
+ my $lineno;
+ sub bad_line {
+ my ($why, $line) = @_;
+ if (!$found_bad) {
+ print STDERR "*\n";
+ print STDERR "* You have some suspicious patch lines:\n";
+ print STDERR "*\n";
+ $found_bad = 1;
+ }
+ if ($reported_filename ne $filename) {
+ print STDERR "* In $filename\n";
+ $reported_filename = $filename;
+ }
+ print STDERR "* $why (line $lineno)\n";
+ print STDERR "$filename:$lineno:$line\n";
}
- open( FILES, "git diff-index --cached --diff-filter=ACM --name-only $head |" ) || die "Cannot run git diff-index.";
- while( my $file = <FILES> ) {
- chomp( $file );
- if ( $file ne "GNUmakefile" &&
- ( $file =~ /\.(c|cpp|cxx|h|hrc|hxx|idl|inl|java|map|MK|pl|pm|pmk|py|sdi|sh|src|tab)/ ) ) {
- open( F, "git diff-index -p --cached $head -- $file |" );
- while ( my $line = <F> ) {
- if ( $line =~ /^\+\+\+ (.*)/ ) {
- %lines = ();
- $line_no = 0;
- $line_max = -1;
- }
- elsif ( $line =~ /^@@ -[0-9]+,[0-9]+ \+([0-9]+),([0-9]+) @@/ ) {
- $line_no = $1;
- $line_max = $line_no + $2;
- }
- elsif ( ( $line_no < $line_max ) && ( $line =~ /^[ +]/ ) ) {
- if ( $line =~ /^\+.*[ \t]$/ ) {
- $lines{$line_no} = 1;
- }
- ++$line_no;
- }
- }
- fix_whitespace( $file, \%lines );
- close( IN );
- if ($stash) {
- system( "git apply < $stash" );
- unlink( $stash );
- }
- }
+ open( FILES, "git-diff-index -p -M --cached $h |" ) || die "Cannot run git diff-index.";
+ while (<FILES>) {
+ if (m|^diff --git a/(.*) b/\1$|) {
+ $filename = $1;
+ next;
+ }
+ if (/^@@ -\S+ \+(\d+)/) {
+ $lineno = $1 - 1;
+ next;
+ }
+ if (/^ /) {
+ $lineno++;
+ next;
+ }
+ if (s/^\+//) {
+ $lineno++;
+ chomp;
+ if (/\s$/) {
+ bad_line("trailing whitespace", $_);
+ }
+ if (/^\s* /) {
+ bad_line("indent SP followed by a TAB", $_);
+ }
+ if (/^(?:[<>=]){7}/) {
+ bad_line("unresolved merge conflict", $_);
+ }
+ }
+ }
+ if ( $found_bad)
+ {
+ exit($found_bad);
}
}
@@ -222,7 +186,7 @@ EOM
}
# fix whitespace in code
-check_and_fix_whitespace( $against );
+check_whitespaces( $against );
# check the rest of the files
my $filter_patches=`git diff-index --check --cached $against -- | sed '/\.\(diff\|patch\):/,/.*/d'`;