git-gui: Optionally save commit buffer on exit.
[gitweb.git] / git-gui.sh
index 09c1b74e753a26094612a35cd6b40a86f131def3..335b5f8b67dead27b82488266698f842199dc494 100755 (executable)
@@ -93,6 +93,22 @@ proc is_Cygwin {} {
        return $_iscygwin
 }
 
+proc is_enabled {option} {
+       global enabled_options
+       if {[catch {set on $enabled_options($option)}]} {return 0}
+       return $on
+}
+
+proc enable_option {option} {
+       global enabled_options
+       set enabled_options($option) 1
+}
+
+proc disable_option {option} {
+       global enabled_options
+       set enabled_options($option) 0
+}
+
 ######################################################################
 ##
 ## config
@@ -303,9 +319,14 @@ set _reponame [lindex [file split \
        [file normalize [file dirname $_gitdir]]] \
        end]
 
-set single_commit 0
+enable_option multicommit
+enable_option branch
+enable_option transport
+
 if {[appname] eq {git-citool}} {
-       set single_commit 1
+       disable_option multicommit
+       disable_option branch
+       disable_option transport
 }
 
 ######################################################################
@@ -427,6 +448,11 @@ proc rescan {after {honor_trustmtime 1}} {
                $ui_comm edit modified false
        }
 
