summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/about.tcl81
-rw-r--r--lib/blame.tcl54
-rw-r--r--lib/branch_checkout.tcl16
-rw-r--r--lib/branch_create.tcl38
-rw-r--r--lib/branch_delete.tcl22
-rw-r--r--lib/branch_rename.tcl22
-rw-r--r--lib/browser.tcl22
-rw-r--r--lib/checkout_op.tcl54
-rw-r--r--lib/choose_repository.tcl1044
-rw-r--r--lib/choose_rev.tcl34
-rw-r--r--lib/commit.tcl56
-rw-r--r--lib/console.tcl91
-rw-r--r--lib/database.tcl34
-rw-r--r--lib/date.tcl53
-rw-r--r--lib/diff.tcl29
-rw-r--r--lib/error.tcl8
-rw-r--r--lib/git-gui.icobin0 -> 318 bytes
-rw-r--r--lib/index.tcl81
-rw-r--r--lib/logo.tcl43
-rw-r--r--lib/merge.tcl60
-rw-r--r--lib/option.tcl131
-rw-r--r--lib/remote.tcl53
-rw-r--r--lib/remote_branch_delete.tcl46
-rw-r--r--lib/shortcut.tcl57
-rw-r--r--lib/status_bar.tcl38
-rw-r--r--lib/transport.tcl48
-rw-r--r--lib/win32.tcl26
-rw-r--r--lib/win32_shortcut.js34
28 files changed, 1748 insertions, 527 deletions
diff --git a/lib/about.tcl b/lib/about.tcl
new file mode 100644
index 0000000..719fc54
--- /dev/null
+++ b/lib/about.tcl
@@ -0,0 +1,81 @@
+# git-gui about git-gui dialog
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc do_about {} {
+ global appvers copyright oguilib
+ global tcl_patchLevel tk_patchLevel
+
+ set w .about_dialog
+ toplevel $w
+ wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
+
+ pack [git_logo $w.git_logo] -side left -fill y -padx 10 -pady 10
+ label $w.header -text [mc "About %s" [appname]] \
+ -font font_uibold
+ pack $w.header -side top -fill x
+
+ frame $w.buttons
+ button $w.buttons.close -text {Close} \
+ -default active \
+ -command [list destroy $w]
+ pack $w.buttons.close -side right
+ pack $w.buttons -side bottom -fill x -pady 10 -padx 10
+
+ label $w.desc \
+ -text "[mc "git-gui - a graphical user interface for Git."]\n$copyright" \
+ -padx 5 -pady 5 \
+ -justify left \
+ -anchor w \
+ -borderwidth 1 \
+ -relief solid
+ pack $w.desc -side top -fill x -padx 5 -pady 5
+
+ set v {}
+ append v "git-gui version $appvers\n"
+ append v "[git version]\n"
+ append v "\n"
+ if {$tcl_patchLevel eq $tk_patchLevel} {
+ append v "Tcl/Tk version $tcl_patchLevel"
+ } else {
+ append v "Tcl version $tcl_patchLevel"
+ append v ", Tk version $tk_patchLevel"
+ }
+
+ set d {}
+ append d "git wrapper: $::_git\n"
+ append d "git exec dir: [gitexec]\n"
+ append d "git-gui lib: $oguilib"
+
+ label $w.vers \
+ -text $v \
+ -padx 5 -pady 5 \
+ -justify left \
+ -anchor w \
+ -borderwidth 1 \
+ -relief solid
+ pack $w.vers -side top -fill x -padx 5 -pady 5
+
+ label $w.dirs \
+ -text $d \
+ -padx 5 -pady 5 \
+ -justify left \
+ -anchor w \
+ -borderwidth 1 \
+ -relief solid
+ pack $w.dirs -side top -fill x -padx 5 -pady 5
+
+ menu $w.ctxm -tearoff 0
+ $w.ctxm add command \
+ -label {Copy} \
+ -command "
+ clipboard clear
+ clipboard append -format STRING -type STRING -- \[$w.vers cget -text\]
+ "
+
+ bind $w <Visibility> "grab $w; focus $w.buttons.close"
+ bind $w <Key-Escape> "destroy $w"
+ bind $w <Key-Return> "destroy $w"
+ bind_button3 $w.vers "tk_popup $w.ctxm %X %Y; grab $w; focus $w"
+ wm title $w "About [appname]"
+ tkwait window $w
+}
diff --git a/lib/blame.tcl b/lib/blame.tcl
index 9607284..00ecf21 100644
--- a/lib/blame.tcl
+++ b/lib/blame.tcl
@@ -74,11 +74,11 @@ constructor new {i_commit i_path} {
set path $i_path
make_toplevel top w
- wm title $top "[appname] ([reponame]): File Viewer"
+ wm title $top [append "[appname] ([reponame]): " [mc "File Viewer"]]
frame $w.header -background gold
label $w.header.commit_l \
- -text {Commit:} \
+ -text [mc "Commit:"] \
-background gold \
-anchor w \
-justify left
@@ -101,7 +101,7 @@ constructor new {i_commit i_path} {
-anchor w \
-justify left
label $w.header.path_l \
- -text {File:} \
+ -text [mc "File:"] \
-background gold \
-anchor w \
-justify left
@@ -246,7 +246,7 @@ constructor new {i_commit i_path} {
menu $w.ctxm -tearoff 0
$w.ctxm add command \
- -label "Copy Commit" \
+ -label [mc "Copy Commit"] \
-command [cb _copycommit]
foreach i $w_columns {
@@ -366,7 +366,7 @@ method _load {jump} {
set amov_data [list [list]]
set asim_data [list [list]]
- $status show "Reading $commit:[escape_path $path]..."
+ $status show [mc "Reading %s..." "$commit:[escape_path $path]"]
$w_path conf -text [escape_path $path]
if {$commit eq {}} {
set fd [open $path r]
@@ -470,7 +470,7 @@ method _read_file {fd jump} {
_exec_blame $this $w_asim @asim_data \
[list] \
- { copy/move tracking}
+ [mc "Loading copy/move tracking annotations..."]
}
} ifdeleted { catch {close $fd} }
@@ -489,8 +489,8 @@ method _exec_blame {cur_w cur_d options cur_s} {
set blame_lines 0
$status start \
- "Loading$cur_s annotations..." \
- {lines annotated}
+ $cur_s \
+ [mc "lines annotated"]
}
method _read_blame {fd cur_w cur_d} {
@@ -671,10 +671,10 @@ method _read_blame {fd cur_w cur_d} {
if {$cur_w eq $w_asim} {
_exec_blame $this $w_amov @amov_data \
$original_options \
- { original location}
+ [mc "Loading original location annotations..."]
} else {
set current_fd {}
- $status stop {Annotation complete.}
+ $status stop [mc "Annotation complete."]
}
} else {
$status update $blame_lines $total_lines
@@ -728,7 +728,7 @@ method _showcommit {cur_w lno} {
if {$dat eq {}} {
set cmit {}
- $w_cviewer insert end "Loading annotation..." still_loading
+ $w_cviewer insert end [mc "Loading annotation..."] still_loading
} else {
set cmit [lindex $dat 0]
set file [lindex $dat 1]
@@ -743,20 +743,14 @@ method _showcommit {cur_w lno} {
set author_time {}
catch {set author_name $header($cmit,author)}
catch {set author_email $header($cmit,author-mail)}
- catch {set author_time [clock format \
- $header($cmit,author-time) \
- -format {%Y-%m-%d %H:%M:%S}
- ]}
+ catch {set author_time [format_date $header($cmit,author-time)]}
set committer_name {}
set committer_email {}
set committer_time {}
catch {set committer_name $header($cmit,committer)}
catch {set committer_email $header($cmit,committer-mail)}
- catch {set committer_time [clock format \
- $header($cmit,committer-time) \
- -format {%Y-%m-%d %H:%M:%S}
- ]}
+ catch {set committer_time [format_date $header($cmit,committer-time)]}
if {[catch {set msg $header($cmit,message)}]} {
set msg {}
@@ -790,16 +784,16 @@ method _showcommit {cur_w lno} {
}
$w_cviewer insert end "commit $cmit\n" header_key
- $w_cviewer insert end "Author:\t" header_key
+ $w_cviewer insert end [strcat [mc "Author:"] "\t"] header_key
$w_cviewer insert end "$author_name $author_email" header_val
$w_cviewer insert end " $author_time\n" header_val
- $w_cviewer insert end "Committer:\t" header_key
+ $w_cviewer insert end [strcat [mc "Committer:"] "\t"] header_key
$w_cviewer insert end "$committer_name $committer_email" header_val
$w_cviewer insert end " $committer_time\n" header_val
if {$file ne $path} {
- $w_cviewer insert end "Original File:\t" header_key
+ $w_cviewer insert end [strcat [mc "Original File:"] "\t"] header_key
$w_cviewer insert end "[escape_path $file]\n" header_val
}
@@ -892,10 +886,7 @@ method _open_tooltip {cur_w} {
set author_time {}
catch {set author_name $header($cmit,author)}
catch {set summary $header($cmit,summary)}
- catch {set author_time [clock format \
- $header($cmit,author-time) \
- -format {%Y-%m-%d %H:%M:%S}
- ]}
+ catch {set author_time [format_date $header($cmit,author-time)]}
$tooltip_t insert end "commit $cmit\n"
$tooltip_t insert end "$author_name $author_time\n"
@@ -914,23 +905,20 @@ method _open_tooltip {cur_w} {
set author_time {}
catch {set author_name $header($cmit,author)}
catch {set summary $header($cmit,summary)}
- catch {set author_time [clock format \
- $header($cmit,author-time) \
- -format {%Y-%m-%d %H:%M:%S}
- ]}
+ catch {set author_time [format_date $header($cmit,author-time)]}
- $tooltip_t insert end "Originally By:\n" section_header
+ $tooltip_t insert end [strcat [mc "Originally By:"] "\n"] section_header
$tooltip_t insert end "commit $cmit\n"
$tooltip_t insert end "$author_name $author_time\n"
$tooltip_t insert end "$summary\n"
if {$file ne $path} {
- $tooltip_t insert end "In File: " section_header
+ $tooltip_t insert end [strcat [mc "In File:"] " "] section_header
$tooltip_t insert end "$file\n"
}
$tooltip_t insert end "\n"
- $tooltip_t insert end "Copied Or Moved Here By:\n" section_header
+ $tooltip_t insert end [strcat [mc "Copied Or Moved Here By:"] "\n"] section_header
$tooltip_t insert end $save
}
diff --git a/lib/branch_checkout.tcl b/lib/branch_checkout.tcl
index 72c45b4..6603703 100644
--- a/lib/branch_checkout.tcl
+++ b/lib/branch_checkout.tcl
@@ -11,37 +11,37 @@ field opt_detach 0; # force a detached head case?
constructor dialog {} {
make_toplevel top w
- wm title $top "[appname] ([reponame]): Checkout Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Checkout Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
- label $w.header -text {Checkout Branch} -font font_uibold
+ label $w.header -text [mc "Checkout Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.create -text Checkout \
+ button $w.buttons.create -text [mc Checkout] \
-default active \
-command [cb _checkout]
pack $w.buttons.create -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.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
- set w_rev [::choose_rev::new $w.rev {Revision}]
+ set w_rev [::choose_rev::new $w.rev [mc Revision]]
$w_rev bind_listbox <Double-Button-1> [cb _checkout]
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
- labelframe $w.options -text {Options}
+ labelframe $w.options -text [mc Options]
checkbutton $w.options.fetch \
- -text {Fetch Tracking Branch} \
+ -text [mc "Fetch Tracking Branch"] \
-variable @opt_fetch
pack $w.options.fetch -anchor nw
checkbutton $w.options.detach \
- -text {Detach From Local Branch} \
+ -text [mc "Detach From Local Branch"] \
-variable @opt_detach
pack $w.options.detach -anchor nw
diff --git a/lib/branch_create.tcl b/lib/branch_create.tcl
index def615d..53dfb4c 100644
--- a/lib/branch_create.tcl
+++ b/lib/branch_create.tcl
@@ -19,28 +19,28 @@ constructor dialog {} {
global repo_config
make_toplevel top w
- wm title $top "[appname] ([reponame]): Create Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Create Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
- label $w.header -text {Create New Branch} -font font_uibold
+ label $w.header -text [mc "Create New Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.create -text Create \
+ button $w.buttons.create -text [mc Create] \
-default active \
-command [cb _create]
pack $w.buttons.create -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.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
- labelframe $w.desc -text {Branch Name}
+ labelframe $w.desc -text [mc "Branch Name"]
radiobutton $w.desc.name_r \
-anchor w \
- -text {Name:} \
+ -text [mc "Name:"] \
-value user \
-variable @name_type
set w_name $w.desc.name_t
@@ -55,7 +55,7 @@ constructor dialog {} {
radiobutton $w.desc.match_r \
-anchor w \
- -text {Match Tracking Branch Name} \
+ -text [mc "Match Tracking Branch Name"] \
-value match \
-variable @name_type
grid $w.desc.match_r -sticky we -padx {0 5} -columnspan 2
@@ -63,38 +63,38 @@ constructor dialog {} {
grid columnconfigure $w.desc 1 -weight 1
pack $w.desc -anchor nw -fill x -pady 5 -padx 5
- set w_rev [::choose_rev::new $w.rev {Starting Revision}]
+ set w_rev [::choose_rev::new $w.rev [mc "Starting Revision"]]
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
- labelframe $w.options -text {Options}
+ labelframe $w.options -text [mc Options]
frame $w.options.merge
- label $w.options.merge.l -text {Update Existing Branch:}
+ label $w.options.merge.l -text [mc "Update Existing Branch:"]
pack $w.options.merge.l -side left
radiobutton $w.options.merge.no \
- -text No \
+ -text [mc No] \
-value none \
-variable @opt_merge
pack $w.options.merge.no -side left
radiobutton $w.options.merge.ff \
- -text {Fast Forward Only} \
+ -text [mc "Fast Forward Only"] \
-value ff \
-variable @opt_merge
pack $w.options.merge.ff -side left
radiobutton $w.options.merge.reset \
- -text {Reset} \
+ -text [mc Reset] \
-value reset \
-variable @opt_merge
pack $w.options.merge.reset -side left
pack $w.options.merge -anchor nw
checkbutton $w.options.fetch \
- -text {Fetch Tracking Branch} \
+ -text [mc "Fetch Tracking Branch"] \
-variable @opt_fetch
pack $w.options.fetch -anchor nw
checkbutton $w.options.checkout \
- -text {Checkout After Creation} \
+ -text [mc "Checkout After Creation"] \
-variable @opt_checkout
pack $w.options.checkout -anchor nw
pack $w.options -anchor nw -fill x -pady 5 -padx 5
@@ -128,7 +128,7 @@ method _create {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please select a tracking branch."
+ -message [mc "Please select a tracking branch."]
return
}
if {![regsub ^refs/heads/ [lindex $spec 2] {} newbranch]} {
@@ -137,7 +137,7 @@ method _create {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Tracking branch [$w get] is not a branch in the remote repository."
+ -message [mc "Tracking branch %s is not a branch in the remote repository." [$w get]]
return
}
}
@@ -150,7 +150,7 @@ method _create {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please supply a branch name."
+ -message [mc "Please supply a branch name."]
focus $w_name
return
}
@@ -161,7 +161,7 @@ method _create {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "'$newbranch' is not an acceptable branch name."
+ -message [mc "'%s' is not an acceptable branch name." $newbranch]
focus $w_name
return
}
diff --git a/lib/branch_delete.tcl b/lib/branch_delete.tcl
index c7573c6..86c4f73 100644
--- a/lib/branch_delete.tcl
+++ b/lib/branch_delete.tcl
@@ -12,29 +12,29 @@ constructor dialog {} {
global current_branch
make_toplevel top w
- wm title $top "[appname] ([reponame]): Delete Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Delete Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
- label $w.header -text {Delete Local Branch} -font font_uibold
+ label $w.header -text [mc "Delete Local Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
set w_delete $w.buttons.delete
button $w_delete \
- -text Delete \
+ -text [mc Delete] \
-default active \
-state disabled \
-command [cb _delete]
pack $w_delete -side right
button $w.buttons.cancel \
- -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
- labelframe $w.list -text {Local Branches}
+ labelframe $w.list -text [mc "Local Branches"]
set w_heads $w.list.l
listbox $w_heads \
-height 10 \
@@ -49,9 +49,9 @@ constructor dialog {} {
set w_check [choose_rev::new \
$w.check \
- {Delete Only If Merged Into} \
+ [mc "Delete Only If Merged Into"] \
]
- $w_check none {Always (Do not perform merge test.)}
+ $w_check none [mc "Always (Do not perform merge test.)"]
pack $w.check -anchor nw -fill x -pady 5 -padx 5
foreach h [load_all_heads] {
@@ -100,7 +100,7 @@ method _delete {} {
lappend to_delete [list $b $o]
}
if {$not_merged ne {}} {
- set msg "The following branches are not completely merged into [$w_check get]:
+ set msg "[mc "The following branches are not completely merged into %s:" [$w_check get]]
- [join $not_merged "\n - "]"
tk_messageBox \
@@ -112,9 +112,7 @@ method _delete {} {
}
if {$to_delete eq {}} return
if {$check_cmt eq {}} {
- set msg {Recovering deleted branches is difficult.
-
-Delete the selected branches?}
+ set msg [mc "Recovering deleted branches is difficult. \n\n Delete the selected branches?"]
if {[tk_messageBox \
-icon warning \
-type yesno \
@@ -140,7 +138,7 @@ Delete the selected branches?}
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Failed to delete branches:\n$failed"
+ -message [mc "Failed to delete branches:\n%s" $failed]
}
destroy $w
diff --git a/lib/branch_rename.tcl b/lib/branch_rename.tcl
index 1cadc31..1665388 100644
--- a/lib/branch_rename.tcl
+++ b/lib/branch_rename.tcl
@@ -11,7 +11,7 @@ constructor dialog {} {
global current_branch
make_toplevel top w
- wm title $top "[appname] ([reponame]): Rename Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Rename Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
@@ -19,24 +19,24 @@ constructor dialog {} {
set oldname $current_branch
set newname [get_config gui.newbranchtemplate]
- label $w.header -text {Rename Branch} -font font_uibold
+ label $w.header -text [mc "Rename Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.rename -text Rename \
+ button $w.buttons.rename -text [mc Rename] \
-default active \
-command [cb _rename]
pack $w.buttons.rename -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.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
frame $w.rename
- label $w.rename.oldname_l -text {Branch:}
+ label $w.rename.oldname_l -text [mc "Branch:"]
eval tk_optionMenu $w.rename.oldname_m @oldname [load_all_heads]
- label $w.rename.newname_l -text {New Name:}
+ label $w.rename.newname_l -text [mc "New Name:"]
entry $w.rename.newname_t \
-borderwidth 1 \
-relief sunken \
@@ -72,7 +72,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please select a branch to rename."
+ -message [mc "Please select a branch to rename."]
focus $w.rename.oldname_m
return
}
@@ -83,7 +83,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please supply a branch name."
+ -message [mc "Please supply a branch name."]
focus $w.rename.newname_t
return
}
@@ -93,7 +93,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Branch '$newname' already exists."
+ -message [mc "Branch '%s' already exists." $newname]
focus $w.rename.newname_t
return
}
@@ -103,7 +103,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "We do not like '$newname' as a branch name."
+ -message [mc "'%s' is not an acceptable branch name." $newname]
focus $w.rename.newname_t
return
}
@@ -114,7 +114,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Failed to rename '$oldname'.\n\n$err"
+ -message [strcat [mc "Failed to rename '%s'." $oldname] "\n\n$err"]
return
}
diff --git a/lib/browser.tcl b/lib/browser.tcl
index 3134900..53d5a62 100644
--- a/lib/browser.tcl
+++ b/lib/browser.tcl
@@ -14,7 +14,7 @@ field w
field browser_commit
field browser_path
field browser_files {}
-field browser_status {Starting...}
+field browser_status [mc "Starting..."]
field browser_stack {}
field browser_busy 1
@@ -23,7 +23,7 @@ field ls_buf {}; # Buffered record output from ls-tree
constructor new {commit {path {}}} {
global cursor_ptr M1B
make_toplevel top w
- wm title $top "[appname] ([reponame]): File Browser"
+ wm title $top [append "[appname] ([reponame]): " [mc "File Browser"]]
set browser_commit $commit
set browser_path $browser_commit:$path
@@ -122,7 +122,7 @@ method _parent {} {
} else {
regsub {/[^/]+$} $browser_path {} browser_path
}
- set browser_status "Loading $browser_path..."
+ set browser_status [mc "Loading %s..." $browser_path]
_ls $this [lindex $parent 0] [lindex $parent 1]
}
}
@@ -139,7 +139,7 @@ method _enter {} {
tree {
set name [lindex $info 2]
set escn [escape_path $name]
- set browser_status "Loading $escn..."
+ set browser_status [mc "Loading %s..." $escn]
append browser_path $escn
_ls $this [lindex $info 1] $name
}
@@ -183,7 +183,7 @@ method _ls {tree_id {name {}}} {
-align center -padx 5 -pady 1 \
-name icon0 \
-image ::browser::img_parent
- $w insert end {[Up To Parent]}
+ $w insert end [mc "\[Up To Parent\]"]
lappend browser_files parent
}
lappend browser_stack [list $tree_id $name]
@@ -242,7 +242,7 @@ method _read {fd} {
if {[eof $fd]} {
close $fd
- set browser_status Ready.
+ set browser_status [mc "Ready."]
set browser_busy 0
set ls_buf {}
if {$n > 0} {
@@ -263,27 +263,27 @@ field w_rev ; # mega-widget to pick the initial revision
constructor dialog {} {
make_toplevel top w
- wm title $top "[appname] ([reponame]): Browse Branch Files"
+ wm title $top [append "[appname] ([reponame]): " [mc "Browse Branch Files"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
label $w.header \
- -text {Browse Branch Files} \
+ -text [mc "Browse Branch Files"] \
-font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.browse -text Browse \
+ button $w.buttons.browse -text [mc Browse] \
-default active \
-command [cb _open]
pack $w.buttons.browse -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.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
- set w_rev [::choose_rev::new $w.rev {Revision}]
+ set w_rev [::choose_rev::new $w.rev [mc Revision]]
$w_rev bind_listbox <Double-Button-1> [cb _open]
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
diff --git a/lib/checkout_op.tcl b/lib/checkout_op.tcl
index 76f04f2..f243966 100644
--- a/lib/checkout_op.tcl
+++ b/lib/checkout_op.tcl
@@ -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]
@@ -124,7 +124,7 @@ method _finish_fetch {ok} {
}
if {[catch {set new_hash [git rev-parse --verify "$l_trck^0"]} err]} {
set ok 0
- $w_cons insert "fatal: Cannot resolve $l_trck"
+ $w_cons insert [mc "fatal: Cannot resolve %s" $l_trck]
$w_cons insert $err
}
}
@@ -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 @@ 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
}
@@ -176,7 +176,7 @@ method _update_ref {} {
# 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.
@@ -203,7 +203,7 @@ method _update_ref {} {
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
}
}
@@ -217,7 +217,7 @@ method _update_ref {} {
}
}
default {
- _error $this "Merge strategy '$merge_type' not supported."
+ _error $this [mc "Merge strategy '%s' not supported." $merge_type]
return 0
}
}
@@ -236,7 +236,7 @@ method _update_ref {} {
if {[catch {
git update-ref -m $reflog_msg $ref $new $cur
} err]} {
- _error $this "Failed to update '$newbranch'.\n\n$err"
+ _error $this [strcat [mc "Failed to update '%s'." $newbranch] "\n\n$err"]
return 0
}
}
@@ -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 @@ 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
@@ -319,7 +319,7 @@ method _readtree {} {
set readtree_d {}
$::main_status start \
- "Updating working directory to '[_name $this]'..." \
+ [mc "Updating working directory to '%s'..." [_name $this]] \
{files checked out}
set fd [git_read --stderr read-tree \
@@ -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 [strcat [mc "File level merge required."] "
$err
-Staying on branch '$current_branch'."
+" [mc "Staying on branch '%s'." $current_branch]]
unlock_index
delete_this
return
@@ -426,9 +426,9 @@ method _after_readtree {} {
}
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
@@ -443,7 +443,7 @@ If you wanted to be on a branch, create one now starting from 'This Detached Che
$ui_comm delete 0.0 end
$ui_comm edit reset
$ui_comm edit modified false
- rescan [list ui_status "Checked out '$name'."]
+ rescan [list ui_status [mc "Checked out '%s'." $name]]
} else {
repository_state commit_type HEAD MERGE_HEAD
set PARENT $HEAD
@@ -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
@@ -497,21 +497,21 @@ method _confirm_reset {cur} {
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
@@ -519,7 +519,7 @@ method _confirm_reset {cur} {
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 @@ method _toplevel {title} {
}
method _fatal {err} {
- error_popup "Failed to set current branch.
+ error_popup [strcat [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
}
diff --git a/lib/choose_repository.tcl b/lib/choose_repository.tcl
new file mode 100644
index 0000000..2bac50e
--- /dev/null
+++ b/lib/choose_repository.tcl
@@ -0,0 +1,1044 @@
+# git-gui Git repository chooser
+# Copyright (C) 2007 Shawn Pearce
+
+class choose_repository {
+
+field top
+field w
+field w_body ; # Widget holding the center content
+field w_next ; # Next button
+field w_quit ; # Quit button
+field o_cons ; # Console object (if active)
+field w_types ; # List of type buttons in clone
+field w_recentlist ; # Listbox containing recent repositories
+
+field done 0 ; # Finished picking the repository?
+field local_path {} ; # Where this repository is locally
+field origin_url {} ; # Where we are cloning from
+field origin_name origin ; # What we shall call 'origin'
+field clone_type hardlink ; # Type of clone to construct
+field readtree_err ; # Error output from read-tree (if any)
+field sorted_recent ; # recent repositories (sorted)
+
+constructor pick {} {
+ global M1T M1B
+
+ make_toplevel top w
+ wm title $top [mc "Git Gui"]
+
+ if {$top eq {.}} {
+ menu $w.mbar -tearoff 0
+ $top configure -menu $w.mbar
+
+ set m_repo $w.mbar.repository
+ $w.mbar add cascade \
+ -label [mc Repository] \
+ -menu $m_repo
+ menu $m_repo
+
+ if {[is_MacOSX]} {
+ $w.mbar add cascade -label [mc Apple] -menu .mbar.apple
+ menu $w.mbar.apple
+ $w.mbar.apple add command \
+ -label [mc "About %s" [appname]] \
+ -command do_about
+ } else {
+ $w.mbar add cascade -label [mc Help] -menu $w.mbar.help
+ menu $w.mbar.help
+ $w.mbar.help add command \
+ -label [mc "About %s" [appname]] \
+ -command do_about
+ }
+
+ wm protocol $top WM_DELETE_WINDOW exit
+ bind $top <$M1B-q> exit
+ bind $top <$M1B-Q> exit
+ bind $top <Key-Escape> exit
+ } else {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ bind $top <Key-Escape> [list destroy $top]
+ set m_repo {}
+ }
+
+ pack [git_logo $w.git_logo] -side left -fill y -padx 10 -pady 10
+
+ set w_body $w.body
+ set opts $w_body.options
+ frame $w_body
+ text $opts \
+ -cursor $::cursor_ptr \
+ -relief flat \
+ -background [$w_body cget -background] \
+ -wrap none \
+ -spacing1 5 \
+ -width 50 \
+ -height 3
+ pack $opts -anchor w -fill x
+
+ $opts tag conf link_new -foreground blue -underline 1
+ $opts tag bind link_new <1> [cb _next new]
+ $opts insert end [mc "Create New Repository"] link_new
+ $opts insert end "\n"
+ if {$m_repo ne {}} {
+ $m_repo add command \
+ -command [cb _next new] \
+ -accelerator $M1T-N \
+ -label [mc "New..."]
+ bind $top <$M1B-n> [cb _next new]
+ bind $top <$M1B-N> [cb _next new]
+ }
+
+ $opts tag conf link_clone -foreground blue -underline 1
+ $opts tag bind link_clone <1> [cb _next clone]
+ $opts insert end [mc "Clone Existing Repository"] link_clone
+ $opts insert end "\n"
+ if {$m_repo ne {}} {
+ $m_repo add command \
+ -command [cb _next clone] \
+ -accelerator $M1T-C \
+ -label [mc "Clone..."]
+ bind $top <$M1B-c> [cb _next clone]
+ bind $top <$M1B-C> [cb _next clone]
+ }
+
+ $opts tag conf link_open -foreground blue -underline 1
+ $opts tag bind link_open <1> [cb _next open]
+ $opts insert end [mc "Open Existing Repository"] link_open
+ $opts insert end "\n"
+ if {$m_repo ne {}} {
+ $m_repo add command \
+ -command [cb _next open] \
+ -accelerator $M1T-O \
+ -label [mc "Open..."]
+ bind $top <$M1B-o> [cb _next open]
+ bind $top <$M1B-O> [cb _next open]
+ }
+
+ $opts conf -state disabled
+
+ set sorted_recent [_get_recentrepos]
+ if {[llength $sorted_recent] > 0} {
+ if {$m_repo ne {}} {
+ $m_repo add separator
+ $m_repo add command \
+ -state disabled \
+ -label [mc "Recent Repositories"]
+ }
+
+ label $w_body.space
+ label $w_body.recentlabel \
+ -anchor w \
+ -text [mc "Open Recent Repository:"]
+ set w_recentlist $w_body.recentlist
+ text $w_recentlist \
+ -cursor $::cursor_ptr \
+ -relief flat \
+ -background [$w_body.recentlabel cget -background] \
+ -wrap none \
+ -width 50 \
+ -height 10
+ $w_recentlist tag conf link \
+ -foreground blue \
+ -underline 1
+ set home $::env(HOME)
+ if {[is_Cygwin]} {
+ set home [exec cygpath --windows --absolute $home]
+ }
+ set home "[file normalize $home]/"
+ set hlen [string length $home]
+ foreach p $sorted_recent {
+ set path $p
+ if {[string equal -length $hlen $home $p]} {
+ set p "~/[string range $p $hlen end]"
+ }
+ regsub -all "\n" $p "\\n" p
+ $w_recentlist insert end $p link
+ $w_recentlist insert end "\n"
+
+ if {$m_repo ne {}} {
+ $m_repo add command \
+ -command [cb _open_recent_path $path] \
+ -label " $p"
+ }
+ }
+ $w_recentlist conf -state disabled
+ $w_recentlist tag bind link <1> [cb _open_recent %x,%y]
+ pack $w_body.space -anchor w -fill x
+ pack $w_body.recentlabel -anchor w -fill x
+ pack $w_recentlist -anchor w -fill x
+ }
+ pack $w_body -fill x -padx 10 -pady 10
+
+ frame $w.buttons
+ set w_next $w.buttons.next
+ set w_quit $w.buttons.quit
+ button $w_quit \
+ -text [mc "Quit"] \
+ -command exit
+ pack $w_quit -side right -padx 5
+ pack $w.buttons -side bottom -fill x -padx 10 -pady 10
+
+ if {$m_repo ne {}} {
+ $m_repo add separator
+ $m_repo add command \
+ -label [mc Quit] \
+ -command exit \
+ -accelerator $M1T-Q
+ }
+
+ bind $top <Return> [cb _invoke_next]
+ bind $top <Visibility> "
+ [cb _center]
+ grab $top
+ focus $top
+ bind $top <Visibility> {}
+ "
+ wm deiconify $top
+ tkwait variable @done
+
+ if {$top eq {.}} {
+ eval destroy [winfo children $top]
+ }
+}
+
+proc _home {} {
+ if {[catch {set h $::env(HOME)}]
+ || ![file isdirectory $h]} {
+ set h .
+ }
+ return $h
+}
+
+method _center {} {
+ set nx [winfo reqwidth $top]
+ set ny [winfo reqheight $top]
+ set rx [expr {([winfo screenwidth $top] - $nx) / 3}]
+ set ry [expr {([winfo screenheight $top] - $ny) / 3}]
+ wm geometry $top [format {+%d+%d} $rx $ry]
+}
+
+method _invoke_next {} {
+ if {[winfo exists $w_next]} {
+ uplevel #0 [$w_next cget -command]
+ }
+}
+
+proc _get_recentrepos {} {
+ set recent [list]
+ foreach p [get_config gui.recentrepo] {
+ if {[_is_git [file join $p .git]]} {
+ lappend recent $p
+ }
+ }
+ return [lsort $recent]
+}
+
+proc _unset_recentrepo {p} {
+ regsub -all -- {([()\[\]{}\.^$+*?\\])} $p {\\\1} p
+ git config --global --unset gui.recentrepo "^$p\$"
+}
+
+proc _append_recentrepos {path} {
+ set path [file normalize $path]
+ set recent [get_config gui.recentrepo]
+
+ if {[lindex $recent end] eq $path} {
+ return
+ }
+
+ set i [lsearch $recent $path]
+ if {$i >= 0} {
+ _unset_recentrepo $path
+ set recent [lreplace $recent $i $i]
+ }
+
+ lappend recent $path
+ git config --global --add gui.recentrepo $path
+
+ while {[llength $recent] > 10} {
+ _unset_recentrepo [lindex $recent 0]
+ set recent [lrange $recent 1 end]
+ }
+}
+
+method _open_recent {xy} {
+ set id [lindex [split [$w_recentlist index @$xy] .] 0]
+ set local_path [lindex $sorted_recent [expr {$id - 1}]]
+ _do_open2 $this
+}
+
+method _open_recent_path {p} {
+ set local_path $p
+ _do_open2 $this
+}
+
+method _next {action} {
+ destroy $w_body
+ if {![winfo exists $w_next]} {
+ button $w_next -default active
+ pack $w_next -side right -padx 5 -before $w_quit
+ }
+ _do_$action $this
+}
+
+method _write_local_path {args} {
+ if {$local_path eq {}} {
+ $w_next conf -state disabled
+ } else {
+ $w_next conf -state normal
+ }
+}
+
+method _git_init {} {
+ if {[file exists $local_path]} {
+ error_popup [mc "Location %s already exists." $local_path]
+ return 0
+ }
+
+ if {[catch {file mkdir $local_path} err]} {
+ error_popup [strcat \
+ [mc "Failed to create repository %s:" $local_path] \
+ "\n\n$err"]
+ return 0
+ }
+
+ if {[catch {cd $local_path} err]} {
+ error_popup [strcat \
+ [mc "Failed to create repository %s:" $local_path] \
+ "\n\n$err"]
+ return 0
+ }
+
+ if {[catch {git init} err]} {
+ error_popup [strcat \
+ [mc "Failed to create repository %s:" $local_path] \
+ "\n\n$err"]
+ return 0
+ }
+
+ _append_recentrepos [pwd]
+ set ::_gitdir .git
+ set ::_prefix {}
+ return 1
+}
+
+proc _is_git {path} {
+ if {[file exists [file join $path HEAD]]
+ && [file exists [file join $path objects]]
+ && [file exists [file join $path config]]} {
+ return 1
+ }
+ if {[is_Cygwin]} {
+ if {[file exists [file join $path HEAD]]
+ && [file exists [file join $path objects.lnk]]
+ && [file exists [file join $path config.lnk]]} {
+ return 1
+ }
+ }
+ return 0
+}
+
+proc _objdir {path} {
+ set objdir [file join $path .git objects]
+ if {[file isdirectory $objdir]} {
+ return $objdir
+ }
+
+ set objdir [file join $path objects]
+ if {[file isdirectory $objdir]} {
+ return $objdir
+ }
+
+ if {[is_Cygwin]} {
+ set objdir [file join $path .git objects.lnk]
+ if {[file isfile $objdir]} {
+ return [win32_read_lnk $objdir]
+ }
+
+ set objdir [file join $path objects.lnk]
+ if {[file isfile $objdir]} {
+ return [win32_read_lnk $objdir]
+ }
+ }
+
+ return {}
+}
+
+######################################################################
+##
+## Create New Repository
+
+method _do_new {} {
+ $w_next conf \
+ -state disabled \
+ -command [cb _do_new2] \
+ -text [mc "Create"]
+
+ frame $w_body
+ label $w_body.h \
+ -font font_uibold \
+ -text [mc "Create New Repository"]
+ pack $w_body.h -side top -fill x -pady 10
+ pack $w_body -fill x -padx 10
+
+ frame $w_body.where
+ label $w_body.where.l -text [mc "Directory:"]
+ entry $w_body.where.t \
+ -textvariable @local_path \
+ -font font_diff \
+ -width 50
+ button $w_body.where.b \
+ -text [mc "Browse"] \
+ -command [cb _new_local_path]
+
+ pack $w_body.where.b -side right
+ pack $w_body.where.l -side left
+ pack $w_body.where.t -fill x
+ pack $w_body.where -fill x
+
+ trace add variable @local_path write [cb _write_local_path]
+ bind $w_body.h <Destroy> [list trace remove variable @local_path write [cb _write_local_path]]
+ update
+ focus $w_body.where.t
+}
+
+method _new_local_path {} {
+ if {$local_path ne {}} {
+ set p [file dirname $local_path]
+ } else {
+ set p [_home]
+ }
+
+ set p [tk_chooseDirectory \
+ -initialdir $p \
+ -parent $top \
+ -title [mc "Git Repository"] \
+ -mustexist false]
+ if {$p eq {}} return
+
+ set p [file normalize $p]
+ if {[file isdirectory $p]} {
+ foreach i [glob \
+ -directory $p \
+ -tails \
+ -nocomplain \
+ * .*] {
+ switch -- $i {
+ . continue
+ .. continue
+ default {
+ error_popup [mc "Directory %s already exists." $p]
+ return
+ }
+ }
+ }
+ if {[catch {file delete $p} err]} {
+ error_popup [strcat \
+ [mc "Directory %s already exists." $p] \
+ "\n\n$err"]
+ return
+ }
+ } elseif {[file exists $p]} {
+ error_popup [mc "File %s already exists." $p]
+ return
+ }
+ set local_path $p
+}
+
+method _do_new2 {} {
+ if {![_git_init $this]} {
+ return
+ }
+ set done 1
+}
+
+######################################################################
+##
+## Clone Existing Repository
+
+method _do_clone {} {
+ $w_next conf \
+ -state disabled \
+ -command [cb _do_clone2] \
+ -text [mc "Clone"]
+
+ frame $w_body
+ label $w_body.h \
+ -font font_uibold \
+ -text [mc "Clone Existing Repository"]
+ pack $w_body.h -side top -fill x -pady 10
+ pack $w_body -fill x -padx 10
+
+ set args $w_body.args
+ frame $w_body.args
+ pack $args -fill both
+
+ label $args.origin_l -text [mc "URL:"]
+ entry $args.origin_t \
+ -textvariable @origin_url \
+ -font font_diff \
+ -width 50
+ button $args.origin_b \
+ -text [mc "Browse"] \
+ -command [cb _open_origin]
+ grid $args.origin_l $args.origin_t $args.origin_b -sticky ew
+
+ label $args.where_l -text [mc "Directory:"]
+ entry $args.where_t \
+ -textvariable @local_path \
+ -font font_diff \
+ -width 50
+ button $args.where_b \
+ -text [mc "Browse"] \
+ -command [cb _new_local_path]
+ grid $args.where_l $args.where_t $args.where_b -sticky ew
+
+ label $args.type_l -text [mc "Clone Type:"]
+ frame $args.type_f
+ set w_types [list]
+ lappend w_types [radiobutton $args.type_f.hardlink \
+ -state disabled \
+ -anchor w \
+ -text [mc "Standard (Fast, Semi-Redundant, Hardlinks)"] \
+ -variable @clone_type \
+ -value hardlink]
+ lappend w_types [radiobutton $args.type_f.full \
+ -state disabled \
+ -anchor w \
+ -text [mc "Full Copy (Slower, Redundant Backup)"] \
+ -variable @clone_type \
+ -value full]
+ lappend w_types [radiobutton $args.type_f.shared \
+ -state disabled \
+ -anchor w \
+ -text [mc "Shared (Fastest, Not Recommended, No Backup)"] \
+ -variable @clone_type \
+ -value shared]
+ foreach r $w_types {
+ pack $r -anchor w
+ }
+ grid $args.type_l $args.type_f -sticky new
+
+ grid columnconfigure $args 1 -weight 1
+
+ trace add variable @local_path write [cb _update_clone]
+ trace add variable @origin_url write [cb _update_clone]
+ bind $w_body.h <Destroy> "
+ [list trace remove variable @local_path write [cb _update_clone]]
+ [list trace remove variable @origin_url write [cb _update_clone]]
+ "
+ update
+ focus $args.origin_t
+}
+
+method _open_origin {} {
+ if {$origin_url ne {} && [file isdirectory $origin_url]} {
+ set p $origin_url
+ } else {
+ set p [_home]
+ }
+
+ set p [tk_chooseDirectory \
+ -initialdir $p \
+ -parent $top \
+ -title [mc "Git Repository"] \
+ -mustexist true]
+ if {$p eq {}} return
+
+ set p [file normalize $p]
+ if {![_is_git [file join $p .git]] && ![_is_git $p]} {
+ error_popup [mc "Not a Git repository: %s" [file tail $p]]
+ return
+ }
+ set origin_url $p
+}
+
+method _update_clone {args} {
+ if {$local_path ne {} && $origin_url ne {}} {
+ $w_next conf -state normal
+ } else {
+ $w_next conf -state disabled
+ }
+
+ if {$origin_url ne {} &&
+ ( [_is_git [file join $origin_url .git]]
+ || [_is_git $origin_url])} {
+ set e normal
+ if {[[lindex $w_types 0] cget -state] eq {disabled}} {
+ set clone_type hardlink
+ }
+ } else {
+ set e disabled
+ set clone_type full
+ }
+
+ foreach r $w_types {
+ $r conf -state $e
+ }
+}
+
+method _do_clone2 {} {
+ if {[file isdirectory $origin_url]} {
+ set origin_url [file normalize $origin_url]
+ }
+
+ if {$clone_type eq {hardlink} && ![file isdirectory $origin_url]} {
+ error_popup [mc "Standard only available for local repository."]
+ return
+ }
+ if {$clone_type eq {shared} && ![file isdirectory $origin_url]} {
+ error_popup [mc "Shared only available for local repository."]
+ return
+ }
+
+ if {$clone_type eq {hardlink} || $clone_type eq {shared}} {
+ set objdir [_objdir $origin_url]
+ if {$objdir eq {}} {
+ error_popup [mc "Not a Git repository: %s" [file tail $origin_url]]
+ return
+ }
+ }
+
+ set giturl $origin_url
+ if {[is_Cygwin] && [file isdirectory $giturl]} {
+ set giturl [exec cygpath --unix --absolute $giturl]
+ if {$clone_type eq {shared}} {
+ set objdir [exec cygpath --unix --absolute $objdir]
+ }
+ }
+
+ if {![_git_init $this]} return
+ set local_path [pwd]
+
+ if {[catch {
+ git config remote.$origin_name.url $giturl
+ git config remote.$origin_name.fetch +refs/heads/*:refs/remotes/$origin_name/*
+ } err]} {
+ error_popup [strcat [mc "Failed to configure origin"] "\n\n$err"]
+ return
+ }
+
+ destroy $w_body $w_next
+
+ switch -exact -- $clone_type {
+ hardlink {
+ set o_cons [status_bar::two_line $w_body]
+ pack $w_body -fill x -padx 10 -pady 10
+
+ $o_cons start \
+ [mc "Counting objects"] \
+ [mc "buckets"]
+ update
+
+ if {[file exists [file join $objdir info alternates]]} {
+ set pwd [pwd]
+ if {[catch {
+ file mkdir [gitdir objects info]
+ set f_in [open [file join $objdir info alternates] r]
+ set f_cp [open [gitdir objects info alternates] w]
+ fconfigure $f_in -translation binary -encoding binary
+ fconfigure $f_cp -translation binary -encoding binary
+ cd $objdir
+ while {[gets $f_in line] >= 0} {
+ if {[is_Cygwin]} {
+ puts $f_cp [exec cygpath --unix --absolute $line]
+ } else {
+ puts $f_cp [file normalize $line]
+ }
+ }
+ close $f_in
+ close $f_cp
+ cd $pwd
+ } err]} {
+ catch {cd $pwd}
+ _clone_failed $this [mc "Unable to copy objects/info/alternates: %s" $err]
+ return
+ }
+ }
+
+ set tolink [list]
+ set buckets [glob \
+ -tails \
+ -nocomplain \
+ -directory [file join $objdir] ??]
+ set bcnt [expr {[llength $buckets] + 2}]
+ set bcur 1
+ $o_cons update $bcur $bcnt
+ update
+
+ file mkdir [file join .git objects pack]
+ foreach i [glob -tails -nocomplain \
+ -directory [file join $objdir pack] *] {
+ lappend tolink [file join pack $i]
+ }
+ $o_cons update [incr bcur] $bcnt
+ update
+
+ foreach i $buckets {
+ file mkdir [file join .git objects $i]
+ foreach j [glob -tails -nocomplain \
+ -directory [file join $objdir $i] *] {
+ lappend tolink [file join $i $j]
+ }
+ $o_cons update [incr bcur] $bcnt
+ update
+ }
+ $o_cons stop
+
+ if {$tolink eq {}} {
+ info_popup [strcat \
+ [mc "Nothing to clone from %s." $origin_url] \
+ "\n" \
+ [mc "The 'master' branch has not been initialized."] \
+ ]
+ destroy $w_body
+ set done 1
+ return
+ }
+
+ set i [lindex $tolink 0]
+ if {[catch {
+ file link -hard \
+ [file join .git objects $i] \
+ [file join $objdir $i]
+ } err]} {
+ info_popup [mc "Hardlinks are unavailable. Falling back to copying."]
+ set i [_copy_files $this $objdir $tolink]
+ } else {
+ set i [_link_files $this $objdir [lrange $tolink 1 end]]
+ }
+ if {!$i} return
+
+ destroy $w_body
+ }
+ full {
+ set o_cons [console::embed \
+ $w_body \
+ [mc "Cloning from %s" $origin_url]]
+ pack $w_body -fill both -expand 1 -padx 10
+ $o_cons exec \
+ [list git fetch --no-tags -k $origin_name] \
+ [cb _do_clone_tags]
+ }
+ shared {
+ set fd [open [gitdir objects info alternates] w]
+ fconfigure $fd -translation binary
+ puts $fd $objdir
+ close $fd
+ }
+ }
+
+ if {$clone_type eq {hardlink} || $clone_type eq {shared}} {
+ if {![_clone_refs $this]} return
+ set pwd [pwd]
+ if {[catch {
+ cd $origin_url
+ set HEAD [git rev-parse --verify HEAD^0]
+ } err]} {
+ _clone_failed $this [mc "Not a Git repository: %s" [file tail $origin_url]]
+ return 0
+ }
+ cd $pwd
+ _do_clone_checkout $this $HEAD
+ }
+}
+
+method _copy_files {objdir tocopy} {
+ $o_cons start \
+ [mc "Copying objects"] \
+ [mc "KiB"]
+ set tot 0
+ set cmp 0
+ foreach p $tocopy {
+ incr tot [file size [file join $objdir $p]]
+ }
+ foreach p $tocopy {
+ if {[catch {
+ set f_in [open [file join $objdir $p] r]
+ set f_cp [open [file join .git objects $p] w]
+ fconfigure $f_in -translation binary -encoding binary
+ fconfigure $f_cp -translation binary -encoding binary
+
+ while {![eof $f_in]} {
+ incr cmp [fcopy $f_in $f_cp -size 16384]
+ $o_cons update \
+ [expr {$cmp / 1024}] \
+ [expr {$tot / 1024}]
+ update
+ }
+
+ close $f_in
+ close $f_cp
+ } err]} {
+ _clone_failed $this [mc "Unable to copy object: %s" $err]
+ return 0
+ }
+ }
+ return 1
+}
+
+method _link_files {objdir tolink} {
+ set total [llength $tolink]
+ $o_cons start \
+ [mc "Linking objects"] \
+ [mc "objects"]
+ for {set i 0} {$i < $total} {} {
+ set p [lindex $tolink $i]
+ if {[catch {
+ file link -hard \
+ [file join .git objects $p] \
+ [file join $objdir $p]
+ } err]} {
+ _clone_failed $this [mc "Unable to hardlink object: %s" $err]
+ return 0
+ }
+
+ incr i
+ if {$i % 5 == 0} {
+ $o_cons update $i $total
+ update
+ }
+ }
+ return 1
+}
+
+method _clone_refs {} {
+ set pwd [pwd]
+ if {[catch {cd $origin_url} err]} {
+ error_popup [mc "Not a Git repository: %s" [file tail $origin_url]]
+ return 0
+ }
+ set fd_in [git_read for-each-ref \
+ --tcl \
+ {--format=list %(refname) %(objectname) %(*objectname)}]
+ cd $pwd
+
+ set fd [open [gitdir packed-refs] w]
+ fconfigure $fd -translation binary
+ puts $fd "# pack-refs with: peeled"
+ while {[gets $fd_in line] >= 0} {
+ set line [eval $line]
+ set refn [lindex $line 0]
+ set robj [lindex $line 1]
+ set tobj [lindex $line 2]
+
+ if {[regsub ^refs/heads/ $refn \
+ "refs/remotes/$origin_name/" refn]} {
+ puts $fd "$robj $refn"
+ } elseif {[string match refs/tags/* $refn]} {
+ puts $fd "$robj $refn"
+ if {$tobj ne {}} {
+ puts $fd "^$tobj"
+ }
+ }
+ }
+ close $fd_in
+ close $fd
+ return 1
+}
+
+method _do_clone_tags {ok} {
+ if {$ok} {
+ $o_cons exec \
+ [list git fetch --tags -k $origin_name] \
+ [cb _do_clone_HEAD]
+ } else {
+ $o_cons done $ok
+ _clone_failed $this [mc "Cannot fetch branches and objects. See console output for details."]
+ }
+}
+
+method _do_clone_HEAD {ok} {
+ if {$ok} {
+ $o_cons exec \
+ [list git fetch $origin_name HEAD] \
+ [cb _do_clone_full_end]
+ } else {
+ $o_cons done $ok
+ _clone_failed $this [mc "Cannot fetch tags. See console output for details."]
+ }
+}
+
+method _do_clone_full_end {ok} {
+ $o_cons done $ok
+
+ if {$ok} {
+ destroy $w_body
+
+ set HEAD {}
+ if {[file exists [gitdir FETCH_HEAD]]} {
+ set fd [open [gitdir FETCH_HEAD] r]
+ while {[gets $fd line] >= 0} {
+ if {[regexp "^(.{40})\t\t" $line line HEAD]} {
+ break
+ }
+ }
+ close $fd
+ }
+
+ catch {git pack-refs}
+ _do_clone_checkout $this $HEAD
+ } else {
+ _clone_failed $this [mc "Cannot determine HEAD. See console output for details."]
+ }
+}
+
+method _clone_failed {{why {}}} {
+ if {[catch {file delete -force $local_path} err]} {
+ set why [strcat \
+ $why \
+ "\n\n" \
+ [mc "Unable to cleanup %s" $local_path] \
+ "\n\n" \
+ $err]
+ }
+ if {$why ne {}} {
+ update
+ error_popup [strcat [mc "Clone failed."] "\n" $why]
+ }
+}
+
+method _do_clone_checkout {HEAD} {
+ if {$HEAD eq {}} {
+ info_popup [strcat \
+ [mc "No default branch obtained."] \
+ "\n" \
+ [mc "The 'master' branch has not been initialized."] \
+ ]
+ set done 1
+ return
+ }
+ if {[catch {
+ git update-ref HEAD $HEAD^0
+ } err]} {
+ info_popup [strcat \
+ [mc "Cannot resolve %s as a commit." $HEAD^0] \
+ "\n $err" \
+ "\n" \
+ [mc "The 'master' branch has not been initialized."] \
+ ]
+ set done 1
+ return
+ }
+
+ set o_cons [status_bar::two_line $w_body]
+ pack $w_body -fill x -padx 10 -pady 10
+ $o_cons start \
+ [mc "Creating working directory"] \
+ [mc "files"]
+
+ set readtree_err {}
+ set fd [git_read --stderr read-tree \
+ -m \
+ -u \
+ -v \
+ HEAD \
+ HEAD \
+ ]
+ fconfigure $fd -blocking 0 -translation binary
+ fileevent $fd readable [cb _readtree_wait $fd]
+}
+
+method _readtree_wait {fd} {
+ set buf [read $fd]
+ $o_cons update_meter $buf
+ append readtree_err $buf
+
+ fconfigure $fd -blocking 1
+ if {![eof $fd]} {
+ fconfigure $fd -blocking 0
+ return
+ }
+
+ if {[catch {close $fd}]} {
+ set err $readtree_err
+ regsub {^fatal: } $err {} err
+ error_popup [strcat \
+ [mc "Initial file checkout failed."] \
+ "\n\n$err"]
+ return
+ }
+
+ set done 1
+}
+
+######################################################################
+##
+## Open Existing Repository
+
+method _do_open {} {
+ $w_next conf \
+ -state disabled \
+ -command [cb _do_open2] \
+ -text [mc "Open"]
+
+ frame $w_body
+ label $w_body.h \
+ -font font_uibold \
+ -text [mc "Open Existing Repository"]
+ pack $w_body.h -side top -fill x -pady 10
+ pack $w_body -fill x -padx 10
+
+ frame $w_body.where
+ label $w_body.where.l -text [mc "Repository:"]
+ entry $w_body.where.t \
+ -textvariable @local_path \
+ -font font_diff \
+ -width 50
+ button $w_body.where.b \
+ -text [mc "Browse"] \
+ -command [cb _open_local_path]
+
+ pack $w_body.where.b -side right
+ pack $w_body.where.l -side left
+ pack $w_body.where.t -fill x
+ pack $w_body.where -fill x
+
+ trace add variable @local_path write [cb _write_local_path]
+ bind $w_body.h <Destroy> [list trace remove variable @local_path write [cb _write_local_path]]
+ update
+ focus $w_body.where.t
+}
+
+method _open_local_path {} {
+ if {$local_path ne {}} {
+ set p $local_path
+ } else {
+ set p [_home]
+ }
+
+ set p [tk_chooseDirectory \
+ -initialdir $p \
+ -parent $top \
+ -title [mc "Git Repository"] \
+ -mustexist true]
+ if {$p eq {}} return
+
+ set p [file normalize $p]
+ if {![_is_git [file join $p .git]]} {
+ error_popup [mc "Not a Git repository: %s" [file tail $p]]
+ return
+ }
+ set local_path $p
+}
+
+method _do_open2 {} {
+ if {![_is_git [file join $local_path .git]]} {
+ error_popup [mc "Not a Git repository: %s" [file tail $local_path]]
+ return
+ }
+
+ if {[catch {cd $local_path} err]} {
+ error_popup [strcat \
+ [mc "Failed to open repository %s:" $local_path] \
+ "\n\n$err"]
+ return
+ }
+
+ _append_recentrepos [pwd]
+ set ::_gitdir .git
+ set ::_prefix {}
+ set done 1
+}
+
+}
diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl
index ec064b3..a063c5b 100644
--- a/lib/choose_rev.tcl
+++ b/lib/choose_rev.tcl
@@ -50,14 +50,14 @@ constructor _new {path unmerged_only title} {
if {$is_detached} {
radiobutton $w.detachedhead_r \
-anchor w \
- -text {This Detached Checkout} \
+ -text [mc "This Detached Checkout"] \
-value HEAD \
-variable @revtype
grid $w.detachedhead_r -sticky we -padx {0 5} -columnspan 2
}
radiobutton $w.expr_r \
- -text {Revision Expression:} \
+ -text [mc "Revision Expression:"] \
-value expr \
-variable @revtype
entry $w.expr_t \
@@ -71,17 +71,17 @@ constructor _new {path unmerged_only title} {
frame $w.types
radiobutton $w.types.head_r \
- -text {Local Branch} \
+ -text [mc "Local Branch"] \
-value head \
-variable @revtype
pack $w.types.head_r -side left
radiobutton $w.types.trck_r \
- -text {Tracking Branch} \
+ -text [mc "Tracking Branch"] \
-value trck \
-variable @revtype
pack $w.types.trck_r -side left
radiobutton $w.types.tag_r \
- -text {Tag} \
+ -text [mc "Tag"] \
-value tag \
-variable @revtype
pack $w.types.tag_r -side left
@@ -133,13 +133,13 @@ constructor _new {path unmerged_only title} {
append fmt { %(objecttype)}
append fmt { %(objectname)}
append fmt { [concat %(taggername) %(authorname)]}
- append fmt { [concat %(taggerdate) %(authordate)]}
+ append fmt { [reformat_date [concat %(taggerdate) %(authordate)]]}
append fmt { %(subject)}
append fmt {] [list}
append fmt { %(*objecttype)}
append fmt { %(*objectname)}
append fmt { %(*authorname)}
- append fmt { %(*authordate)}
+ append fmt { [reformat_date %(*authordate)]}
append fmt { %(*subject)}
append fmt {]}
set all_refn [list]
@@ -314,7 +314,7 @@ method commit_or_die {} {
}
set top [winfo toplevel $w]
- set msg "Invalid revision: [get $this]\n\n$err"
+ set msg [strcat [mc "Invalid revision: %s" [get $this]] "\n\n$err"]
tk_messageBox \
-icon error \
-type ok \
@@ -335,7 +335,7 @@ method _expr {} {
if {$i ne {}} {
return [lindex $cur_specs $i 1]
} else {
- error "No revision selected."
+ error [mc "No revision selected."]
}
}
@@ -343,7 +343,7 @@ method _expr {} {
if {$c_expr ne {}} {
return $c_expr
} else {
- error "Revision expression is empty."
+ error [mc "Revision expression is empty."]
}
}
HEAD { return HEAD }
@@ -527,14 +527,14 @@ method _open_tooltip {} {
set last [_reflog_last $this [lindex $spec 1]]
if {$last ne {}} {
$tooltip_t insert end "\n"
- $tooltip_t insert end "updated"
+ $tooltip_t insert end [mc "Updated"]
$tooltip_t insert end " $last"
}
$tooltip_t insert end "\n"
if {$tag ne {}} {
$tooltip_t insert end "\n"
- $tooltip_t insert end "tag" section_header
+ $tooltip_t insert end [mc "Tag"] section_header
$tooltip_t insert end " [lindex $tag 1]\n"
$tooltip_t insert end [lindex $tag 2]
$tooltip_t insert end " ([lindex $tag 3])\n"
@@ -544,7 +544,7 @@ method _open_tooltip {} {
if {$cmit ne {}} {
$tooltip_t insert end "\n"
- $tooltip_t insert end "commit" section_header
+ $tooltip_t insert end [mc "Commit@@noun"] section_header
$tooltip_t insert end " [lindex $cmit 1]\n"
$tooltip_t insert end [lindex $cmit 2]
$tooltip_t insert end " ([lindex $cmit 3])\n"
@@ -553,11 +553,11 @@ method _open_tooltip {} {
if {[llength $spec] > 2} {
$tooltip_t insert end "\n"
- $tooltip_t insert end "remote" section_header
+ $tooltip_t insert end [mc "Remote"] section_header
$tooltip_t insert end " [lindex $spec 2]\n"
- $tooltip_t insert end "url"
+ $tooltip_t insert end [mc "URL"]
$tooltip_t insert end " $remote_url([lindex $spec 2])\n"
- $tooltip_t insert end "branch"
+ $tooltip_t insert end [mc "Branch"]
$tooltip_t insert end " [lindex $spec 3]"
}
@@ -583,7 +583,7 @@ method _reflog_last {name} {
}
if {$last ne {}} {
- set last [clock format $last -format {%a %b %e %H:%M:%S %Y}]
+ set last [format_date $last]
}
set reflog_last($name) $last
return $last
diff --git a/lib/commit.tcl b/lib/commit.tcl
index 5723812..10b0430 100644
--- a/lib/commit.tcl
+++ b/lib/commit.tcl
@@ -6,19 +6,19 @@ proc load_last_commit {} {
global repo_config
if {[llength $PARENT] == 0} {
- error_popup {There is nothing to amend.
+ error_popup [mc "There is nothing to amend.
You are about to create the initial commit. There is no commit before this to amend.
-}
+"]
return
}
repository_state curType curHEAD curMERGE_HEAD
if {$curType eq {merge}} {
- error_popup {Cannot amend while merging.
+ error_popup [mc "Cannot amend while merging.
You are currently in the middle of a merge that has not been fully completed. You cannot amend the prior commit unless you first abort the current merge activity.
-}
+"]
return
}
@@ -46,7 +46,7 @@ You are currently in the middle of a merge that has not been fully completed. Y
}
set msg [string trim $msg]
} err]} {
- error_popup "Error loading commit data for amend:\n\n$err"
+ error_popup [strcat [mc "Error loading commit data for amend:"] "\n\n$err"]
return
}
@@ -73,12 +73,12 @@ proc committer_ident {} {
if {$GIT_COMMITTER_IDENT eq {}} {
if {[catch {set me [git var GIT_COMMITTER_IDENT]} err]} {
- error_popup "Unable to obtain your identity:\n\n$err"
+ error_popup [strcat [mc "Unable to obtain your identity:"] "\n\n$err"]
return {}
}
if {![regexp {^(.*) [0-9]+ [-+0-9]+$} \
$me me GIT_COMMITTER_IDENT]} {
- error_popup "Invalid GIT_COMMITTER_IDENT:\n\n$me"
+ error_popup [strcat [mc "Invalid GIT_COMMITTER_IDENT:"] "\n\n$me"]
return {}
}
}
@@ -130,12 +130,12 @@ proc commit_tree {} {
&& $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 another commit can be created.
The rescan will be automatically started now.
-}
+"]
unlock_index
rescan ui_ready
return
@@ -151,26 +151,26 @@ The rescan will be automatically started now.
D? -
M? {set files_ready 1}
U? {
- error_popup "Unmerged files cannot be committed.
+ error_popup [mc "Unmerged files cannot be committed.
-File [short_path $path] has merge conflicts. You must resolve them and stage the file before committing.
-"
+File %s has merge conflicts. You must resolve them and stage the file before committing.
+" [short_path $path]]
unlock_index
return
}
default {
- error_popup "Unknown file state [lindex $s 0] detected.
+ error_popup [mc "Unknown file state %s detected.
-File [short_path $path] cannot be committed by this program.
-"
+File %s cannot be committed by this program.
+" [lindex $s 0] [short_path $path]]
}
}
}
if {!$files_ready && ![string match *merge $curType]} {
- info_popup {No changes to commit.
+ info_popup [mc "No changes to commit.
You must stage at least 1 file before you can commit.
-}
+"]
unlock_index
return
}
@@ -180,14 +180,14 @@ You must stage at least 1 file before you can commit.
set msg [string trim [$ui_comm get 1.0 end]]
regsub -all -line {[ \t\r]+$} $msg {} msg
if {$msg eq {}} {
- error_popup {Please supply a commit message.
+ error_popup [mc "Please supply a commit message.
A good commit message has the following format:
- First line: Describe in one sentance what you did.
- Second line: Blank
- Remaining lines: Describe why this change is good.
-}
+"]
unlock_index
return
}
@@ -254,7 +254,7 @@ proc commit_committree {fd_wt curHEAD msg} {
gets $fd_wt tree_id
if {[catch {close $fd_wt} err]} {
- error_popup "write-tree failed:\n\n$err"
+ error_popup [strcat [mc "write-tree failed:"] "\n\n$err"]
ui_status {Commit failed.}
unlock_index
return
@@ -272,18 +272,18 @@ proc commit_committree {fd_wt curHEAD msg} {
&& [string length $old_tree] == 45} {
set old_tree [string range $old_tree 5 end]
} else {
- error "Commit $PARENT appears to be corrupt"
+ error [mc "Commit %s appears to be corrupt" $PARENT]
}
if {$tree_id eq $old_tree} {
- info_popup {No changes to commit.
+ info_popup [mc "No changes to commit.
No files were modified by this commit and it was not a merge commit.
A rescan will be automatically started now.
-}
+"]
unlock_index
- rescan {ui_status {No changes to commit.}}
+ rescan {ui_status [mc "No changes to commit."]}
return
}
}
@@ -300,7 +300,7 @@ A rescan will be automatically started now.
if {$use_enc ne {}} {
fconfigure $msg_wt -encoding $use_enc
} else {
- puts stderr "warning: Tcl does not support encoding '$enc'."
+ puts stderr [mc "warning: Tcl does not support encoding '%s'." $enc]
fconfigure $msg_wt -encoding utf-8
}
puts -nonewline $msg_wt $msg
@@ -314,7 +314,7 @@ A rescan will be automatically started now.
}
lappend cmd <$msg_p
if {[catch {set cmt_id [eval git $cmd]} err]} {
- error_popup "commit-tree failed:\n\n$err"
+ error_popup [strcat [mc "commit-tree failed:"] "\n\n$err"]
ui_status {Commit failed.}
unlock_index
return
@@ -336,7 +336,7 @@ A rescan will be automatically started now.
if {[catch {
git update-ref -m $reflogm HEAD $cmt_id $curHEAD
} err]} {
- error_popup "update-ref failed:\n\n$err"
+ error_popup [strcat [mc "update-ref failed:"] "\n\n$err"]
ui_status {Commit failed.}
unlock_index
return
@@ -427,5 +427,5 @@ A rescan will be automatically started now.
display_all_files
unlock_index
reshow_diff
- ui_status "Created commit [string range $cmt_id 0 7]: $subject"
+ ui_status [mc "Created commit %s: %s" [string range $cmt_id 0 7] $subject]
}
diff --git a/lib/console.tcl b/lib/console.tcl
index b038a78..5597188 100644
--- a/lib/console.tcl
+++ b/lib/console.tcl
@@ -6,6 +6,7 @@ class console {
field t_short
field t_long
field w
+field w_t
field console_cr
field is_toplevel 1; # are we our own window?
@@ -36,6 +37,7 @@ method _init {} {
}
set console_cr 1.0
+ set w_t $w.m.t
frame $w.m
label $w.m.l1 \
@@ -43,51 +45,47 @@ method _init {} {
-anchor w \
-justify left \
-font font_uibold
- text $w.m.t \
+ text $w_t \
-background white -borderwidth 1 \
-relief sunken \
-width 80 -height 10 \
-wrap none \
-font font_diff \
-state disabled \
- -xscrollcommand [list $w.m.sbx set] \
- -yscrollcommand [list $w.m.sby set]
- label $w.m.s -text {Working... please wait...} \
+ -xscrollcommand [cb _sb_set $w.m.sbx h] \
+ -yscrollcommand [cb _sb_set $w.m.sby v]
+ label $w.m.s -text [mc "Working... please wait..."] \
-anchor w \
-justify left \
-font font_uibold
- scrollbar $w.m.sbx -command [list $w.m.t xview] -orient h
- scrollbar $w.m.sby -command [list $w.m.t yview]
pack $w.m.l1 -side top -fill x
pack $w.m.s -side bottom -fill x
- pack $w.m.sbx -side bottom -fill x
- pack $w.m.sby -side right -fill y
- pack $w.m.t -side left -fill both -expand 1
+ pack $w_t -side left -fill both -expand 1
pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10
menu $w.ctxm -tearoff 0
- $w.ctxm add command -label "Copy" \
- -command "tk_textCopy $w.m.t"
- $w.ctxm add command -label "Select All" \
- -command "focus $w.m.t;$w.m.t tag add sel 0.0 end"
- $w.ctxm add command -label "Copy All" \
+ $w.ctxm add command -label [mc "Copy"] \
+ -command "tk_textCopy $w_t"
+ $w.ctxm add command -label [mc "Select All"] \
+ -command "focus $w_t;$w_t tag add sel 0.0 end"
+ $w.ctxm add command -label [mc "Copy All"] \
-command "
- $w.m.t tag add sel 0.0 end
- tk_textCopy $w.m.t
- $w.m.t tag remove sel 0.0 end
+ $w_t tag add sel 0.0 end
+ tk_textCopy $w_t
+ $w_t tag remove sel 0.0 end
"
if {$is_toplevel} {
- button $w.ok -text {Close} \
+ button $w.ok -text [mc "Close"] \
-state disabled \
-command [list destroy $w]
pack $w.ok -side bottom -anchor e -pady 10 -padx 10
bind $w <Visibility> [list focus $w]
}
- bind_button3 $w.m.t "tk_popup $w.ctxm %X %Y"
- bind $w.m.t <$M1B-Key-a> "$w.m.t tag add sel 0.0 end;break"
- bind $w.m.t <$M1B-Key-A> "$w.m.t tag add sel 0.0 end;break"
+ bind_button3 $w_t "tk_popup $w.ctxm %X %Y"
+ bind $w_t <$M1B-Key-a> "$w_t tag add sel 0.0 end;break"
+ bind $w_t <$M1B-Key-A> "$w_t tag add sel 0.0 end;break"
}
method exec {cmd {after {}}} {
@@ -104,8 +102,8 @@ method exec {cmd {after {}}} {
method _read {fd after} {
set buf [read $fd]
if {$buf ne {}} {
- if {![winfo exists $w.m.t]} {_init $this}
- $w.m.t conf -state normal
+ if {![winfo exists $w_t]} {_init $this}
+ $w_t conf -state normal
set c 0
set n [string length $buf]
while {$c < $n} {
@@ -115,20 +113,20 @@ method _read {fd after} {
if {$lf < 0} {set lf [expr {$n + 1}]}
if {$lf < $cr} {
- $w.m.t insert end [string range $buf $c $lf]
- set console_cr [$w.m.t index {end -1c}]
+ $w_t insert end [string range $buf $c $lf]
+ set console_cr [$w_t index {end -1c}]
set c $lf
incr c
} else {
- $w.m.t delete $console_cr end
- $w.m.t insert end "\n"
- $w.m.t insert end [string range $buf $c [expr {$cr - 1}]]
+ $w_t delete $console_cr end
+ $w_t insert end "\n"
+ $w_t insert end [string range $buf $c [expr {$cr - 1}]]
set c $cr
incr c
}
}
- $w.m.t conf -state disabled
- $w.m.t see end
+ $w_t conf -state disabled
+ $w_t see end
}
fconfigure $fd -blocking 1
@@ -171,33 +169,50 @@ method chain {cmdlist {ok 1}} {
}
method insert {txt} {
- if {![winfo exists $w.m.t]} {_init $this}
- $w.m.t conf -state normal
- $w.m.t insert end "$txt\n"
- set console_cr [$w.m.t index {end -1c}]
- $w.m.t conf -state disabled
+ if {![winfo exists $w_t]} {_init $this}
+ $w_t conf -state normal
+ $w_t insert end "$txt\n"
+ set console_cr [$w_t index {end -1c}]
+ $w_t conf -state disabled
}
method done {ok} {
if {$ok} {
if {[winfo exists $w.m.s]} {
- $w.m.s conf -background green -text {Success}
+ bind $w.m.s <Destroy> [list delete_this $this]
+ $w.m.s conf -background green -text [mc "Success"]
if {$is_toplevel} {
$w.ok conf -state normal
focus $w.ok
}
+ } else {
+ delete_this
}
} else {
if {![winfo exists $w.m.s]} {
_init $this
}
- $w.m.s conf -background red -text {Error: Command Failed}
+ bind $w.m.s <Destroy> [list delete_this $this]
+ $w.m.s conf -background red -text [mc "Error: Command Failed"]
if {$is_toplevel} {
$w.ok conf -state normal
focus $w.ok
}
}
- delete_this
+}
+
+method _sb_set {sb orient first last} {
+ if {![winfo exists $sb]} {
+ if {$first == $last || ($first == 0 && $last == 1)} return
+ if {$orient eq {h}} {
+ scrollbar $sb -orient h -command [list $w_t xview]
+ pack $sb -fill x -side bottom -before $w_t
+ } else {
+ scrollbar $sb -orient v -command [list $w_t yview]
+ pack $sb -fill y -side right -before $w_t
+ }
+ }
+ $sb set $first $last
}
}
diff --git a/lib/database.tcl b/lib/database.tcl
index 0657cc2..d66aa3f 100644
--- a/lib/database.tcl
+++ b/lib/database.tcl
@@ -24,14 +24,14 @@ proc do_stats {} {
toplevel $w
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
- label $w.header -text {Database Statistics}
+ label $w.header -text [mc "Database Statistics"]
pack $w.header -side top -fill x
frame $w.buttons -border 1
- button $w.buttons.close -text Close \
+ button $w.buttons.close -text [mc Close] \
-default active \
-command [list destroy $w]
- button $w.buttons.gc -text {Compress Database} \
+ button $w.buttons.gc -text [mc "Compress Database"] \
-default normal \
-command "destroy $w;do_gc"
pack $w.buttons.close -side right
@@ -40,16 +40,16 @@ proc do_stats {} {
frame $w.stat -borderwidth 1 -relief solid
foreach s {
- {count {Number of loose objects}}
- {size {Disk space used by loose objects} { KiB}}
- {in-pack {Number of packed objects}}
- {packs {Number of packs}}
- {size-pack {Disk space used by packed objects} { KiB}}
- {prune-packable {Packed objects waiting for pruning}}
- {garbage {Garbage files}}
+ {count {mc "Number of loose objects"}}
+ {size {mc "Disk space used by loose objects"} { KiB}}
+ {in-pack {mc "Number of packed objects"}}
+ {packs {mc "Number of packs"}}
+ {size-pack {mc "Disk space used by packed objects"} { KiB}}
+ {prune-packable {mc "Packed objects waiting for pruning"}}
+ {garbage {mc "Garbage files"}}
} {
set name [lindex $s 0]
- set label [lindex $s 1]
+ set label [eval [lindex $s 1]]
if {[catch {set value $stats($name)}]} continue
if {[llength $s] > 2} {
set value "$value[lindex $s 2]"
@@ -64,12 +64,12 @@ proc do_stats {} {
bind $w <Visibility> "grab $w; focus $w.buttons.close"
bind $w <Key-Escape> [list destroy $w]
bind $w <Key-Return> [list destroy $w]
- wm title $w "[appname] ([reponame]): Database Statistics"
+ wm title $w [append "[appname] ([reponame]): " [mc "Database Statistics"]]
tkwait window $w
}
proc do_gc {} {
- set w [console::new {gc} {Compressing the object database}]
+ set w [console::new {gc} [mc "Compressing the object database"]]
console::chain $w {
{exec git pack-refs --prune}
{exec git reflog expire --all}
@@ -80,7 +80,7 @@ proc do_gc {} {
proc do_fsck_objects {} {
set w [console::new {fsck-objects} \
- {Verifying the object database with fsck-objects}]
+ [mc "Verifying the object database with fsck-objects"]]
set cmd [list git fsck-objects]
lappend cmd --full
lappend cmd --cache
@@ -105,11 +105,11 @@ proc hint_gc {} {
set objects_current [expr {$objects_current * 256}]
set object_limit [expr {$object_limit * 256}]
if {[ask_popup \
- "This repository currently has approximately $objects_current loose objects.
+ [mc "This repository currently has approximately %i loose objects.
-To maintain optimal performance it is strongly recommended that you compress the database when more than $object_limit loose objects exist.
+To maintain optimal performance it is strongly recommended that you compress the database when more than %i loose objects exist.
-Compress the database now?"] eq yes} {
+Compress the database now?" $objects_current $object_limit]] eq yes} {
do_gc
}
}
diff --git a/lib/date.tcl b/lib/date.tcl
new file mode 100644
index 0000000..abe8299
--- /dev/null
+++ b/lib/date.tcl
@@ -0,0 +1,53 @@
+# git-gui date processing support
+# Copyright (C) 2007 Shawn Pearce
+
+set git_month(Jan) 1
+set git_month(Feb) 2
+set git_month(Mar) 3
+set git_month(Apr) 4
+set git_month(May) 5
+set git_month(Jun) 6
+set git_month(Jul) 7
+set git_month(Aug) 8
+set git_month(Sep) 9
+set git_month(Oct) 10
+set git_month(Nov) 11
+set git_month(Dec) 12
+
+proc parse_git_date {s} {
+ if {$s eq {}} {
+ return {}
+ }
+
+ if {![regexp \
+ {^... (...) (\d{1,2}) (\d\d):(\d\d):(\d\d) (\d{4}) ([+-]?)(\d\d)(\d\d)$} $s s \
+ month day hr mm ss yr ew tz_h tz_m]} {
+ error [mc "Invalid date from Git: %s" $s]
+ }
+
+ set s [clock scan [format {%4.4i%2.2i%2.2iT%2s%2s%2s} \
+ $yr $::git_month($month) $day \
+ $hr $mm $ss] \
+ -gmt 1]
+
+ regsub ^0 $tz_h {} tz_h
+ regsub ^0 $tz_m {} tz_m
+ switch -- $ew {
+ - {set ew +}
+ + {set ew -}
+ {} {set ew -}
+ }
+
+ return [expr "$s $ew ($tz_h * 3600 + $tz_m * 60)"]
+}
+
+proc format_date {s} {
+ if {$s eq {}} {
+ return {}
+ }
+ return [clock format $s -format {%a %b %e %H:%M:%S %Y}]
+}
+
+proc reformat_date {s} {
+ return [format_date [parse_git_date $s]]
+}
diff --git a/lib/diff.tcl b/lib/diff.tcl
index 694834a..43565e4 100644
--- a/lib/diff.tcl
+++ b/lib/diff.tcl
@@ -39,13 +39,13 @@ proc handle_empty_diff {} {
set s $file_states($path)
if {[lindex $s 0] ne {_M}} return
- info_popup "No differences detected.
+ info_popup [mc "No differences detected.
-[short_path $path] has no changes.
+%s has no changes.
The modification date of this file was updated by another application, but the content within the file was not changed.
-A rescan will be automatically started to find other files which may have the same state."
+A rescan will be automatically started to find other files which may have the same state." [short_path $path]]
clear_diff
display_file $path __
@@ -78,7 +78,7 @@ proc show_diff {path w {lno {}}} {
set current_diff_path $path
set current_diff_side $w
set current_diff_header {}
- ui_status "Loading diff of [escape_path $path]..."
+ ui_status [mc "Loading diff of %s..." [escape_path $path]]
# - Git won't give us the diff, there's nothing to compare to!
#
@@ -111,13 +111,16 @@ proc show_diff {path w {lno {}}} {
} err ]} {
set diff_active 0
unlock_index
- ui_status "Unable to display [escape_path $path]"
- error_popup "Error loading file:\n\n$err"
+ ui_status [mc "Unable to display %s" [escape_path $path]]
+ error_popup [strcat [mc "Error loading file:"] "\n\n$err"]
return
}
$ui_diff conf -state normal
if {$type eq {submodule}} {
- $ui_diff insert end "* Git Repository (subproject)\n" d_@
+ $ui_diff insert end [append \
+ "* " \
+ [mc "Git Repository (subproject)"] \
+ "\n"] d_@
} elseif {![catch {set type [exec file $path]}]} {
set n [string length $path]
if {[string equal -length $n $path $type]} {
@@ -128,7 +131,7 @@ proc show_diff {path w {lno {}}} {
}
if {[string first "\0" $content] != -1} {
$ui_diff insert end \
- "* Binary file (not showing content)." \
+ [mc "* Binary file (not showing content)."] \
d_@
} else {
if {$sz > $max_sz} {
@@ -178,8 +181,8 @@ proc show_diff {path w {lno {}}} {
if {[catch {set fd [eval git_read --nice $cmd]} err]} {
set diff_active 0
unlock_index
- ui_status "Unable to display [escape_path $path]"
- error_popup "Error loading diff:\n\n$err"
+ ui_status [mc "Unable to display %s" [escape_path $path]]
+ error_popup [strcat [mc "Error loading diff:"] "\n\n$err"]
return
}
@@ -296,14 +299,14 @@ proc apply_hunk {x y} {
set apply_cmd {apply --cached --whitespace=nowarn}
set mi [lindex $file_states($current_diff_path) 0]
if {$current_diff_side eq $ui_index} {
- set mode unstage
+ set failed_msg [mc "Failed to unstage selected hunk."]
lappend apply_cmd --reverse
if {[string index $mi 0] ne {M}} {
unlock_index
return
}
} else {
- set mode stage
+ set failed_msg [mc "Failed to stage selected hunk."]
if {[string index $mi 1] ne {M}} {
unlock_index
return
@@ -328,7 +331,7 @@ proc apply_hunk {x y} {
puts -nonewline $p $current_diff_header
puts -nonewline $p [$ui_diff get $s_lno $e_lno]
close $p} err]} {
- error_popup "Failed to $mode selected hunk.\n\n$err"
+ error_popup [append $failed_msg "\n\n$err"]
unlock_index
return
}
diff --git a/lib/error.tcl b/lib/error.tcl
index 16a2218..13565b7 100644
--- a/lib/error.tcl
+++ b/lib/error.tcl
@@ -9,7 +9,7 @@ proc error_popup {msg} {
set cmd [list tk_messageBox \
-icon error \
-type ok \
- -title "$title: error" \
+ -title [append "$title: " [mc "error"]] \
-message $msg]
if {[winfo ismapped .]} {
lappend cmd -parent .
@@ -25,7 +25,7 @@ proc warn_popup {msg} {
set cmd [list tk_messageBox \
-icon warning \
-type ok \
- -title "$title: warning" \
+ -title [append "$title: " [mc "warning"]] \
-message $msg]
if {[winfo ismapped .]} {
lappend cmd -parent .
@@ -78,7 +78,7 @@ proc hook_failed_popup {hook msg} {
-font font_diff \
-yscrollcommand [list $w.m.sby set]
label $w.m.l2 \
- -text {You must correct the above errors before committing.} \
+ -text [mc "You must correct the above errors before committing."] \
-anchor w \
-justify left \
-font font_uibold
@@ -99,6 +99,6 @@ proc hook_failed_popup {hook msg} {
bind $w <Visibility> "grab $w; focus $w"
bind $w <Key-Return> "destroy $w"
- wm title $w "[appname] ([reponame]): error"
+ wm title $w [append "[appname] ([reponame]): " [mc "error"]]
tkwait window $w
}
diff --git a/lib/git-gui.ico b/lib/git-gui.ico
new file mode 100644
index 0000000..563dd66
--- /dev/null
+++ b/lib/git-gui.ico
Binary files differ
diff --git a/lib/index.tcl b/lib/index.tcl
index 44689ab..9e04f2b 100644
--- a/lib/index.tcl
+++ b/lib/index.tcl
@@ -12,12 +12,7 @@ proc update_indexinfo {msg pathList after} {
set batch [expr {int($totalCnt * .01) + 1}]
if {$batch > 25} {set batch 25}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- 0.0]
+ $::main_status start $msg [mc "files"]
set fd [git_write update-index -z --index-info]
fconfigure $fd \
-blocking 0 \
@@ -31,18 +26,18 @@ proc update_indexinfo {msg pathList after} {
$pathList \
$totalCnt \
$batch \
- $msg \
$after \
]
}
-proc write_update_indexinfo {fd pathList totalCnt batch msg after} {
+proc write_update_indexinfo {fd pathList totalCnt batch after} {
global update_index_cp
global file_states current_diff_path
if {$update_index_cp >= $totalCnt} {
close $fd
unlock_index
+ $::main_status stop
uplevel #0 $after
return
}
@@ -68,12 +63,7 @@ proc write_update_indexinfo {fd pathList totalCnt batch msg after} {
display_file $path $new
}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- [expr {100.0 * $update_index_cp / $totalCnt}]]
+ $::main_status update $update_index_cp $totalCnt
}
proc update_index {msg pathList after} {
@@ -87,12 +77,7 @@ proc update_index {msg pathList after} {
set batch [expr {int($totalCnt * .01) + 1}]
if {$batch > 25} {set batch 25}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- 0.0]
+ $::main_status start $msg [mc "files"]
set fd [git_write update-index --add --remove -z --stdin]
fconfigure $fd \
-blocking 0 \
@@ -106,18 +91,18 @@ proc update_index {msg pathList after} {
$pathList \
$totalCnt \
$batch \
- $msg \
$after \
]
}
-proc write_update_index {fd pathList totalCnt batch msg after} {
+proc write_update_index {fd pathList totalCnt batch after} {
global update_index_cp
global file_states current_diff_path
if {$update_index_cp >= $totalCnt} {
close $fd
unlock_index
+ $::main_status stop
uplevel #0 $after
return
}
@@ -147,12 +132,7 @@ proc write_update_index {fd pathList totalCnt batch msg after} {
display_file $path $new
}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- [expr {100.0 * $update_index_cp / $totalCnt}]]
+ $::main_status update $update_index_cp $totalCnt
}
proc checkout_index {msg pathList after} {
@@ -166,12 +146,7 @@ proc checkout_index {msg pathList after} {
set batch [expr {int($totalCnt * .01) + 1}]
if {$batch > 25} {set batch 25}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- 0.0]
+ $::main_status start $msg [mc "files"]
set fd [git_write checkout-index \
--index \
--quiet \
@@ -191,18 +166,18 @@ proc checkout_index {msg pathList after} {
$pathList \
$totalCnt \
$batch \
- $msg \
$after \
]
}
-proc write_checkout_index {fd pathList totalCnt batch msg after} {
+proc write_checkout_index {fd pathList totalCnt batch after} {
global update_index_cp
global file_states current_diff_path
if {$update_index_cp >= $totalCnt} {
close $fd
unlock_index
+ $::main_status stop
uplevel #0 $after
return
}
@@ -222,12 +197,7 @@ proc write_checkout_index {fd pathList totalCnt batch msg after} {
}
}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- [expr {100.0 * $update_index_cp / $totalCnt}]]
+ $::main_status update $update_index_cp $totalCnt
}
proc unstage_helper {txt paths} {
@@ -268,7 +238,7 @@ proc do_unstage_selection {} {
[array names selected_paths]
} elseif {$current_diff_path ne {}} {
unstage_helper \
- "Unstaging [short_path $current_diff_path] from commit" \
+ [mc "Unstaging %s from commit" [short_path $current_diff_path]] \
[list $current_diff_path]
}
}
@@ -312,7 +282,7 @@ proc do_add_selection {} {
[array names selected_paths]
} elseif {$current_diff_path ne {}} {
add_helper \
- "Adding [short_path $current_diff_path]" \
+ [mc "Adding %s" [short_path $current_diff_path]] \
[list $current_diff_path]
}
}
@@ -351,26 +321,35 @@ proc revert_helper {txt paths} {
}
}
+
+ # Split question between singular and plural cases, because
+ # such distinction is needed in some languages. Previously, the
+ # code used "Revert changes in" for both, but that can't work
+ # in languages where 'in' must be combined with word from
+ # rest of string (in diffrent way for both cases of course).
+ #
+ # FIXME: Unfortunately, even that isn't enough in some languages
+ # as they have quite complex plural-form rules. Unfortunately,
+ # msgcat doesn't seem to support that kind of string translation.
+ #
set n [llength $pathList]
if {$n == 0} {
unlock_index
return
} elseif {$n == 1} {
- set s "[short_path [lindex $pathList]]"
+ set query [mc "Revert changes in file %s?" [short_path [lindex $pathList]]]
} else {
- set s "these $n files"
+ set query [mc "Revert changes in these %i files?" $n]
}
set reply [tk_dialog \
.confirm_revert \
"[appname] ([reponame])" \
- "Revert changes in $s?
-
-Any unstaged changes will be permanently lost by the revert." \
+ [mc "Any unstaged changes will be permanently lost by the revert."] \
question \
1 \
- {Do Nothing} \
- {Revert Changes} \
+ [mc "Do Nothing"] \
+ [mc "Revert Changes"] \
]
if {$reply == 1} {
checkout_index \
diff --git a/lib/logo.tcl b/lib/logo.tcl
new file mode 100644
index 0000000..5ff7669
--- /dev/null
+++ b/lib/logo.tcl
@@ -0,0 +1,43 @@
+# git-gui Git Gui logo
+# Copyright (C) 2007 Shawn Pearce
+
+# Henrik Nyh's alternative Git logo, from his blog post
+# http://henrik.nyh.se/2007/06/alternative-git-logo-and-favicon
+#
+image create photo ::git_logo_data -data {
+R0lGODdhYQC8AIQbAGZmZtg4LW9vb3l5eYKCgoyMjEC/TOJpYZWVlZ+fn2/PeKmpqbKysry8vMXF
+xZ/fpc/Pz7fnvPXNytnZ2eLi4s/v0vja1+zs7Of36fX19f3z8v///////////////////ywAAAAA
+YQC8AAAF/uAmjmRpnmiqrmzrvq4hz3RtGw+s7zx5/7dcb0hUAY8zYXHJRCKVzGjPeYRKry8q0Irt
+GrVBr3gFDo/PprKNix6ra+y2902Ly7H05L2dl9n3UX04gGeCf4RFhohiiotdjY5XkJGBfYeUOpOY
+iZablXmXURgPpKWmp6ipqYIKqq6vqREjFYK1trUKs7e7vFq5IrS9wsM0vxvBxMm8xsjKzqy6z9J5
+zNPWatXX2k7Z29433d/iMuHj3+Xm2+jp1+vs0+7vz/HyyvT1xPf4wvr7y9H+pBkbBasgLFYGE8ba
+o8nTlE4OOYGKKJFOKIopGmLMAnHjDo0eWYAM+WUiSRgj/k+eSKmyBMuWI17C3CATZs2WN1XmPLmT
+ZM+QPz0G3VihqNGjSJNWwDCzqdOnUKPu0SChqtWrWLNq3cq1q9evYCVYGCEhgNmzaNOqXcu2rdu3
+cOMGOEBWrt27ePPCpSuirN6/gAO35bvBr+DDiPMSNpy4sWO2ix9Lnmw2MuXLiS1j3gxYM+fPdz2D
+Hv1WNOnTak2jXj23LuvXlV3DZq16Nujatjnjzo15N2/Kvn9LDi7cMfHimaUqX868ufPn0KPPpOCA
+AQMWCQBo3869u/fv4MNrd3DlQoMC3QlkSJFdvPv38LVDWJLBAYHwE1LE38+/+/UhGTAggHv5odDf
+gfv9/seDgPAVeAKCELqnIAwU3BefgyZEqOF3E7rAQH8YlrDhiNt1uEIG6IGoH4kjmpjCBRaqaCCL
+G7p4AgUDIhgiCTTW2AKOEe44Qo8a2khCBgNoKKQIREZopAgZxAjhkhs0CeGTG7Sn5IpW9vekAyRS
+2eWBRl6Q44ZijhlfAQlQmeKIaarpHZsMTHABCxDQGKec3JH3QpIs7snndn6yAKaeXA7aZwuABppo
+fAws0GiEhaKQJ40F3DkjfwVC8CaCAlCgAgIkJjDfCgdiOMGn/Q2w3gkZtPgqC6ma0ECECaBwa4QE
+aOpCrSYAqeMJpEKYqw7ABnsmfwQ8aCwPySqLYKUb/kwAYbPQyoiCtQcOUMKHBwrgK7LaogBuuaxC
+OkS0KEwa37EiLBufALPuwO4Jh/InwAixkknEvSe4C9+p3PY3rr3lpnDufguIcCmzRQAc7IHYLhxf
+w/8mnILA74lg8cARa4xCsZxusMCBomZccgsfv0deuh2HvLKh/sLs3hJSvieuCwUzvIHN4tGXc3ih
+vtDzmj8fSNLR8BWQdH9LH+g00OFF3d/UBx4cUcvuOc21eFRiouV+Xvvr0dDvlX21R/2uzTR89TqU
+L3+5UoBgAxtRHd5/CHpLkd13i4D2e3hHRLKMY+9Hr0Nvx/fq3Pw57cng7/m9wQVObnIyhAiQwHF8
+/tQS8nDgI2wOYeh3CAvhuIBHiDEgqvdtwudkaz3GBPKaTcKuGgqAJRMZmK6h1hnk3ncDcUvhgPFS
+o5B476ZKQcECzCN4qgmYN4lAncmzcAEEkhJp+QlfkyhAAdtbN8H67FvHQAF6b4g6v9UryqfkKkBu
+v/0prxD//kR63YnqB8AeqcdoBRxU/1zAuwRaaX4reJ4DSSRAHUhwgrgqwgUx2B94EWGDHISPBzUY
+QgSNcAn6K6F4fscDCtBOhdoRwPW6kIHDwZA7vWoDBF44Qd/tIUAEBCACbIeG4AXxfmFrQ4B4OCYE
+JBEQELChmgbAACJioj4JOCKCCLCABZ6EAg1IHwDlyLYAB1gRJhSYgHUQAD9WnQ9+CWBAA+wknTpC
+JwQAOw==
+}
+
+proc git_logo {w} {
+ label $w \
+ -borderwidth 1 \
+ -relief sunken \
+ -background white \
+ -image ::git_logo_data
+ return $w
+}
diff --git a/lib/merge.tcl b/lib/merge.tcl
index 0e50919..63e1427 100644
--- a/lib/merge.tcl
+++ b/lib/merge.tcl
@@ -10,10 +10,10 @@ method _can_merge {} {
global HEAD commit_type file_states
if {[string match amend* $commit_type]} {
- info_popup {Cannot merge while amending.
+ info_popup [mc "Cannot merge while amending.
You must finish amending this commit before starting any type of merge.
-}
+"]
return 0
}
@@ -24,12 +24,12 @@ You must finish amending this commit before starting any type of merge.
#
repository_state curType curHEAD curMERGE_HEAD
if {$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 a merge can be performed.
The rescan will be automatically started now.
-}
+"]
unlock_index
rescan ui_ready
return 0
@@ -41,22 +41,22 @@ The rescan will be automatically started now.
continue; # and pray it works!
}
U? {
- error_popup "You are in the middle of a conflicted merge.
+ error_popup [mc "You are in the middle of a conflicted merge.
-File [short_path $path] has merge conflicts.
+File %s has merge conflicts.
You must resolve them, stage the file, and commit to complete the current merge. Only then can you begin another merge.
-"
+" [short_path $path]]
unlock_index
return 0
}
?? {
- error_popup "You are in the middle of a change.
+ error_popup [mc "You are in the middle of a change.
-File [short_path $path] is modified.
+File %s is modified.
You should complete the current commit before starting a merge. Doing so will help you abort a failed merge, should the need arise.
-"
+" [short_path $path]]
unlock_index
return 0
}
@@ -103,7 +103,7 @@ method _start {} {
regsub {^[^:@]*@} $remote {} remote
}
set branch [lindex $spec 2]
- set stitle "$branch of $remote"
+ set stitle [mc "%s of %s" $branch $remote]
}
regsub ^refs/heads/ $branch {} branch
puts $fh "$cmit\t\tbranch '$branch' of $remote"
@@ -116,9 +116,9 @@ method _start {} {
lappend cmd HEAD
lappend cmd $name
- set msg "Merging $current_branch and $stitle"
+ set msg [mc "Merging %s and %s" $current_branch $stitle]
ui_status "$msg..."
- set cons [console::new "Merge" "merge $stitle"]
+ set cons [console::new [mc "Merge"] "merge $stitle"]
console::exec $cons $cmd [cb _finish $cons]
wm protocol $w WM_DELETE_WINDOW {}
@@ -128,9 +128,9 @@ method _start {} {
method _finish {cons ok} {
console::done $cons $ok
if {$ok} {
- set msg {Merge completed successfully.}
+ set msg [mc "Merge completed successfully."]
} else {
- set msg {Merge failed. Conflict resolution is required.}
+ set msg [mc "Merge failed. Conflict resolution is required."]
}
unlock_index
rescan [list ui_status $msg]
@@ -147,7 +147,7 @@ constructor dialog {} {
}
make_toplevel top w
- wm title $top "[appname] ([reponame]): Merge"
+ wm title $top [append "[appname] ([reponame]): " [mc "Merge"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
@@ -155,26 +155,26 @@ constructor dialog {} {
set _start [cb _start]
label $w.header \
- -text "Merge Into $current_branch" \
+ -text [mc "Merge Into %s" $current_branch] \
-font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
button $w.buttons.visualize \
- -text Visualize \
+ -text [mc Visualize] \
-command [cb _visualize]
pack $w.buttons.visualize -side left
button $w.buttons.merge \
- -text Merge \
+ -text [mc Merge] \
-command $_start
pack $w.buttons.merge -side right
button $w.buttons.cancel \
- -text {Cancel} \
+ -text [mc "Cancel"] \
-command [cb _cancel]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- set w_rev [::choose_rev::new_unmerged $w.rev {Revision To Merge}]
+ set w_rev [::choose_rev::new_unmerged $w.rev [mc "Revision To Merge"]]
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
bind $w <$M1B-Key-Return> $_start
@@ -209,34 +209,34 @@ proc reset_hard {} {
global HEAD commit_type file_states
if {[string match amend* $commit_type]} {
- info_popup {Cannot abort while amending.
+ info_popup [mc "Cannot abort while amending.
You must finish amending this commit.
-}
+"]
return
}
if {![lock_index abort]} return
if {[string match *merge* $commit_type]} {
- set op_question "Abort merge?
+ set op_question [mc "Abort merge?
Aborting the current merge will cause *ALL* uncommitted changes to be lost.
-Continue with aborting the current merge?"
+Continue with aborting the current merge?"]
} else {
- set op_question "Reset changes?
+ set op_question [mc "Reset changes?
Resetting the changes will cause *ALL* uncommitted changes to be lost.
-Continue with resetting the current changes?"
+Continue with resetting the current changes?"]
}
if {[ask_popup $op_question] eq {yes}} {
set fd [git_read --stderr read-tree --reset -u -v HEAD]
fconfigure $fd -blocking 0 -translation binary
fileevent $fd readable [namespace code [list _reset_wait $fd]]
- $::main_status start {Aborting} {files reset}
+ $::main_status start [mc "Aborting"] {files reset}
} else {
unlock_index
}
@@ -263,9 +263,9 @@ proc _reset_wait {fd} {
catch {file delete [gitdir GITGUI_MSG]}
if {$fail} {
- warn_popup "Abort failed.\n\n$err"
+ warn_popup "[mc "Abort failed."]\n\n$err"
}
- rescan {ui_status {Abort completed. Ready.}}
+ rescan {ui_status [mc "Abort completed. Ready."]}
} else {
fconfigure $fd -blocking 0
}
diff --git a/lib/option.tcl b/lib/option.tcl
index 063f5df..f812e5e 100644
--- a/lib/option.tcl
+++ b/lib/option.tcl
@@ -54,85 +54,6 @@ proc save_config {} {
}
}
-proc do_about {} {
- global appvers copyright oguilib
- global tcl_patchLevel tk_patchLevel
-
- set w .about_dialog
- toplevel $w
- wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
-
- label $w.header -text "About [appname]" \
- -font font_uibold
- pack $w.header -side top -fill x
-
- frame $w.buttons
- button $w.buttons.close -text {Close} \
- -default active \
- -command [list destroy $w]
- pack $w.buttons.close -side right
- pack $w.buttons -side bottom -fill x -pady 10 -padx 10
-
- label $w.desc \
- -text "git-gui - a graphical user interface for Git.
-$copyright" \
- -padx 5 -pady 5 \
- -justify left \
- -anchor w \
- -borderwidth 1 \
- -relief solid
- pack $w.desc -side top -fill x -padx 5 -pady 5
-
- set v {}
- append v "git-gui version $appvers\n"
- append v "[git version]\n"
- append v "\n"
- if {$tcl_patchLevel eq $tk_patchLevel} {
- append v "Tcl/Tk version $tcl_patchLevel"
- } else {
- append v "Tcl version $tcl_patchLevel"
- append v ", Tk version $tk_patchLevel"
- }
-
- set d {}
- append d "git wrapper: $::_git\n"
- append d "git exec dir: [gitexec]\n"
- append d "git-gui lib: $oguilib"
-
- label $w.vers \
- -text $v \
- -padx 5 -pady 5 \
- -justify left \
- -anchor w \
- -borderwidth 1 \
- -relief solid
- pack $w.vers -side top -fill x -padx 5 -pady 5
-
- label $w.dirs \
- -text $d \
- -padx 5 -pady 5 \
- -justify left \
- -anchor w \
- -borderwidth 1 \
- -relief solid
- pack $w.dirs -side top -fill x -padx 5 -pady 5
-
- menu $w.ctxm -tearoff 0
- $w.ctxm add command \
- -label {Copy} \
- -command "
- clipboard clear
- clipboard append -format STRING -type STRING -- \[$w.vers cget -text\]
- "
-
- bind $w <Visibility> "grab $w; focus $w.buttons.close"
- bind $w <Key-Escape> "destroy $w"
- bind $w <Key-Return> "destroy $w"
- bind_button3 $w.vers "tk_popup $w.ctxm %X %Y; grab $w; focus $w"
- wm title $w "About [appname]"
- tkwait window $w
-}
-
proc do_options {} {
global repo_config global_config font_descs
global repo_config_new global_config_new
@@ -157,48 +78,44 @@ proc do_options {} {
toplevel $w
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
- label $w.header -text "Options" \
- -font font_uibold
- pack $w.header -side top -fill x
-
frame $w.buttons
- button $w.buttons.restore -text {Restore Defaults} \
+ button $w.buttons.restore -text [mc "Restore Defaults"] \
-default normal \
-command do_restore_defaults
pack $w.buttons.restore -side left
- button $w.buttons.save -text Save \
+ button $w.buttons.save -text [mc Save] \
-default active \
-command [list do_save_config $w]
pack $w.buttons.save -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.cancel -text [mc "Cancel"] \
-default normal \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- labelframe $w.repo -text "[reponame] Repository"
- labelframe $w.global -text {Global (All Repositories)}
+ labelframe $w.repo -text [mc "%s Repository" [reponame]]
+ labelframe $w.global -text [mc "Global (All Repositories)"]
pack $w.repo -side left -fill both -expand 1 -pady 5 -padx 5
pack $w.global -side right -fill both -expand 1 -pady 5 -padx 5
set optid 0
foreach option {
- {t user.name {User Name}}
- {t user.email {Email Address}}
-
- {b merge.summary {Summarize Merge Commits}}
- {i-1..5 merge.verbosity {Merge Verbosity}}
- {b merge.diffstat {Show Diffstat After Merge}}
-
- {b gui.trustmtime {Trust File Modification Timestamps}}
- {b gui.pruneduringfetch {Prune Tracking Branches During Fetch}}
- {b gui.matchtrackingbranch {Match Tracking Branches}}
- {i-0..99 gui.diffcontext {Number of Diff Context Lines}}
- {t gui.newbranchtemplate {New Branch Name Template}}
+ {t user.name {mc "User Name"}}
+ {t user.email {mc "Email Address"}}
+
+ {b merge.summary {mc "Summarize Merge Commits"}}
+ {i-1..5 merge.verbosity {mc "Merge Verbosity"}}
+ {b merge.diffstat {mc "Show Diffstat After Merge"}}
+
+ {b gui.trustmtime {mc "Trust File Modification Timestamps"}}
+ {b gui.pruneduringfetch {mc "Prune Tracking Branches During Fetch"}}
+ {b gui.matchtrackingbranch {mc "Match Tracking Branches"}}
+ {i-0..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
+ {t gui.newbranchtemplate {mc "New Branch Name Template"}}
} {
set type [lindex $option 0]
set name [lindex $option 1]
- set text [lindex $option 2]
+ set text [eval [lindex $option 2]]
incr optid
foreach f {repo global} {
switch -glob -- $type {
@@ -246,7 +163,7 @@ proc do_options {} {
foreach option $font_descs {
set name [lindex $option 0]
set font [lindex $option 1]
- set text [lindex $option 2]
+ set text [eval [lindex $option 2]]
set global_config_new(gui.$font^^family) \
[font configure $font -family]
@@ -278,7 +195,13 @@ proc do_options {} {
bind $w <Visibility> "grab $w; focus $w.buttons.save"
bind $w <Key-Escape> "destroy $w"
bind $w <Key-Return> [list do_save_config $w]
- wm title $w "[appname] ([reponame]): Options"
+
+ if {[is_MacOSX]} {
+ set t [mc "Preferences"]
+ } else {
+ set t [mc "Options"]
+ }
+ wm title $w "[appname] ([reponame]): $t"
tkwait window $w
}
@@ -309,7 +232,7 @@ proc do_restore_defaults {} {
proc do_save_config {w} {
if {[catch {save_config} err]} {
- error_popup "Failed to completely save options:\n\n$err"
+ error_popup [strcat [mc "Failed to completely save options:"] "\n\n$err"]
}
reshow_diff
destroy $w
diff --git a/lib/remote.tcl b/lib/remote.tcl
index cf9b9d5..0e86dda 100644
--- a/lib/remote.tcl
+++ b/lib/remote.tcl
@@ -135,8 +135,10 @@ proc load_all_remotes {} {
proc populate_fetch_menu {} {
global all_remotes repo_config
- set m .mbar.fetch
- set prune_list [list]
+ set remote_m .mbar.remote
+ set fetch_m $remote_m.fetch
+ set prune_m $remote_m.prune
+
foreach r $all_remotes {
set enable 0
if {![catch {set a $repo_config(remote.$r.url)}]} {
@@ -157,28 +159,34 @@ proc populate_fetch_menu {} {
}
if {$enable} {
- lappend prune_list $r
- $m add command \
- -label "Fetch from $r..." \
+ if {![winfo exists $fetch_m]} {
+ menu $prune_m
+ $remote_m insert 0 cascade \
+ -label [mc "Prune from"] \
+ -menu $prune_m
+
+ menu $fetch_m
+ $remote_m insert 0 cascade \
+ -label [mc "Fetch from"] \
+ -menu $fetch_m
+ }
+
+ $fetch_m add command \
+ -label $r \
-command [list fetch_from $r]
+ $prune_m add command \
+ -label $r \
+ -command [list prune_from $r]
}
}
-
- if {$prune_list ne {}} {
- $m add separator
- }
- foreach r $prune_list {
- $m add command \
- -label "Prune from $r..." \
- -command [list prune_from $r]
- }
}
proc populate_push_menu {} {
global all_remotes repo_config
- set m .mbar.push
- set fast_count 0
+ set remote_m .mbar.remote
+ set push_m $remote_m.push
+
foreach r $all_remotes {
set enable 0
if {![catch {set a $repo_config(remote.$r.url)}]} {
@@ -199,13 +207,16 @@ proc populate_push_menu {} {
}
if {$enable} {
- if {!$fast_count} {
- $m add separator
+ if {![winfo exists $push_m]} {
+ menu $push_m
+ $remote_m insert 0 cascade \
+ -label [mc "Push to"] \
+ -menu $push_m
}
- $m add command \
- -label "Push to $r..." \
+
+ $push_m add command \
+ -label $r \
-command [list push_to $r]
- incr fast_count
}
}
}
diff --git a/lib/remote_branch_delete.tcl b/lib/remote_branch_delete.tcl
index c88a360..c7b8148 100644
--- a/lib/remote_branch_delete.tcl
+++ b/lib/remote_branch_delete.tcl
@@ -26,28 +26,28 @@ constructor dialog {} {
global all_remotes M1B
make_toplevel top w
- wm title $top "[appname] ([reponame]): Delete Remote Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Delete Remote Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
- label $w.header -text {Delete Remote Branch} -font font_uibold
+ label $w.header -text [mc "Delete Remote Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.delete -text Delete \
+ button $w.buttons.delete -text [mc Delete] \
-default active \
-command [cb _delete]
pack $w.buttons.delete -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.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
- labelframe $w.dest -text {From Repository}
+ labelframe $w.dest -text [mc "From Repository"]
if {$all_remotes ne {}} {
radiobutton $w.dest.remote_r \
- -text {Remote:} \
+ -text [mc "Remote:"] \
-value remote \
-variable @urltype
eval tk_optionMenu $w.dest.remote_m @remote $all_remotes
@@ -63,7 +63,7 @@ constructor dialog {} {
set urltype url
}
radiobutton $w.dest.url_r \
- -text {Arbitrary URL:} \
+ -text [mc "Arbitrary URL:"] \
-value url \
-variable @urltype
entry $w.dest.url_t \
@@ -81,7 +81,7 @@ constructor dialog {} {
grid columnconfigure $w.dest 1 -weight 1
pack $w.dest -anchor nw -fill x -pady 5 -padx 5
- labelframe $w.heads -text {Branches}
+ labelframe $w.heads -text [mc "Branches"]
listbox $w.heads.l \
-height 10 \
-width 70 \
@@ -96,7 +96,7 @@ constructor dialog {} {
-anchor w \
-justify left
button $w.heads.footer.rescan \
- -text {Rescan} \
+ -text [mc "Rescan"] \
-command [cb _rescan]
pack $w.heads.footer.status -side left -fill x
pack $w.heads.footer.rescan -side right
@@ -106,9 +106,9 @@ constructor dialog {} {
pack $w.heads.l -side left -fill both -expand 1
pack $w.heads -fill both -expand 1 -pady 5 -padx 5
- labelframe $w.validate -text {Delete Only If}
+ labelframe $w.validate -text [mc "Delete Only If"]
radiobutton $w.validate.head_r \
- -text {Merged Into:} \
+ -text [mc "Merged Into:"] \
-value head \
-variable @checktype
set head_m [tk_optionMenu $w.validate.head_m @check_head {}]
@@ -116,7 +116,7 @@ constructor dialog {} {
trace add variable @check_head write [cb _write_check_head]
grid $w.validate.head_r $w.validate.head_m -sticky w
radiobutton $w.validate.always_r \
- -text {Always (Do not perform merge checks)} \
+ -text [mc "Always (Do not perform merge checks)"] \
-value always \
-variable @checktype
grid $w.validate.always_r -columnspan 2 -sticky w
@@ -149,7 +149,7 @@ method _delete {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "A branch is required for 'Merged Into'."
+ -message [mc "A branch is required for 'Merged Into'."]
return
}
set crev $full_cache("$cache\nrefs/heads/$check_head")
@@ -181,14 +181,12 @@ method _delete {} {
}
if {$not_merged ne {}} {
- set msg "The following branches are not completely merged into $check_head:
+ set msg [mc "The following branches are not completely merged into %s:
- - [join $not_merged "\n - "]"
+ - %s" $check_head [join $not_merged "\n - "]]
if {$need_fetch} {
- append msg "
-
-One or more of the merge tests failed because you have not fetched the necessary commits. Try fetching from $uri first."
+ append msg "\n\n" [mc "One or more of the merge tests failed because you have not fetched the necessary commits. Try fetching from %s first." $uri]
}
tk_messageBox \
@@ -206,7 +204,7 @@ One or more of the merge tests failed because you have not fetched the necessary
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please select one or more branches to delete."
+ -message [mc "Please select one or more branches to delete."]
return
}
@@ -215,9 +213,9 @@ One or more of the merge tests failed because you have not fetched the necessary
-type yesno \
-title [wm title $w] \
-parent $w \
- -message {Recovering deleted branches is difficult.
+ -message [mc "Recovering deleted branches is difficult.
-Delete the selected branches?}] ne yes} {
+Delete the selected branches?"]] ne yes} {
return
}
@@ -225,7 +223,7 @@ Delete the selected branches?}] ne yes} {
set cons [console::new \
"push $uri" \
- "Deleting branches from $uri"]
+ [mc "Deleting branches from %s" $uri]]
console::exec $cons $push_cmd
}
@@ -285,12 +283,12 @@ method _load {cache uri} {
$w.heads.l conf -state disabled
set head_list [list]
set full_list [list]
- set status {No repository selected.}
+ set status [mc "No repository selected."]
return
}
if {[catch {set x $cached($cache)}]} {
- set status "Scanning $uri..."
+ set status [mc "Scanning %s..." $uri]
$w.heads.l conf -state disabled
set head_list [list]
set full_list [list]
diff --git a/lib/shortcut.tcl b/lib/shortcut.tcl
index c36be2f..38c3151 100644
--- a/lib/shortcut.tcl
+++ b/lib/shortcut.tcl
@@ -2,28 +2,22 @@
# Copyright (C) 2006, 2007 Shawn Pearce
proc do_windows_shortcut {} {
- global argv0
-
set fn [tk_getSaveFile \
-parent . \
- -title "[appname] ([reponame]): Create Desktop Icon" \
- -initialfile "Git [reponame].bat"]
+ -title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
+ -initialfile "Git [reponame].lnk"]
if {$fn != {}} {
- if {[file extension $fn] ne {.bat}} {
- set fn ${fn}.bat
+ if {[file extension $fn] ne {.lnk}} {
+ set fn ${fn}.lnk
}
if {[catch {
- set ge [file normalize [file dirname $::_git]]
- set fd [open $fn w]
- puts $fd "@ECHO Entering [reponame]"
- puts $fd "@ECHO Starting git-gui... please wait..."
- puts $fd "@SET PATH=$ge;%PATH%"
- puts $fd "@SET GIT_DIR=[file normalize [gitdir]]"
- puts -nonewline $fd "@\"[info nameofexecutable]\""
- puts $fd " \"[file normalize $argv0]\""
- close $fd
+ win32_create_lnk $fn [list \
+ [info nameofexecutable] \
+ [file normalize $::argv0] \
+ ] \
+ [file dirname [file normalize [gitdir]]]
} err]} {
- error_popup "Cannot write script:\n\n$err"
+ error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
}
}
}
@@ -42,15 +36,14 @@ proc do_cygwin_shortcut {} {
}
set fn [tk_getSaveFile \
-parent . \
- -title "[appname] ([reponame]): Create Desktop Icon" \
+ -title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
-initialdir $desktop \
- -initialfile "Git [reponame].bat"]
+ -initialfile "Git [reponame].lnk"]
if {$fn != {}} {
- if {[file extension $fn] ne {.bat}} {
- set fn ${fn}.bat
+ if {[file extension $fn] ne {.lnk}} {
+ set fn ${fn}.lnk
}
if {[catch {
- set fd [open $fn w]
set sh [exec cygpath \
--windows \
--absolute \
@@ -59,19 +52,13 @@ proc do_cygwin_shortcut {} {
--unix \
--absolute \
$argv0]
- set gd [exec cygpath \
- --unix \
- --absolute \
- [gitdir]]
- puts $fd "@ECHO Entering [reponame]"
- puts $fd "@ECHO Starting git-gui... please wait..."
- puts -nonewline $fd "@\"$sh\" --login -c \""
- puts -nonewline $fd "GIT_DIR=[sq $gd]"
- puts -nonewline $fd " [sq $me]"
- puts $fd " &\""
- close $fd
+ win32_create_lnk $fn [list \
+ $sh -c \
+ "CHERE_INVOKING=1 source /etc/profile;[sq $me]" \
+ ] \
+ [file dirname [file normalize [gitdir]]]
} err]} {
- error_popup "Cannot write script:\n\n$err"
+ error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
}
}
}
@@ -81,7 +68,7 @@ proc do_macosx_app {} {
set fn [tk_getSaveFile \
-parent . \
- -title "[appname] ([reponame]): Create Desktop Icon" \
+ -title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
-initialdir [file join $env(HOME) Desktop] \
-initialfile "Git [reponame].app"]
if {$fn != {}} {
@@ -146,7 +133,7 @@ proc do_macosx_app {} {
file attributes $exe -permissions u+x,g+x,o+x
} err]} {
- error_popup "Cannot write icon:\n\n$err"
+ error_popup [strcat [mc "Cannot write icon:"] "\n\n$err"]
}
}
}
diff --git a/lib/status_bar.tcl b/lib/status_bar.tcl
index 3bf79eb..51d4177 100644
--- a/lib/status_bar.tcl
+++ b/lib/status_bar.tcl
@@ -6,6 +6,7 @@ class status_bar {
field w ; # our own window path
field w_l ; # text widget we draw messages into
field w_c ; # canvas we draw a progress bar into
+field c_pack ; # script to pack the canvas with
field status {}; # single line of text we show
field prefix {}; # text we format into status
field units {}; # unit of progress
@@ -24,6 +25,29 @@ constructor new {path} {
-anchor w \
-justify left
pack $w_l -side left
+ set c_pack [cb _oneline_pack]
+
+ bind $w <Destroy> [cb _delete %W]
+ return $this
+}
+
+method _oneline_pack {} {
+ $w_c conf -width 100
+ pack $w_c -side right
+}
+
+constructor two_line {path} {
+ set w $path
+ set w_l $w.l
+ set w_c $w.c
+
+ frame $w
+ label $w_l \
+ -textvariable @status \
+ -anchor w \
+ -justify left
+ pack $w_l -anchor w -fill x
+ set c_pack [list pack $w_c -fill x]
bind $w <Destroy> [cb _delete %W]
return $this
@@ -34,13 +58,12 @@ method start {msg uds} {
$w_c coords bar 0 0 0 20
} else {
canvas $w_c \
- -width 100 \
-height [expr {int([winfo reqheight $w_l] * 0.6)}] \
-borderwidth 1 \
-relief groove \
-highlightt 0
$w_c create rectangle 0 0 0 20 -tags bar -fill navy
- pack $w_c -side right
+ eval $c_pack
}
set status $msg
@@ -53,11 +76,16 @@ method update {have total} {
set pdone 0
if {$total > 0} {
set pdone [expr {100 * $have / $total}]
+ set cdone [expr {[winfo width $w_c] * $have / $total}]
}
- set status [format "%s ... %i of %i %s (%2i%%)" \
- $prefix $have $total $units $pdone]
- $w_c coords bar 0 0 $pdone 20
+ set prec [string length [format %i $total]]
+ set status [mc "%s ... %*i of %*i %s (%3i%%)" \
+ $prefix \
+ $prec $have \
+ $prec $total \
+ $units $pdone]
+ $w_c coords bar 0 0 $cdone 20
}
method update_meter {buf} {
diff --git a/lib/transport.tcl b/lib/transport.tcl
index 3a22bd4..8e6a9d0 100644
--- a/lib/transport.tcl
+++ b/lib/transport.tcl
@@ -3,8 +3,8 @@
proc fetch_from {remote} {
set w [console::new \
- "fetch $remote" \
- "Fetching new changes from $remote"]
+ [mc "fetch %s" $remote] \
+ [mc "Fetching new changes from %s" $remote]]
set cmds [list]
lappend cmds [list exec git fetch $remote]
if {[is_config_true gui.pruneduringfetch]} {
@@ -15,15 +15,15 @@ proc fetch_from {remote} {
proc prune_from {remote} {
set w [console::new \
- "remote prune $remote" \
- "Pruning tracking branches deleted from $remote"]
+ [mc "remote prune %s" $remote] \
+ [mc "Pruning tracking branches deleted from %s" $remote]]
console::exec $w [list git remote prune $remote]
}
proc push_to {remote} {
set w [console::new \
- "push $remote" \
- "Pushing changes to $remote"]
+ [mc "push %s" $remote] \
+ [mc "Pushing changes to %s" $remote]]
set cmd [list git push]
lappend cmd -v
lappend cmd $remote
@@ -32,6 +32,7 @@ proc push_to {remote} {
proc start_push_anywhere_action {w} {
global push_urltype push_remote push_url push_thin push_tags
+ global push_force
set r_url {}
switch -- $push_urltype {
@@ -45,6 +46,9 @@ proc start_push_anywhere_action {w} {
if {$push_thin} {
lappend cmd --thin
}
+ if {$push_force} {
+ lappend cmd --force
+ }
if {$push_tags} {
lappend cmd --tags
}
@@ -64,8 +68,8 @@ proc start_push_anywhere_action {w} {
}
set cons [console::new \
- "push $r_url" \
- "Pushing $cnt $unit to $r_url"]
+ [mc "push %s" $r_url] \
+ [mc "Pushing %s %s to %s" $cnt $unit $r_url]]
console::exec $cons $cmd
destroy $w
}
@@ -76,26 +80,27 @@ trace add variable push_remote write \
proc do_push_anywhere {} {
global all_remotes current_branch
global push_urltype push_remote push_url push_thin push_tags
+ global push_force
set w .push_setup
toplevel $w
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
- label $w.header -text {Push Branches} -font font_uibold
+ label $w.header -text [mc "Push Branches"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.create -text Push \
+ button $w.buttons.create -text [mc Push] \
-default active \
-command [list start_push_anywhere_action $w]
pack $w.buttons.create -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.cancel -text [mc "Cancel"] \
-default normal \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- labelframe $w.source -text {Source Branches}
+ labelframe $w.source -text [mc "Source Branches"]
listbox $w.source.l \
-height 10 \
-width 70 \
@@ -112,10 +117,10 @@ proc do_push_anywhere {} {
pack $w.source.l -side left -fill both -expand 1
pack $w.source -fill both -expand 1 -pady 5 -padx 5
- labelframe $w.dest -text {Destination Repository}
+ labelframe $w.dest -text [mc "Destination Repository"]
if {$all_remotes ne {}} {
radiobutton $w.dest.remote_r \
- -text {Remote:} \
+ -text [mc "Remote:"] \
-value remote \
-variable push_urltype
eval tk_optionMenu $w.dest.remote_m push_remote $all_remotes
@@ -130,7 +135,7 @@ proc do_push_anywhere {} {
set push_urltype url
}
radiobutton $w.dest.url_r \
- -text {Arbitrary URL:} \
+ -text [mc "Arbitrary URL:"] \
-value url \
-variable push_urltype
entry $w.dest.url_t \
@@ -150,25 +155,30 @@ proc do_push_anywhere {} {
grid columnconfigure $w.dest 1 -weight 1
pack $w.dest -anchor nw -fill x -pady 5 -padx 5
- labelframe $w.options -text {Transfer Options}
+ labelframe $w.options -text [mc "Transfer Options"]
+ checkbutton $w.options.force \
+ -text [mc "Force overwrite existing branch (may discard changes)"] \
+ -variable push_force
+ grid $w.options.force -columnspan 2 -sticky w
checkbutton $w.options.thin \
- -text {Use thin pack (for slow network connections)} \
+ -text [mc "Use thin pack (for slow network connections)"] \
-variable push_thin
grid $w.options.thin -columnspan 2 -sticky w
checkbutton $w.options.tags \
- -text {Include tags} \
+ -text [mc "Include tags"] \
-variable push_tags
grid $w.options.tags -columnspan 2 -sticky w
grid columnconfigure $w.options 1 -weight 1
pack $w.options -anchor nw -fill x -pady 5 -padx 5
set push_url {}
+ set push_force 0
set push_thin 0
set push_tags 0
bind $w <Visibility> "grab $w; focus $w.buttons.create"
bind $w <Key-Escape> "destroy $w"
bind $w <Key-Return> [list start_push_anywhere_action $w]
- wm title $w "[appname] ([reponame]): Push"
+ wm title $w [append "[appname] ([reponame]): " [mc "Push"]]
tkwait window $w
}
diff --git a/lib/win32.tcl b/lib/win32.tcl
new file mode 100644
index 0000000..d7f93d0
--- /dev/null
+++ b/lib/win32.tcl
@@ -0,0 +1,26 @@
+# git-gui Misc. native Windows 32 support
+# Copyright (C) 2007 Shawn Pearce
+
+proc win32_read_lnk {lnk_path} {
+ return [exec cscript.exe \
+ /E:jscript \
+ /nologo \
+ [file join $::oguilib win32_shortcut.js] \
+ $lnk_path]
+}
+
+proc win32_create_lnk {lnk_path lnk_exec lnk_dir} {
+ global oguilib
+
+ set lnk_args [lrange $lnk_exec 1 end]
+ set lnk_exec [lindex $lnk_exec 0]
+
+ eval [list exec wscript.exe \
+ /E:jscript \
+ /nologo \
+ [file join $oguilib win32_shortcut.js] \
+ $lnk_path \
+ [file join $oguilib git-gui.ico] \
+ $lnk_dir \
+ $lnk_exec] $lnk_args
+}
diff --git a/lib/win32_shortcut.js b/lib/win32_shortcut.js
new file mode 100644
index 0000000..117923f
--- /dev/null
+++ b/lib/win32_shortcut.js
@@ -0,0 +1,34 @@
+// git-gui Windows shortcut support
+// Copyright (C) 2007 Shawn Pearce
+
+var WshShell = WScript.CreateObject("WScript.Shell");
+var argv = WScript.Arguments;
+var argi = 0;
+var lnk_path = argv.item(argi++);
+var ico_path = argi < argv.length ? argv.item(argi++) : undefined;
+var dir_path = argi < argv.length ? argv.item(argi++) : undefined;
+var lnk_exec = argi < argv.length ? argv.item(argi++) : undefined;
+var lnk_args = '';
+while (argi < argv.length) {
+ var s = argv.item(argi++);
+ if (lnk_args != '')
+ lnk_args += ' ';
+ if (s.indexOf(' ') >= 0) {
+ lnk_args += '"';
+ lnk_args += s;
+ lnk_args += '"';
+ } else {
+ lnk_args += s;
+ }
+}
+
+var lnk = WshShell.CreateShortcut(lnk_path);
+if (argv.length == 1) {
+ WScript.echo(lnk.TargetPath);
+} else {
+ lnk.TargetPath = lnk_exec;
+ lnk.Arguments = lnk_args;
+ lnk.IconLocation = ico_path + ", 0";
+ lnk.WorkingDirectory = dir_path;
+ lnk.Save();
+}