@matheusbsbs / matheus-bagliano / commits / c21398be6d
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 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