Merge branch 'maint'
authorShawn O. Pearce <spearce@spearce.org>
Tue, 4 Sep 2007 03:07:59 +0000 (23:07 -0400)
committerShawn O. Pearce <spearce@spearce.org>
Tue, 4 Sep 2007 03:07:59 +0000 (23:07 -0400)
* maint:
git-gui: Properly set the state of "Stage/Unstage Hunk" action
git-gui: Fix detaching current branch during checkout
git-gui: Correct starting of git-remote to handle -w option

Conflicts:

git-gui.sh

1  2 
git-gui.sh
lib/checkout_op.tcl
diff --combined git-gui.sh
index 5635eeae360932b45bcf7fd44bad5ecbea010ef3,44977aa2124c034f3711548763cd6a69a2c52c77..b3d447e598019eefc3f3d27029b18017a934f724
@@@ -42,24 -42,6 +42,24 @@@ if {[catch {package require Tcl 8.4} er
        exit 1
  }
  
 +######################################################################
 +##
 +## locate our library
 +
 +set oguilib {@@GITGUI_LIBDIR@@}
 +set oguirel {@@GITGUI_RELATIVE@@}
 +if {$oguirel eq {1}} {
 +      set oguilib [file dirname [file dirname [file normalize $argv0]]]
 +      set oguilib [file join $oguilib share git-gui lib]
 +      set oguimsg [file join $oguilib msgs]
 +} elseif {[string match @@* $oguirel]} {
 +      set oguilib [file join [file dirname [file normalize $argv0]] lib]
 +      set oguimsg [file join [file dirname [file normalize $argv0]] po]
 +} else {
 +      set oguimsg [file join $oguilib msgs]
 +}
 +unset oguirel
 +
  ######################################################################
  ##
  ## enable verbose loading?
@@@ -78,16 -60,6 +78,16 @@@ if {![catch {set _verbose $env(GITGUI_V
        }
  }
  
 +######################################################################
 +##
 +## Internationalization (i18n) through msgcat and gettext. See
 +## http://www.gnu.org/software/gettext/manual/html_node/Tcl.html
 +
 +package require msgcat
 +namespace import ::msgcat::mc
 +::msgcat::mcload $oguimsg
 +unset oguimsg
 +
  ######################################################################
  ##
  ## read only globals
@@@ -289,7 -261,7 +289,7 @@@ proc _git_cmd {name} 
                        set s [gets $f]
                        close $f
  
-                       switch -glob -- $s {
+                       switch -glob -- [lindex $s 0] {
                        #!*sh     { set i sh     }
                        #!*perl   { set i perl   }
                        #!*python { set i python }
                        if {$interp eq {}} {
                                error "git-$name requires $i (not in PATH)"
                        }
-                       set v [list $interp $p]
+                       set v [concat [list $interp] [lrange $s 1 end] [list $p]]
                } else {
                        # Assume it is builtin to git somehow and we
                        # aren't actually able to see a file for it.
@@@ -502,7 -474,7 +502,7 @@@ proc tk_optionMenu {w varName args} 
  set _git  [_which git]
  if {$_git eq {}} {
        catch {wm withdraw .}
 -      error_popup "Cannot find git in PATH."
 +      error_popup [mc "Cannot find git in PATH."]
        exit 1
  }
  
@@@ -529,7 -501,7 +529,7 @@@ if {![regsub {^git version } $_git_vers
                -icon error \
                -type ok \
                -title "git-gui: fatal error" \
 -              -message "Cannot parse Git version string:\n\n$_git_version"
 +              -message [append [mc "Cannot parse Git version string:"] "\n\n$_git_version"]
        exit 1
  }
  
@@@ -546,14 -518,14 +546,14 @@@ if {![regexp {^[1-9]+(\.[0-9]+)+$} $_gi
                -type yesno \
                -default no \
                -title "[appname]: warning" \
 -              -message "Git version cannot be determined.
 +               -message [mc "Git version cannot be determined.
  
 -$_git claims it is version '$_real_git_version'.
 +%s claims it is version '%s'.
  
 -[appname] requires at least Git 1.5.0 or later.
 +%s requires at least Git 1.5.0 or later.
  
 -Assume '$_real_git_version' is version 1.5.0?
 -"] eq {yes}} {
 +Assume '%s' is version 1.5.0?
 +" $_git $_real_git_version [appname] $_real_git_version]] eq {yes}} {
                set _git_version 1.5.0
        } else {
                exit 1
@@@ -623,6 -595,15 +623,6 @@@ You are using [git-version]
  ##
  ## configure our library
  
 -set oguilib {@@GITGUI_LIBDIR@@}
 -set oguirel {@@GITGUI_RELATIVE@@}
 -if {$oguirel eq {1}} {
 -      set oguilib [file dirname [file dirname [file normalize $argv0]]]
 -      set oguilib [file join $oguilib share git-gui lib]
 -} elseif {[string match @@* $oguirel]} {
 -      set oguilib [file join [file dirname [file normalize $argv0]] lib]
 -}
 -
  set idx [file join $oguilib tclIndex]
  if {[catch {set fd [open $idx r]} err]} {
        catch {wm withdraw .}
@@@ -656,7 -637,7 +656,7 @@@ if {$idx ne {}} 
  } else {
        set auto_path [concat [list $oguilib] $auto_path]
  }
 -unset -nocomplain oguirel idx fd
 +unset -nocomplain idx fd
  
  ######################################################################
  ##
@@@ -711,7 -692,7 +711,7 @@@ if {[catch 
                set _prefix [git rev-parse --show-prefix]
        } err]} {
        catch {wm withdraw .}
 -      error_popup "Cannot find the git directory:\n\n$err"
 +      error_popup [append [mc "Cannot find the git directory:"] "\n\n$err"]
        exit 1
  }
  if {![file isdirectory $_gitdir] && [is_Cygwin]} {
  }
  if {![file isdirectory $_gitdir]} {
        catch {wm withdraw .}
 -      error_popup "Git directory not found:\n\n$_gitdir"
 +      error_popup [append [mc "Git directory not found:"] "\n\n$_gitdir"]
        exit 1
  }
  if {$_prefix ne {}} {
  } elseif {![is_enabled bare]} {
        if {[lindex [file split $_gitdir] end] ne {.git}} {
                catch {wm withdraw .}
 -              error_popup "Cannot use funny .git directory:\n\n$_gitdir"
 +              error_popup [append [mc "Cannot use funny .git directory:"] "\n\n$_gitdir"]
                exit 1
        }
        if {[catch {cd [file dirname $_gitdir]} err]} {
                catch {wm withdraw .}
 -              error_popup "No working directory [file dirname $_gitdir]:\n\n$err"
 +              error_popup [append [mc "No working directory"] " [file dirname $_gitdir]:\n\n$err"]
                exit 1
        }
  }
@@@ -885,7 -866,7 +885,7 @@@ proc rescan {after {honor_trustmtime 1}
                rescan_stage2 {} $after
        } else {
                set rescan_active 1
 -              ui_status {Refreshing file status...}
 +              ui_status [mc "Refreshing file status..."]
                set fd_rf [git_read update-index \
                        -q \
                        --unmerged \
@@@ -922,7 -903,7 +922,7 @@@ proc rescan_stage2 {fd after} 
        set buf_rlo {}
  
        set rescan_active 3
 -      ui_status {Scanning for modified files ...}
 +      ui_status [mc "Scanning for modified files ..."]
        set fd_di [git_read diff-index --cached -z [PARENT]]
        set fd_df [git_read diff-files -z]
        set fd_lo [eval git_read ls-files --others -z $ls_others]
@@@ -1088,7 -1069,7 +1088,7 @@@ proc ui_status {msg} 
  }
  
  proc ui_ready {{test {}}} {
 -      $::main_status show {Ready.} $test
 +      $::main_status show [mc "Ready."] $test
  }
  
  proc escape_path {path} {
@@@ -1353,32 -1334,31 +1353,32 @@@ set all_icons(O$ui_workdir) file_plai
  
  set max_status_desc 0
  foreach i {
 -              {__ "Unmodified"}
 -
 -              {_M "Modified, not staged"}
 -              {M_ "Staged for commit"}
 -              {MM "Portions staged for commit"}
 -              {MD "Staged for commit, missing"}
 -
 -              {_O "Untracked, not staged"}
 -              {A_ "Staged for commit"}
 -              {AM "Portions staged for commit"}
 -              {AD "Staged for commit, missing"}
 -
 -              {_D "Missing"}
 -              {D_ "Staged for removal"}
 -              {DO "Staged for removal, still present"}
 -
 -              {U_ "Requires merge resolution"}
 -              {UU "Requires merge resolution"}
 -              {UM "Requires merge resolution"}
 -              {UD "Requires merge resolution"}
 +              {__ {mc "Unmodified"}}
 +
 +              {_M {mc "Modified, not staged"}}
 +              {M_ {mc "Staged for commit"}}
 +              {MM {mc "Portions staged for commit"}}
 +              {MD {mc "Staged for commit, missing"}}
 +
 +              {_O {mc "Untracked, not staged"}}
 +              {A_ {mc "Staged for commit"}}
 +              {AM {mc "Portions staged for commit"}}
 +              {AD {mc "Staged for commit, missing"}}
 +
 +              {_D {mc "Missing"}}
 +              {D_ {mc "Staged for removal"}}
 +              {DO {mc "Staged for removal, still present"}}
 +
 +              {U_ {mc "Requires merge resolution"}}
 +              {UU {mc "Requires merge resolution"}}
 +              {UM {mc "Requires merge resolution"}}
 +              {UD {mc "Requires merge resolution"}}
        } {
 -      if {$max_status_desc < [string length [lindex $i 1]]} {
 -              set max_status_desc [string length [lindex $i 1]]
 +      set text [eval [lindex $i 1]]
 +      if {$max_status_desc < [string length $text]} {
 +              set max_status_desc [string length $text]
        }
 -      set all_descs([lindex $i 0]) [lindex $i 1]
 +      set all_descs([lindex $i 0]) $text
  }
  unset i
  
@@@ -1417,7 -1397,7 +1417,7 @@@ proc incr_font_size {font {amt 1}} 
  ##
  ## ui commands
  
 -set starting_gitk_msg {Starting gitk... please wait...}
 +set starting_gitk_msg [mc "Starting gitk... please wait..."]
  
  proc do_gitk {revs} {
        # -- Always start gitk through whatever we were loaded with.  This
        set exe [file join [file dirname $::_git] gitk]
        set cmd [list [info nameofexecutable] $exe]
        if {! [file exists $exe]} {
 -              error_popup "Unable to start gitk:\n\n$exe does not exist"
 +              error_popup [mc "Unable to start gitk:\n\n%s does not exist" $exe]
        } else {
                eval exec $cmd $revs &
                ui_status $::starting_gitk_msg
@@@ -1643,7 -1623,7 +1643,7 @@@ proc apply_config {} 
                                font configure $font $cn $cv
                        }
                        } err]} {
 -                      error_popup "Invalid font specified in gui.$name:\n\n$err"
 +                      error_popup [append [mc "Invalid font specified in %s:" "gui.$name"] "\n\n$err"]
                }
                foreach {cn cv} [font configure $font] {
                        font configure ${font}bold $cn $cv
@@@ -1668,8 -1648,8 +1668,8 @@@ set default_config(gui.newbranchtemplat
  set default_config(gui.fontui) [font configure font_ui]
  set default_config(gui.fontdiff) [font configure font_diff]
  set font_descs {
 -      {fontui   font_ui   {Main Font}}
 -      {fontdiff font_diff {Diff/Console Font}}
 +      {fontui   font_ui   {mc "Main Font"}}
 +      {fontdiff font_diff {mc "Diff/Console Font"}}
  }
  load_config 0
  apply_config
@@@ -1683,18 -1663,18 +1683,18 @@@ set ui_comm {
  # -- Menu Bar
  #
  menu .mbar -tearoff 0
 -.mbar add cascade -label Repository -menu .mbar.repository
 -.mbar add cascade -label Edit -menu .mbar.edit
 +.mbar add cascade -label [mc Repository] -menu .mbar.repository
 +.mbar add cascade -label [mc Edit] -menu .mbar.edit
  if {[is_enabled branch]} {
 -      .mbar add cascade -label Branch -menu .mbar.branch
 +      .mbar add cascade -label [mc Branch] -menu .mbar.branch
  }
  if {[is_enabled multicommit] || [is_enabled singlecommit]} {
 -      .mbar add cascade -label Commit -menu .mbar.commit
 +      .mbar add cascade -label [mc Commit] -menu .mbar.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
 +      .mbar add cascade -label [mc Merge] -menu .mbar.merge
 +      .mbar add cascade -label [mc Fetch] -menu .mbar.fetch
 +      .mbar add cascade -label [mc Push] -menu .mbar.push
  }
  . configure -menu .mbar
  
  menu .mbar.repository
  
  .mbar.repository add command \
 -      -label {Browse Current Branch's Files} \
 +      -label [mc "Browse Current Branch's Files"] \
        -command {browser::new $current_branch}
  set ui_browse_current [.mbar.repository index last]
  .mbar.repository add command \
 -      -label {Browse Branch Files...} \
 +      -label [mc "Browse Branch Files..."] \
        -command browser_open::dialog
  .mbar.repository add separator
  
  .mbar.repository add command \
 -      -label {Visualize Current Branch's History} \
 +      -label [mc "Visualize Current Branch's History"] \
        -command {do_gitk $current_branch}
  set ui_visualize_current [.mbar.repository index last]
  .mbar.repository add command \
 -      -label {Visualize All Branch History} \
 +      -label [mc "Visualize All Branch History"] \
        -command {do_gitk --all}
  .mbar.repository add separator
  
  proc current_branch_write {args} {
        global current_branch
        .mbar.repository entryconf $::ui_browse_current \
 -              -label "Browse $current_branch's Files"
 +              -label [mc "Browse %s's Files" $current_branch]
        .mbar.repository entryconf $::ui_visualize_current \
 -              -label "Visualize $current_branch's History"
 +              -label [mc "Visualize %s's History" $current_branch]
  }
  trace add variable current_branch write current_branch_write
  
  if {[is_enabled multicommit]} {
 -      .mbar.repository add command -label {Database Statistics} \
 +      .mbar.repository add command -label [mc "Database Statistics"] \
                -command do_stats
  
 -      .mbar.repository add command -label {Compress Database} \
 +      .mbar.repository add command -label [mc "Compress Database"] \
                -command do_gc
  
 -      .mbar.repository add command -label {Verify Database} \
 +      .mbar.repository add command -label [mc "Verify Database"] \
                -command do_fsck_objects
  
        .mbar.repository add separator
  
        if {[is_Cygwin]} {
                .mbar.repository add command \
 -                      -label {Create Desktop Icon} \
 +                      -label [mc "Create Desktop Icon"] \
                        -command do_cygwin_shortcut
        } elseif {[is_Windows]} {
                .mbar.repository add command \
 -                      -label {Create Desktop Icon} \
 +                      -label [mc "Create Desktop Icon"] \
                        -command do_windows_shortcut
        } elseif {[is_MacOSX]} {
                .mbar.repository add command \
 -                      -label {Create Desktop Icon} \
 +                      -label [mc "Create Desktop Icon"] \
                        -command do_macosx_app
        }
  }
  
 -.mbar.repository add command -label Quit \
 +.mbar.repository add command -label [mc Quit] \
        -command do_quit \
        -accelerator $M1T-Q
  
  # -- Edit Menu
  #
  menu .mbar.edit
 -.mbar.edit add command -label Undo \
 +.mbar.edit add command -label [mc Undo] \
        -command {catch {[focus] edit undo}} \
        -accelerator $M1T-Z
 -.mbar.edit add command -label Redo \
 +.mbar.edit add command -label [mc Redo] \
        -command {catch {[focus] edit redo}} \
        -accelerator $M1T-Y
  .mbar.edit add separator
 -.mbar.edit add command -label Cut \
 +.mbar.edit add command -label [mc Cut] \
        -command {catch {tk_textCut [focus]}} \
        -accelerator $M1T-X
 -.mbar.edit add command -label Copy \
 +.mbar.edit add command -label [mc Copy] \
        -command {catch {tk_textCopy [focus]}} \
        -accelerator $M1T-C
 -.mbar.edit add command -label Paste \
 +.mbar.edit add command -label [mc Paste] \
        -command {catch {tk_textPaste [focus]; [focus] see insert}} \
        -accelerator $M1T-V
 -.mbar.edit add command -label Delete \
 +.mbar.edit add command -label [mc Delete] \
        -command {catch {[focus] delete sel.first sel.last}} \
        -accelerator Del
  .mbar.edit add separator
 -.mbar.edit add command -label {Select All} \
 +.mbar.edit add command -label [mc "Select All"] \
        -command {catch {[focus] tag add sel 0.0 end}} \
        -accelerator $M1T-A
  
  if {[is_enabled branch]} {
        menu .mbar.branch
  
 -      .mbar.branch add command -label {Create...} \
 +      .mbar.branch add command -label [mc "Create..."] \
                -command branch_create::dialog \
                -accelerator $M1T-N
        lappend disable_on_lock [list .mbar.branch entryconf \
                [.mbar.branch index last] -state]
  
 -      .mbar.branch add command -label {Checkout...} \
 +      .mbar.branch add command -label [mc "Checkout..."] \
                -command branch_checkout::dialog \
                -accelerator $M1T-O
        lappend disable_on_lock [list .mbar.branch entryconf \
                [.mbar.branch index last] -state]
  
 -      .mbar.branch add command -label {Rename...} \
 +      .mbar.branch add command -label [mc "Rename..."] \
                -command branch_rename::dialog
        lappend disable_on_lock [list .mbar.branch entryconf \
                [.mbar.branch index last] -state]
  
 -      .mbar.branch add command -label {Delete...} \
 +      .mbar.branch add command -label [mc "Delete..."] \
                -command branch_delete::dialog
        lappend disable_on_lock [list .mbar.branch entryconf \
                [.mbar.branch index last] -state]
  
 -      .mbar.branch add command -label {Reset...} \
 +      .mbar.branch add command -label [mc "Reset..."] \
                -command merge::reset_hard
        lappend disable_on_lock [list .mbar.branch entryconf \
                [.mbar.branch index last] -state]
@@@ -1826,7 -1806,7 +1826,7 @@@ if {[is_enabled multicommit] || [is_ena
        menu .mbar.commit
  
        .mbar.commit add radiobutton \
 -              -label {New Commit} \
 +              -label [mc "New Commit"] \
                -command do_select_commit_type \
                -variable selected_commit_type \
                -value new
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
  
        .mbar.commit add radiobutton \
 -              -label {Amend Last Commit} \
 +              -label [mc "Amend Last Commit"] \
                -command do_select_commit_type \
                -variable selected_commit_type \
                -value amend
  
        .mbar.commit add separator
  
 -      .mbar.commit add command -label Rescan \
 +      .mbar.commit add command -label [mc Rescan] \
                -command do_rescan \
                -accelerator F5
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
  
 -      .mbar.commit add command -label {Stage To Commit} \
 +      .mbar.commit add command -label [mc "Stage To Commit"] \
                -command do_add_selection
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
  
 -      .mbar.commit add command -label {Stage Changed Files To Commit} \
 +      .mbar.commit add command -label [mc "Stage Changed Files To Commit"] \
                -command do_add_all \
                -accelerator $M1T-I
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
  
 -      .mbar.commit add command -label {Unstage From Commit} \
 +      .mbar.commit add command -label [mc "Unstage From Commit"] \
                -command do_unstage_selection
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
  
 -      .mbar.commit add command -label {Revert Changes} \
 +      .mbar.commit add command -label [mc "Revert Changes"] \
                -command do_revert_selection
        lappend disable_on_lock \
                [list .mbar.commit entryconf [.mbar.commit index last] -state]
  
        .mbar.commit add separator
  
 -      .mbar.commit add command -label {Sign Off} \
 +      .mbar.commit add command -label [mc "Sign Off"] \
                -command do_signoff \
                -accelerator $M1T-S
  
 -      .mbar.commit add command -label Commit \
 +      .mbar.commit add command -label [mc Commit] \
                -command do_commit \
                -accelerator $M1T-Return
        lappend disable_on_lock \
  #
  if {[is_enabled branch]} {
        menu .mbar.merge
 -      .mbar.merge add command -label {Local Merge...} \
 +      .mbar.merge add command -label [mc "Local Merge..."] \
                -command merge::dialog \
                -accelerator $M1T-M
        lappend disable_on_lock \
                [list .mbar.merge entryconf [.mbar.merge index last] -state]
 -      .mbar.merge add command -label {Abort Merge...} \
 +      .mbar.merge add command -label [mc "Abort Merge..."] \
                -command merge::reset_hard
        lappend disable_on_lock \
                [list .mbar.merge entryconf [.mbar.merge index last] -state]
@@@ -1904,38 -1884,38 +1904,38 @@@ if {[is_enabled transport]} 
        menu .mbar.fetch
  
        menu .mbar.push
 -      .mbar.push add command -label {Push...} \
 +      .mbar.push add command -label [mc "Push..."] \
                -command do_push_anywhere \
                -accelerator $M1T-P
 -      .mbar.push add command -label {Delete...} \
 +      .mbar.push add command -label [mc "Delete..."] \
                -command remote_branch_delete::dialog
  }
  
  if {[is_MacOSX]} {
        # -- Apple Menu (Mac OS X only)
        #
 -      .mbar add cascade -label Apple -menu .mbar.apple
 +      .mbar add cascade -label [mc Apple] -menu .mbar.apple
        menu .mbar.apple
  
 -      .mbar.apple add command -label "About [appname]" \
 +      .mbar.apple add command -label [mc "About %s" [appname]] \
                -command do_about
 -      .mbar.apple add command -label "Options..." \
 +      .mbar.apple add command -label [mc "Options..."] \
                -command do_options
  } else {
        # -- Edit Menu
        #
        .mbar.edit add separator
 -      .mbar.edit add command -label {Options...} \
 +      .mbar.edit add command -label [mc "Options..."] \
                -command do_options
  }
  
  # -- Help Menu
  #
 -.mbar add cascade -label Help -menu .mbar.help
 +.mbar add cascade -label [mc Help] -menu .mbar.help
  menu .mbar.help
  
  if {![is_MacOSX]} {
 -      .mbar.help add command -label "About [appname]" \
 +      .mbar.help add command -label [mc "About %s" [appname]] \
                -command do_about
  }
  
@@@ -1972,7 -1952,7 +1972,7 @@@ if {[file isfile $doc_path]} 
  }
  
  if {$browser ne {}} {
 -      .mbar.help add command -label {Online Documentation} \
 +      .mbar.help add command -label [mc "Online Documentation"] \
                -command [list exec $browser $doc_url &]
  }
  unset browser doc_path doc_url
@@@ -2094,7 -2074,7 +2094,7 @@@ frame .branch 
        -borderwidth 1 \
        -relief sunken
  label .branch.l1 \
 -      -text {Current Branch:} \
 +      -text [mc "Current Branch:"] \
        -anchor w \
        -justify left
  label .branch.cb \
@@@ -2115,7 -2095,7 +2115,7 @@@ pack .vpane -anchor n -side top -fill b
  # -- Index File List
  #
  frame .vpane.files.index -height 100 -width 200
 -label .vpane.files.index.title -text {Staged Changes (Will Be Committed)} \
 +label .vpane.files.index.title -text [mc "Staged Changes (Will Be Committed)"] \
        -background lightgreen
  text $ui_index -background white -borderwidth 0 \
        -width 20 -height 10 \
@@@ -2135,7 -2115,7 +2135,7 @@@ pack $ui_index -side left -fill both -e
  # -- Working Directory File List
  #
  frame .vpane.files.workdir -height 100 -width 200
 -label .vpane.files.workdir.title -text {Unstaged Changes (Will Not Be Committed)} \
 +label .vpane.files.workdir.title -text [mc "Unstaged Changes (Will Not Be Committed)"] \
        -background lightsalmon
  text $ui_workdir -background white -borderwidth 0 \
        -width 20 -height 10 \
@@@ -2176,29 -2156,29 +2176,29 @@@ label .vpane.lower.commarea.buttons.l -
  pack .vpane.lower.commarea.buttons.l -side top -fill x
  pack .vpane.lower.commarea.buttons -side left -fill y
  
 -button .vpane.lower.commarea.buttons.rescan -text {Rescan} \
 +button .vpane.lower.commarea.buttons.rescan -text [mc Rescan] \
        -command do_rescan
  pack .vpane.lower.commarea.buttons.rescan -side top -fill x
  lappend disable_on_lock \
        {.vpane.lower.commarea.buttons.rescan conf -state}
  
 -button .vpane.lower.commarea.buttons.incall -text {Stage Changed} \
 +button .vpane.lower.commarea.buttons.incall -text [mc "Stage Changed"] \
        -command do_add_all
  pack .vpane.lower.commarea.buttons.incall -side top -fill x
  lappend disable_on_lock \
        {.vpane.lower.commarea.buttons.incall conf -state}
  
 -button .vpane.lower.commarea.buttons.signoff -text {Sign Off} \
 +button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \
        -command do_signoff
  pack .vpane.lower.commarea.buttons.signoff -side top -fill x
  
 -button .vpane.lower.commarea.buttons.commit -text {Commit} \
 +button .vpane.lower.commarea.buttons.commit -text [mc Commit] \
        -command do_commit
  pack .vpane.lower.commarea.buttons.commit -side top -fill x
  lappend disable_on_lock \
        {.vpane.lower.commarea.buttons.commit conf -state}
  
 -button .vpane.lower.commarea.buttons.push -text {Push} \
 +button .vpane.lower.commarea.buttons.push -text [mc Push] \
        -command do_push_anywhere
  pack .vpane.lower.commarea.buttons.push -side top -fill x
  
@@@ -2209,14 -2189,14 +2209,14 @@@ frame .vpane.lower.commarea.buffer.head
  set ui_comm .vpane.lower.commarea.buffer.t
  set ui_coml .vpane.lower.commarea.buffer.header.l
  radiobutton .vpane.lower.commarea.buffer.header.new \
 -      -text {New Commit} \
 +      -text [mc "New Commit"] \
        -command do_select_commit_type \
        -variable selected_commit_type \
        -value new
  lappend disable_on_lock \
        [list .vpane.lower.commarea.buffer.header.new conf -state]
  radiobutton .vpane.lower.commarea.buffer.header.amend \
 -      -text {Amend Last Commit} \
 +      -text [mc "Amend Last Commit"] \
        -command do_select_commit_type \
        -variable selected_commit_type \
        -value amend
@@@ -2228,12 -2208,12 +2228,12 @@@ label $ui_coml 
  proc trace_commit_type {varname args} {
        global ui_coml commit_type
        switch -glob -- $commit_type {
 -      initial       {set txt {Initial Commit Message:}}
 -      amend         {set txt {Amended Commit Message:}}
 -      amend-initial {set txt {Amended Initial Commit Message:}}
 -      amend-merge   {set txt {Amended Merge Commit Message:}}
 -      merge         {set txt {Merge Commit Message:}}
 -      *             {set txt {Commit Message:}}
 +      initial       {set txt [mc "Initial Commit Message:"]}
 +      amend         {set txt [mc "Amended Commit Message:"]}
 +      amend-initial {set txt [mc "Amended Initial Commit Message:"]}
 +      amend-merge   {set txt [mc "Amended Merge Commit Message:"]}
 +      merge         {set txt [mc "Merge Commit Message:"]}
 +      *             {set txt [mc "Commit Message:"]}
        }
        $ui_coml conf -text $txt
  }
@@@ -2262,23 -2242,23 +2262,23 @@@ pack .vpane.lower.commarea.buffer -sid
  set ctxm .vpane.lower.commarea.buffer.ctxm
  menu $ctxm -tearoff 0
  $ctxm add command \
 -      -label {Cut} \
 +      -label [mc Cut] \
        -command {tk_textCut $ui_comm}
  $ctxm add command \
 -      -label {Copy} \
 +      -label [mc Copy] \
        -command {tk_textCopy $ui_comm}
  $ctxm add command \
 -      -label {Paste} \
 +      -label [mc Paste] \
        -command {tk_textPaste $ui_comm}
  $ctxm add command \
 -      -label {Delete} \
 +      -label [mc Delete] \
        -command {$ui_comm delete sel.first sel.last}
  $ctxm add separator
  $ctxm add command \
 -      -label {Select All} \
 +      -label [mc "Select All"] \
        -command {focus $ui_comm;$ui_comm tag add sel 0.0 end}
  $ctxm add command \
 -      -label {Copy All} \
 +      -label [mc "Copy All"] \
        -command {
                $ui_comm tag add sel 0.0 end
                tk_textCopy $ui_comm
        }
  $ctxm add separator
  $ctxm add command \
 -      -label {Sign Off} \
 +      -label [mc "Sign Off"] \
        -command do_signoff
  bind_button3 $ui_comm "tk_popup $ctxm %X %Y"
  
@@@ -2302,7 -2282,7 +2302,7 @@@ proc trace_current_diff_path {varname a
        } else {
                set p $current_diff_path
                set s [mapdesc [lindex $file_states($p) 0] $p]
 -              set f {File:}
 +              set f [mc "File:"]
                set p [escape_path $p]
                set o normal
        }
@@@ -2336,7 -2316,7 +2336,7 @@@ pack .vpane.lower.diff.header.path -fil
  set ctxm .vpane.lower.diff.header.ctxm
  menu $ctxm -tearoff 0
  $ctxm add command \
 -      -label {Copy} \
 +      -label [mc Copy] \
        -command {
                clipboard clear
                clipboard append \
@@@ -2404,19 -2384,19 +2404,19 @@@ $ui_diff tag raise se
  set ctxm .vpane.lower.diff.body.ctxm
  menu $ctxm -tearoff 0
  $ctxm add command \
 -      -label {Refresh} \
 +      -label [mc Refresh] \
        -command reshow_diff
  lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
  $ctxm add command \
 -      -label {Copy} \
 +      -label [mc Copy] \
        -command {tk_textCopy $ui_diff}
  lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
  $ctxm add command \
 -      -label {Select All} \
 +      -label [mc "Select All"] \
        -command {focus $ui_diff;$ui_diff tag add sel 0.0 end}
  lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
  $ctxm add command \
 -      -label {Copy All} \
 +      -label [mc "Copy All"] \
        -command {
                $ui_diff tag add sel 0.0 end
                tk_textCopy $ui_diff
  lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
  $ctxm add separator
  $ctxm add command \
 -      -label {Apply/Reverse Hunk} \
 +      -label [mc "Apply/Reverse Hunk"] \
        -command {apply_hunk $cursorX $cursorY}
  set ui_diff_applyhunk [$ctxm index last]
  lappend diff_actions [list $ctxm entryconf $ui_diff_applyhunk -state]
  $ctxm add separator
  $ctxm add command \
 -      -label {Decrease Font Size} \
 +      -label [mc "Decrease Font Size"] \
        -command {incr_font_size font_diff -1}
  lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
  $ctxm add command \
 -      -label {Increase Font Size} \
 +      -label [mc "Increase Font Size"] \
        -command {incr_font_size font_diff 1}
  lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
  $ctxm add separator
  $ctxm add command \
 -      -label {Show Less Context} \
 +      -label [mc "Show Less Context"] \
        -command {if {$repo_config(gui.diffcontext) >= 1} {
                incr repo_config(gui.diffcontext) -1
                reshow_diff
        }}
  lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
  $ctxm add command \
 -      -label {Show More Context} \
 +      -label [mc "Show More Context"] \
        -command {if {$repo_config(gui.diffcontext) < 99} {
                incr repo_config(gui.diffcontext)
                reshow_diff
        }}
  lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
  $ctxm add separator
 -$ctxm add command -label {Options...} \
 +$ctxm add command -label [mc "Options..."] \
        -command do_options
  proc popup_diff_menu {ctxm x y X Y} {
        global current_diff_path file_states
        set ::cursorX $x
        set ::cursorY $y
        if {$::ui_index eq $::current_diff_side} {
-               set s normal
 -              set l "Unstage Hunk From Commit"
 +              set l [mc "Unstage Hunk From Commit"]
        } else {
-               if {$current_diff_path eq {}
-                       || ![info exists file_states($current_diff_path)]
-                       || {_O} eq [lindex $file_states($current_diff_path) 0]} {
-                       set s disabled
-               } else {
-                       set s normal
-               }
 -              set l "Stage Hunk For Commit"
 +              set l [mc "Stage Hunk For Commit"]
        }
-       if {$::is_3way_diff} {
+       if {$::is_3way_diff
+               || $current_diff_path eq {}
+               || ![info exists file_states($current_diff_path)]
+               || {_O} eq [lindex $file_states($current_diff_path) 0]} {
                set s disabled
+       } else {
+               set s normal
        }
        $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
        tk_popup $ctxm $X $Y
@@@ -2485,7 -2462,7 +2482,7 @@@ bind_button3 $ui_diff [list popup_diff_
  #
  set main_status [::status_bar::new .status]
  pack .status -anchor w -side bottom -fill x
 -$main_status show {Initializing...}
 +$main_status show [mc "Initializing..."]
  
  # -- Load geometry
  #
diff --combined lib/checkout_op.tcl
index b98c9cbcd8d840b95ffc1cc0e92e2d5effeb2496,76f04f2854e85d51caface604d4fc10627f67620..f07262ca00876d885954ae15310a0faa197aa5ff
@@@ -76,7 -76,7 +76,7 @@@ method run {} 
                _toplevel $this {Refreshing Tracking Branch}
                set w_cons [::console::embed \
                        $w.console \
 -                      "Fetching $r_name from $remote"]
 +                      [mc "Fetching %s from %s" $r_name $remote]]
                pack $w.console -fill both -expand 1
                $w_cons exec $cmd [cb _finish_fetch]
  
@@@ -137,7 -137,7 +137,7 @@@ method _finish_fetch {ok} 
                destroy $w
                set w {}
        } else {
 -              button $w.close -text Close -command [list destroy $w]
 +              button $w.close -text [mc Close] -command [list destroy $w]
                pack $w.close -side bottom -anchor e -padx 10 -pady 10
        }
  
@@@ -166,7 -166,7 +166,7 @@@ method _update_ref {} 
                # Assume it does not exist, and that is what the error was.
                #
                if {!$create} {
 -                      _error $this "Branch '$newbranch' does not exist."
 +                      _error $this [mc "Branch '%s' does not exist." $newbranch]
                        return 0
                }
  
                # We were told to create it, but not do a merge.
                # Bad.  Name shouldn't have existed.
                #
 -              _error $this "Branch '$newbranch' already exists."
 +              _error $this [mc "Branch '%s' already exists." $newbranch]
                return 0
        } elseif {!$create && $merge_type eq {none}} {
                # We aren't creating, it exists and we don't merge.
                                        set new $cur
                                        set new_hash $cur
                                } else {
 -                                      _error $this "Branch '$newbranch' already exists.\n\nIt cannot fast-forward to $new_expr.\nA merge is required."
 +                                      _error $this [mc "Branch '%s' already exists.\n\nIt cannot fast-forward to %s.\nA merge is required." $newbranch $new_expr]
                                        return 0
                                }
                        }
                                }
                        }
                        default {
 -                              _error $this "Merge strategy '$merge_type' not supported."
 +                              _error $this [mc "Merge strategy '%s' not supported." $merge_type]
                                return 0
                        }
                        }
                if {[catch {
                                git update-ref -m $reflog_msg $ref $new $cur
                        } err]} {
 -                      _error $this "Failed to update '$newbranch'.\n\n$err"
 +                      _error $this [append [mc "Failed to update '%s'." $newbranch] "\n\n$err"]
                        return 0
                }
        }
@@@ -248,7 -248,7 +248,7 @@@ method _checkout {} 
        if {[lock_index checkout_op]} {
                after idle [cb _start_checkout]
        } else {
 -              _error $this "Staging area (index) is already locked."
 +              _error $this [mc "Staging area (index) is already locked."]
                delete_this
        }
  }
@@@ -263,12 -263,12 +263,12 @@@ method _start_checkout {} 
                && $curType eq {normal}
                && $curHEAD eq $HEAD} {
        } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} {
 -              info_popup {Last scanned state does not match repository state.
 +              info_popup [mc "Last scanned state does not match repository state.
  
  Another Git program has modified this repository since the last scan.  A rescan must be performed before the current branch can be changed.
  
  The rescan will be automatically started now.
 -}
 +"]
                unlock_index
                rescan ui_ready
                delete_this
@@@ -350,12 -350,12 +350,12 @@@ method _readtree_wait {fd} 
        if {[catch {close $fd}]} {
                set err $readtree_d
                regsub {^fatal: } $err {} err
 -              $::main_status stop "Aborted checkout of '[_name $this]' (file level merging is required)."
 -              warn_popup "File level merge required.
 +              $::main_status stop [mc "Aborted checkout of '%s' (file level merging is required)." [_name $this]]
 +              warn_popup [append [mc "File level merge required."] "
  
  $err
  
 -Staying on branch '$current_branch'."
 +" [mc "Staying on branch '%s'." $current_branch]]
                unlock_index
                delete_this
                return
@@@ -396,7 -396,7 +396,7 @@@ method _after_readtree {} 
                        set is_detached 0
                }
        } else {
-               if {$new_hash ne $HEAD} {
+               if {!$is_detached || $new_hash ne $HEAD} {
                        append log " to $new_expr"
                        if {[catch {
                                        _detach_HEAD $log $new_hash
        }
  
        if {$is_detached} {
 -              info_popup "You are no longer on a local branch.
 +              info_popup [mc "You are no longer on a local branch.
  
 -If you wanted to be on a branch, create one now starting from 'This Detached Checkout'."
 +If you wanted to be on a branch, create one now starting from 'This Detached Checkout'."]
        }
  
        # -- Update our repository state.  If we were previously in
@@@ -475,7 -475,7 +475,7 @@@ method _confirm_reset {cur} 
        pack [label $w.msg1 \
                -anchor w \
                -justify left \
 -              -text "Resetting '$name' to $new_expr will lose the following commits:" \
 +              -text [mc "Resetting '%s' to '%s' will lose the following commits:" $name $new_expr]\
                ] -anchor w
  
        set list $w.list.l
        pack [label $w.msg2 \
                -anchor w \
                -justify left \
 -              -text {Recovering lost commits may not be easy.} \
 +              -text [mc "Recovering lost commits may not be easy."] \
                ]
        pack [label $w.msg3 \
                -anchor w \
                -justify left \
 -              -text "Reset '$name'?" \
 +              -text [mc "Reset '%s'?" $name] \
                ]
  
        frame $w.buttons
        button $w.buttons.visualize \
 -              -text Visualize \
 +              -text [mc Visualize] \
                -command $gitk
        pack $w.buttons.visualize -side left
        button $w.buttons.reset \
 -              -text Reset \
 +              -text [mc Reset] \
                -command "
                        set @reset_ok 1
                        destroy $w
        pack $w.buttons.reset -side right
        button $w.buttons.cancel \
                -default active \
 -              -text Cancel \
 +              -text [mc Cancel] \
                -command [list destroy $w]
        pack $w.buttons.cancel -side right -padx 5
        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
@@@ -575,13 -575,13 +575,13 @@@ method _toplevel {title} 
  }
  
  method _fatal {err} {
 -      error_popup "Failed to set current branch.
 +      error_popup [append [mc "Failed to set current branch.
  
  This working directory is only partially switched.  We successfully updated your files, but failed to update an internal Git file.
  
 -This should not have occurred.  [appname] will now close and give up.
 +This should not have occurred.  %s will now close and give up." [appname]] "
  
 -$err"
 +$err"]
        exit 1
  }