From: Paul Mackerras Date: Thu, 9 Apr 2009 12:10:20 +0000 (+1000) Subject: gitk: Add a command to compare two strings of commits X-Git-Tag: v1.6.3-rc4~4^2~9 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=010509f2;p=git.git gitk: Add a command to compare two strings of commits This adds a row context menu command to compare this commit and its descendants with the marked commit and its descendants. The results are shown in the bottom-left pane. Commits are compared by checking whether their headlines are the same and their patches have the same patch ID as generated by git patch-id. Merges are ignored and skipped over (as long as they have one descendant). If two commits have the same patch ID then the process will continue and compare their descendants, as long as they both have exactly one descendant. If either commit has 0 or 2 or more descendants, the comparison stops there. There is currently a limit of 100 comparisons. This can be useful for checking whether one string of commits is just a rebased version of another string of commits. Mark the end of one string (i.e. the oldest commit in the string) and invoke "Compare with marked commit" on the end of the other string. As this is implemented, the UI will be unresponsive while the results are being generated. This should be fixed. Signed-off-by: Paul Mackerras --- diff --git a/gitk b/gitk index 628f6e5c5..bdd12236b 100755 --- a/gitk +++ b/gitk @@ -2362,6 +2362,7 @@ proc makewindow {} { {mc "Mark this commit" command markhere} {mc "Return to mark" command gotomark} {mc "Find descendant of this and mark" command find_common_desc} + {mc "Compare with marked commit" command compare_commits} } $rowctxmenu configure -tearoff 0 @@ -8037,9 +8038,11 @@ proc rowmenu {x y id} { if {[info exists markedid] && $markedid ne $id} { $menu entryconfigure 9 -state normal $menu entryconfigure 10 -state normal + $menu entryconfigure 11 -state normal } else { $menu entryconfigure 9 -state disabled $menu entryconfigure 10 -state disabled + $menu entryconfigure 11 -state disabled } } else { set menu $fakerowmenu @@ -8103,6 +8106,92 @@ proc find_common_desc {} { #puts "took [expr {$t2-$t1}]ms" } +proc compare_commits {} { + global markedid rowmenuid curview children + + if {![info exists markedid]} return + if {![commitinview $markedid $curview]} return + addtohistory [list do_cmp_commits $markedid $rowmenuid] + do_cmp_commits $markedid $rowmenuid +} + +proc getpatchid {id} { + global patchids + + if {![info exists patchids($id)]} { + set x [exec git diff-tree -p --root $id | git patch-id] + set patchids($id) [lindex $x 0] + } + return $patchids($id) +} + +proc do_cmp_commits {a b} { + global ctext curview parents children patchids commitinfo + + $ctext conf -state normal + clear_ctext + init_flist {} + for {set i 0} {$i < 100} {incr i} { + set shorta [string range $a 0 7] + set shortb [string range $b 0 7] + set skipa 0 + set skipb 0 + if {[llength $parents($curview,$a)] > 1} { + appendwithlinks [mc "Skipping merge commit %s\n" $shorta] {} + set skipa 1 + } else { + set patcha [getpatchid $a] + } + if {[llength $parents($curview,$b)] > 1} { + appendwithlinks [mc "Skipping merge commit %s\n" $shortb] {} + set skipb 1 + } else { + set patchb [getpatchid $b] + } + if {!$skipa && !$skipb} { + set heada [lindex $commitinfo($a) 0] + set headb [lindex $commitinfo($b) 0] + if {$patcha eq $patchb} { + if {$heada eq $headb} { + appendwithlinks [mc "Commit %s == %s %s\n" \ + $shorta $shortb $heada] {} + } else { + appendwithlinks [mc "Commit %s %s\n" $shorta $heada] {} + appendwithlinks [mc " is the same patch as\n"] {} + appendwithlinks [mc " %s %s\n" $shortb $headb] {} + } + set skipa 1 + set skipb 1 + } else { + $ctext insert end "\n" + appendwithlinks [mc "Commit %s %s\n" $shorta $heada] {} + appendwithlinks [mc " differs from\n"] {} + appendwithlinks [mc " %s %s\n" $shortb $headb] {} + appendwithlinks [mc "- stopping\n"] + break + } + } + if {$skipa} { + if {[llength $children($curview,$a)] != 1} { + $ctext insert end "\n" + appendwithlinks [mc "Commit %s has %s children - stopping\n" \ + $shorta [llength $children($curview,$a)]] {} + break + } + set a [lindex $children($curview,$a) 0] + } + if {$skipb} { + if {[llength $children($curview,$b)] != 1} { + appendwithlinks [mc "Commit %s has %s children - stopping\n" \ + $shortb [llength $children($curview,$b)]] {} + break + } + set b [lindex $children($curview,$b) 0] + } + } + $ctext conf -state disabled +} + proc diffvssel {dirn} { global rowmenuid selectedline