git-gui: Allow staging/unstaging individual diff hunks.
authorShawn O. Pearce <spearce@spearce.org>
Thu, 25 Jan 2007 02:20:57 +0000 (21:20 -0500)
committerShawn O. Pearce <spearce@spearce.org>
Thu, 25 Jan 2007 05:25:32 +0000 (00:25 -0500)
commita25c51893317bcbd8e8a85b6da3a573fcd096d86
treeb984e4e18aa9fc10cb3e7c972cda34cf7bb57e8e
parent86773d9bfc6124dec7b33094103f4819684bc4ae
git-gui: Allow staging/unstaging individual diff hunks.

Just like `git-add --interactive` we can now stage and unstage individual
hunks within a file, rather than the entire file at once.  This works
on the basic idea of scanning backwards from the mouse position to
find the hunk header, then going forwards to find the end of the hunk.
Everything in that is sent to `git apply --cached`, prefixed by the
diff header lines.

We ignore whitespace errors while applying a hunk, as we expect the
user's pre-commit hook to catch any possible problems. This matches
our existing behavior with regards to adding an entire file with
no whitespace error checking.

Applying hunks means that we now have to capture and save the diff header
lines, rather than chucking them.  Not really a big deal, we just needed
a new global to hang onto that current header information.  We probably
could have recreated it on demand during apply_hunk but that would mean
we need to implement all of the funny rules about how to encode weird
path names (e.g. ones containing LF) into a diff header so that the
`git apply` process would understand what we are asking it to do.  Much
simpler to just store this small amount of data in a global and replay
it when needed.

I'm making absolutely no attempt to correct the line numbers on the
remaining hunk headers after one hunk has been applied.  This may
cause some hunks to fail, as the position information would not be
correct.  Users can always refresh the current diff before applying a
failing hunk to work around the issue.  Perhaps if we ever implement
hunk splitting we could also fix the remaining hunk headers.

Applying hunks directly means that we need to process the diff data in
binary, rather than using the system encoding and an automatic linefeed
translation.  This ensures that CRLF formatted files will be able to be
fed directly to `git apply` without failures.  Unfortunately it also means
we will see CRs show up in the GUI as ugly little boxes at the end of
each line in a CRLF file.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui.sh