[PATCH] gitk: add Update menu item.
authorSven Verdoolaege <skimo@kotnet.org>
Tue, 29 Nov 2005 21:15:51 +0000 (22:15 +0100)
committerPaul Mackerras <paulus@samba.org>
Thu, 1 Dec 2005 09:01:51 +0000 (20:01 +1100)
Update will redraw the commits if any commits have been added to any
of the selected heads.  The new commits appear on the top.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
gitk

diff --git a/gitk b/gitk
index a847ef6..db61a15 100755 (executable)
--- a/gitk
+++ b/gitk
@@ -16,8 +16,24 @@ proc gitdir {} {
     }
 }
 
     }
 }
 
+proc parse_args {rargs} {
+    global parsed_args
+
+    if [catch {
+       set parse_args [concat --default HEAD $rargs]
+       set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
+    }] {
+       # if git-rev-parse failed for some reason...
+       if {$rargs == {}} {
+           set rargs HEAD
+       }
+       set parsed_args $rargs
+    }
+    return $parsed_args
+}
+
 proc getcommits {rargs} {
 proc getcommits {rargs} {
-    global commits commfd phase canv mainfont env
+    global oldcommits commits commfd phase canv mainfont env
     global startmsecs nextupdate ncmupdate
     global ctext maincursor textcursor leftover gitencoding
 
     global startmsecs nextupdate ncmupdate
     global ctext maincursor textcursor leftover gitencoding
 
@@ -27,21 +43,13 @@ proc getcommits {rargs} {
        error_popup "Cannot find the git directory \"$gitdir\"."
        exit 1
     }
        error_popup "Cannot find the git directory \"$gitdir\"."
        exit 1
     }
+    set oldcommits {}
     set commits {}
     set phase getcommits
     set startmsecs [clock clicks -milliseconds]
     set nextupdate [expr {$startmsecs + 100}]
     set ncmupdate 1
     set commits {}
     set phase getcommits
     set startmsecs [clock clicks -milliseconds]
     set nextupdate [expr {$startmsecs + 100}]
     set ncmupdate 1
-    if [catch {
-       set parse_args [concat --default HEAD $rargs]
-       set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
-    }] {
-       # if git-rev-parse failed for some reason...
-       if {$rargs == {}} {
-           set rargs HEAD
-       }
-       set parsed_args $rargs
-    }
+    set parsed_args [parse_args $rargs]
     if [catch {
        set commfd [open "|git-rev-list --header --topo-order --parents $parsed_args" r]
     } err] {
     if [catch {
        set commfd [open "|git-rev-list --header --topo-order --parents $parsed_args" r]
     } err] {
@@ -59,9 +67,10 @@ proc getcommits {rargs} {
 }
 
 proc getcommitlines {commfd}  {
 }
 
 proc getcommitlines {commfd}  {
-    global commits parents cdate children
+    global oldcommits commits parents cdate children nchildren
     global commitlisted phase nextupdate
     global stopped redisplaying leftover
     global commitlisted phase nextupdate
     global stopped redisplaying leftover
+    global canv
 
     set stuff [read $commfd]
     if {$stuff == {}} {
 
     set stuff [read $commfd]
     if {$stuff == {}} {
@@ -119,10 +128,18 @@ proc getcommitlines {commfd}  {
        set id [lindex $ids 0]
        set olds [lrange $ids 1 end]
        set cmit [string range $cmit [expr {$j + 1}] end]
        set id [lindex $ids 0]
        set olds [lrange $ids 1 end]
        set cmit [string range $cmit [expr {$j + 1}] end]
+       if {$phase == "updatecommits"} {
+           $canv delete all
+           set oldcommits $commits
+           set commits {}
+           unset children
+           unset nchildren
+           set phase getcommits
+       }
        lappend commits $id
        set commitlisted($id) 1
        parsecommit $id $cmit 1 [lrange $ids 1 end]
        lappend commits $id
        set commitlisted($id) 1
        parsecommit $id $cmit 1 [lrange $ids 1 end]
-       drawcommit $id
+       drawcommit $id 1
        if {[clock clicks -milliseconds] >= $nextupdate} {
            doupdate 1
        }
        if {[clock clicks -milliseconds] >= $nextupdate} {
            doupdate 1
        }
@@ -132,7 +149,7 @@ proc getcommitlines {commfd}  {
                set stopped 0
                set phase "getcommits"
                foreach id $commits {
                set stopped 0
                set phase "getcommits"
                foreach id $commits {
-                   drawcommit $id
+                   drawcommit $id 1
                    if {$stopped} break
                    if {[clock clicks -milliseconds] >= $nextupdate} {
                        doupdate 1
                    if {$stopped} break
                    if {[clock clicks -milliseconds] >= $nextupdate} {
                        doupdate 1
@@ -168,16 +185,9 @@ proc readcommit {id} {
     parsecommit $id $contents 0 {}
 }
 
     parsecommit $id $contents 0 {}
 }
 
-proc parsecommit {id contents listed olds} {
-    global commitinfo children nchildren parents nparents cdate ncleft
+proc updatechildren {id olds} {
+    global children nchildren parents nparents ncleft
 
 
-    set inhdr 1
-    set comment {}
-    set headline {}
-    set auname {}
-    set audate {}
-    set comname {}
-    set comdate {}
     if {![info exists nchildren($id)]} {
        set children($id) {}
        set nchildren($id) 0
     if {![info exists nchildren($id)]} {
        set children($id) {}
        set nchildren($id) 0
@@ -196,6 +206,19 @@ proc parsecommit {id contents listed olds} {
            incr ncleft($p)
        }
     }
            incr ncleft($p)
        }
     }
+}
+
+proc parsecommit {id contents listed olds} {
+    global commitinfo cdate
+
+    set inhdr 1
+    set comment {}
+    set headline {}
+    set auname {}
+    set audate {}
+    set comname {}
+    set comdate {}
+    updatechildren $id $olds
     set hdrend [string first "\n\n" $contents]
     if {$hdrend < 0} {
        # should never happen...
     set hdrend [string first "\n\n" $contents]
     if {$hdrend < 0} {
        # should never happen...
@@ -243,6 +266,9 @@ proc readrefs {} {
     global tagids idtags headids idheads tagcontents
     global otherrefids idotherrefs
 
     global tagids idtags headids idheads tagcontents
     global otherrefids idotherrefs
 
+    foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
+       catch {unset $v}
+    }
     set refd [open [list | git-ls-remote [gitdir]] r]
     while {0 <= [set n [gets $refd line]]} {
        if {![regexp {^([0-9a-f]{40})   refs/([^^]*)$} $line \
     set refd [open [list | git-ls-remote [gitdir]] r]
     while {0 <= [set n [gets $refd line]]} {
        if {![regexp {^([0-9a-f]{40})   refs/([^^]*)$} $line \
@@ -292,7 +318,7 @@ proc error_popup msg {
     tkwait window $w
 }
 
     tkwait window $w
 }
 
-proc makewindow {} {
+proc makewindow {rargs} {
     global canv canv2 canv3 linespc charspc ctext cflist textfont
     global findtype findtypemenu findloc findstring fstring geometry
     global entries sha1entry sha1string sha1but
     global canv canv2 canv3 linespc charspc ctext cflist textfont
     global findtype findtypemenu findloc findstring fstring geometry
     global entries sha1entry sha1string sha1but
@@ -302,6 +328,7 @@ proc makewindow {} {
     menu .bar
     .bar add cascade -label "File" -menu .bar.file
     menu .bar.file
     menu .bar
     .bar add cascade -label "File" -menu .bar.file
     menu .bar.file
+    .bar.file add command -label "Update" -command [list updatecommits $rargs]
     .bar.file add command -label "Reread references" -command rereadrefs
     .bar.file add command -label "Quit" -command doquit
     menu .bar.edit
     .bar.file add command -label "Reread references" -command rereadrefs
     .bar.file add command -label "Quit" -command doquit
     menu .bar.edit
@@ -1412,8 +1439,9 @@ proc decidenext {{noread 0}} {
     return $level
 }
 
     return $level
 }
 
-proc drawcommit {id} {
+proc drawcommit {id reading} {
     global phase todo nchildren datemode nextupdate revlistorder
     global phase todo nchildren datemode nextupdate revlistorder
+    global numcommits ncmupdate displayorder todo onscreen
     global numcommits ncmupdate displayorder todo onscreen parents
 
     if {$phase != "incrdraw"} {
     global numcommits ncmupdate displayorder todo onscreen parents
 
     if {$phase != "incrdraw"} {
@@ -1451,20 +1479,29 @@ proc drawcommit {id} {
            }
        }
     }
            }
        }
     }
-    drawmore 1
+    drawmore $reading
 }
 
 proc finishcommits {} {
 }
 
 proc finishcommits {} {
-    global phase
+    global phase oldcommits commits
     global canv mainfont ctext maincursor textcursor
     global canv mainfont ctext maincursor textcursor
+    global parents
 
 
-    if {$phase != "incrdraw"} {
+    if {$phase == "incrdraw" || $phase == "removecommits"} {
+       foreach id $oldcommits {
+           lappend commits $id
+           updatechildren $id $parents($id)
+           drawcommit $id 0
+       }
+       set oldcommits {}
+       drawrest
+    } elseif {$phase == "updatecommits"} {
+       set phase {}
+    } else {
        $canv delete all
        $canv create text 3 3 -anchor nw -text "No commits selected" \
            -font $mainfont -tags textitems
        set phase {}
        $canv delete all
        $canv create text 3 3 -anchor nw -text "No commits selected" \
            -font $mainfont -tags textitems
        set phase {}
-    } else {
-       drawrest
     }
     . config -cursor $maincursor
     settextcursor $textcursor
     }
     . config -cursor $maincursor
     settextcursor $textcursor
@@ -3578,9 +3615,6 @@ proc rereadrefs {} {
            set ref($id) [listrefs $id]
        }
     }
            set ref($id) [listrefs $id]
        }
     }
-    foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
-       catch {unset $v}
-    }
     readrefs
     set refids [lsort -unique [concat $refids [array names idtags] \
                        [array names idheads] [array names idotherrefs]]]
     readrefs
     set refids [lsort -unique [concat $refids [array names idtags] \
                        [array names idheads] [array names idotherrefs]]]
@@ -3592,6 +3626,80 @@ proc rereadrefs {} {
     }
 }
 
     }
 }
 
+proc updatecommits {rargs} {
+    global commitlisted commfd phase
+    global startmsecs nextupdate ncmupdate
+    global idtags idheads idotherrefs
+    global leftover
+    global parsed_args
+    global canv
+    global oldcommits commits
+    global parents nchildren children ncleft
+
+    set old_args $parsed_args
+    parse_args $rargs
+
+    foreach id $old_args {
+       if {![regexp {^[0-9a-f]{40}$} $id]} continue
+       if {[info exists oldref($id)]} continue
+       set oldref($id) $id
+       lappend ignoreold "^$id"
+    }
+    foreach id $parsed_args {
+       if {![regexp {^[0-9a-f]{40}$} $id]} continue
+       if {[info exists ref($id)]} continue
+       set ref($id) $id
+       lappend ignorenew "^$id"
+    }
+
+    foreach a $old_args {
+       if {![info exists ref($a)]} {
+           lappend ignorenew $a
+       }
+    }
+
+    set phase updatecommits
+    set removed_commits [split [eval exec git-rev-list $ignorenew] "\n" ]
+    if {[llength $removed_commits] > 0} {
+       $canv delete all
+       set oldcommits {}
+       foreach c $commits {
+           if {[lsearch $c $removed_commits] < 0} {
+               lappend oldcommits $c
+           } else {
+               unset commitlisted($c)
+           }
+       }
+       set commits {}
+       unset children
+       unset nchildren
+       set phase removecommits
+    }
+
+    set args {}
+    foreach a $parsed_args {
+       if {![info exists oldref($a)]} {
+           lappend args $a
+       }
+    }
+
+    readrefs
+    if [catch {
+       set commfd [open "|git-rev-list --header --topo-order --parents $ignoreold $args" r]
+    } err] {
+       puts stderr "Error executing git-rev-list: $err"
+       exit 1
+    }
+    set startmsecs [clock clicks -milliseconds]
+    set nextupdate [expr $startmsecs + 100]
+    set ncmupdate 1
+    set leftover {}
+    fconfigure $commfd -blocking 0 -translation lf
+    fileevent $commfd readable [list getcommitlines $commfd]
+    . config -cursor watch
+    settextcursor watch
+}
+
 proc showtag {tag isnew} {
     global ctext cflist tagcontents tagids linknum
 
 proc showtag {tag isnew} {
     global ctext cflist tagcontents tagids linknum
 
@@ -3738,6 +3846,6 @@ set redisplaying 0
 set stuffsaved 0
 set patchnum 0
 setcoords
 set stuffsaved 0
 set patchnum 0
 setcoords
-makewindow
+makewindow $revtreeargs
 readrefs
 getcommits $revtreeargs
 readrefs
 getcommits $revtreeargs