Hi Kendy, Here is a git pre-commit patch. The motivation is that I regularly use git add -p to stage a part of a file, then git commit to commit the staged changes only. The hook staged the entire file till now in case I introduced a whitespace error. The patch should fix this issue. OK to push to master? Thanks.
From fb4a829b5f8a1eb4fb8a62d105217a8375dd6a62 Mon Sep 17 00:00:00 2001 From: Miklos Vajna <vmiklos@frugalware.org> Date: Thu, 3 Mar 2011 01:30:27 +0100 Subject: [PATCH] git-hooks: don't stage unstaged hunks before commit We call 'git add' for files where we fixed whitespaces in. This is a problem in case the user staged only part of a file - as a result we do not just fix up whitespace in the patch but also stage other hunks of the file. Fix the problem by removing/restoring not staged changes before/after whitespace fixing. The operation is cheap enough, as it's a noop in case there are no unstaged changes. --- git-hooks/pre-commit | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/git-hooks/pre-commit b/git-hooks/pre-commit index cee3a7f..8192e58 100755 --- a/git-hooks/pre-commit +++ b/git-hooks/pre-commit @@ -58,6 +58,18 @@ sub check_and_fix_whitespace($) 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 ." ); + } open( IN, "git diff-index -p --no-prefix --cached $head -- |" ) || die "Cannot get git diff-index"; while ( my $line = <IN> ) { if ( $line =~ /^\+\+\+ (.*)/ ) { @@ -80,6 +92,10 @@ sub check_and_fix_whitespace($) } fix_whitespace( $file, \%lines ); close( IN ); + if ($stash) { + system( "git apply < $stash" ); + unlink( $stash ); + } } # Do the work :-) -- 1.7.4.1
Attachment:
pgpMXtGyPZyUU.pgp
Description: PGP signature