{"thread":{"id":"32946","subject":"[Patch] gitk: added a file history browser","startedAt":"2013-02-19T23:14:20Z","lastAt":"2013-04-01T07:24:08Z","messageCount":2,"participants":["Dirk","Paul Mackerras"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"209873","messageId":"0063A4B3-8C79-4F2F-97C7-D14AEBB17DEC@freunde-aus-berlin.net","threadId":"32946","inReplyTo":null,"subject":"[Patch] gitk: added a file history browser","fromName":"Dirk","fromEmail":"dirk@freunde-aus-berlin.net","sentAt":"2013-02-19T23:14:20Z","receivedAt":"2013-02-19T23:14:20Z","isPatch":true,"sender":{"key":"dirk@freunde-aus-berlin.net","avatar":null},"body":"Hi,\n\nI added a file history browser for a single file in the gitk. I use git log with the option --follow. This option is useful for the user switch from cvs to git. He misses a history from only one file and the function \"Highlight this only\" breaks by moved files. The new option do not break by the moved files. I use ideas from the tkcvs branch dialog.\n\nDirk\n\n\n\n\nFrom 60ff82dbcf1cfd07af515940c474a8c2efb97443 Mon Sep 17 00:00:00 2001\nFrom: Dirk <dirk@freunde-aus-berlin.net>\nDate: Tue, 19 Feb 2013 23:28:34 +0100\nSubject: [PATCH] Add a file history browser\n\nThe file history browser used the git log with the option --follow\nand show the diff. Use the ideas from tkcvs branch window.\n\nThis option is helpful for the users changed from cvs to git.\n---\n gitk |  574 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 573 insertions(+), 1 deletions(-)\n\ndiff --git a/gitk b/gitk\nindex b3706fc..52c13c8 100755\n--- a/gitk\n+++ b/gitk\n@@ -2584,6 +2584,7 @@ proc makewindow {} {\n     makemenu $flist_menu {\n \t{mc \"Highlight this too\" command {flist_hl 0}}\n \t{mc \"Highlight this only\" command {flist_hl 1}}\n+        {mc \"File history browser for this only\" command {flist_hb 0}}\n \t{mc \"External diff\" command {external_diff}}\n \t{mc \"Blame parent commit\" command {external_blame 1}}\n     }\n@@ -3352,7 +3353,7 @@ proc pop_flist_menu {w X Y x y} {\n \tset xdiffstate \"disabled\"\n     }\n     # Disable \"External diff\" item in tree mode\n-    $flist_menu entryconf 2 -state $xdiffstate\n+    $flist_menu entryconf 3 -state $xdiffstate\n     tk_popup $flist_menu $X $Y\n }\n \n@@ -11982,6 +11983,577 @@ if {[tk windowingsystem] eq \"win32\"} {\n \n getcommits {}\n \n+# Bindings to make canvases scroll.  Canvases have no bindings at all\n+# by default.\n+proc scrollbindings {bindtag} {\n+        # Page keys\n+        bind $bindtag <ButtonPress-1>    [list focus %W]\n+        bind $bindtag <Next>  [list %W yview scroll  1 pages]\n+        bind $bindtag <Prior> [list %W yview scroll -1 pages]\n+        bind $bindtag <Up>    [list %W yview scroll -1 units]\n+        bind $bindtag <Down>  [list %W yview scroll  1 units]\n+        bind $bindtag <Left>  [list %W xview scroll -1 pages]\n+        bind $bindtag <Right> [list %W xview scroll  1 pages]\n+        # Middle button dragging\n+        bind $bindtag <B2-Motion> [list dragbind %W %x %y]\n+        # Wheelmouse\n+        bind $bindtag <MouseWheel> [list wheelbind %W %D]\n+        bind $bindtag <ButtonPress-4> [list %W yview scroll -1 pages]\n+        bind $bindtag <ButtonPress-5> [list %W yview scroll 1 pages]\n+}\n+\n+\n+proc diff_revision {revA revB} {\n+        global flist_menu_file\n+        global extdifftool\n+        global id2file\n+\n+        set fileA $id2file($revA)\n+        set fileB $id2file($revB)\n+\n+        set diffdir [gitknewtmpdir]\n+\n+        if {$diffdir eq {}} return\n+\n+        # gather files to diff\n+        set difffromfile [external_diff_get_one_file $revA $fileA $diffdir]\n+        set difftofile [external_diff_get_one_file $revB $fileB $diffdir]\n+\n+        if {$difffromfile ne {} && $difftofile ne {}} {\n+                set cmd [list [shellsplit $extdifftool] $difffromfile $difftofile]\n+                if {[catch {set fl [open |$cmd r]} err]} {\n+                        file delete -force $diffdir\n+                        error_popup \"$extdifftool: [mc \"command failed:\"] $err\"\n+                } else {\n+                        fconfigure $fl -blocking 0\n+                        filerun $fl [list delete_at_eof $fl $diffdir]\n+                }\n+        }\n+}\n+\n+namespace eval ::logcanvas {\n+        variable instance 0\n+\n+        proc new {filename how scope} {\n+                #\n+                # Creates a new log canvas.\n+                #\n+                variable instance\n+                set my_idx $instance\n+                incr instance\n+                global current_tagname\n+                global module_dir\n+\n+                variable sys\n+                variable loc\n+\n+                namespace eval $my_idx {\n+                        set my_idx [uplevel {concat $my_idx}]\n+                        set how [uplevel {concat $how}]\n+                        set filename [uplevel {concat $filename}]\n+                        set scope [uplevel {concat $scope}]\n+\n+                        #variable cmd_log\n+                        # Global constants scaled by current scaling factor for this instance\n+                        variable curr\n+                        global tcl_platform\n+                        # User options for info display for this instance\n+                        variable opt\n+                        variable revwho\n+                        variable revdate\n+                        variable revtime\n+                        variable revstate\n+                        variable revbranches\n+                        variable branchrevs\n+                        variable revcomment\n+                        variable revtags\n+                        variable revbtags\n+                        variable revpath\n+                        variable sel_tag\n+                        set sel_tag(A) {}\n+                        set sel_tag(B) {}\n+                        variable sel_rev\n+                        variable revnum_current\n+                        set sel_rev(A) {}\n+                        set sel_rev(B) {}\n+                        variable logcanvas \".logcanvas$my_idx\"\n+\n+                        set sys_loc [split $how {,}]\n+                        set sys [lindex $sys_loc 0]\n+                        set loc [lindex $sys_loc 1]\n+\n+                        proc SetCommitIds {idList} {\n+                                variable commitIds\n+\n+                                set commitIds $idList\n+                        }\n+\n+                        proc GetCommitter {id} {\n+                                variable committer\n+                                set committer [exec git log --pretty=format:%an -n 1 $id]\n+                                return $committer\n+                        }\n+\n+                        proc GetDate {id} {\n+                                variable date\n+                                set date [exec git log --pretty=format:%ad -n 1 $id]\n+                                return $date\n+                        }\n+\n+                        proc GetLogMessage {id} {\n+                                variable msg\n+                                set msg [exec git log --pretty=format:%B -n 1 $id]\n+                                return $msg\n+                        }\n+\n+                        proc GetShortCommitId {id} {\n+                                variable sid\n+                                set sid [exec git log --pretty=format:%h -n 1 $id]\n+                                return $sid\n+                        }\n+\n+                        proc GetDrawText { sid committer date } {\n+                                variable text\n+                                set text {}\n+                                append text $sid\n+                                append text \"\\n\"\n+                                append text $committer\n+                                append text \"\\n\"\n+                                append text $date\n+                                append text \"\\n\"\n+                                return $text\n+                        }\n+\n+                        proc ClearSelection {AorB} {\n+                                variable logcanvas\n+                                variable sel_tag\n+                                variable sel_rev\n+                                #catch {$logcanvas.canvas itemconfigure Sel$AorB -outline black}\n+                                catch {$logcanvas.canvas itemconfigure Sel$AorB -fill gray90}\n+                                $logcanvas.canvas dtag Sel$AorB\n+                                $logcanvas.up.rev${AorB}_rvers configure -text {}\n+                                $logcanvas.up.log${AorB}_rlogfm.rcomment configure -state normal\n+                                $logcanvas.up.log${AorB}_rlogfm.rcomment delete 1.0 end\n+                                $logcanvas.up.log${AorB}_rlogfm.rcomment configure -state disabled\n+                                $logcanvas.up.rev${AorB}_rwho configure -text {}\n+                                $logcanvas.up.rev${AorB}_rdate configure -text {}\n+                                set sel_tag($AorB) {}\n+                                set sel_rev($AorB) {}\n+                                return\n+                        }\n+\n+                        proc SetSelection {AorB revision} {\n+                                variable logcanvas\n+                                variable revdate\n+                                variable sel_rev\n+\n+                                ClearSelection $AorB\n+                                set other [expr {$AorB == \"A\" ? {B} : {A}}]\n+                                if {$revision == $sel_rev($other)} { ClearSelection $other }\n+\n+                                $logcanvas.up.rev${AorB}_rvers configure -text $revision\n+\n+                                if {$revision != {} } {\n+                                        $logcanvas.up.rev${AorB}_rwho configure -text [GetCommitter $revision]\n+                                        $logcanvas.up.log${AorB}_rlogfm.rcomment configure -state normal\n+                                        $logcanvas.up.log${AorB}_rlogfm.rcomment insert end [GetLogMessage $revision]\n+                                        $logcanvas.up.log${AorB}_rlogfm.rcomment configure -state disabled\n+                                }\n+                                $logcanvas.canvas itemconfigure SelA -fill Green\n+                                $logcanvas.canvas itemconfigure SelB -fill Red\n+                                set sel_rev($AorB) $revision\n+                                return\n+                        }\n+\n+                        proc RevSelect {AorB} {\n+                                variable logcanvas\n+                                set t [$logcanvas.canvas gettags current]\n+                                SetSelection $AorB \\\n+                                        [string range [lindex $t [lsearch -glob $t {R*}]] 1 end]\n+                                return\n+                        }\n+\n+                        proc DiffRevision { revA revB filename } {\n+                                diff_revision $revA $revB\n+                        }\n+\n+                        proc DrawCurrent { x y box_width box_height revision } {\n+\n+                                variable font_bold\n+                                variable curr_x\n+                                variable curr_y\n+                                variable logcanvas\n+\n+                                set curr_x $x\n+                                set curr_y $y\n+                                # draw the box\n+                                set tx [expr {$x + $box_width}]\n+                                set ty [expr {$y - $box_height}]\n+                                $logcanvas.canvas create rectangle \\\n+                                        $x $y $tx $ty \\\n+                                        -width 4 -fill gray90 -outline red3\n+                                set pad \\\n+                                        [expr {($box_width - \\\n+                                                                [font measure $font_bold -displayof $logcanvas.canvas {You are}]) \\\n+                                                           / 3}]\n+                                set ty [expr {$y - [expr {$box_height/2}]}]\n+                                # add the contents\n+                                $logcanvas.canvas create text \\\n+                                        [expr {$x + $box_width - $pad}] $ty \\\n+                                        -text \"You are\\nhere\" -anchor e \\\n+                                        -fill red3 \\\n+                                        -font $font_bold\n+                                return\n+                        }\n+\n+                        proc DrawRevision { x y box_width box_height revision} {\n+                                variable font_bold\n+                                variable curr_x\n+                                variable curr_y\n+                                variable logcanvas\n+\n+                                set committer [GetCommitter $revision]\n+                                set date [GetDate $revision]\n+                                set sid [GetShortCommitId $revision]\n+                                set text [GetDrawText $sid $committer $date]\n+\n+                                set curr_x $x\n+                                set curr_y $y\n+                                # draw the box\n+                                set tx [expr {$x + $box_width}]\n+                                set ty [expr {$y - $box_height}]\n+                                $logcanvas.canvas create rectangle \\\n+                                        $x $y $tx $ty \\\n+                                        -width 4 -fill gray90 -outline red3 \\\n+                                        -tag [list box R$revision rect$revision active]\n+                                set pad \\\n+                                        [expr {($box_width -[font measure $font_bold \\\n+                                                                                         -displayof $logcanvas.canvas {$text}]) }]\n+                                set ty [expr {$y - [expr {$box_height/2}]}]\n+                                # add the contents\n+                                $logcanvas.canvas create text \\\n+                                        [expr {$x + $pad}] $ty \\\n+                                        -text $text -anchor e \\\n+                                        -fill red3 \\\n+                                        -font $font_bold \\\n+                                        -tags [list R$revision box active]\n+                                return\n+                        }\n+\n+                        proc DrawTree { filename } {\n+                                variable font_norm\n+                                variable font_norm_h\n+                                variable font_bold\n+                                variable font_bold_h\n+                                variable logcanvas\n+                                variable commitIds\n+\n+                                set my_size 8\n+                                set font_norm [font create \\\n+                                                                   -family Helvetica -size $my_size]\n+                                set font_norm_h [font metrics \\\n+                                                                         $font_norm -displayof $logcanvas -linespace]\n+                                set font_bold [font create \\\n+                                                                   -family Helvetica -size $my_size -weight bold]\n+                                set font_bold_h [font metrics \\\n+                                                                         $font_bold -displayof $logcanvas -linespace]\n+\n+                                set height 100\n+\n+                                DrawCurrent 100 $height 300 100 \"bla\"\n+\n+                                foreach id $commitIds {\n+                                        set height [expr $height + 110]\n+                                        DrawRevision 100 $height 300 100 $id\n+                                }\n+                        }\n+\n+                        toplevel $logcanvas\n+                        wm title $logcanvas \"$sys Log $filename\"\n+                        $logcanvas configure -menu $logcanvas.menubar\n+                        menu $logcanvas.menubar\n+\n+                        $logcanvas.menubar add cascade -label \"File\"\\\n+                                -menu $logcanvas.menubar.file -underline 0\n+                        menu $logcanvas.menubar.file -tearoff 0\n+                        $logcanvas.menubar.file add command -label \"Close\" -underline 0 \\\n+                                -command [namespace code {$logcanvas.close invoke}]\n+                        $logcanvas.menubar.file add command -label \"Exit\" -underline 1 \\\n+                                -command { exit }\n+                        wm protocol $logcanvas WM_DELETE_WINDOW \\\n+                                [namespace code {$logcanvas.close invoke}]\n+                        frame $logcanvas.up -relief groove -border 2\n+                        set disbg [lindex [$logcanvas.up configure -background] 4]\n+                        label $logcanvas.up.lfname -width 12 -anchor w\n+                        entry $logcanvas.up.rfname -font $textfont -relief groove\n+\n+                        pack $logcanvas.up -side top -fill x\n+                        foreach fm {A B} {\n+                                label $logcanvas.up.rev${fm}_lvers -text \"Revision $fm\"\n+                                label $logcanvas.up.rev${fm}_rvers -text {} \\\n+                                        -anchor w -font $textfont\n+\n+                                label $logcanvas.up.rev${fm}_ldate -text \"Committed\"\n+                                label $logcanvas.up.rev${fm}_rdate -text {} \\\n+                                        -anchor w -font $textfont\n+                                label $logcanvas.up.rev${fm}_lwho -text \" by \"\n+                                label $logcanvas.up.rev${fm}_rwho -text {} \\\n+                                        -anchor w -font $textfont\n+                                label $logcanvas.up.log${fm}_lcomment -text \"Log $fm\"\n+\n+                                frame $logcanvas.up.log${fm}_rlogfm -bd 3\n+                                text  $logcanvas.up.log${fm}_rlogfm.rcomment -height 5 \\\n+                                        -state disabled \\\n+                                        -yscrollcommand [namespace code\\\n+                                                                                 \"$logcanvas.up.log${fm}_rlogfm.yscroll set\"]\n+                                scrollbar $logcanvas.up.log${fm}_rlogfm.yscroll \\\n+                                        -command [namespace code\\\n+                                                                  \"$logcanvas.up.log${fm}_rlogfm.rcomment yview\"]\n+                        }\n+\n+                        grid columnconf $logcanvas.up 5 -weight 1\n+                        grid $logcanvas.up.lfname -column 0 -row 0 -sticky nw\n+                        grid $logcanvas.up.rfname -column 1 -row 0 -columnspan 5 -sticky ew\n+                        grid $logcanvas.up.revA_lvers -column 0 -row 1 -sticky w\n+                        grid $logcanvas.up.revA_rvers -column 1 -row 1 -sticky w\n+                        grid $logcanvas.up.revA_ldate -column 2 -row 1 -sticky w\n+                        grid $logcanvas.up.revA_rdate -column 3 -row 1 -sticky w\n+                        grid $logcanvas.up.revA_lwho -column 4 -row 1 -sticky w\n+                        grid $logcanvas.up.revA_rwho -column 5 -row 1 -sticky ew\n+                        grid $logcanvas.up.logA_lcomment -column 0 -row 2 -sticky nw\n+                        grid $logcanvas.up.logA_rlogfm -column 1 -row 2 -columnspan 7 -sticky ew\n+                        pack $logcanvas.up.logA_rlogfm.yscroll -side right -fill y\n+                        pack $logcanvas.up.logA_rlogfm.rcomment -side left -fill x -expand y\n+                        grid $logcanvas.up.revB_lvers -column 0 -row 3 -sticky w\n+                        grid $logcanvas.up.revB_rvers -column 1 -row 3 -sticky w\n+                        grid $logcanvas.up.revB_ldate -column 2 -row 3 -sticky w\n+                        grid $logcanvas.up.revB_rdate -column 3 -row 3 -sticky w\n+                        grid $logcanvas.up.revB_lwho -column 4 -row 3 -sticky w\n+                        grid $logcanvas.up.revB_rwho -column 5 -row 3 -sticky ew\n+                        grid $logcanvas.up.logB_lcomment -column 0 -row 4 -sticky nw\n+                        grid $logcanvas.up.logB_rlogfm -column 1 -row 4 -columnspan 7 -sticky ew\n+                        pack $logcanvas.up.logB_rlogfm.yscroll -side right -fill y\n+                        pack $logcanvas.up.logB_rlogfm.rcomment -side left -fill x -expand y\n+                        # Pack the bottom before the middle so it doesnt disappear if\n+                        # the window is resized smaller\n+                        frame $logcanvas.down -relief groove -border 2\n+                        pack $logcanvas.down -side bottom -fill x\n+\n+                        # The canvas for the big picture\n+                        canvas $logcanvas.canvas -relief sunken -border 2 \\\n+                                -height 300 \\\n+                                -yscrollcommand [namespace code \"$logcanvas.yscroll set\"] \\\n+                                -xscrollcommand [namespace code \"$logcanvas.xscroll set\"]\n+                        scrollbar $logcanvas.xscroll -relief sunken -orient horizontal \\\n+                                -command [namespace code \"$logcanvas.canvas xview\"]\n+                        scrollbar $logcanvas.yscroll -relief sunken \\\n+                                -command [namespace code \"$logcanvas.canvas yview\"]\n+                        #\n+                        # Create buttons\n+                        #\n+                        button $logcanvas.diff  -text \"Diff\"\\\n+                                -command [namespace code {\n+                                        DiffRevision [$logcanvas.up.revA_rvers cget -text] \\\n+                                                [$logcanvas.up.revB_rvers cget -text] $filename\n+                                }]\n+                        button $logcanvas.close -text \"Close\" \\\n+                                -command [namespace code {\n+                                        variable logcanvas\n+                                        destroy $logcanvas\n+                                        namespace delete [namespace current]\n+                                }]\n+\n+                        #\n+                        # Put the canvas on to the display.\n+                        #\n+                        pack $logcanvas.xscroll -side bottom -fill x -padx 1 -pady 1\n+                        pack $logcanvas.yscroll -side right -fill y -padx 1 -pady 1\n+                        pack $logcanvas.canvas -fill both -expand 1\n+                        scrollbindings $logcanvas.canvas\n+\n+                        pack $logcanvas.diff \\\n+                                -in $logcanvas.down -side left \\\n+                                -ipadx 4 -ipady 4\n+                        pack $logcanvas.close \\\n+                                -in $logcanvas.down -side right \\\n+                                -fill both -expand 1\n+\n+                        #\n+                        # Window manager stuff.\n+                        #\n+                        wm minsize $logcanvas 1 1\n+\n+                        $logcanvas.canvas bind active <Enter> \\\n+                                \"$logcanvas.canvas config -cursor hand2\"\n+                        $logcanvas.canvas bind active <Leave> \\\n+                                \"$logcanvas.canvas config -cursor {}\"\n+\n+\n+                        $logcanvas.canvas bind tag <Button-1> \\\n+                                [namespace code \"PopupTags %X %Y\"]\n+\n+                        $logcanvas.canvas bind box <ButtonPress-1> \\\n+                                [namespace code \"RevSelect A\"]\n+                        # Tcl/TK for Windows doesn't do Button 3, so we duplicate it on Button 2\n+                        $logcanvas.canvas bind box <ButtonPress-2> \\\n+                                [namespace code \"RevSelect B\"]\n+                        $logcanvas.canvas bind box <ButtonPress-3> \\\n+                                [namespace code \"RevSelect B\"]\n+\n+                        focus $logcanvas.canvas\n+                        # FIXME: Why isn't there a bbox when we get here?\n+                        # Then the yview moveto doesn't work, although it does in tkinter\n+                        $logcanvas.canvas xview moveto 0\n+                        $logcanvas.canvas yview moveto 0\n+\n+                        return [list [namespace current] $logcanvas]\n+                }\n+        }\n+}\n+\n+\n+proc flist_hb {only} {\n+        global flist_menu_file\n+\n+        set x [shellquote $flist_menu_file]\n+        git_file_history $x\n+}\n+\n+proc git_file_history {file} {\n+\n+        if {$file == \"\"} {\n+                error_popup \"[mc \"File history browser for file %s not implemented yet\" $file]\"\n+                return\n+        }\n+\n+        ::git_filelog::new \"Git,loc\" \"$file\"\n+}\n+\n+namespace eval ::git_filelog {\n+        variable instance 0\n+\n+        proc new {how filename} {\n+                variable instance\n+                variable commit_ids\n+                set my_idx $instance\n+                incr instance\n+\n+                namespace eval $my_idx {\n+                        set filename [uplevel {concat $filename}]\n+                        set how [uplevel {concat $filename}]\n+\n+                        variable command\n+                        variable rev_list\n+                        variable rev_ids\n+                        variable rev_id\n+                        variable rev_date\n+                        variable rev_comment\n+                        variable rev_commiter\n+                        variable id 0\n+                        variable lc\n+\n+                        set newlc [logcanvas::new $filename $how [namespace current]]\n+                        set ln [lindex $newlc 0]\n+                        set lc [lindex $newlc 1]\n+\n+                        set command \"git log --follow --pretty=format:%H --name-only -- $filename\"\n+                        if {[catch {set fd [open [concat | $command] r]} err]} {\n+                                error_popup \"[mc \"Error executing git log:\"] $err\"\n+                                return 0\n+                        }\n+                        #set i [reg_instance $fd]\n+                        #fconfigure $fd -blocking 1\n+                        #filerun $fd [list eval_commit_id $fd $ln]\n+                        eval_commit_id $fd $ln\n+\n+                        $ln\\::DrawTree $filename\n+\n+                }\n+                return [namespace current]\n+        }\n+}\n+\n+proc eval_commit_id {fd ln} {\n+\n+        set stuff [read $fd 500000]\n+        if {$stuff == {} && [eof $fd]} {\n+                set stuff \"\\0\"\n+        }\n+        if {$stuff == {}} {\n+                if {![eof $fd]} {\n+                        return 1\n+                }\n+                # set it blocking so we wait for the process to terminate\n+                fconfigure $fd -blocking 1\n+                if {[catch {close $fd} err]} {\n+                        set fv {}\n+                        if {[string range $err 0 4] == \"usage\"} {\n+                                set err \"Gitk: error reading commits$fv:\\\n+                                                bad arguments to git log.\"\n+                        } else {\n+                                set err \"Error reading commits$fv: $err\"\n+                        }\n+                        error_popup $err\n+                }\n+                return 0\n+        }\n+        set start 0\n+        set gotsome 0\n+        set commit_ids {}\n+\n+        # every commid has 3 lines\n+        # first line: commit id\n+        # second line: file name\n+        # third line: empty line\n+\n+    set line 0\n+        set id {}\n+        global id2file\n+\n+        while 1 {\n+                set i [string first \"\\n\" $stuff $start]\n+                incr line\n+                if {$i < 0} {\n+                        set cmit [string range $stuff $start end]\n+                        if { $line == 1 } {\n+                                lappend commit_ids $cmit\n+                                set id $cmit\n+                        }\n+                        if { $line == 2 } {\n+                                set pos [llength $commit_ids]\n+                                set id [lindex $commit_ids $pos]\n+                                set id2file($id) $cmit\n+                        }\n+                        break\n+                }\n+                if {$start == 0} {\n+                        set cmit [string range $stuff 0 [expr {$i - 1}]]\n+                        if { $line == 1 } {\n+                                lappend commit_ids $cmit\n+                                set id $cmit\n+                        }\n+                        if { $line == 2 } {\n+                                set id2file($id) $cmit\n+                        }\n+                } else {\n+                        set cmit [string range $stuff $start [expr {$i - 1}]]\n+                        if { $line == 1 } {\n+                                lappend commit_ids $cmit\n+                                set id $cmit\n+                        }\n+                        if { $line == 2 } {\n+                                set id2file($id) $cmit\n+                        }\n+                }\n+                if { $line == 3 } {\n+                        set line 0\n+                }\n+                set start [expr {$i + 1}]\n+        }\n+\n+        $ln\\::SetCommitIds $commit_ids\n+}\n+\n # Local variables:\n # mode: tcl\n # indent-tabs-mode: t\n-- \n1.7.7.5 (Apple Git-26)\n\n"},{"id":"212788","messageId":"20130401072408.GB4427@iris.ozlabs.ibm.com","threadId":"32946","inReplyTo":"0063A4B3-8C79-4F2F-97C7-D14AEBB17DEC@freunde-aus-berlin.net","subject":"Re: [Patch] gitk: added a file history browser","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2013-04-01T07:24:08Z","receivedAt":"2013-04-01T07:24:08Z","isPatch":true,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"On Wed, Feb 20, 2013 at 12:14:20AM +0100, Dirk wrote:\n> Hi,\n> \n> I added a file history browser for a single file in the gitk. I use git log with the option --follow. This option is useful for the user switch from cvs to git. He misses a history from only one file and the function \"Highlight this only\" breaks by moved files. The new option do not break by the moved files. I use ideas from the tkcvs branch dialog.\n\nHow is this better than running \"gitk --follow -- file\"?\n\nAlso, it's rather a large patch with only a two-line patch description,\nwhich is not really adequate.  And it's missing a Signed-off-by.\n\nI think the right way to do this is to have the file menu option\ncreate a new view specifying the file and the --follow option,\nrather than creating a whole new window.\n\nPaul.\n"}]}