@matheusbsbs / matheus-bagliano / commits / 4a3da5d91a
Fork 0

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