[PATCH] git-gui: Implement "Stage/Unstage Line"

Previous thread: An alternate model for preparing partial commits by Robert Anderson on Thursday, June 26, 2008 - 11:50 pm. (32 messages)

Next thread: Using url.insteadOf in git-clone by Pieter de Bie on Friday, June 27, 2008 - 2:35 am. (26 messages)
From: Johannes Sixt
Date: Friday, June 27, 2008 - 12:22 am

From: Johannes Sixt <johannes.sixt@telecom.at>

This adds a context menu entry below "Stage/Unstage Hunk" that stages or
unstages just the line under the mouse pointer.

This is by itself useful, for example, if there are unrelated changes in
the same hunk and the hunk cannot be split by reducing the context.

The feature can also be used to split a hunk by staging a number of
additions (or unstaging a number of removals) until there are enough
context lines that the hunk gets split.

The implementation reads the complete hunk that the line lives in, and
constructs a new hunk by picking existing context lines, removing unneeded
change lines and transforming other change lines to context lines. The
resulting hunk is fed through 'git apply' just like in the "Stage/Unstage
Hunk" case.

Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
	Disclaimer: I'm Tcl/Tk illiterate. Feel free to munge the patch
	to your taste.

	The 'do_rescan' is probably a bit heavy-weight. But editing the
	diff window like we do in "Stage Hunk" would be a bit complex, and
	just redisplaying the diff is easier.

	Furthermore, I don't know why I have to do the loop until
	"end - 1 chars". If it goes until "end", then the hunk contains
	an extra line, so that the patch in general does not apply.
	Is there an extra newline in the diff view that is not in the
	git diff output?

	-- Hannes

 git-gui.sh   |    8 +++++
 lib/diff.tcl |   87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/git-gui.sh b/git-gui.sh
index 1bbae15..d89f156 100755
--- a/git-gui.sh
+++ b/git-gui.sh
@@ -2666,6 +2666,11 @@ $ctxm add command \
 	-command {apply_hunk $cursorX $cursorY}
 set ui_diff_applyhunk [$ctxm index last]
 lappend diff_actions [list $ctxm entryconf $ui_diff_applyhunk -state]
+$ctxm add command \
+	-label [mc "Apply/Reverse Line"] \
+	-command {apply_line $cursorX $cursorY; do_rescan}
+set ui_diff_applyline [$ctxm index ...
From: Shawn O. Pearce
Date: Tuesday, July 1, 2008 - 10:23 pm

Yea, I see why you are doing a do_rescan at the end.  I was going
to suggest just calling reshow_diff but that doesn't get the lists
updated properly when a file is being initially staged as a result
of the current line being added.


Yup.  Tk text widgets have an extra "\n" at the end of the content
that was inserted into it.  Thus an empty text widget has a single
LF as its content.  Weird, I know.
 
-- 
Shawn.
--

Previous thread: An alternate model for preparing partial commits by Robert Anderson on Thursday, June 26, 2008 - 11:50 pm. (32 messages)

Next thread: Using url.insteadOf in git-clone by Pieter de Bie on Friday, June 27, 2008 - 2:35 am. (26 messages)