3238
external_blame $parent_idx $line
3239
}
3240
3241
+# Find the SHA1 ID of the blob for file $fname in the index
3242
+# at stage 0 or 2
3243
+proc index_sha1 {fname} {
3244
+ set f [open [list | git ls-files -s $fname] r]
3245
+ while {[gets $f line] >= 0} {
3246
+ set info [lindex [split $line "\t"] 0]
3247
+ set stage [lindex $info 2]
3248
+ if {$stage eq "0" || $stage eq "2"} {
3249
+ close $f
3250
+ return [lindex $info 1]
3251
+ }
3252
+ }
3253
+ close $f
3254
+ return {}
3255
+}
3256
+
3257
proc external_blame {parent_idx {line {}}} {
3258
global flist_menu_file
3259
global nullid nullid2
3283
proc show_line_source {} {
3284
global cmitmode currentid parents curview blamestuff blameinst
3285
global diff_menu_line diff_menu_filebase flist_menu_file
3286
+ global nullid nullid2 gitdir
3287
3288
+ set from_index {}
3289
if {$cmitmode eq "tree"} {
3290
set id $currentid
3291
set line [expr {$diff_menu_line - $diff_menu_filebase}]
3297
mark_ctext_line $diff_menu_line
3298
return
3299
}
3282
- set id [lindex $parents($curview,$currentid) [expr {$pi - 1}]]
3300
+ incr pi -1
3301
+ if {$currentid eq $nullid} {
3302
+ if {$pi > 0} {
3303
+ # must be a merge in progress...
3304
+ if {[catch {
3305
+ # get the last line from .git/MERGE_HEAD
3306
+ set f [open [file join $gitdir MERGE_HEAD] r]
3307
+ set id [lindex [split [read $f] "\n"] end-1]
3308
+ close $f
3309
+ } err]} {
3310
+ error_popup [mc "Couldn't read merge head: %s" $err]
3311
+ return
3312
+ }
3313
+ } elseif {$parents($curview,$currentid) eq $nullid2} {
3314
+ # need to do the blame from the index
3315
+ if {[catch {
3316
+ set from_index [index_sha1 $flist_menu_file]
3317
+ } err]} {
3318
+ error_popup [mc "Error reading index: %s" $err]
3319
+ return
3320
+ }
3321
+ }
3322
+ } else {
3323
+ set id [lindex $parents($curview,$currentid) $pi]
3324
+ }
3325
set line [lindex $h 1]
3326
}
3327
+ set blameargs {}
3328
+ if {$from_index ne {}} {
3329
+ lappend blameargs | git cat-file blob $from_index
3330
+ }
3331
+ lappend blameargs | git blame -p -L$line,+1
3332
+ if {$from_index ne {}} {
3333
+ lappend blameargs --contents -
3334
+ } else {
3335
+ lappend blameargs $id
3336
+ }
3337
+ lappend blameargs -- $flist_menu_file
3338
if {[catch {
3286
- set f [open [list | git blame -p -L$line,+1 $id -- $flist_menu_file] r]
3339
+ set f [open $blameargs r]
3340
} err]} {
3341
error_popup [mc "Couldn't start git blame: %s" $err]
3342
return
3358
}
3359
3360
proc read_line_source {fd inst} {
3308
- global blamestuff curview commfd blameinst
3361
+ global blamestuff curview commfd blameinst nullid nullid2
3362
3363
while {[gets $fd line] >= 0} {
3364
lappend blamestuff($inst) $line
3390
}
3391
if {$fname ne {}} {
3392
# all looks good, select it
3393
+ if {$id eq $nullid} {
3394
+ # blame uses all-zeroes to mean not committed,
3395
+ # which would mean a change in the index
3396
+ set id $nullid2
3397
+ }
3398
if {[commitinview $id $curview]} {
3399
selectline [rowofcommit $id] 1 [list $fname $lnum]
3400
} else {