Skip to content

Commit c21398b

Browse files
committed
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 <[email protected]>
1 parent b53bb30 commit c21398b

File tree

1 file changed

+58
-23
lines changed

1 file changed

+58
-23
lines changed

gitk

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3167,6 +3167,28 @@ proc flist_hl {only} {
31673167
set gdttype [mc "touching paths:"]
31683168
}
31693169

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+
31703192
proc save_file_from_commit {filename output what} {
31713193
global nullfile
31723194

@@ -3201,11 +3223,10 @@ proc external_diff_get_one_file {diffid filename diffdir} {
32013223
}
32023224

32033225
proc external_diff {} {
3204-
global gitktmpdir nullid nullid2
3226+
global nullid nullid2
32053227
global flist_menu_file
32063228
global diffids
3207-
global diffnum
3208-
global gitdir extdifftool
3229+
global extdifftool
32093230

32103231
if {[llength $diffids] == 1} {
32113232
# no reference commit given
@@ -3227,22 +3248,8 @@ proc external_diff {} {
32273248
}
32283249

32293250
# 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
32463253

32473254
# gather files to diff
32483255
set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir]
@@ -7400,7 +7407,7 @@ proc getblobdiffline {bdf ids} {
74007407
$ctext conf -state normal
74017408
while {[incr nr] <= 1000 && [gets $bdf line] >= 0} {
74027409
if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
7403-
close $bdf
7410+
catch {close $bdf}
74047411
return 0
74057412
}
74067413
if {![string compare -length 5 "diff " $line]} {
@@ -7552,7 +7559,7 @@ proc getblobdiffline {bdf ids} {
75527559
}
75537560
$ctext conf -state disabled
75547561
if {[eof $bdf]} {
7555-
close $bdf
7562+
catch {close $bdf}
75567563
return 0
75577564
}
75587565
return [expr {$nr >= 1000? 2: 1}]
@@ -8273,8 +8280,11 @@ proc do_cmp_commits {a b} {
82738280
appendshortlink $a [mc "Commit "] " $heada\n"
82748281
appendshortlink $b [mc " differs from\n "] \
82758282
" $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
82788288
}
82798289
}
82808290
if {$skipa} {
@@ -8300,6 +8310,31 @@ proc do_cmp_commits {a b} {
83008310
$ctext conf -state disabled
83018311
}
83028312

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+
83038338
proc diffvssel {dirn} {
83048339
global rowmenuid selectedline
83058340

0 commit comments

Comments
 (0)