+       if {[is_enabled branch]} {
+               load_all_heads
+               populate_branch_menu
+       }
+
        if {$honor_trustmtime && $repo_config(gui.trustmtime) eq {true}} {
                rescan_stage2 {} $after
        } else {
@@ -1176,7 +1202,7 @@ proc commit_writetree {curHEAD msg} {
 
 proc commit_committree {fd_wt curHEAD msg} {
        global HEAD PARENT MERGE_HEAD commit_type
-       global single_commit all_heads current_branch
+       global all_heads current_branch
        global ui_status_value ui_comm selected_commit_type
        global file_states selected_paths rescan_active
        global repo_config
@@ -1281,7 +1307,7 @@ proc commit_committree {fd_wt curHEAD msg} {
        $ui_comm edit reset
        $ui_comm edit modified false
 
-       if {$single_commit} do_quit
+       if {![is_enabled multicommit]} do_quit
 
        # -- Update in memory status
        #
@@ -1376,6 +1402,7 @@ proc mapdesc {state path} {
 }
 
 proc escape_path {path} {
+       regsub -all {\\} $path "\\\\" path
        regsub -all "\n" $path "\\n" path
        return $path
 }
@@ -2952,7 +2979,7 @@ proc reset_hard_wait {fd} {
 set next_browser_id 0
 
 proc new_browser {commit} {
-       global next_browser_id cursor_ptr
+       global next_browser_id cursor_ptr M1B
        global browser_commit browser_status browser_stack browser_path browser_busy
 
        set w .browser[incr next_browser_id]
@@ -3002,6 +3029,16 @@ proc new_browser {commit} {
 
        bind $w_list <Button-1>        "browser_click 0 $w_list @%x,%y;break"
        bind $w_list <Double-Button-1> "browser_click 1 $w_list @%x,%y;break"
+       bind $w_list <$M1B-Up>         "browser_parent $w_list;break"
+       bind $w_list <$M1B-Left>       "browser_parent $w_list;break"
+       bind $w_list <Up>              "browser_move -1 $w_list;break"
+       bind $w_list <Down>            "browser_move 1 $w_list;break"
+       bind $w_list <$M1B-Right>      "browser_enter $w_list;break"
+       bind $w_list <Return>          "browser_enter $w_list;break"
+       bind $w_list <Prior>           "browser_page -1 $w_list;break"
+       bind $w_list <Next>            "browser_page 1 $w_list;break"
+       bind $w_list <Left>            break
+       bind $w_list <Right>           break
 
        bind $w <Visibility> "focus $w"
        bind $w <Destroy> "
@@ -3017,52 +3054,100 @@ proc new_browser {commit} {
        ls_tree $w_list $browser_commit($w_list) {}
 }
 
-proc browser_click {was_double_click w pos} {
+proc browser_move {dir w} {
+       global browser_files browser_busy
+
+       if {$browser_busy($w)} return
+       set lno [lindex [split [$w index in_sel.first] .] 0]
+       incr lno $dir
+       if {[lindex $browser_files($w) [expr {$lno - 1}]] ne {}} {
+               $w tag remove in_sel 0.0 end
+               $w tag add in_sel $lno.0 [expr {$lno + 1}].0
+               $w see $lno.0
+       }
+}
+
+proc browser_page {dir w} {
+       global browser_files browser_busy
+
+       if {$browser_busy($w)} return
+       $w yview scroll $dir pages
+       set lno [expr {int(
+                 [lindex [$w yview] 0]
+               * [llength $browser_files($w)]
+               + 1)}]
+       if {[lindex $browser_files($w) [expr {$lno - 1}]] ne {}} {
+               $w tag remove in_sel 0.0 end
+               $w tag add in_sel $lno.0 [expr {$lno + 1}].0
+               $w see $lno.0
+       }
+}
+
+proc browser_parent {w} {
+       global browser_files browser_status browser_path
+       global browser_stack browser_busy
+
+       if {$browser_busy($w)} return
+       set info [lindex $browser_files($w) 0]
+       if {[lindex $info 0] eq {parent}} {
+               set parent [lindex $browser_stack($w) end-1]
+               set browser_stack($w) [lrange $browser_stack($w) 0 end-2]
+               if {$browser_stack($w) eq {}} {
+                       regsub {:.*$} $browser_path($w) {:} browser_path($w)
+               } else {
+                       regsub {/[^/]+$} $browser_path($w) {} browser_path($w)
+               }
+               set browser_status($w) "Loading $browser_path($w)..."
+               ls_tree $w [lindex $parent 0] [lindex $parent 1]
+       }
+}
+
+proc browser_enter {w} {
        global browser_files browser_status browser_path
        global browser_commit browser_stack browser_busy
 
        if {$browser_busy($w)} return
-       set lno [lindex [split [$w index $pos] .] 0]
+       set lno [lindex [split [$w index in_sel.first] .] 0]
        set info [lindex $browser_files($w) [expr {$lno - 1}]]
-
-       $w conf -state normal
-       $w tag remove sel 0.0 end
-       $w tag remove in_sel 0.0 end
        if {$info ne {}} {
+               switch -- [lindex $info 0] {
+               parent {
+                       browser_parent $w
+               }
+               tree {
+                       set name [lindex $info 2]
+                       set escn [escape_path $name]
+                       set browser_status($w) "Loading $escn..."
+                       append browser_path($w) $escn
+                       ls_tree $w [lindex $info 1] $name
+               }
+               blob {
+                       set name [lindex $info 2]
+                       set p {}
+                       foreach n $browser_stack($w) {
+                               append p [lindex $n 1]
+                       }
+                       append p $name
+                       show_blame $browser_commit($w) $p
+               }
+               }
+       }
+}
+
+proc browser_click {was_double_click w pos} {
+       global browser_files browser_busy
+
+       if {$browser_busy($w)} return
+       set lno [lindex [split [$w index $pos] .] 0]
+       focus $w
+
+       if {[lindex $browser_files($w) [expr {$lno - 1}]] ne {}} {
+               $w tag remove in_sel 0.0 end
                $w tag add in_sel $lno.0 [expr {$lno + 1}].0
                if {$was_double_click} {
-                       switch -- [lindex $info 0] {
-                       parent {
-                               set parent [lindex $browser_stack($w) end-1]
-                               set browser_stack($w) [lrange $browser_stack($w) 0 end-2]
-                               if {$browser_stack($w) eq {}} {
-                                       regsub {:.*$} $browser_path($w) {:} browser_path($w)
-                               } else {
-                                       regsub {/[^/]+$} $browser_path($w) {} browser_path($w)
-                               }
-                               set browser_status($w) "Loading $browser_path($w)..."
-                               ls_tree $w [lindex $parent 0] [lindex $parent 1]
-                       }
-                       tree {
-                               set name [lindex $info 2]
-                               set escn [escape_path $name]
-                               set browser_status($w) "Loading $escn..."
-                               append browser_path($w) $escn
-                               ls_tree $w [lindex $info 1] $name
-                       }
-                       blob {
-                               set name [lindex $info 2]
-                               set p {}
-                               foreach n $browser_stack($w) {
-                                       append p [lindex $n 1]
-                               }
-                               append p $name
-                               show_blame $browser_commit($w) $p
-                       }
-                       }
+                       browser_enter $w
                }
        }
-       $w conf -state disabled
 }
 
 proc ls_tree {w tree_id name} {
@@ -3074,7 +3159,6 @@ proc ls_tree {w tree_id name} {
 
        $w conf -state normal
        $w tag remove in_sel 0.0 end
-       $w tag remove sel 0.0 end
        $w delete 0.0 end
        if {$browser_stack($w) ne {}} {
                $w image create end \
@@ -3087,7 +3171,8 @@ proc ls_tree {w tree_id name} {
        lappend browser_stack($w) [list $tree_id $name]
        $w conf -state disabled
 
-       set fd [open "| git ls-tree -z $tree_id" r]
+       set cmd [list git ls-tree -z $tree_id]
+       set fd [open "| $cmd" r]
        fconfigure $fd -blocking 0 -translation binary -encoding binary
        fileevent $fd readable [list read_ls_tree $fd $w]
 }
@@ -3141,6 +3226,10 @@ proc read_ls_tree {fd w} {
                set browser_status($w) Ready.
                set browser_busy($w) 0
                array unset browser_buffer $w
+               if {$n > 0} {
+                       $w tag add in_sel 1.0 2.0
+                       focus -force $w
+               }
        }
 }
 
@@ -3152,7 +3241,6 @@ proc show_blame {commit path} {
        set texts [list]
 
        toplevel $w
-       panedwindow $w.out -orient horizontal
 
        label $w.path -text "$commit:$path" \
                -anchor w \
@@ -3160,53 +3248,126 @@ proc show_blame {commit path} {
                -borderwidth 1 \
                -relief sunken \
                -font font_uibold
-       pack $w.path -anchor w -side top -fill x
+       pack $w.path -side top -fill x
 
-       text $w.out.commit -background white -borderwidth 0 \
+       set hbg #e2effa
+       frame $w.out
+       label $w.out.commit_l -text Commit \
+               -relief solid \
+               -borderwidth 1 \
+               -background $hbg \
+               -font font_uibold
+       text $w.out.commit_t \
+               -background white -borderwidth 0 \
                -state disabled \
                -wrap none \
                -height 40 \
-               -width 8 \
+               -width 9 \
                -font font_diff
-       $w.out add $w.out.commit
-       lappend texts $w.out.commit
+       lappend texts $w.out.commit_t
 
-       text $w.out.author -background white -borderwidth 0 \
+       label $w.out.author_l -text Author \
+               -relief solid \
+               -borderwidth 1 \
+               -background $hbg \
+               -font font_uibold
+       text $w.out.author_t \
+               -background white -borderwidth 0 \
                -state disabled \
                -wrap none \
                -height 40 \
                -width 20 \
                -font font_diff
-       $w.out add $w.out.author
-       lappend texts $w.out.author
+       lappend texts $w.out.author_t
 
-       text $w.out.date -background white -borderwidth 0 \
+       label $w.out.date_l -text Date \
+               -relief solid \
+               -borderwidth 1 \
+               -background $hbg \
+               -font font_uibold
+       text $w.out.date_t \
+               -background white -borderwidth 0 \
                -state disabled \
                -wrap none \
                -height 40 \
                -width [string length "yyyy-mm-dd hh:mm:ss"] \
                -font font_diff
-       $w.out add $w.out.date
-       lappend texts $w.out.date
+       lappend texts $w.out.date_t
+
+       label $w.out.filename_l -text Filename \
+               -relief solid \
+               -borderwidth 1 \
+               -background $hbg \
+               -font font_uibold
+       text $w.out.filename_t \
+               -background white -borderwidth 0 \
+               -state disabled \
+               -wrap none \
+               -height 40 \
+               -width 20 \
+               -font font_diff
+       lappend texts $w.out.filename_t
+
+       label $w.out.origlinenumber_l -text {Orig Line} \
+               -relief solid \
+               -borderwidth 1 \
+               -background $hbg \
+               -font font_uibold
+       text $w.out.origlinenumber_t \
+               -background white -borderwidth 0 \
+               -state disabled \
+               -wrap none \
+               -height 40 \
+               -width 5 \
+               -font font_diff
+       $w.out.origlinenumber_t tag conf linenumber -justify right
+       lappend texts $w.out.origlinenumber_t
 
-       text $w.out.linenumber -background white -borderwidth 0 \
+       label $w.out.linenumber_l -text {Curr Line} \
+               -relief solid \
+               -borderwidth 1 \
+               -background $hbg \
+               -font font_uibold
+       text $w.out.linenumber_t \
+               -background white -borderwidth 0 \
                -state disabled \
                -wrap none \
                -height 40 \
                -width 5 \
                -font font_diff
-       $w.out.linenumber tag conf linenumber -justify right
-       $w.out add $w.out.linenumber
-       lappend texts $w.out.linenumber
+       $w.out.linenumber_t tag conf linenumber -justify right
+       lappend texts $w.out.linenumber_t
 
-       text $w.out.file -background white -borderwidth 0 \
+       label $w.out.file_l -text {File Content} \
+               -relief solid \
+               -borderwidth 1 \
+               -background $hbg \
+               -font font_uibold
+       text $w.out.file_t \
+               -background white -borderwidth 0 \
                -state disabled \
                -wrap none \
                -height 40 \
                -width 80 \
+               -xscrollcommand [list $w.out.sbx set] \
                -font font_diff
-       $w.out add $w.out.file
-       lappend texts $w.out.file
+       lappend texts $w.out.file_t
+
+       scrollbar $w.out.sbx -orient h -command [list $w.out.file_t xview]
+       scrollbar $w.out.sby -orient v \
+               -command [list scrollbar2many $texts yview]
+       set labels [list]
+       foreach i $texts {
+               regsub {_t$} $i _l l
+               lappend labels $l
+       }
+       set file_col [expr {[llength $texts] - 1}]
+       eval grid $labels -sticky we
+       eval grid $texts $w.out.sby -sticky nsew
+       grid conf $w.out.sbx -column $file_col -sticky we
+       grid columnconfigure $w.out $file_col -weight 1
+       grid rowconfigure $w.out 1 -weight 1
+       pack $w.out -fill both -expand 1
 
        label $w.status -textvariable blame_status($w) \
                -anchor w \
@@ -3214,11 +3375,7 @@ proc show_blame {commit path} {
                -borderwidth 1 \
                -relief sunken \
                -font font_ui
-       pack $w.status -anchor w -side bottom -fill x
-
-       scrollbar $w.sby -orient v -command [list scrollbar2many $texts yview]
-       pack $w.sby -side right -fill y
-       pack $w.out -side left -fill both -expand 1
+       pack $w.status -side bottom -fill x
 
        menu $w.ctxm -tearoff 0
        $w.ctxm add command -label "Copy Commit" \
@@ -3229,7 +3386,8 @@ proc show_blame {commit path} {
                $i tag conf in_sel \
                        -background [$i cget -foreground] \
                        -foreground [$i cget -background]
-               $i conf -yscrollcommand [list many2scrollbar $texts yview $w.sby]
+               $i conf -yscrollcommand \
+                       [list many2scrollbar $texts yview $w.out.sby]
                bind $i <Button-1> "blame_highlight $i @%x,%y $texts;break"
                bind_button3 $i "
                        set cursorX %x
@@ -3239,6 +3397,8 @@ proc show_blame {commit path} {
                "
        }
 
+       set blame_data($w,colors) {}
+
        bind $w <Visibility> "focus $w"
        bind $w <Destroy> "
                array unset blame_status $w
@@ -3247,10 +3407,12 @@ proc show_blame {commit path} {
        wm title $w "[appname] ([reponame]): File Viewer"
 
        set blame_data($w,total_lines) 0
-       set fd [open "| git cat-file blob $commit:$path" r]
+       set cmd [list git cat-file blob "$commit:$path"]
+       set fd [open "| $cmd" r]
        fconfigure $fd -blocking 0 -translation lf -encoding binary
-       fileevent $fd readable [list read_blame_catfile $fd $w $commit $path \
-               $texts $w.out.linenumber $w.out.file]
+       fileevent $fd readable [list read_blame_catfile \
+               $fd $w $commit $path \
+               $texts $w.out.linenumber_t $w.out.file_t]
 }
 
 proc read_blame_catfile {fd w commit path texts w_lno w_file} {
@@ -3276,13 +3438,17 @@ proc read_blame_catfile {fd w commit path texts w_lno w_file} {
        if {[eof $fd]} {
                close $fd
                set blame_status($w) {Loading annotations...}
-               set fd [open "| git blame --incremental $commit -- $path" r]
+               set cmd [list git blame -M -C --incremental]
+               lappend cmd $commit -- $path
+               set fd [open "| $cmd" r]
                fconfigure $fd -blocking 0 -translation lf -encoding binary
                fileevent $fd readable "read_blame_incremental $fd $w $texts"
        }
 }
 
-proc read_blame_incremental {fd w w_commit w_author w_date w_lno w_file} {
+proc read_blame_incremental {fd w
+       w_commit w_author w_date w_filename w_olno
+       w_lno w_file} {
        global blame_status blame_data
 
        if {![winfo exists $w_commit]} {
@@ -3290,47 +3456,99 @@ proc read_blame_incremental {fd w w_commit w_author w_date w_lno w_file} {
                return
        }
 
+       set all [list \
+               $w_commit \
+               $w_author \
+               $w_date \
+               $w_filename \
+               $w_olno \
+               $w_lno \
+               $w_file]
+
        $w_commit conf -state normal
        $w_author conf -state normal
        $w_date conf -state normal
+       $w_filename conf -state normal
+       $w_olno conf -state normal
 
        while {[gets $fd line] >= 0} {
                if {[regexp {^([a-z0-9]{40}) (\d+) (\d+) (\d+)$} $line line \
-                       commit original_line final_line line_count]} {
-                       set blame_data($w,commit) $commit
+                       cmit original_line final_line line_count]} {
+                       set blame_data($w,commit) $cmit
                        set blame_data($w,original_line) $original_line
                        set blame_data($w,final_line) $final_line
                        set blame_data($w,line_count) $line_count
+
+                       if {[catch {set g $blame_data($w,$cmit,seen)}]} {
+                               if {$blame_data($w,colors) eq {}} {
+                                       set blame_data($w,colors) {
+                                               yellow
+                                               red
+                                               pink
+                                               orange
+                                               green
+                                               grey
+                                       }
+                               }
+                               set c [lindex $blame_data($w,colors) 0]
+                               set blame_data($w,colors) \
+                                       [lrange $blame_data($w,colors) 1 end]
+                               foreach t $all {
+                                       $t tag conf g$cmit -background $c
+                               }
+                       } else {
+                               set blame_data($w,$cmit,seen) 1
+                       }
                } elseif {[string match {filename *} $line]} {
                        set n $blame_data($w,line_count)
                        set lno $blame_data($w,final_line)
+                       set ol $blame_data($w,original_line)
                        set file [string range $line 9 end]
-                       set commit $blame_data($w,commit)
-                       set abbrev [string range $commit 0 8]
+                       set cmit $blame_data($w,commit)
+                       set abbrev [string range $cmit 0 8]
 
-                       if {[catch {set author $blame_data($w,$commit,author)} err]} {
-                       puts $err
+                       if {[catch {set author $blame_data($w,$cmit,author)} err]} {
                                set author {}
                        }
 
-                       if {[catch {set atime $blame_data($w,$commit,author-time)}]} {
+                       if {[catch {set atime $blame_data($w,$cmit,author-time)}]} {
                                set atime {}
                        } else {
                                set atime [clock format $atime -format {%Y-%m-%d %T}]
                        }
 
                        while {$n > 0} {
-                               $w_commit delete $lno.0 "$lno.0 lineend"
-                               $w_author delete $lno.0 "$lno.0 lineend"
-                               $w_date delete $lno.0 "$lno.0 lineend"
+                               if {![catch {set g g$blame_data($w,line$lno,commit)}]} {
+                                       foreach t $all {
+                                               $t tag remove $g $lno.0 "$lno.0 lineend + 1c"
+                                       }
+                               }
+
+                               foreach t [list \
+                                       $w_commit \
+                                       $w_author \
+                                       $w_date \
+                                       $w_filename \
+                                       $w_olno] {
+                                       $t delete $lno.0 "$lno.0 lineend"
+                               }
 
                                $w_commit insert $lno.0 $abbrev
                                $w_author insert $lno.0 $author
                                $w_date insert $lno.0 $atime
-                               set blame_data($w,line$lno,commit) $commit
+                               $w_filename insert $lno.0 $file
+                               $w_olno insert $lno.0 $ol linenumber
+
+                               set g g$cmit
+                               foreach t $all {
+                                       $t tag add $g $lno.0 "$lno.0 lineend + 1c"
+                               }
+
+                               set blame_data($w,line$lno,commit) $cmit
 
                                incr n -1
                                incr lno
+                               incr ol
                        }
                } elseif {[regexp {^([a-z-]+) (.*)$} $line line header data]} {
                        set blame_data($w,$blame_data($w,commit),$header) $data
@@ -3340,6 +3558,8 @@ proc read_blame_incremental {fd w w_commit w_author w_date w_lno w_file} {
        $w_commit conf -state disabled
        $w_author conf -state disabled
        $w_date conf -state disabled
+       $w_filename conf -state disabled
+       $w_olno conf -state disabled
 
        if {[eof $fd]} {
                close $fd
@@ -3906,34 +4126,36 @@ proc do_quit {} {
        if {$is_quitting} return
        set is_quitting 1
 
-       # -- Stash our current commit buffer.
-       #
-       set save [gitdir GITGUI_MSG]
-       set msg [string trim [$ui_comm get 0.0 end]]
-       regsub -all -line {[ \r\t]+$} $msg {} msg
-       if {(![string match amend* $commit_type]
-               || [$ui_comm edit modified])
-               && $msg ne {}} {
-               catch {
-                       set fd [open $save w]
-                       puts -nonewline $fd $msg
-                       close $fd
+       if {[winfo exists $ui_comm]} {
+               # -- Stash our current commit buffer.
+               #
+               set save [gitdir GITGUI_MSG]
+               set msg [string trim [$ui_comm get 0.0 end]]
+               regsub -all -line {[ \r\t]+$} $msg {} msg
+               if {(![string match amend* $commit_type]
+                       || [$ui_comm edit modified])
+                       && $msg ne {}} {
+                       catch {
+                               set fd [open $save w]
+                               puts -nonewline $fd $msg
+                               close $fd
+                       }
+               } else {
+                       catch {file delete $save}
                }
-       } else {
-               catch {file delete $save}
-       }
 
-       # -- Stash our current window geometry into this repository.
-       #
-       set cfg_geometry [list]
-       lappend cfg_geometry [wm geometry .]
-       lappend cfg_geometry [lindex [.vpane sash coord 0] 1]
-       lappend cfg_geometry [lindex [.vpane.files sash coord 0] 0]
-       if {[catch {set rc_geometry $repo_config(gui.geometry)}]} {
-               set rc_geometry {}
-       }
-       if {$cfg_geometry ne $rc_geometry} {
-               catch {exec git repo-config gui.geometry $cfg_geometry}
+               # -- Stash our current window geometry into this repository.
+               #
+               set cfg_geometry [list]
+               lappend cfg_geometry [wm geometry .]
+               lappend cfg_geometry [lindex [.vpane sash coord 0] 1]
+               lappend cfg_geometry [lindex [.vpane.files sash coord 0] 0]
+               if {[catch {set rc_geometry $repo_config(gui.geometry)}]} {
+                       set rc_geometry {}
+               }
+               if {$cfg_geometry ne $rc_geometry} {
+                       catch {exec git repo-config gui.geometry $cfg_geometry}
+               }
        }
 
        destroy .
@@ -4703,11 +4925,11 @@ apply_config
 menu .mbar -tearoff 0
 .mbar add cascade -label Repository -menu .mbar.repository
 .mbar add cascade -label Edit -menu .mbar.edit
-if {!$single_commit} {
+if {[is_enabled branch]} {
        .mbar add cascade -label Branch -menu .mbar.branch
 }
 .mbar add cascade -label Commit -menu .mbar.commit
-if {!$single_commit} {
+if {[is_enabled transport]} {
        .mbar add cascade -label Merge -menu .mbar.merge
        .mbar add cascade -label Fetch -menu .mbar.fetch
        .mbar add cascade -label Push -menu .mbar.push
@@ -4734,7 +4956,7 @@ menu .mbar.repository
        -font font_ui
 .mbar.repository add separator
 
-if {!$single_commit} {
+if {[is_enabled multicommit]} {
        .mbar.repository add command -label {Database Statistics} \
                -command do_stats \
                -font font_ui
@@ -4808,7 +5030,7 @@ menu .mbar.edit
 
 # -- Branch Menu
 #
-if {!$single_commit} {
+if {[is_enabled branch]} {
        menu .mbar.branch
 
        .mbar.branch add command -label {Create...} \
@@ -5015,7 +5237,7 @@ pack .branch.l1 -side left
 pack .branch.cb -side left -fill x
 pack .branch -side top -fill x
 
-if {!$single_commit} {
+if {[is_enabled branch]} {
        menu .mbar.merge
        .mbar.merge add command -label {Local Merge...} \
                -command do_local_merge \
@@ -5487,7 +5709,7 @@ bind $ui_diff <Key-Left>   {catch {%W xview scroll -1 units};break}
 bind $ui_diff <Key-Right>  {catch {%W xview scroll  1 units};break}
 bind $ui_diff <Button-1>   {focus %W}
 
-if {!$single_commit} {
+if {[is_enabled branch]} {
        bind . <$M1B-Key-n> do_create_branch
        bind . <$M1B-Key-N> do_create_branch
 }
@@ -5584,7 +5806,7 @@ user.email settings into your personal
 
 # -- Only initialize complex UI if we are going to stay running.
 #
-if {!$single_commit} {
+if {[is_enabled transport]} {
        load_all_remotes
        load_all_heads
 
@@ -5595,7 +5817,7 @@ if {!$single_commit} {
 
 # -- Only suggest a gc run if we are going to stay running.
 #
-if {!$single_commit} {
+if {[is_enabled multicommit]} {
        set object_limit 2000
        if {[is_Windows]} {set object_limit 200}
        regexp {^([0-9]+) objects,} [exec git count-objects] _junk objects_current