Skip to content

Commit 3c461ff

Browse files
Paul Mackerraspaulusmack
authored andcommitted
Calculate the list of interesting files for a merge.
If there is a GCA for the parents of the merge, then a file is interesting if some parent has a version that is different from both the child and the GCA. If there is no GCA (e.g. for a merge that pulls in an external project) then a file is interesting if the child's version is different from all of the parents. Next step is to actually show the differences for the interesting files...
1 parent f065486 commit 3c461ff

File tree

1 file changed

+133
-47
lines changed

1 file changed

+133
-47
lines changed

gitk

Lines changed: 133 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,7 +1504,7 @@ proc donefilediff {} {
15041504
}
15051505

15061506
proc findcont {ids} {
1507-
global findids treediffs parents nparents treepending
1507+
global findids treediffs parents nparents
15081508
global ffileline findstartline finddidsel
15091509
global lineid numcommits matchinglines findinprogress
15101510
global findmergefiles
@@ -1692,27 +1692,121 @@ proc selectline {l} {
16921692

16931693
$cflist delete 0 end
16941694
$cflist insert end "Comments"
1695-
startdiff $id $parents($id)
1695+
if {$nparents($id) == 1} {
1696+
startdiff [concat $id $parents($id)]
1697+
} elseif {$nparents($id) > 1} {
1698+
mergediff $id
1699+
}
1700+
}
1701+
1702+
proc selnextline {dir} {
1703+
global selectedline
1704+
if {![info exists selectedline]} return
1705+
set l [expr $selectedline + $dir]
1706+
unmarkmatches
1707+
selectline $l
16961708
}
16971709

1698-
proc startdiff {id vs} {
1699-
global diffpending diffpindex
1700-
global diffindex difffilestart
1701-
global curdifftag curtagstart
1710+
proc mergediff {id} {
1711+
global parents diffmergeid diffmergegca mergefilelist diffpindex
17021712

1703-
set diffpending $vs
1704-
set diffpindex 0
1705-
set diffindex 0
1706-
catch {unset difffilestart}
1707-
set curdifftag Comments
1708-
set curtagstart 0.0
1709-
contdiff [list $id [lindex $vs 0]]
1713+
set diffmergeid $id
1714+
set diffpindex -1
1715+
set diffmergegca [findgca $parents($id)]
1716+
if {[info exists mergefilelist($id)]} {
1717+
showmergediff
1718+
} else {
1719+
contmergediff {}
1720+
}
1721+
}
1722+
1723+
proc findgca {ids} {
1724+
set gca {}
1725+
foreach id $ids {
1726+
if {$gca eq {}} {
1727+
set gca $id
1728+
} else {
1729+
if {[catch {
1730+
set gca [exec git-merge-base $gca $id]
1731+
} err]} {
1732+
return {}
1733+
}
1734+
}
1735+
}
1736+
return $gca
1737+
}
1738+
1739+
proc contmergediff {ids} {
1740+
global diffmergeid diffpindex parents nparents diffmergegca
1741+
global treediffs mergefilelist diffids
1742+
1743+
# diff the child against each of the parents, and diff
1744+
# each of the parents against the GCA.
1745+
while 1 {
1746+
if {[lindex $ids 0] == $diffmergeid && $diffmergegca ne {}} {
1747+
set ids [list [lindex $ids 1] $diffmergegca]
1748+
} else {
1749+
if {[incr diffpindex] >= $nparents($diffmergeid)} break
1750+
set p [lindex $parents($diffmergeid) $diffpindex]
1751+
set ids [list $diffmergeid $p]
1752+
}
1753+
if {![info exists treediffs($ids)]} {
1754+
set diffids $ids
1755+
gettreediffs $ids
1756+
return
1757+
}
1758+
}
1759+
1760+
# If a file in some parent is different from the child and also
1761+
# different from the GCA, then it's interesting.
1762+
# If we don't have a GCA, then a file is interesting if it is
1763+
# different from the child in all the parents.
1764+
if {$diffmergegca ne {}} {
1765+
set files {}
1766+
foreach p $parents($diffmergeid) {
1767+
set gcadiffs $treediffs([list $p $diffmergegca])
1768+
foreach f $treediffs([list $diffmergeid $p]) {
1769+
if {[lsearch -exact $files $f] < 0
1770+
&& [lsearch -exact $gcadiffs $f] >= 0} {
1771+
lappend files $f
1772+
}
1773+
}
1774+
}
1775+
set files [lsort $files]
1776+
} else {
1777+
set p [lindex $parents($diffmergeid) 0]
1778+
set files $treediffs([list $diffmergeid $p])
1779+
for {set i 1} {$i < $nparents($diffmergeid) && $files ne {}} {incr i} {
1780+
set p [lindex $parents($diffmergeid) $i]
1781+
set df $treediffs([list $diffmergeid $p])
1782+
set nf {}
1783+
foreach f $files {
1784+
if {[lsearch -exact $df $f] >= 0} {
1785+
lappend nf $f
1786+
}
1787+
}
1788+
set files $nf
1789+
}
1790+
}
1791+
1792+
set mergefilelist($diffmergeid) $files
1793+
showmergediff
1794+
}
1795+
1796+
proc showmergediff {} {
1797+
global cflist diffmergeid mergefilelist
1798+
1799+
set files $mergefilelist($diffmergeid)
1800+
foreach f $files {
1801+
$cflist insert end $f
1802+
}
17101803
}
17111804

1712-
proc contdiff {ids} {
1713-
global treediffs diffids treepending
1805+
proc startdiff {ids} {
1806+
global treediffs diffids treepending diffmergeid
17141807

17151808
set diffids $ids
1809+
catch {unset diffmergeid}
17161810
if {![info exists treediffs($ids)]} {
17171811
if {![info exists treepending]} {
17181812
gettreediffs $ids
@@ -1722,79 +1816,76 @@ proc contdiff {ids} {
17221816
}
17231817
}
17241818

1725-
proc selnextline {dir} {
1726-
global selectedline
1727-
if {![info exists selectedline]} return
1728-
set l [expr $selectedline + $dir]
1729-
unmarkmatches
1730-
selectline $l
1731-
}
1732-
17331819
proc addtocflist {ids} {
1734-
global treediffs cflist diffpindex
1735-
1736-
set colors {black blue green red cyan magenta}
1737-
set color [lindex $colors [expr {$diffpindex % [llength $colors]}]]
1820+
global treediffs cflist
17381821
foreach f $treediffs($ids) {
17391822
$cflist insert end $f
1740-
$cflist itemconf end -foreground $color
17411823
}
17421824
getblobdiffs $ids
17431825
}
17441826

17451827
proc gettreediffs {ids} {
1746-
global treediffs parents treepending
1828+
global treediff parents treepending
17471829
set treepending $ids
1748-
set treediffs($ids) {}
1830+
set treediff {}
17491831
set id [lindex $ids 0]
17501832
set p [lindex $ids 1]
17511833
if [catch {set gdtf [open "|git-diff-tree -r $p $id" r]}] return
17521834
fconfigure $gdtf -blocking 0
1753-
fileevent $gdtf readable "gettreediffline $gdtf {$ids}"
1835+
fileevent $gdtf readable [list gettreediffline $gdtf $ids]
17541836
}
17551837

17561838
proc gettreediffline {gdtf ids} {
1757-
global treediffs treepending diffids
1839+
global treediff treediffs treepending diffids diffmergeid
1840+
17581841
set n [gets $gdtf line]
17591842
if {$n < 0} {
17601843
if {![eof $gdtf]} return
17611844
close $gdtf
1845+
set treediffs($ids) $treediff
17621846
unset treepending
1763-
if {[info exists diffids]} {
1764-
if {$ids != $diffids} {
1765-
gettreediffs $diffids
1847+
if {$ids != $diffids} {
1848+
gettreediffs $diffids
1849+
} else {
1850+
if {[info exists diffmergeid]} {
1851+
contmergediff $ids
17661852
} else {
17671853
addtocflist $ids
17681854
}
17691855
}
17701856
return
17711857
}
17721858
set file [lindex $line 5]
1773-
lappend treediffs($ids) $file
1859+
lappend treediff $file
17741860
}
17751861

17761862
proc getblobdiffs {ids} {
1777-
global diffopts blobdifffd diffids env
1778-
global nextupdate diffinhdr
1863+
global diffopts blobdifffd diffids env curdifftag curtagstart
1864+
global diffindex difffilestart nextupdate diffinhdr
17791865

17801866
set id [lindex $ids 0]
17811867
set p [lindex $ids 1]
17821868
set env(GIT_DIFF_OPTS) $diffopts
1783-
if [catch {set bdf [open "|git-diff-tree -r -p $p $id" r]} err] {
1869+
set cmd [list | git-diff-tree -r -p -C $p $id]
1870+
if {[catch {set bdf [open $cmd r]} err]} {
17841871
puts "error getting diffs: $err"
17851872
return
17861873
}
17871874
set diffinhdr 0
17881875
fconfigure $bdf -blocking 0
17891876
set blobdifffd($ids) $bdf
1790-
fileevent $bdf readable [list getblobdiffline $bdf $ids]
1877+
set curdifftag Comments
1878+
set curtagstart 0.0
1879+
set diffindex 0
1880+
catch {unset difffilestart}
1881+
fileevent $bdf readable [list getblobdiffline $bdf $diffids]
17911882
set nextupdate [expr {[clock clicks -milliseconds] + 100}]
17921883
}
17931884

17941885
proc getblobdiffline {bdf ids} {
17951886
global diffids blobdifffd ctext curdifftag curtagstart
17961887
global diffnexthead diffnextnote diffindex difffilestart
1797-
global nextupdate diffpending diffpindex diffinhdr
1888+
global nextupdate diffinhdr
17981889
global gaudydiff
17991890

18001891
set n [gets $bdf line]
@@ -1803,11 +1894,6 @@ proc getblobdiffline {bdf ids} {
18031894
close $bdf
18041895
if {$ids == $diffids && $bdf == $blobdifffd($ids)} {
18051896
$ctext tag add $curdifftag $curtagstart end
1806-
if {[incr diffpindex] < [llength $diffpending]} {
1807-
set id [lindex $ids 0]
1808-
set p [lindex $diffpending $diffpindex]
1809-
contdiff [list $id $p]
1810-
}
18111897
}
18121898
}
18131899
return
@@ -2157,7 +2243,7 @@ proc diffvssel {dirn} {
21572243
$ctext conf -state disabled
21582244
$ctext tag delete Comments
21592245
$ctext tag remove found 1.0 end
2160-
startdiff [list $newid $oldid]
2246+
startdiff $newid [list $oldid]
21612247
}
21622248

21632249
proc mkpatch {} {

0 commit comments

Comments
 (0)