+ set diffmergeid $id
+ set diffpindex -1
+ set diffmergegca [findgca $parents($id)]
+ if {[info exists mergefilelist($id)]} {
+ showmergediff
+ } else {
+ contmergediff {}
+ }
+}
+
+proc findgca {ids} {
+ set gca {}
+ foreach id $ids {
+ if {$gca eq {}} {
+ set gca $id
+ } else {
+ if {[catch {
+ set gca [exec git-merge-base $gca $id]
+ } err]} {
+ return {}
+ }
+ }
+ }
+ return $gca
+}
+
+proc contmergediff {ids} {
+ global diffmergeid diffpindex parents nparents diffmergegca
+ global treediffs mergefilelist diffids
+
+ # diff the child against each of the parents, and diff
+ # each of the parents against the GCA.
+ while 1 {
+ if {[lindex $ids 0] == $diffmergeid && $diffmergegca ne {}} {
+ set ids [list [lindex $ids 1] $diffmergegca]
+ } else {
+ if {[incr diffpindex] >= $nparents($diffmergeid)} break
+ set p [lindex $parents($diffmergeid) $diffpindex]
+ set ids [list $diffmergeid $p]
+ }
+ if {![info exists treediffs($ids)]} {
+ set diffids $ids
+ gettreediffs $ids
+ return
+ }
+ }
+
+ # If a file in some parent is different from the child and also
+ # different from the GCA, then it's interesting.
+ # If we don't have a GCA, then a file is interesting if it is
+ # different from the child in all the parents.
+ if {$diffmergegca ne {}} {
+ set files {}
+ foreach p $parents($diffmergeid) {
+ set gcadiffs $treediffs([list $p $diffmergegca])
+ foreach f $treediffs([list $diffmergeid $p]) {
+ if {[lsearch -exact $files $f] < 0
+ && [lsearch -exact $gcadiffs $f] >= 0} {
+ lappend files $f
+ }
+ }
+ }
+ set files [lsort $files]
+ } else {
+ set p [lindex $parents($diffmergeid) 0]
+ set files $treediffs([list $diffmergeid $p])
+ for {set i 1} {$i < $nparents($diffmergeid) && $files ne {}} {incr i} {
+ set p [lindex $parents($diffmergeid) $i]
+ set df $treediffs([list $diffmergeid $p])
+ set nf {}
+ foreach f $files {
+ if {[lsearch -exact $df $f] >= 0} {
+ lappend nf $f
+ }
+ }
+ set files $nf
+ }
+ }
+
+ set mergefilelist($diffmergeid) $files
+ showmergediff
+}
+
+proc showmergediff {} {
+ global cflist diffmergeid mergefilelist
+
+ set files $mergefilelist($diffmergeid)
+ foreach f $files {
+ $cflist insert end $f
+ }