gitk: Show diff of commits at end of compare-commits output
When comparing a string of commits, when we find two non-merge commits that differ, we now write the two commits to files and diff the files. This pulls out the logic for creating a temporary directory from external_diff into a separate procedure so that the new diffcommits procedure can use it. Because the diff command returns an exit status of 1 when the files differ, and Tcl treats that as an error, this adds catch {} around the close statements in getblobdiffline. At present this only removes the temporary files when gitk exits. It should remove them when the diff is done. Signed-off-by: Paul Mackerras <paulus@samba.org>
Paul Mackerras committed
Sep 7, 2009 at 10:08 UTC
4a3da5d91a4768a8abe6a8c64f1c3a49125a5bcf
1 file changed
+58
-23
gitk
+58
-23
@@ -3278,6 +3278,28 @@ proc flist_hl {only} {
3278
set gdttype [mc "touching paths:"]
3279
}
3280
3281
+proc gitknewtmpdir {} {
3282
+ global diffnum gitktmpdir gitdir
3283
+
3284
+ if {![info exists gitktmpdir]} {
3285
+ set gitktmpdir [file join [file dirname $gitdir] \
3286
+ [format ".gitk-tmp.%s" [pid]]]
3287
+ if {[catch {file mkdir $gitktmpdir} err]} {
3288
+ error_popup "[mc "Error creating temporary directory %s:" $gitktmpdir] $err"
3289
+ unset gitktmpdir
3290
+ return {}
3291
+ }
3292
+ set diffnum 0
3293
+ }
3294
+ incr diffnum
3295
+ set diffdir [file join $gitktmpdir $diffnum]
3296
+ if {[catch {file mkdir $diffdir} err]} {
3297
+ error_popup "[mc "Error creating temporary directory %s:" $diffdir] $err"
3298
+ return {}
3299
+ }
3300
+ return $diffdir
3301
+}
3302
+
3303
proc save_file_from_commit {filename output what} {
3304
global nullfile
3305
@@ -3312,11 +3334,10 @@ proc external_diff_get_one_file {diffid filename diffdir} {
3334
}
3335
3336
proc external_diff {} {
3315
- global gitktmpdir nullid nullid2
3337
+ global nullid nullid2
3338
global flist_menu_file
3339
global diffids
3318
- global diffnum
3319
- global gitdir extdifftool
3340
+ global extdifftool
3341
3342
if {[llength $diffids] == 1} {
3343
# no reference commit given
@@ -3338,22 +3359,8 @@ proc external_diff {} {
3359
}
3360
3361
# make sure that several diffs wont collide
3341
- if {![info exists gitktmpdir]} {
3342
- set gitktmpdir [file join [file dirname $gitdir] \
3343
- [format ".gitk-tmp.%s" [pid]]]
3344
- if {[catch {file mkdir $gitktmpdir} err]} {
3345
- error_popup "[mc "Error creating temporary directory %s:" $gitktmpdir] $err"
3346
- unset gitktmpdir
3347
- return
3348
- }
3349
- set diffnum 0
3350
- }
3351
- incr diffnum
3352
- set diffdir [file join $gitktmpdir $diffnum]
3353
- if {[catch {file mkdir $diffdir} err]} {
3354
- error_popup "[mc "Error creating temporary directory %s:" $diffdir] $err"
3355
- return
3356
- }
3362
+ set diffdir [gitknewtmpdir]
3363
+ if {$diffdir eq {}} return
3364
3365
# gather files to diff
3366
set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir]
@@ -7573,7 +7580,7 @@ proc getblobdiffline {bdf ids} {
7580
$ctext conf -state normal
7581
while {[incr nr] <= 1000 && [gets $bdf line] >= 0} {
7582
if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
7576
- close $bdf
7583
+ catch {close $bdf}
7584
return 0
7585
}
7586
if {![string compare -length 5 "diff " $line]} {
@@ -7726,7 +7733,7 @@ proc getblobdiffline {bdf ids} {
7733
maybe_scroll_ctext [eof $bdf]
7734
$ctext conf -state disabled
7735
if {[eof $bdf]} {
7729
- close $bdf
7736
+ catch {close $bdf}
7737
return 0
7738
}
7739
return [expr {$nr >= 1000? 2: 1}]
@@ -8448,8 +8455,11 @@ proc do_cmp_commits {a b} {
8455
appendshortlink $a [mc "Commit "] " $heada\n"
8456
appendshortlink $b [mc " differs from\n "] \
8457
" $headb\n"
8451
- $ctext insert end [mc "- stopping\n"]
8452
- break
8458
+ $ctext insert end [mc "Diff of commits:\n\n"]
8459
+ $ctext conf -state disabled
8460
+ update
8461
+ diffcommits $a $b
8462
+ return
8463
}
8464
}
8465
if {$skipa} {
@@ -8475,6 +8485,31 @@ proc do_cmp_commits {a b} {
8485
$ctext conf -state disabled
8486
}
8487
8488
+proc diffcommits {a b} {
8489
+ global diffcontext diffids blobdifffd diffinhdr
8490
+
8491
+ set tmpdir [gitknewtmpdir]
8492
+ set fna [file join $tmpdir "commit-[string range $a 0 7]"]
8493
+ set fnb [file join $tmpdir "commit-[string range $b 0 7]"]
8494
+ if {[catch {
8495
+ exec git diff-tree -p --pretty $a >$fna
8496
+ exec git diff-tree -p --pretty $b >$fnb
8497
+ } err]} {
8498
+ error_popup [mc "Error writing commit to file: %s" $err]
8499
+ return
8500
+ }
8501
+ if {[catch {
8502
+ set fd [open "| diff -U$diffcontext $fna $fnb" r]
8503
+ } err]} {
8504
+ error_popup [mc "Error diffing commits: %s" $err]
8505
+ return
8506
+ }
8507
+ set diffids [list commits $a $b]
8508
+ set blobdifffd($diffids) $fd
8509
+ set diffinhdr 0
8510
+ filerun $fd [list getblobdiffline $fd $diffids]
8511
+}
8512
+
8513
proc diffvssel {dirn} {
8514
global rowmenuid selectedline
8515