Code

git-gui: Fix gitk for branch whose name matches local file
[git.git] / git-gui.sh
index 4a762355d64f41e89af3aa1ceab713ba16eae380..211494587e604615987b447add5794d17831701c 100755 (executable)
@@ -122,6 +122,7 @@ unset oguimsg
 set _appname {Git Gui}
 set _gitdir {}
 set _gitexec {}
+set _githtmldir {}
 set _reponame {}
 set _iscygwin {}
 set _search_path {}
@@ -168,6 +169,28 @@ proc gitexec {args} {
        return [eval [list file join $_gitexec] $args]
 }
 
+proc githtmldir {args} {
+       global _githtmldir
+       if {$_githtmldir eq {}} {
+               if {[catch {set _githtmldir [git --html-path]}]} {
+                       # Git not installed or option not yet supported
+                       return {}
+               }
+               if {[is_Cygwin]} {
+                       set _githtmldir [exec cygpath \
+                               --windows \
+                               --absolute \
+                               $_githtmldir]
+               } else {
+                       set _githtmldir [file normalize $_githtmldir]
+               }
+       }
+       if {$args eq {}} {
+               return $_githtmldir
+       }
+       return [eval [list file join $_githtmldir] $args]
+}
+
 proc reponame {} {
        return $::_reponame
 }
