aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-11-04 12:57:44 +1100
committerPaul Mackerras <paulus@samba.org>2008-11-04 12:57:44 +1100
commitfc4977e1b989503c6dcfbc527cda2458d63d0400 (patch)
tree4417becbd6e41cbbc5f725d3e56e6e9002a3e971
parent8b07dca18a498c5900edc717d216e841d6c15dc9 (diff)
downloadgit-fc4977e1b989503c6dcfbc527cda2458d63d0400.tar.gz
git-fc4977e1b989503c6dcfbc527cda2458d63d0400.tar.xz
gitk: Make "show origin of this line" work on fake commits
This makes the "Show origin of this line" menu item work correctly on the fake commits that gitk shows for local uncommitted changes. With the fake commit for changes that aren't checked in to the index, we can actually get a 3-way diff shown, which means we might have to blame either the parent or the commit being merged in (which we get from .git/MERGE_HEAD). If the parent is the fake commit which shows the changes that have been checked in to the index, then we need to get the SHA1 of the blob for the version of the file that is in the index, then use git cat-file blob to get the contents of the blob, and give that to git blame with --contents - so that git blame will do the blame on the index version of the file. In that case, we might get the all-zeroes SHA1 back from git blame, meaning that the line is new in the index version of the file, so then we have to use $nullid2 (the pseudo-SHA1 of the fake commit for the checked-in changes). Signed-off-by: Paul Mackerras <paulus@samba.org>
-rwxr-xr-xgitk64
1 files changed, 61 insertions, 3 deletions
diff --git a/gitk b/gitk
index e6e49fc5c..f386981cc 100755
--- a/gitk
+++ b/gitk
@@ -3238,6 +3238,22 @@ proc external_blame_diff {} {
external_blame $parent_idx $line
}
+# Find the SHA1 ID of the blob for file $fname in the index
+# at stage 0 or 2
+proc index_sha1 {fname} {
+ set f [open [list | git ls-files -s $fname] r]
+ while {[gets $f line] >= 0} {
+ set info [lindex [split $line "\t"] 0]
+ set stage [lindex $info 2]
+ if {$stage eq "0" || $stage eq "2"} {
+ close $f
+ return [lindex $info 1]
+ }
+ }
+ close $f
+ return {}
+}
+
proc external_blame {parent_idx {line {}}} {
global flist_menu_file
global nullid nullid2
@@ -3267,7 +3283,9 @@ proc external_blame {parent_idx {line {}}} {
proc show_line_source {} {
global cmitmode currentid parents curview blamestuff blameinst
global diff_menu_line diff_menu_filebase flist_menu_file
+ global nullid nullid2 gitdir
+ set from_index {}
if {$cmitmode eq "tree"} {
set id $currentid
set line [expr {$diff_menu_line - $diff_menu_filebase}]
@@ -3279,11 +3297,46 @@ proc show_line_source {} {
mark_ctext_line $diff_menu_line
return
}
- set id [lindex $parents($curview,$currentid) [expr {$pi - 1}]]
+ incr pi -1
+ if {$currentid eq $nullid} {
+ if {$pi > 0} {
+ # must be a merge in progress...
+ if {[catch {
+ # get the last line from .git/MERGE_HEAD
+ set f [open [file join $gitdir MERGE_HEAD] r]
+ set id [lindex [split [read $f] "\n"] end-1]
+ close $f
+ } err]} {
+ error_popup [mc "Couldn't read merge head: %s" $err]
+ return
+ }
+ } elseif {$parents($curview,$currentid) eq $nullid2} {
+ # need to do the blame from the index
+ if {[catch {
+ set from_index [index_sha1 $flist_menu_file]
+ } err]} {
+ error_popup [mc "Error reading index: %s" $err]
+ return
+ }
+ }
+ } else {
+ set id [lindex $parents($curview,$currentid) $pi]
+ }
set line [lindex $h 1]
}
+ set blameargs {}
+ if {$from_index ne {}} {
+ lappend blameargs | git cat-file blob $from_index
+ }
+ lappend blameargs | git blame -p -L$line,+1
+ if {$from_index ne {}} {
+ lappend blameargs --contents -
+ } else {
+ lappend blameargs $id
+ }
+ lappend blameargs -- $flist_menu_file
if {[catch {
- set f [open [list | git blame -p -L$line,+1 $id -- $flist_menu_file] r]
+ set f [open $blameargs r]
} err]} {
error_popup [mc "Couldn't start git blame: %s" $err]
return
@@ -3305,7 +3358,7 @@ proc stopblaming {} {
}
proc read_line_source {fd inst} {
- global blamestuff curview commfd blameinst
+ global blamestuff curview commfd blameinst nullid nullid2
while {[gets $fd line] >= 0} {
lappend blamestuff($inst) $line
@@ -3337,6 +3390,11 @@ proc read_line_source {fd inst} {
}
if {$fname ne {}} {
# all looks good, select it
+ if {$id eq $nullid} {
+ # blame uses all-zeroes to mean not committed,
+ # which would mean a change in the index
+ set id $nullid2
+ }
if {[commitinview $id $curview]} {
selectline [rowofcommit $id] 1 [list $fname $lnum]
} else {