All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Gavrilov <angavrilov@gmail.com>
To: git@vger.kernel.org
Cc: Paul Mackerras <paulus@samba.org>,
	"Shawn O. Pearce" <spearce@spearce.org>,
	Junio C Hamano <gitster@pobox.com>
Subject: [PATCH (GITK,GIT-GUI,DOCS) 5/7] git-gui: Better positioning in Blame Parent Commit
Date: Sat, 23 Aug 2008 12:31:35 +0400	[thread overview]
Message-ID: <200808231231.35635.angavrilov@gmail.com> (raw)
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

  reply	other threads:[~2008-08-23  8:32 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-23  8:25 [PATCH (GITK,GIT-GUI,DOCS) 0/7] Improve gui blame and gitk integration Alexander Gavrilov
2008-08-23  8:27 ` [PATCH (GITK,GIT-GUI,DOCS) 1/7] gitk: Allow overriding the default commit Alexander Gavrilov
2008-08-23  8:29   ` [PATCH (GITK,GIT-GUI,DOCS) 2/7] gitk: Support calling git gui blame from gitk Alexander Gavrilov
2008-08-26 10:27     ` Paul Mackerras
2008-08-26 12:10       ` Johannes Sixt
2008-08-26 10:13   ` [PATCH (GITK,GIT-GUI,DOCS) 1/7] gitk: Allow overriding the default commit Paul Mackerras
2008-08-23  8:30 ` [PATCH (GITK,GIT-GUI,DOCS) 3/7] git-gui: Support starting gitk from Gui Blame Alexander Gavrilov
2008-08-23  8:30   ` [PATCH (GITK,GIT-GUI,DOCS) 4/7] git-gui: Support passing blame to a parent commit Alexander Gavrilov
2008-08-23  8:31     ` Alexander Gavrilov [this message]
2008-08-23  8:32       ` [PATCH (GITK,GIT-GUI,DOCS) 6/7] git-gui: Allow specifying an initial line for git gui blame Alexander Gavrilov
2008-08-25  5:06   ` [PATCH (GITK,GIT-GUI,DOCS) 3/7] git-gui: Support starting gitk from Gui Blame Shawn O. Pearce
2008-08-23  8:33 ` [PATCH (GITK,GIT-GUI,DOCS) 7/7] Document new options of gui tools Alexander Gavrilov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200808231231.35635.angavrilov@gmail.com \
    --to=angavrilov@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=paulus@samba.org \
    --cc=spearce@spearce.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.