@@ -591,6 +614,34 @@ bind . <Visibility> {
 
 if {[is_Windows]} {
        wm iconbitmap . -default $oguilib/git-gui.ico
+       set ::tk::AlwaysShowSelection 1
+
+       # Spoof an X11 display for SSH
+       if {![info exists env(DISPLAY)]} {
+               set env(DISPLAY) :9999
+       }
+} else {
+       catch {
+               image create photo gitlogo -width 16 -height 16
+
+               gitlogo put #33CC33 -to  7  0  9  2
+               gitlogo put #33CC33 -to  4  2 12  4
+               gitlogo put #33CC33 -to  7  4  9  6
+               gitlogo put #CC3333 -to  4  6 12  8
+               gitlogo put gray26  -to  4  9  6 10
+               gitlogo put gray26  -to  3 10  6 12
+               gitlogo put gray26  -to  8  9 13 11
+               gitlogo put gray26  -to  8 11 10 12
+               gitlogo put gray26  -to 11 11 13 14
+               gitlogo put gray26  -to  3 12  5 14
+               gitlogo put gray26  -to  5 13
+               gitlogo put gray26  -to 10 13
+               gitlogo put gray26  -to  4 14 12 15
+               gitlogo put gray26  -to  5 15 11 16
+               gitlogo redither
+
+               wm iconphoto . -default gitlogo
+       }
 }
 
 ######################################################################
@@ -612,10 +663,13 @@ font create font_diffbold
 font create font_diffitalic
 
 foreach class {Button Checkbutton Entry Label
-               Labelframe Listbox Menu Message
+               Labelframe Listbox Message
                Radiobutton Spinbox Text} {
        option add *$class.font font_ui
 }
+if {![is_MacOSX]} {
+       option add *Menu.font font_ui
+}
 unset class
 
 if {[is_Windows] || [is_MacOSX]} {
@@ -671,13 +725,14 @@ proc apply_config {} {
 
 set default_config(branch.autosetupmerge) true
 set default_config(merge.tool) {}
-set default_config(merge.keepbackup) true
+set default_config(mergetool.keepbackup) true
 set default_config(merge.diffstat) true
 set default_config(merge.summary) false
 set default_config(merge.verbosity) 2
 set default_config(user.name) {}
 set default_config(user.email) {}
 
+set default_config(gui.encoding) [encoding system]
 set default_config(gui.matchtrackingbranch) false
 set default_config(gui.pruneduringfetch) false
 set default_config(gui.trustmtime) false
@@ -690,6 +745,8 @@ set default_config(gui.newbranchtemplate) {}
 set default_config(gui.spellingdictionary) {}
 set default_config(gui.fontui) [font configure font_ui]
 set default_config(gui.fontdiff) [font configure font_diff]
+# TODO: this option should be added to the git-config documentation
+set default_config(gui.maxfilesdisplayed) 5000
 set font_descs {
        {fontui   font_ui   {mc "Main Font"}}
        {fontdiff font_diff {mc "Diff/Console Font"}}
@@ -740,9 +797,9 @@ if {![regsub {^git version } $_git_version {} _git_version]} {
 set _real_git_version $_git_version
 regsub -- {[\-\.]dirty$} $_git_version {} _git_version
 regsub {\.[0-9]+\.g[0-9a-f]+$} $_git_version {} _git_version
-regsub {\.rc[0-9]+$} $_git_version {} _git_version
+regsub {\.[a-zA-Z]+\.?[0-9]+$} $_git_version {} _git_version
 regsub {\.GIT$} $_git_version {} _git_version
-regsub {\.[a-zA-Z]+\.[0-9]+$} $_git_version {} _git_version
+regsub {\.[a-zA-Z]+\.?[0-9]+$} $_git_version {} _git_version
 
 if {![regexp {^[1-9]+(\.[0-9]+)+$} $_git_version]} {
        catch {wm withdraw .}
@@ -911,19 +968,25 @@ git-version proc _parse_config {arr_name args} {
 }
 
 proc load_config {include_global} {
-       global repo_config global_config default_config
+       global repo_config global_config system_config default_config
 
        if {$include_global} {
+               _parse_config system_config --system
                _parse_config global_config --global
        }
        _parse_config repo_config
 
        foreach name [array names default_config] {
+               if {[catch {set v $system_config($name)}]} {
+                       set system_config($name) $default_config($name)
+               }
+       }
+       foreach name [array names system_config] {
                if {[catch {set v $global_config($name)}]} {
-                       set global_config($name) $default_config($name)
+                       set global_config($name) $system_config($name)
                }
                if {[catch {set v $repo_config($name)}]} {
-                       set repo_config($name) $default_config($name)
+                       set repo_config($name) $system_config($name)
                }
        }
 }
@@ -990,10 +1053,22 @@ citool {
 }
 }
 
+######################################################################
+##
+## execution environment
+
+set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
+
+# Suggest our implementation of askpass, if none is set
+if {![info exists env(SSH_ASKPASS)]} {
+       set env(SSH_ASKPASS) [gitexec git-gui--askpass]
+}
+
 ######################################################################
 ##
 ## repository setup
 
+set picked 0
 if {[catch {
                set _gitdir $env(GIT_DIR)
                set _prefix {}
@@ -1005,6 +1080,7 @@ if {[catch {
        load_config 1
        apply_config
        choose_repository::pick
+       set picked 1
 }
 if {![file isdirectory $_gitdir] && [is_Cygwin]} {
        catch {set _gitdir [exec cygpath --windows $_gitdir]}
@@ -1058,7 +1134,10 @@ set current_branch {}
 set is_detached 0
 set current_diff_path {}
 set is_3way_diff 0
+set is_submodule_diff 0
+set is_conflict_diff 0
 set selected_commit_type new
+set diff_empty_count 0
 
 set nullid "0000000000000000000000000000000000000000"
 set nullid2 "0000000000000000000000000000000000000001"
@@ -1442,10 +1521,8 @@ proc rescan_done {fd buf after} {
        prune_selection
        unlock_index
        display_all_files
-       if {$current_diff_path ne {}} reshow_diff
-       if {$current_diff_path eq {}} select_first_diff
-
-       uplevel #0 $after
+       if {$current_diff_path ne {}} { reshow_diff $after }
+       if {$current_diff_path eq {}} { select_first_diff $after }
 }
 
 proc prune_selection {} {
@@ -1624,10 +1701,12 @@ proc display_all_files_helper {w path icon_name m} {
        $w insert end "[escape_path $path]\n"
 }
 
+set files_warning 0
 proc display_all_files {} {
        global ui_index ui_workdir
        global file_states file_lists
        global last_clicked
+       global files_warning
 
        $ui_index conf -state normal
        $ui_workdir conf -state normal
@@ -1639,7 +1718,18 @@ proc display_all_files {} {
        set file_lists($ui_index) [list]
        set file_lists($ui_workdir) [list]
 
-       foreach path [lsort [array names file_states]] {
+       set to_display [lsort [array names file_states]]
+       set display_limit [get_config gui.maxfilesdisplayed]
+       if {[llength $to_display] > $display_limit} {
+               if {!$files_warning} {
+                       # do not repeatedly warn:
+                       set files_warning 1
+                       info_popup [mc "Displaying only %s of %s files." \
+                               $display_limit [llength $to_display]]
+               }
+               set to_display [lrange $to_display 0 [expr {$display_limit-1}]]
+       }
+       foreach path $to_display {
                set s $file_states($path)
                set m [lindex $s 0]
                set icon_name [lindex $s 1]
@@ -1851,7 +1941,7 @@ proc do_gitk {revs} {
                cd [file dirname [gitdir]]
                set env(GIT_DIR) [file tail [gitdir]]
 
-               eval exec $cmd $revs &
+               eval exec $cmd $revs "--" "--" &
 
                if {$old_GIT_DIR eq {}} {
                        unset env(GIT_DIR)
@@ -1867,6 +1957,19 @@ proc do_gitk {revs} {
        }
 }
 
+proc do_explore {} {
+       set explorer {}
+       if {[is_Cygwin] || [is_Windows]} {
+               set explorer "explorer.exe"
+       } elseif {[is_MacOSX]} {
+               set explorer "open"
+       } else {
+               # freedesktop.org-conforming system is our best shot
+               set explorer "xdg-open"
+       }
+       eval exec $explorer [list [file nativename [file dirname [gitdir]]]] &
+}
+
 set is_quitting 0
 set ret_code    1
 
@@ -1923,6 +2026,19 @@ proc do_quit {{rc {1}}} {
 
                # -- Stash our current window geometry into this repository.
                #
+               set cfg_wmstate [wm state .]
+               if {[catch {set rc_wmstate $repo_config(gui.wmstate)}]} {
+                       set rc_wmstate {}
+               }
+               if {$cfg_wmstate ne $rc_wmstate} {
+                       catch {git config gui.wmstate $cfg_wmstate}
+               }
+               if {$cfg_wmstate eq {zoomed}} {
+                       # on Windows wm geometry will lie about window
+                       # position (but not size) when window is zoomed
+                       # restore the window before querying wm geometry
+                       wm state . normal
+               }
                set cfg_geometry [list]
                lappend cfg_geometry [wm geometry .]
                lappend cfg_geometry [lindex [.vpane sash coord 0] 0]
@@ -1936,6 +2052,11 @@ proc do_quit {{rc {1}}} {
        }
 
        set ret_code $rc
+
+       # Briefly enable send again, working around Tk bug
+       # http://sourceforge.net/tracker/?func=detail&atid=112997&aid=1821174&group_id=12997
+       tk appname [appname]
+
        destroy .
 }
 
@@ -1944,16 +2065,16 @@ proc do_rescan {} {
 }
 
 proc ui_do_rescan {} {
-       rescan {force_first_diff; ui_ready}
+       rescan {force_first_diff ui_ready}
 }
 
 proc do_commit {} {
        commit_tree
 }
 
-proc next_diff {} {
+proc next_diff {{after {}}} {
        global next_diff_p next_diff_w next_diff_i
-       show_diff $next_diff_p $next_diff_w {}
+       show_diff $next_diff_p $next_diff_w {} {} $after
 }
 
 proc find_anchor_pos {lst name} {
@@ -2038,25 +2159,42 @@ proc next_diff_after_action {w path {lno {}} {mmask {}}} {
        }
 }
 
-proc select_first_diff {} {
+proc select_first_diff {after} {
        global ui_workdir
 
        if {[find_next_diff $ui_workdir {} 1 {^_?U}] ||
            [find_next_diff $ui_workdir {} 1 {[^O]$}]} {
-               next_diff
+               next_diff $after
+       } else {
+               uplevel #0 $after
        }
 }
 
-proc force_first_diff {} {
-       global current_diff_path
+proc force_first_diff {after} {
+       global ui_workdir current_diff_path file_states
 
        if {[info exists file_states($current_diff_path)]} {
                set state [lindex $file_states($current_diff_path) 0]
+       } else {
+               set state {OO}
+       }
 
-               if {[string index $state 1] ne {O}} return
+       set reselect 0
+       if {[string first {U} $state] >= 0} {
+               # Already a conflict, do nothing
+       } elseif {[find_next_diff $ui_workdir $current_diff_path {} {^_?U}]} {
+               set reselect 1
+       } elseif {[string index $state 1] ne {O}} {
+               # Already a diff & no conflicts, do nothing
+       } elseif {[find_next_diff $ui_workdir $current_diff_path {} {[^O]$}]} {
+               set reselect 1
        }
 
-       select_first_diff
+       if {$reselect} {
+               next_diff $after
+       } else {
+               uplevel #0 $after
+       }
 }
 
 proc toggle_or_diff {w x y} {
@@ -2077,19 +2215,23 @@ proc toggle_or_diff {w x y} {
        $ui_index tag remove in_sel 0.0 end
        $ui_workdir tag remove in_sel 0.0 end
 
-       # Do not stage files with conflicts
+       # Determine the state of the file
        if {[info exists file_states($path)]} {
                set state [lindex $file_states($path) 0]
        } else {
                set state {__}
        }
 
-       if {[string first {U} $state] >= 0} {
-               set col 1
-       }
-
        # Restage the file, or simply show the diff
        if {$col == 0 && $y > 1} {
+               # Conflicts need special handling
+               if {[string first {U} $state] >= 0} {
+                       # $w must always be $ui_workdir, but...
+                       if {$w ne $ui_workdir} { set lno {} }
+                       merge_stage_workdir $path $lno
+                       return
+               }
+
                if {[string index $state 1] eq {O}} {
                        set mmask {}
                } else {
@@ -2196,6 +2338,12 @@ set ui_comm {}
 # -- Menu Bar
 #
 menu .mbar -tearoff 0
+if {[is_MacOSX]} {
+       # -- Apple Menu (Mac OS X only)
+       #
+       .mbar add cascade -label Apple -menu .mbar.apple
+       menu .mbar.apple
+}
 .mbar add cascade -label [mc Repository] -menu .mbar.repository
 .mbar add cascade -label [mc Edit] -menu .mbar.edit
 if {[is_enabled branch]} {
@@ -2208,12 +2356,19 @@ if {[is_enabled transport]} {
        .mbar add cascade -label [mc Merge] -menu .mbar.merge
        .mbar add cascade -label [mc Remote] -menu .mbar.remote
 }
-. configure -menu .mbar
+if {[is_enabled multicommit] || [is_enabled singlecommit]} {
+       .mbar add cascade -label [mc Tools] -menu .mbar.tools
+}
 
 # -- Repository Menu
 #
 menu .mbar.repository
 
+.mbar.repository add command \
+       -label [mc "Explore Working Copy"] \
+       -command {do_explore}
+.mbar.repository add separator
+
 .mbar.repository add command \
        -label [mc "Browse Current Branch's Files"] \
        -command {browser::new $current_branch}
@@ -2388,12 +2543,14 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
 
        .mbar.commit add command -label [mc "Unstage From Commit"] \
-               -command do_unstage_selection
+               -command do_unstage_selection \
+               -accelerator $M1T-U
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
 
        .mbar.commit add command -label [mc "Revert Changes"] \
-               -command do_revert_selection
+               -command do_revert_selection \
+               -accelerator $M1T-J
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
 
@@ -2409,7 +2566,7 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
 
        .mbar.commit add separator
 
-       if {![is_enabled nocommit]} {
+       if {![is_enabled nocommitmsg]} {
                .mbar.commit add command -label [mc "Sign Off"] \
                        -command do_signoff \
                        -accelerator $M1T-S
@@ -2442,29 +2599,21 @@ if {[is_enabled branch]} {
 if {[is_enabled transport]} {
        menu .mbar.remote
 
+       .mbar.remote add command \
+               -label [mc "Add..."] \
+               -command remote_add::dialog \
+               -accelerator $M1T-A
        .mbar.remote add command \
                -label [mc "Push..."] \
                -command do_push_anywhere \
                -accelerator $M1T-P
        .mbar.remote add command \
-               -label [mc "Delete..."] \
+               -label [mc "Delete Branch..."] \
                -command remote_branch_delete::dialog
 }
 
 if {[is_MacOSX]} {
-       # -- Apple Menu (Mac OS X only)
-       #
-       .mbar add cascade -label Apple -menu .mbar.apple
-       menu .mbar.apple
-
-       .mbar.apple add command -label [mc "About %s" [appname]] \
-               -command do_about
-       .mbar.apple add separator
-       .mbar.apple add command \
-               -label [mc "Preferences..."] \
-               -command do_options \
-               -accelerator $M1T-,
-       bind . <$M1B-,> do_options
+       proc ::tk::mac::ShowPreferences {} {do_options}
 } else {
        # -- Edit Menu
        #
@@ -2473,39 +2622,41 @@ if {[is_MacOSX]} {
                -command do_options
 }
 
+# -- Tools Menu
+#
+if {[is_enabled multicommit] || [is_enabled singlecommit]} {
+       set tools_menubar .mbar.tools
+       menu $tools_menubar
+       $tools_menubar add separator
+       $tools_menubar add command -label [mc "Add..."] -command tools_add::dialog
+       $tools_menubar add command -label [mc "Remove..."] -command tools_remove::dialog
+       set tools_tailcnt 3
+       if {[array names repo_config guitool.*.cmd] ne {}} {
+               tools_populate_all
+       }
+}
+
 # -- Help Menu
 #
 .mbar add cascade -label [mc Help] -menu .mbar.help
 menu .mbar.help
 
-if {![is_MacOSX]} {
+if {[is_MacOSX]} {
+       .mbar.apple add command -label [mc "About %s" [appname]] \
+               -command do_about
+       .mbar.apple add separator
+} else {
        .mbar.help add command -label [mc "About %s" [appname]] \
                -command do_about
 }
+. configure -menu .mbar
 
-set browser {}
-catch {set browser $repo_config(instaweb.browser)}
-set doc_path [file dirname [gitexec]]
-set doc_path [file join $doc_path Documentation index.html]
+set doc_path [githtmldir]
+if {$doc_path ne {}} {
+       set doc_path [file join $doc_path index.html]
 
-if {[is_Cygwin]} {
-       set doc_path [exec cygpath --mixed $doc_path]
-}
-
-if {$browser eq {}} {
-       if {[is_MacOSX]} {
-               set browser open
-       } elseif {[is_Cygwin]} {
-               set program_files [file dirname [exec cygpath --windir]]
-               set program_files [file join $program_files {Program Files}]
-               set firefox [file join $program_files {Mozilla Firefox} firefox.exe]
-               set ie [file join $program_files {Internet Explorer} IEXPLORE.EXE]
-               if {[file exists $firefox]} {
-                       set browser $firefox
-               } elseif {[file exists $ie]} {
-                       set browser $ie
-               }
-               unset program_files firefox ie
+       if {[is_Cygwin]} {
+               set doc_path [exec cygpath --mixed $doc_path]
        }
 }
 
@@ -2515,11 +2666,17 @@ if {[file isfile $doc_path]} {
        set doc_url {http://www.kernel.org/pub/software/scm/git/docs/}
 }
 
-if {$browser ne {}} {
-       .mbar.help add command -label [mc "Online Documentation"] \
-               -command [list exec $browser $doc_url &]
+proc start_browser {url} {
+       git "web--browse" $url
 }
-unset browser doc_path doc_url
+
+.mbar.help add command -label [mc "Online Documentation"] \
+       -command [list start_browser $doc_url]
+
+.mbar.help add command -label [mc "Show SSH Key"] \
+       -command do_ssh_key
+
+unset doc_path doc_url
 
 # -- Standard bindings
 #
@@ -2535,6 +2692,20 @@ proc usage {} {
        exit 1
 }
 
+proc normalize_relpath {path} {
+       set elements {}
+       foreach item [file split $path] {
+               if {$item eq {.}} continue
+               if {$item eq {..} && [llength $elements] > 0
+                   && [lindex $elements end] ne {..}} {
+                       set elements [lrange $elements 0 end-1]
+                       continue
+               }
+               lappend elements $item
+       }
+       return [eval file join $elements]
+}
+
 # -- Not a normal commit type invocation?  Do that instead!
 #
 switch -- $subcommand {
@@ -2553,7 +2724,7 @@ blame {
        foreach a $argv {
                if {$is_path || [file exists $_prefix$a]} {
                        if {$path ne {}} usage
-                       set path $_prefix$a
+                       set path [normalize_relpath $_prefix$a]
                        break
                } elseif {$a eq {--}} {
                        if {$path ne {}} {
@@ -2576,7 +2747,7 @@ blame {
        unset is_path
 
        if {$head ne {} && $path eq {}} {
-               set path $_prefix$head
+               set path [normalize_relpath $_prefix$head]
                set head {}
        }
 
@@ -2739,7 +2910,7 @@ pack .vpane.lower.commarea.buttons.incall -side top -fill x
 lappend disable_on_lock \
        {.vpane.lower.commarea.buttons.incall conf -state}
 
-if {![is_enabled nocommit]} {
+if {![is_enabled nocommitmsg]} {
        button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \
                -command do_signoff
        pack .vpane.lower.commarea.buttons.signoff -side top -fill x
@@ -2835,7 +3006,7 @@ $ctxm add command \
        -command {tk_textPaste $ui_comm}
 $ctxm add command \
        -label [mc Delete] \
-       -command {$ui_comm delete sel.first sel.last}
+       -command {catch {$ui_comm delete sel.first sel.last}}
 $ctxm add separator
 $ctxm add command \
        -label [mc "Select All"] \
@@ -2919,7 +3090,7 @@ frame .vpane.lower.diff.body
 set ui_diff .vpane.lower.diff.body.t
 text $ui_diff -background white -foreground black \
        -borderwidth 0 \
-       -width 80 -height 15 -wrap none \
+       -width 80 -height 5 -wrap none \
        -font font_diff \
        -xscrollcommand {.vpane.lower.diff.body.sbx set} \
        -yscrollcommand {.vpane.lower.diff.body.sby set} \
@@ -3009,6 +3180,14 @@ proc create_common_diff_popup {ctxm} {
                -command {incr_font_size font_diff 1}
        lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
        $ctxm add separator
+       set emenu $ctxm.enc
+       menu $emenu
+       build_encoding_menu $emenu [list force_diff_encoding]
+       $ctxm add cascade \
+               -label [mc "Encoding"] \
+               -menu $emenu
+       lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+       $ctxm add separator
        $ctxm add command -label [mc "Options..."] \
                -command do_options
 }
@@ -3048,11 +3227,6 @@ $ctxmmg add command \
        -command {merge_resolve_one 1}
 lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
 $ctxmmg add separator
-$ctxmmg add command \
-       -label [mc "Stage Working Copy"] \
-       -command {merge_resolve_one 0}
-lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
-$ctxmmg add separator
 create_common_diff_popup $ctxmmg
 
 proc popup_diff_menu {ctxm ctxmmg x y X Y} {
@@ -3074,7 +3248,7 @@ proc popup_diff_menu {ctxm ctxmmg x y X Y} {
                        set l [mc "Stage Hunk For Commit"]
                        set t [mc "Stage Line For Commit"]
                }
-               if {$::is_3way_diff
+               if {$::is_3way_diff || $::is_submodule_diff
                        || $current_diff_path eq {}
                        || {__} eq $state
                        || {_O} eq $state
@@ -3111,11 +3285,23 @@ wm geometry . [lindex $gm 0]
 unset gm
 }
 
+# -- Load window state
+#
+catch {
+set gws $repo_config(gui.wmstate)
+wm state . $gws
+unset gws
+}
+
 # -- Key Bindings
 #
 bind $ui_comm <$M1B-Key-Return> {do_commit;break}
 bind $ui_comm <$M1B-Key-t> {do_add_selection;break}
 bind $ui_comm <$M1B-Key-T> {do_add_selection;break}
+bind $ui_comm <$M1B-Key-u> {do_unstage_selection;break}
+bind $ui_comm <$M1B-Key-U> {do_unstage_selection;break}
+bind $ui_comm <$M1B-Key-j> {do_revert_selection;break}
+bind $ui_comm <$M1B-Key-J> {do_revert_selection;break}
 bind $ui_comm <$M1B-Key-i> {do_add_all;break}
 bind $ui_comm <$M1B-Key-I> {do_add_all;break}
 bind $ui_comm <$M1B-Key-x> {tk_textCut %W;break}
@@ -3217,7 +3403,6 @@ by %s:
                {^GIT_PAGER$} -
                {^GIT_TRACE$} -
                {^GIT_CONFIG$} -
-               {^GIT_CONFIG_LOCAL$} -
                {^GIT_(AUTHOR|COMMITTER)_DATE$} {
                        append msg " - $name\n"
                        incr ignored_env
@@ -3254,8 +3439,7 @@ if {[is_enabled transport]} {
        load_all_remotes
 
        set n [.mbar.remote index end]
-       populate_push_menu
-       populate_fetch_menu
+       populate_remotes_menu
        set n [expr {[.mbar.remote index end] - $n}]
        if {$n > 0} {
                if {[.mbar.remote type 0] eq "tearoff"} { incr n }
@@ -3362,3 +3546,6 @@ if {[is_enabled multicommit]} {
 if {[is_enabled retcode]} {
        bind . <Destroy> {+terminate_me %W}
 }
+if {$picked && [is_config_true gui.autoexplore]} {
+       do_explore
+}