git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH (GITK,GIT-GUI,DOCS) 5/7] git-gui: Better positioning in Blame Parent Commit

From
Alexander Gavrilov <angavrilov@gmail.com>
Date
Aug 23, 2008, 08:31 UTC
Message-ID
<200808231231.35635.angavrilov@gmail.com>
In-Reply-To
<200808231230.51693.angavrilov@gmail.com>

Invoke diff-tree between the commit and its parent, and use the hunks to fix the target line number, accounting for addition and removal of lines.

Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
---
 lib/blame.tcl |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/lib/blame.tcl b/lib/blame.tcl
index 8b555a1..1be8145 100644
--- a/lib/blame.tcl
+++ b/lib/blame.tcl
@@ -984,19 +984,76 @@ method _blameparent {} {
 	set dat [_get_click_amov_info $this]
 	if {$dat ne {}} {
 		set cmit [lindex $dat 0]
+		set new_path [lindex $dat 1]
 
 		if {[catch {set cparent [git rev-parse --verify "$cmit^"]}]} {
 			error_popup [strcat [mc "Cannot find parent commit:"] "\n\n$err"]
 			return;
 		}
 
-		_load_new_commit $this  \
-			$cparent \
-			[lindex $dat 1] \
-			[list [lindex $dat 2]]
+		_kill $this
+
+		# Generate a diff between the commit and its parent,
+		# and use the hunks to update the line number.
+		# Request zero context to simplify calculations.
+		if {[catch {set fd [eval git_read diff-tree \
+				--unified=0 $cparent $cmit $new_path]} err]} {
+			$status stop [mc "Unable to display parent"]
+			error_popup [strcat [mc "Error loading diff:"] "\n\n$err"]
+			return
+		}
+
+		set r_orig_line [lindex $dat 2]
+
+		fconfigure $fd \
+			-blocking 0 \
+			-encoding binary \
+			-translation binary
+		fileevent $fd readable [cb _read_diff_load_commit \
+			$fd $cparent $new_path $r_orig_line]
+		set current_fd $fd
 	}
 }
 
+method _read_diff_load_commit {fd cparent new_path tline} {
+	if {$fd ne $current_fd} {
+		catch {close $fd}
+		return
+	}
+
+	while {[gets $fd line] >= 0} {
+		if {[regexp {^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@} $line line \
+			old_line osz old_size new_line nsz new_size]} {
+
+			if {$osz eq {}} { set old_size 1 }
+			if {$nsz eq {}} { set new_size 1 }
+
+			if {$new_line <= $tline} {
+				if {[expr {$new_line + $new_size}] > $tline} {
+					# Target line within the hunk
+					set line_shift [expr {
+						($new_size-$old_size)*($tline-$new_line)/$new_size
+						}]
+				} else {
+					set line_shift [expr {$new_size-$old_size}]
+				}
+
+				set r_orig_line [expr {$r_orig_line - $line_shift}]
+			}
+		}
+	}
+
+	if {[eof $fd]} {
+		close $fd;
+		set current_fd {}
+
+		_load_new_commit $this  \
+			$cparent        \
+			$new_path       \
+			[list $r_orig_line]
+	}
+} ifdeleted { catch {close $fd} }
+
 method _show_tooltip {cur_w pos} {
 	if {$tooltip_wm ne {}} {
 		_open_tooltip $this $cur_w
-- 
1.6.0.rc2
Previous: Alexander GavrilovNext: Alexander Gavrilov
Message 9 of 12 in “Improve gui blame and gitk integration”
  1. 0/7 Improve gui blame and gitk integrationAlexander Gavrilov, Aug 23, 2008
  2. 1/7 gitk: Allow overriding the default commit.Alexander Gavrilov, Aug 23, 2008
  3. 2/7 gitk: Support calling git gui blame from gitk.Alexander Gavrilov, Aug 23, 2008
  4. Paul MackerrasAug 26, 2008
  5. Johannes SixtAug 26, 2008
  6. Paul MackerrasAug 26, 2008
  7. 3/7 git-gui: Support starting gitk from Gui BlameAlexander Gavrilov, Aug 23, 2008
  8. 4/7 git-gui: Support passing blame to a parent commit.Alexander Gavrilov, Aug 23, 2008
  9. 5/7 git-gui: Better positioning in Blame Parent CommitAlexander Gavrilov, Aug 23, 2008
  10. 6/7 git-gui: Allow specifying an initial line for git gui blame.Alexander Gavrilov, Aug 23, 2008
  11. Shawn O. PearceAug 25, 2008
  12. 7/7 Document new options of gui tools.Alexander Gavrilov, Aug 23, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.