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
c21398be6d7b112fa3a041b4b7d869d9954bf753
1 file changed
+58
-23
gitk
+58
-23
@@ -3167,6 +3167,28 @@ proc flist_hl {only} {
3167
set gdttype [mc "touching paths:"]
3168
}
3169
3170
+proc gitknewtmpdir {} {
3171
+ global diffnum gitktmpdir gitdir
3172
+
3173
+ if {![info exists gitktmpdir]} {
3174
+ set gitktmpdir [file join [file dirname $gitdir] \
3175
+ [format ".gitk-tmp.%s" [pid]]]
3176
+ if {[catch {file mkdir $gitktmpdir} err]} {
3177
+ error_popup "[mc "Error creating temporary directory %s:" $gitktmpdir] $err"
3178
+ unset gitktmpdir
3179
+ return {}
3180
+ }
3181
+ set diffnum 0
3182
+ }
3183
+ incr diffnum
3184
+ set diffdir [file join $gitktmpdir $diffnum]
3185
+ if {[catch {file mkdir $diffdir} err]} {
3186
+ error_popup "[mc "Error creating temporary directory %s:" $diffdir] $err"
3187
+ return {}
3188
+ }
3189
+ return $diffdir
3190
+}
3191
+
3192
proc save_file_from_commit {filename output what} {
3193
global nullfile
3194
@@ -3201,11 +3223,10 @@ proc external_diff_get_one_file {diffid filename diffdir} {
3223
}
3224
3225
proc external_diff {} {
3204
- global gitktmpdir nullid nullid2
3226
+ global nullid nullid2
3227
global flist_menu_file
3228
global diffids
3207
- global diffnum
3208
- global gitdir extdifftool
3229
+ global extdifftool
3230
3231
if {[llength $diffids] == 1} {
3232
# no reference commit given
@@ -3227,22 +3248,8 @@ proc external_diff {} {
3248
}
3249
3250
# make sure that several diffs wont collide
3230
- if {![info exists gitktmpdir]} {
3231
- set gitktmpdir [file join [file dirname $gitdir] \
3232
- [format ".gitk-tmp.%s" [pid]]]
3233
- if {[catch {file mkdir $gitktmpdir} err]} {
3234
- error_popup "[mc "Error creating temporary directory %s:" $gitktmpdir] $err"
3235
- unset gitktmpdir
3236
- return
3237
- }
3238
- set diffnum 0
3239
- }
3240
- incr diffnum
3241
- set diffdir [file join $gitktmpdir $diffnum]
3242
- if {[catch {file mkdir $diffdir} err]} {
3243
- error_popup "[mc "Error creating temporary directory %s:" $diffdir] $err"
3244
- return
3245
- }
3251
+ set diffdir [gitknewtmpdir]
3252
+ if {$diffdir eq {}} return
3253
3254
# gather files to diff
3255
set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir]
@@ -7400,7 +7407,7 @@ proc getblobdiffline {bdf ids} {
7407
$ctext conf -state normal
7408
while {[incr nr] <= 1000 && [gets $bdf line] >= 0} {
7409
if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
7403
- close $bdf
7410
+ catch {close $bdf}
7411
return 0
7412
}
7413
if {![string compare -length 5 "diff " $line]} {
@@ -7552,7 +7559,7 @@ proc getblobdiffline {bdf ids} {
7559
}
7560
$ctext conf -state disabled
7561
if {[eof $bdf]} {
7555
- close $bdf
7562
+ catch {close $bdf}
7563
return 0
7564
}
7565
return [expr {$nr >= 1000? 2: 1}]
@@ -8273,8 +8280,11 @@ proc do_cmp_commits {a b} {
8280
appendshortlink $a [mc "Commit "] " $heada\n"
8281
appendshortlink $b [mc " differs from\n "] \
8282
" $headb\n"
8276
- $ctext insert end [mc "- stopping\n"]
8277
- break
8283
+ $ctext insert end [mc "Diff of commits:\n\n"]
8284
+ $ctext conf -state disabled
8285
+ update
8286
+ diffcommits $a $b
8287
+ return
8288
}
8289
}
8290
if {$skipa} {
@@ -8300,6 +8310,31 @@ proc do_cmp_commits {a b} {
8310
$ctext conf -state disabled
8311
}
8312
8313
+proc diffcommits {a b} {
8314
+ global diffcontext diffids blobdifffd diffinhdr
8315
+
8316
+ set tmpdir [gitknewtmpdir]
8317
+ set fna [file join $tmpdir "commit-[string range $a 0 7]"]
8318
+ set fnb [file join $tmpdir "commit-[string range $b 0 7]"]
8319
+ if {[catch {
8320
+ exec git diff-tree -p --pretty $a >$fna
8321
+ exec git diff-tree -p --pretty $b >$fnb
8322
+ } err]} {
8323
+ error_popup [mc "Error writing commit to file: %s" $err]
8324
+ return
8325
+ }
8326
+ if {[catch {
8327
+ set fd [open "| diff -U$diffcontext $fna $fnb" r]
8328
+ } err]} {
8329
+ error_popup [mc "Error diffing commits: %s" $err]
8330
+ return
8331
+ }
8332
+ set diffids [list commits $a $b]
8333
+ set blobdifffd($diffids) $fd
8334
+ set diffinhdr 0
8335
+ filerun $fd [list getblobdiffline $fd $diffids]
8336
+}
8337
+
8338
proc diffvssel {dirn} {
8339
global rowmenuid selectedline
8340