Merge git://repo.or.cz/git-gui

* git://repo.or.cz/git-gui: (27 commits)
  git-gui: Update German translation.
  git-gui: Do not munge conflict marker lines in a normal diff
  git-gui: Add a simple implementation of SSH_ASKPASS.
  git-gui: Add a dialog that shows the OpenSSH public key.
  git-gui: Mark-up strings in show_{other,unmerged}_diff() for localization
  git-gui: Show a round number of bytes of large untracked text files
  git-gui: Fix the blame viewer destroy handler.
  git-gui: Add a search command to the blame viewer.
  git-gui: Fix the blame window shape.
  git-gui: Fix switch statement in lib/merge.tcl
  git-gui: Fix fetching from remotes when adding them
  git-gui: Fix removing non-pushable remotes
  git-gui: Make input boxes in init/clone/open dialogs consistent
  git-gui: Avoid using the term URL when specifying repositories
  git-gui: gui.autoexplore makes explorer to pop up automatically after picking
  git-gui: Add Explore Working Copy to the Repository menu
  git-gui: Use git web--browser for web browsing
  git-gui: mkdir -p when initializing new remote repository
  git-gui: Add support for removing remotes
  git-gui: Add support for adding remotes
  ...
This commit is contained in:
Junio C Hamano 2008-11-01 22:31:46 -07:00
commit f6576f4c0c
17 changed files with 1084 additions and 194 deletions

View File

@ -285,6 +285,7 @@ all:: $(GITGUI_MAIN) lib/tclIndex $(ALL_MSGFILES)
install: all install: all
$(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL_D1) $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL_D1)
$(QUIET)$(INSTALL_X0)git-gui $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(QUIET)$(INSTALL_X0)git-gui $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(QUIET)$(INSTALL_X0)git-gui--askpass $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(INSTALL_L0)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L1)'$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' $(INSTALL_L2)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L3) &&) true $(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(INSTALL_L0)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L1)'$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' $(INSTALL_L2)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L3) &&) true
ifdef GITGUI_WINDOWS_WRAPPER ifdef GITGUI_WINDOWS_WRAPPER
$(QUIET)$(INSTALL_R0)git-gui.tcl $(INSTALL_R1) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(QUIET)$(INSTALL_R0)git-gui.tcl $(INSTALL_R1) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
@ -302,6 +303,7 @@ endif
uninstall: uninstall:
$(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui $(REMOVE_F1) $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui $(REMOVE_F1)
$(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui--askpass $(REMOVE_F1)
$(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/$p $(REMOVE_F1) &&) true $(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/$p $(REMOVE_F1) &&) true
ifdef GITGUI_WINDOWS_WRAPPER ifdef GITGUI_WINDOWS_WRAPPER
$(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui.tcl $(REMOVE_F1) $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui.tcl $(REMOVE_F1)

59
git-gui/git-gui--askpass Executable file
View File

@ -0,0 +1,59 @@
#!/bin/sh
# Tcl ignores the next line -*- tcl -*- \
exec wish "$0" -- "$@"
# This is a trivial implementation of an SSH_ASKPASS handler.
# Git-gui uses this script if none are already configured.
set answer {}
set yesno 0
set rc 255
if {$argc < 1} {
set prompt "Enter your OpenSSH passphrase:"
} else {
set prompt [join $argv " "]
if {[regexp -nocase {\(yes\/no\)\?\s*$} $prompt]} {
set yesno 1
}
}
message .m -text $prompt -justify center -aspect 4000
pack .m -side top -fill x -padx 20 -pady 20 -expand 1
entry .e -textvariable answer -width 50
pack .e -side top -fill x -padx 10 -pady 10
if {!$yesno} {
.e configure -show "*"
}
frame .b
button .b.ok -text OK -command finish
button .b.cancel -text Cancel -command {destroy .}
pack .b.ok -side left -expand 1
pack .b.cancel -side right -expand 1
pack .b -side bottom -fill x -padx 10 -pady 10
bind . <Visibility> {focus -force .e}
bind . <Key-Return> finish
bind . <Key-Escape> {destroy .}
bind . <Destroy> {exit $rc}
proc finish {} {
if {$::yesno} {
if {$::answer ne "yes" && $::answer ne "no"} {
tk_messageBox -icon error -title "Error" -type ok \
-message "Only 'yes' or 'no' input allowed."
return
}
}
set ::rc 0
puts $::answer
destroy .
}
wm title . "OpenSSH"
tk::PlaceWindow .

View File

@ -591,6 +591,12 @@ bind . <Visibility> {
if {[is_Windows]} { if {[is_Windows]} {
wm iconbitmap . -default $oguilib/git-gui.ico wm iconbitmap . -default $oguilib/git-gui.ico
set ::tk::AlwaysShowSelection 1
# Spoof an X11 display for SSH
if {![info exists env(DISPLAY)]} {
set env(DISPLAY) :9999
}
} }
###################################################################### ######################################################################
@ -995,6 +1001,7 @@ citool {
## ##
## repository setup ## repository setup
set picked 0
if {[catch { if {[catch {
set _gitdir $env(GIT_DIR) set _gitdir $env(GIT_DIR)
set _prefix {} set _prefix {}
@ -1006,6 +1013,7 @@ if {[catch {
load_config 1 load_config 1
apply_config apply_config
choose_repository::pick choose_repository::pick
set picked 1
} }
if {![file isdirectory $_gitdir] && [is_Cygwin]} { if {![file isdirectory $_gitdir] && [is_Cygwin]} {
catch {set _gitdir [exec cygpath --windows $_gitdir]} catch {set _gitdir [exec cygpath --windows $_gitdir]}
@ -1065,6 +1073,15 @@ set selected_commit_type new
set nullid "0000000000000000000000000000000000000000" set nullid "0000000000000000000000000000000000000000"
set nullid2 "0000000000000000000000000000000000000001" set nullid2 "0000000000000000000000000000000000000001"
set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
######################################################################
# Suggest our implementation of askpass, if none is set
if {![info exists env(SSH_ASKPASS)]} {
set env(SSH_ASKPASS) [gitexec git-gui--askpass]
}
###################################################################### ######################################################################
## ##
## task management ## task management
@ -1869,6 +1886,19 @@ proc do_gitk {revs} {
} }
} }
proc do_explore {} {
set explorer {}
if {[is_Cygwin] || [is_Windows]} {
set explorer "explorer.exe"
} elseif {[is_MacOSX]} {
set explorer "open"
} else {
# freedesktop.org-conforming system is our best shot
set explorer "xdg-open"
}
eval exec $explorer [file dirname [gitdir]] &
}
set is_quitting 0 set is_quitting 0
set ret_code 1 set ret_code 1
@ -2090,7 +2120,9 @@ proc toggle_or_diff {w x y} {
if {$col == 0 && $y > 1} { if {$col == 0 && $y > 1} {
# Conflicts need special handling # Conflicts need special handling
if {[string first {U} $state] >= 0} { if {[string first {U} $state] >= 0} {
merge_stage_workdir $path $w $lno # $w must always be $ui_workdir, but...
if {$w ne $ui_workdir} { set lno {} }
merge_stage_workdir $path $lno
return return
} }
@ -2218,6 +2250,11 @@ if {[is_enabled transport]} {
# #
menu .mbar.repository menu .mbar.repository
.mbar.repository add command \
-label [mc "Explore Working Copy"] \
-command {do_explore}
.mbar.repository add separator
.mbar.repository add command \ .mbar.repository add command \
-label [mc "Browse Current Branch's Files"] \ -label [mc "Browse Current Branch's Files"] \
-command {browser::new $current_branch} -command {browser::new $current_branch}
@ -2413,7 +2450,7 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
.mbar.commit add separator .mbar.commit add separator
if {![is_enabled nocommit]} { if {![is_enabled nocommitmsg]} {
.mbar.commit add command -label [mc "Sign Off"] \ .mbar.commit add command -label [mc "Sign Off"] \
-command do_signoff \ -command do_signoff \
-accelerator $M1T-S -accelerator $M1T-S
@ -2446,12 +2483,16 @@ if {[is_enabled branch]} {
if {[is_enabled transport]} { if {[is_enabled transport]} {
menu .mbar.remote menu .mbar.remote
.mbar.remote add command \
-label [mc "Add..."] \
-command remote_add::dialog \
-accelerator $M1T-A
.mbar.remote add command \ .mbar.remote add command \
-label [mc "Push..."] \ -label [mc "Push..."] \
-command do_push_anywhere \ -command do_push_anywhere \
-accelerator $M1T-P -accelerator $M1T-P
.mbar.remote add command \ .mbar.remote add command \
-label [mc "Delete..."] \ -label [mc "Delete Branch..."] \
-command remote_branch_delete::dialog -command remote_branch_delete::dialog
} }
@ -2487,8 +2528,7 @@ if {![is_MacOSX]} {
-command do_about -command do_about
} }
set browser {}
catch {set browser $repo_config(instaweb.browser)}
set doc_path [file dirname [gitexec]] set doc_path [file dirname [gitexec]]
set doc_path [file join $doc_path Documentation index.html] set doc_path [file join $doc_path Documentation index.html]
@ -2496,34 +2536,23 @@ if {[is_Cygwin]} {
set doc_path [exec cygpath --mixed $doc_path] set doc_path [exec cygpath --mixed $doc_path]
} }
if {$browser eq {}} {
if {[is_MacOSX]} {
set browser open
} elseif {[is_Cygwin]} {
set program_files [file dirname [exec cygpath --windir]]
set program_files [file join $program_files {Program Files}]
set firefox [file join $program_files {Mozilla Firefox} firefox.exe]
set ie [file join $program_files {Internet Explorer} IEXPLORE.EXE]
if {[file exists $firefox]} {
set browser $firefox
} elseif {[file exists $ie]} {
set browser $ie
}
unset program_files firefox ie
}
}
if {[file isfile $doc_path]} { if {[file isfile $doc_path]} {
set doc_url "file:$doc_path" set doc_url "file:$doc_path"
} else { } else {
set doc_url {http://www.kernel.org/pub/software/scm/git/docs/} set doc_url {http://www.kernel.org/pub/software/scm/git/docs/}
} }
if {$browser ne {}} { proc start_browser {url} {
.mbar.help add command -label [mc "Online Documentation"] \ git "web--browse" $url
-command [list exec $browser $doc_url &]
} }
unset browser doc_path doc_url
.mbar.help add command -label [mc "Online Documentation"] \
-command [list start_browser $doc_url]
.mbar.help add command -label [mc "Show SSH Key"] \
-command do_ssh_key
unset doc_path doc_url
# -- Standard bindings # -- Standard bindings
# #
@ -2743,7 +2772,7 @@ pack .vpane.lower.commarea.buttons.incall -side top -fill x
lappend disable_on_lock \ lappend disable_on_lock \
{.vpane.lower.commarea.buttons.incall conf -state} {.vpane.lower.commarea.buttons.incall conf -state}
if {![is_enabled nocommit]} { if {![is_enabled nocommitmsg]} {
button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \ button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \
-command do_signoff -command do_signoff
pack .vpane.lower.commarea.buttons.signoff -side top -fill x pack .vpane.lower.commarea.buttons.signoff -side top -fill x
@ -3261,8 +3290,7 @@ if {[is_enabled transport]} {
load_all_remotes load_all_remotes
set n [.mbar.remote index end] set n [.mbar.remote index end]
populate_push_menu populate_remotes_menu
populate_fetch_menu
set n [expr {[.mbar.remote index end] - $n}] set n [expr {[.mbar.remote index end] - $n}]
if {$n > 0} { if {$n > 0} {
if {[.mbar.remote type 0] eq "tearoff"} { incr n } if {[.mbar.remote type 0] eq "tearoff"} { incr n }
@ -3369,3 +3397,6 @@ if {[is_enabled multicommit]} {
if {[is_enabled retcode]} { if {[is_enabled retcode]} {
bind . <Destroy> {+terminate_me %W} bind . <Destroy> {+terminate_me %W}
} }
if {$picked && [is_config_true gui.autoexplore]} {
do_explore
}

View File

@ -21,9 +21,11 @@ field w_amov ; # text column: annotations + move tracking
field w_asim ; # text column: annotations (simple computation) field w_asim ; # text column: annotations (simple computation)
field w_file ; # text column: actual file data field w_file ; # text column: actual file data
field w_cviewer ; # pane showing commit message field w_cviewer ; # pane showing commit message
field finder ; # find mini-dialog frame
field status ; # status mega-widget instance field status ; # status mega-widget instance
field old_height ; # last known height of $w.file_pane field old_height ; # last known height of $w.file_pane
# Tk UI colors # Tk UI colors
# #
variable active_color #c0edc5 variable active_color #c0edc5
@ -59,7 +61,7 @@ field tooltip_timer {} ; # Current timer event for our tooltip
field tooltip_commit {} ; # Commit(s) in tooltip field tooltip_commit {} ; # Commit(s) in tooltip
constructor new {i_commit i_path i_jump} { constructor new {i_commit i_path i_jump} {
global cursor_ptr global cursor_ptr M1B M1T have_tk85
variable active_color variable active_color
variable group_colors variable group_colors
@ -69,6 +71,8 @@ constructor new {i_commit i_path i_jump} {
make_toplevel top w make_toplevel top w
wm title $top [append "[appname] ([reponame]): " [mc "File Viewer"]] wm title $top [append "[appname] ([reponame]): " [mc "File Viewer"]]
set font_w [font measure font_diff "0"]
frame $w.header -background gold frame $w.header -background gold
label $w.header.commit_l \ label $w.header.commit_l \
-text [mc "Commit:"] \ -text [mc "Commit:"] \
@ -114,9 +118,9 @@ constructor new {i_commit i_path i_jump} {
pack $w_path -fill x -side right pack $w_path -fill x -side right
pack $w.header.path_l -side right pack $w.header.path_l -side right
panedwindow $w.file_pane -orient vertical panedwindow $w.file_pane -orient vertical -borderwidth 0 -sashwidth 3
frame $w.file_pane.out frame $w.file_pane.out -relief flat -borderwidth 1
frame $w.file_pane.cm frame $w.file_pane.cm -relief sunken -borderwidth 1
$w.file_pane add $w.file_pane.out \ $w.file_pane add $w.file_pane.out \
-sticky nsew \ -sticky nsew \
-minsize 100 \ -minsize 100 \
@ -197,6 +201,11 @@ constructor new {i_commit i_path i_jump} {
-width 80 \ -width 80 \
-xscrollcommand [list $w.file_pane.out.sbx set] \ -xscrollcommand [list $w.file_pane.out.sbx set] \
-font font_diff -font font_diff
if {$have_tk85} {
$w_file configure -inactiveselectbackground darkblue
}
$w_file tag conf found \
-background yellow
set w_columns [list $w_amov $w_asim $w_line $w_file] set w_columns [list $w_amov $w_asim $w_line $w_file]
@ -217,6 +226,11 @@ constructor new {i_commit i_path i_jump} {
-weight 1 -weight 1
grid rowconfigure $w.file_pane.out 0 -weight 1 grid rowconfigure $w.file_pane.out 0 -weight 1
set finder [::searchbar::new \
$w.file_pane.out.ff $w_file \
-column [expr {[llength $w_columns] - 1}] \
]
set w_cviewer $w.file_pane.cm.t set w_cviewer $w.file_pane.cm.t
text $w_cviewer \ text $w_cviewer \
-background white \ -background white \
@ -257,6 +271,10 @@ constructor new {i_commit i_path i_jump} {
-label [mc "Copy Commit"] \ -label [mc "Copy Commit"] \
-command [cb _copycommit] -command [cb _copycommit]
$w.ctxm add separator $w.ctxm add separator
$w.ctxm add command \
-label [mc "Find Text..."] \
-accelerator F7 \
-command [list searchbar::show $finder]
menu $w.ctxm.enc menu $w.ctxm.enc
build_encoding_menu $w.ctxm.enc [cb _setencoding] build_encoding_menu $w.ctxm.enc [cb _setencoding]
$w.ctxm add cascade \ $w.ctxm add cascade \
@ -278,9 +296,15 @@ constructor new {i_commit i_path i_jump} {
$i tag conf color$g -background [lindex $group_colors $g] $i tag conf color$g -background [lindex $group_colors $g]
} }
if {$i eq $w_file} {
$w_file tag raise found
}
$i tag raise sel
$i conf -cursor $cursor_ptr $i conf -cursor $cursor_ptr
$i conf -yscrollcommand [list many2scrollbar \ $i conf -yscrollcommand \
$w_columns yview $w.file_pane.out.sby] "[list ::searchbar::scrolled $finder]
[list many2scrollbar $w_columns yview $w.file_pane.out.sby]"
bind $i <Button-1> " bind $i <Button-1> "
[cb _hide_tooltip] [cb _hide_tooltip]
[cb _click $i @%x,%y] [cb _click $i @%x,%y]
@ -317,6 +341,11 @@ constructor new {i_commit i_path i_jump} {
bind $w_cviewer <Tab> "[list focus $w_file];break" bind $w_cviewer <Tab> "[list focus $w_file];break"
bind $w_cviewer <Button-1> [list focus $w_cviewer] bind $w_cviewer <Button-1> [list focus $w_cviewer]
bind $w_file <Visibility> [list focus $w_file] bind $w_file <Visibility> [list focus $w_file]
bind $top <F7> [list searchbar::show $finder]
bind $top <Escape> [list searchbar::hide $finder]
bind $top <F3> [list searchbar::find_next $finder]
bind $top <Shift-F3> [list searchbar::find_prev $finder]
catch { bind $top <Shift-Key-XF86_Switch_VT_3> [list searchbar::find_prev $finder] }
grid configure $w.header -sticky ew grid configure $w.header -sticky ew
grid configure $w.file_pane -sticky nsew grid configure $w.file_pane -sticky nsew
@ -328,9 +357,14 @@ constructor new {i_commit i_path i_jump} {
set req_w [winfo reqwidth $top] set req_w [winfo reqwidth $top]
set req_h [winfo reqheight $top] set req_h [winfo reqheight $top]
set scr_h [expr {[winfo screenheight $top] - 100}] set scr_w [expr {[winfo screenwidth $top] - 40}]
if {$req_w < 600} {set req_w 600} set scr_h [expr {[winfo screenheight $top] - 120}]
set opt_w [expr {$font_w * (80 + 5*3 + 3)}]
if {$req_w < $opt_w} {set req_w $opt_w}
if {$req_w > $scr_w} {set req_w $scr_w}
set opt_h [expr {$req_w*4/3}]
if {$req_h < $scr_h} {set req_h $scr_h} if {$req_h < $scr_h} {set req_h $scr_h}
if {$req_h > $opt_h} {set req_h $opt_h}
set g "${req_w}x${req_h}" set g "${req_w}x${req_h}"
wm geometry $top $g wm geometry $top $g
update update
@ -338,16 +372,23 @@ constructor new {i_commit i_path i_jump} {
set old_height [winfo height $w.file_pane] set old_height [winfo height $w.file_pane]
$w.file_pane sash place 0 \ $w.file_pane sash place 0 \
[lindex [$w.file_pane sash coord 0] 0] \ [lindex [$w.file_pane sash coord 0] 0] \
[expr {int($old_height * 0.70)}] [expr {int($old_height * 0.80)}]
bind $w.file_pane <Configure> \ bind $w.file_pane <Configure> \
"if {{$w.file_pane} eq {%W}} {[cb _resize %h]}" "if {{$w.file_pane} eq {%W}} {[cb _resize %h]}"
wm protocol $top WM_DELETE_WINDOW "destroy $top" wm protocol $top WM_DELETE_WINDOW "destroy $top"
bind $top <Destroy> [cb _kill] bind $top <Destroy> [cb _handle_destroy %W]
_load $this $i_jump _load $this $i_jump
} }
method _handle_destroy {win} {
if {$win eq $w} {
_kill $this
delete_this
}
}
method _kill {} { method _kill {} {
if {$current_fd ne {}} { if {$current_fd ne {}} {
kill_file_process $current_fd kill_file_process $current_fd
@ -866,6 +907,10 @@ method _showcommit {cur_w lno} {
foreach i $w_columns { foreach i $w_columns {
$i tag conf g$cmit -background $active_color $i tag conf g$cmit -background $active_color
$i tag raise g$cmit $i tag raise g$cmit
if {$i eq $w_file} {
$w_file tag raise found
}
$i tag raise sel
} }
set author_name {} set author_name {}

View File

@ -381,7 +381,8 @@ method _do_new {} {
label $w_body.where.l -text [mc "Directory:"] label $w_body.where.l -text [mc "Directory:"]
entry $w_body.where.t \ entry $w_body.where.t \
-textvariable @local_path \ -textvariable @local_path \
-font font_diff \ -borderwidth 1 \
-relief sunken \
-width 50 -width 50
button $w_body.where.b \ button $w_body.where.b \
-text [mc "Browse"] \ -text [mc "Browse"] \
@ -463,20 +464,22 @@ method _do_clone {} {
frame $w_body.args frame $w_body.args
pack $args -fill both pack $args -fill both
label $args.origin_l -text [mc "URL:"] label $args.origin_l -text [mc "Source Location:"]
entry $args.origin_t \ entry $args.origin_t \
-textvariable @origin_url \ -textvariable @origin_url \
-font font_diff \ -borderwidth 1 \
-relief sunken \
-width 50 -width 50
button $args.origin_b \ button $args.origin_b \
-text [mc "Browse"] \ -text [mc "Browse"] \
-command [cb _open_origin] -command [cb _open_origin]
grid $args.origin_l $args.origin_t $args.origin_b -sticky ew grid $args.origin_l $args.origin_t $args.origin_b -sticky ew
label $args.where_l -text [mc "Directory:"] label $args.where_l -text [mc "Target Directory:"]
entry $args.where_t \ entry $args.where_t \
-textvariable @local_path \ -textvariable @local_path \
-font font_diff \ -borderwidth 1 \
-relief sunken \
-width 50 -width 50
button $args.where_b \ button $args.where_b \
-text [mc "Browse"] \ -text [mc "Browse"] \
@ -979,7 +982,8 @@ method _do_open {} {
label $w_body.where.l -text [mc "Repository:"] label $w_body.where.l -text [mc "Repository:"]
entry $w_body.where.t \ entry $w_body.where.t \
-textvariable @local_path \ -textvariable @local_path \
-font font_diff \ -borderwidth 1 \
-relief sunken \
-width 50 -width 50
button $w_body.where.b \ button $w_body.where.b \
-text [mc "Browse"] \ -text [mc "Browse"] \

View File

@ -117,22 +117,22 @@ proc show_unmerged_diff {cont_info} {
if {$merge_stages(2) eq {}} { if {$merge_stages(2) eq {}} {
set is_conflict_diff 1 set is_conflict_diff 1
lappend current_diff_queue \ lappend current_diff_queue \
[list "LOCAL: deleted\nREMOTE:\n" d======= \ [list [mc "LOCAL: deleted\nREMOTE:\n"] d======= \
[list ":1:$current_diff_path" ":3:$current_diff_path"]] [list ":1:$current_diff_path" ":3:$current_diff_path"]]
} elseif {$merge_stages(3) eq {}} { } elseif {$merge_stages(3) eq {}} {
set is_conflict_diff 1 set is_conflict_diff 1
lappend current_diff_queue \ lappend current_diff_queue \
[list "REMOTE: deleted\nLOCAL:\n" d======= \ [list [mc "REMOTE: deleted\nLOCAL:\n"] d======= \
[list ":1:$current_diff_path" ":2:$current_diff_path"]] [list ":1:$current_diff_path" ":2:$current_diff_path"]]
} elseif {[lindex $merge_stages(1) 0] eq {120000} } elseif {[lindex $merge_stages(1) 0] eq {120000}
|| [lindex $merge_stages(2) 0] eq {120000} || [lindex $merge_stages(2) 0] eq {120000}
|| [lindex $merge_stages(3) 0] eq {120000}} { || [lindex $merge_stages(3) 0] eq {120000}} {
set is_conflict_diff 1 set is_conflict_diff 1
lappend current_diff_queue \ lappend current_diff_queue \
[list "LOCAL:\n" d======= \ [list [mc "LOCAL:\n"] d======= \
[list ":1:$current_diff_path" ":2:$current_diff_path"]] [list ":1:$current_diff_path" ":2:$current_diff_path"]]
lappend current_diff_queue \ lappend current_diff_queue \
[list "REMOTE:\n" d======= \ [list [mc "REMOTE:\n"] d======= \
[list ":1:$current_diff_path" ":3:$current_diff_path"]] [list ":1:$current_diff_path" ":3:$current_diff_path"]]
} else { } else {
start_show_diff $cont_info start_show_diff $cont_info
@ -164,7 +164,7 @@ proc show_other_diff {path w m cont_info} {
# - Git won't give us the diff, there's nothing to compare to! # - Git won't give us the diff, there's nothing to compare to!
# #
if {$m eq {_O}} { if {$m eq {_O}} {
set max_sz [expr {128 * 1024}] set max_sz 100000
set type unknown set type unknown
if {[catch { if {[catch {
set type [file type $path] set type [file type $path]
@ -218,17 +218,17 @@ proc show_other_diff {path w m cont_info} {
d_@ d_@
} else { } else {
if {$sz > $max_sz} { if {$sz > $max_sz} {
$ui_diff insert end \ $ui_diff insert end [mc \
"* Untracked file is $sz bytes. "* Untracked file is %d bytes.
* Showing only first $max_sz bytes. * Showing only first %d bytes.
" d_@ " $sz $max_sz] d_@
} }
$ui_diff insert end $content $ui_diff insert end $content
if {$sz > $max_sz} { if {$sz > $max_sz} {
$ui_diff insert end " $ui_diff insert end [mc "
* Untracked file clipped here by [appname]. * Untracked file clipped here by %s.
* To see the entire file, use an external editor. * To see the entire file, use an external editor.
" d_@ " [appname]] d_@
} }
} }
$ui_diff conf -state disabled $ui_diff conf -state disabled
@ -377,7 +377,6 @@ proc read_diff {fd cont_info} {
{+} { {+} {
if {[regexp {^\+([<>]{7} |={7})} $line _g op]} { if {[regexp {^\+([<>]{7} |={7})} $line _g op]} {
set is_conflict_diff 1 set is_conflict_diff 1
set line [string replace $line 0 0 { }]
set tags d$op set tags d$op
} else { } else {
set tags d_+ set tags d_+

View File

@ -298,11 +298,18 @@ proc add_helper {txt paths} {
set after {} set after {}
foreach path $paths { foreach path $paths {
switch -glob -- [lindex $file_states($path) 0] { switch -glob -- [lindex $file_states($path) 0] {
_U -
U? {
if {$path eq $current_diff_path} {
unlock_index
merge_stage_workdir $path
return
}
}
_O - _O -
?M - ?M -
?D - ?D -
?T - ?T {
U? {
lappend pathList $path lappend pathList $path
if {$path eq $current_diff_path} { if {$path eq $current_diff_path} {
set after {reshow_diff;} set after {reshow_diff;}

View File

@ -40,6 +40,7 @@ The rescan will be automatically started now.
_O { _O {
continue; # and pray it works! continue; # and pray it works!
} }
_U -
U? { U? {
error_popup [mc "You are in the middle of a conflicted merge. error_popup [mc "You are in the middle of a conflicted merge.

View File

@ -23,13 +23,14 @@ This operation can be undone only by restarting the merge." \
} }
} }
proc merge_stage_workdir {path w lno} { proc merge_stage_workdir {path {lno {}}} {
global current_diff_path diff_active global current_diff_path diff_active
global current_diff_side ui_workdir
if {$diff_active} return if {$diff_active} return
if {$path ne $current_diff_path} { if {$path ne $current_diff_path || $ui_workdir ne $current_diff_side} {
show_diff $path $w $lno {} [list do_merge_stage_workdir $path] show_diff $path $ui_workdir $lno {} [list do_merge_stage_workdir $path]
} else { } else {
do_merge_stage_workdir $path do_merge_stage_workdir $path
} }
@ -375,14 +376,6 @@ proc merge_tool_finish {fd} {
} }
} }
# Check the modification time of the target file
if {!$failed && [file mtime $mtool_target] eq $mtool_mtime} {
if {[ask_popup [mc "File %s unchanged, still accept as resolved?" \
[short_path $mtool_target]]] ne {yes}} {
set failed 1
}
}
# Finish # Finish
if {$failed} { if {$failed} {
file rename -force -- $backup $mtool_target file rename -force -- $backup $mtool_target
@ -395,6 +388,6 @@ proc merge_tool_finish {fd} {
delete_temp_files $mtool_tmpfiles delete_temp_files $mtool_tmpfiles
merge_add_resolution $mtool_target reshow_diff
} }
} }

View File

@ -132,91 +132,145 @@ proc load_all_remotes {} {
set all_remotes [lsort -unique $all_remotes] set all_remotes [lsort -unique $all_remotes]
} }
proc populate_fetch_menu {} { proc add_fetch_entry {r} {
global all_remotes repo_config global repo_config
set remote_m .mbar.remote set remote_m .mbar.remote
set fetch_m $remote_m.fetch set fetch_m $remote_m.fetch
set prune_m $remote_m.prune set prune_m $remote_m.prune
set remove_m $remote_m.remove
foreach r $all_remotes { set enable 0
set enable 0 if {![catch {set a $repo_config(remote.$r.url)}]} {
if {![catch {set a $repo_config(remote.$r.url)}]} { if {![catch {set a $repo_config(remote.$r.fetch)}]} {
if {![catch {set a $repo_config(remote.$r.fetch)}]} { set enable 1
set enable 1 }
} } else {
} else { catch {
catch { set fd [open [gitdir remotes $r] r]
set fd [open [gitdir remotes $r] r] while {[gets $fd n] >= 0} {
while {[gets $fd n] >= 0} { if {[regexp {^Pull:[ \t]*([^:]+):} $n]} {
if {[regexp {^Pull:[ \t]*([^:]+):} $n]} { set enable 1
set enable 1 break
break
}
} }
close $fd
} }
close $fd
}
}
if {$enable} {
if {![winfo exists $fetch_m]} {
menu $remove_m
$remote_m insert 0 cascade \
-label [mc "Remove Remote"] \
-menu $remove_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
} }
if {$enable} { $fetch_m add command \
if {![winfo exists $fetch_m]} { -label $r \
menu $prune_m -command [list fetch_from $r]
$remote_m insert 0 cascade \ $prune_m add command \
-label [mc "Prune from"] \ -label $r \
-menu $prune_m -command [list prune_from $r]
$remove_m add command \
menu $fetch_m -label $r \
$remote_m insert 0 cascade \ -command [list remove_remote $r]
-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]
}
} }
} }
proc populate_push_menu {} { proc add_push_entry {r} {
global all_remotes repo_config global repo_config
set remote_m .mbar.remote set remote_m .mbar.remote
set push_m $remote_m.push set push_m $remote_m.push
set enable 0
foreach r $all_remotes { if {![catch {set a $repo_config(remote.$r.url)}]} {
set enable 0 if {![catch {set a $repo_config(remote.$r.push)}]} {
if {![catch {set a $repo_config(remote.$r.url)}]} { set enable 1
if {![catch {set a $repo_config(remote.$r.push)}]} {
set enable 1
}
} else {
catch {
set fd [open [gitdir remotes $r] r]
while {[gets $fd n] >= 0} {
if {[regexp {^Push:[ \t]*([^:]+):} $n]} {
set enable 1
break
}
}
close $fd
}
} }
} else {
if {$enable} { catch {
if {![winfo exists $push_m]} { set fd [open [gitdir remotes $r] r]
menu $push_m while {[gets $fd n] >= 0} {
$remote_m insert 0 cascade \ if {[regexp {^Push:[ \t]*([^:]+):} $n]} {
-label [mc "Push to"] \ set enable 1
-menu $push_m break
}
} }
close $fd
$push_m add command \
-label $r \
-command [list push_to $r]
} }
} }
if {$enable} {
if {![winfo exists $push_m]} {
menu $push_m
$remote_m insert 0 cascade \
-label [mc "Push to"] \
-menu $push_m
}
$push_m add command \
-label $r \
-command [list push_to $r]
}
}
proc populate_remotes_menu {} {
global all_remotes
foreach r $all_remotes {
add_fetch_entry $r
add_push_entry $r
}
}
proc add_single_remote {name location} {
global all_remotes repo_config
lappend all_remotes $name
git remote add $name $location
# XXX: Better re-read the config so that we will never get out
# of sync with git remote implementation?
set repo_config(remote.$name.url) $location
set repo_config(remote.$name.fetch) "+refs/heads/*:refs/remotes/$name/*"
add_fetch_entry $name
add_push_entry $name
}
proc delete_from_menu {menu name} {
if {[winfo exists $menu]} {
$menu delete $name
}
}
proc remove_remote {name} {
global all_remotes repo_config
git remote rm $name
catch {
# Missing values are ok
unset repo_config(remote.$name.url)
unset repo_config(remote.$name.fetch)
unset repo_config(remote.$name.push)
}
set i [lsearch -exact all_remotes $name]
lreplace all_remotes $i $i
set remote_m .mbar.remote
delete_from_menu $remote_m.fetch $name
delete_from_menu $remote_m.prune $name
delete_from_menu $remote_m.remove $name
# Not all remotes are in the push menu
catch { delete_from_menu $remote_m.push $name }
} }

191
git-gui/lib/remote_add.tcl Normal file
View File

@ -0,0 +1,191 @@
# git-gui remote adding support
# Copyright (C) 2008 Petr Baudis
class remote_add {
field w ; # widget path
field w_name ; # new remote name widget
field w_loc ; # new remote location widget
field name {}; # name of the remote the user has chosen
field location {}; # location of the remote the user has chosen
field opt_action fetch; # action to do after registering the remote locally
constructor dialog {} {
global repo_config
make_toplevel top w
wm title $top [append "[appname] ([reponame]): " [mc "Add Remote"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
label $w.header -text [mc "Add New Remote"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
button $w.buttons.create -text [mc Add] \
-default active \
-command [cb _add]
pack $w.buttons.create -side right
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 [mc "Remote Details"]
label $w.desc.name_l -text [mc "Name:"]
set w_name $w.desc.name_t
entry $w_name \
-borderwidth 1 \
-relief sunken \
-width 40 \
-textvariable @name \
-validate key \
-validatecommand [cb _validate_name %d %S]
grid $w.desc.name_l $w_name -sticky we -padx {0 5}
label $w.desc.loc_l -text [mc "Location:"]
set w_loc $w.desc.loc_t
entry $w_loc \
-borderwidth 1 \
-relief sunken \
-width 40 \
-textvariable @location
grid $w.desc.loc_l $w_loc -sticky we -padx {0 5}
grid columnconfigure $w.desc 1 -weight 1
pack $w.desc -anchor nw -fill x -pady 5 -padx 5
labelframe $w.action -text [mc "Further Action"]
radiobutton $w.action.fetch \
-text [mc "Fetch Immediately"] \
-value fetch \
-variable @opt_action
pack $w.action.fetch -anchor nw
radiobutton $w.action.push \
-text [mc "Initialize Remote Repository and Push"] \
-value push \
-variable @opt_action
pack $w.action.push -anchor nw
radiobutton $w.action.none \
-text [mc "Do Nothing Else Now"] \
-value none \
-variable @opt_action
pack $w.action.none -anchor nw
grid columnconfigure $w.action 1 -weight 1
pack $w.action -anchor nw -fill x -pady 5 -padx 5
bind $w <Visibility> [cb _visible]
bind $w <Key-Escape> [list destroy $w]
bind $w <Key-Return> [cb _add]\;break
tkwait window $w
}
method _add {} {
global repo_config env
global M1B
if {$name eq {}} {
tk_messageBox \
-icon error \
-type ok \
-title [wm title $w] \
-parent $w \
-message [mc "Please supply a remote name."]
focus $w_name
return
}
# XXX: We abuse check-ref-format here, but
# that should be ok.
if {[catch {git check-ref-format "remotes/$name"}]} {
tk_messageBox \
-icon error \
-type ok \
-title [wm title $w] \
-parent $w \
-message [mc "'%s' is not an acceptable remote name." $name]
focus $w_name
return
}
if {[catch {add_single_remote $name $location}]} {
tk_messageBox \
-icon error \
-type ok \
-title [wm title $w] \
-parent $w \
-message [mc "Failed to add remote '%s' of location '%s'." $name $location]
focus $w_name
return
}
switch -- $opt_action {
fetch {
set c [console::new \
[mc "fetch %s" $name] \
[mc "Fetching the %s" $name]]
console::exec $c [list git fetch $name]
}
push {
set cmds [list]
# Parse the location
if { [regexp {(?:git\+)?ssh://([^/]+)(/.+)} $location xx host path]
|| [regexp {([^:][^:]+):(.+)} $location xx host path]} {
set ssh ssh
if {[info exists env(GIT_SSH)]} {
set ssh $env(GIT_SSH)
}
lappend cmds [list exec $ssh $host mkdir -p $location && git --git-dir=$path init --bare]
} elseif { ! [regexp {://} $location xx] } {
lappend cmds [list exec mkdir -p $location]
lappend cmds [list exec git --git-dir=$location init --bare]
} else {
tk_messageBox \
-icon error \
-type ok \
-title [wm title $w] \
-parent $w \
-message [mc "Do not know how to initialize repository at location '%s'." $location]
destroy $w
return
}
set c [console::new \
[mc "push %s" $name] \
[mc "Setting up the %s (at %s)" $name $location]]
lappend cmds [list exec git push -v --all $name]
console::chain $c $cmds
}
none {
}
}
destroy $w
}
method _validate_name {d S} {
if {$d == 1} {
if {[regexp {[~^:?*\[\0- ]} $S]} {
return 0
}
}
return 1
}
method _visible {} {
grab $w
$w_name icursor end
focus $w_name
}
}

View File

@ -26,12 +26,12 @@ constructor dialog {} {
global all_remotes M1B global all_remotes M1B
make_toplevel top w make_toplevel top w
wm title $top [append "[appname] ([reponame]): " [mc "Delete Remote Branch"]] wm title $top [append "[appname] ([reponame]): " [mc "Delete Branch Remotely"]]
if {$top ne {.}} { if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]" wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
} }
label $w.header -text [mc "Delete Remote Branch"] -font font_uibold label $w.header -text [mc "Delete Branch Remotely"] -font font_uibold
pack $w.header -side top -fill x pack $w.header -side top -fill x
frame $w.buttons frame $w.buttons
@ -63,7 +63,7 @@ constructor dialog {} {
set urltype url set urltype url
} }
radiobutton $w.dest.url_r \ radiobutton $w.dest.url_r \
-text [mc "Arbitrary URL:"] \ -text [mc "Arbitrary Location:"] \
-value url \ -value url \
-variable @urltype -variable @urltype
entry $w.dest.url_t \ entry $w.dest.url_t \

190
git-gui/lib/search.tcl Normal file
View File

@ -0,0 +1,190 @@
# incremental search panel
# based on code from gitk, Copyright (C) Paul Mackerras
class searchbar {
field w
field ctext
field searchstring {}
field casesensitive 1
field searchdirn -forwards
field smarktop
field smarkbot
constructor new {i_w i_text args} {
set w $i_w
set ctext $i_text
frame $w
label $w.l -text [mc Find:]
button $w.bn -text [mc Next] -command [cb find_next]
button $w.bp -text [mc Prev] -command [cb find_prev]
checkbutton $w.cs -text [mc Case-Sensitive] \
-variable ${__this}::casesensitive -command [cb _incrsearch]
entry $w.ent -textvariable ${__this}::searchstring -background lightgreen
pack $w.l -side left
pack $w.cs -side right
pack $w.bp -side right
pack $w.bn -side right
pack $w.ent -side left -expand 1 -fill x
eval grid conf $w -sticky we $args
grid remove $w
trace add variable searchstring write [cb _incrsearch_cb]
bind $w <Destroy> [cb delete_this]
return $this
}
method show {} {
if {![winfo ismapped $w]} {
grid $w
}
focus -force $w.ent
}
method hide {} {
if {[winfo ismapped $w]} {
focus $ctext
grid remove $w
}
}
method _get_new_anchor {} {
# use start of selection if it is visible,
# or the bounds of the visible area
set top [$ctext index @0,0]
set bottom [$ctext index @0,[winfo height $ctext]]
set sel [$ctext tag ranges sel]
if {$sel ne {}} {
set spos [lindex $sel 0]
if {[lindex $spos 0] >= [lindex $top 0] &&
[lindex $spos 0] <= [lindex $bottom 0]} {
return $spos
}
}
if {$searchdirn eq "-forwards"} {
return $top
} else {
return $bottom
}
}
method _get_wrap_anchor {dir} {
if {$dir eq "-forwards"} {
return 1.0
} else {
return end
}
}
method _do_search {start {mlenvar {}} {dir {}} {endbound {}}} {
set cmd [list $ctext search]
if {$mlenvar ne {}} {
upvar $mlenvar mlen
lappend cmd -count mlen
}
if {!$casesensitive} {
lappend cmd -nocase
}
if {$dir eq {}} {
set dir $searchdirn
}
lappend cmd $dir -- $searchstring
if {$endbound ne {}} {
set here [eval $cmd [list $start] [list $endbound]]
} else {
set here [eval $cmd [list $start]]
if {$here eq {}} {
set here [eval $cmd [_get_wrap_anchor $this $dir]]
}
}
return $here
}
method _incrsearch_cb {name ix op} {
after idle [cb _incrsearch]
}
method _incrsearch {} {
$ctext tag remove found 1.0 end
if {[catch {$ctext index anchor}]} {
$ctext mark set anchor [_get_new_anchor $this]
}
if {$searchstring ne {}} {
set here [_do_search $this anchor mlen]
if {$here ne {}} {
$ctext see $here
$ctext tag remove sel 1.0 end
$ctext tag add sel $here "$here + $mlen c"
$w.ent configure -background lightgreen
_set_marks $this 1
} else {
$w.ent configure -background lightpink
}
}
}
method find_prev {} {
find_next $this -backwards
}
method find_next {{dir -forwards}} {
focus $w.ent
$w.ent icursor end
set searchdirn $dir
$ctext mark unset anchor
if {$searchstring ne {}} {
set start [_get_new_anchor $this]
if {$dir eq "-forwards"} {
set start "$start + 1c"
}
set match [_do_search $this $start mlen]
$ctext tag remove sel 1.0 end
if {$match ne {}} {
$ctext see $match
$ctext tag add sel $match "$match + $mlen c"
}
}
}
method _mark_range {first last} {
set mend $first.0
while {1} {
set match [_do_search $this $mend mlen -forwards $last.end]
if {$match eq {}} break
set mend "$match + $mlen c"
$ctext tag add found $match $mend
}
}
method _set_marks {doall} {
set topline [lindex [split [$ctext index @0,0] .] 0]
set botline [lindex [split [$ctext index @0,[winfo height $ctext]] .] 0]
if {$doall || $botline < $smarktop || $topline > $smarkbot} {
# no overlap with previous
_mark_range $this $topline $botline
set smarktop $topline
set smarkbot $botline
} else {
if {$topline < $smarktop} {
_mark_range $this $topline [expr {$smarktop-1}]
set smarktop $topline
}
if {$botline > $smarkbot} {
_mark_range $this [expr {$smarkbot+1}] $botline
set smarkbot $botline
}
}
}
method scrolled {} {
if {$searchstring ne {}} {
after idle [cb _set_marks 0]
}
}
}

View File

@ -80,7 +80,7 @@ method _connect {pipe_fd} {
error_popup [strcat [mc "Unrecognized spell checker"] ":\n\n$s_version"] error_popup [strcat [mc "Unrecognized spell checker"] ":\n\n$s_version"]
return return
} }
set s_version [string range $s_version 5 end] set s_version [string range [string trim $s_version] 5 end]
regexp \ regexp \
{International Ispell Version .* \(but really (Aspell .*?)\)$} \ {International Ispell Version .* \(but really (Aspell .*?)\)$} \
$s_version _junk s_version $s_version _junk s_version
@ -314,6 +314,7 @@ method _run {} {
method _read {} { method _read {} {
while {[gets $s_fd line] >= 0} { while {[gets $s_fd line] >= 0} {
set lineno [lindex $s_pending 0 0] set lineno [lindex $s_pending 0 0]
set line [string trim $line]
if {$s_clear} { if {$s_clear} {
$w_text tag remove misspelled "$lineno.0" "$lineno.end" $w_text tag remove misspelled "$lineno.0" "$lineno.end"

126
git-gui/lib/sshkey.tcl Normal file
View File

@ -0,0 +1,126 @@
# git-gui about git-gui dialog
# Copyright (C) 2006, 2007 Shawn Pearce
proc find_ssh_key {} {
foreach name {~/.ssh/id_dsa.pub ~/.ssh/id_rsa.pub ~/.ssh/identity.pub} {
if {[file exists $name]} {
set fh [open $name r]
set cont [read $fh]
close $fh
return [list $name $cont]
}
}
return {}
}
proc do_ssh_key {} {
global sshkey_title have_tk85 sshkey_fd
set w .sshkey_dialog
if {[winfo exists $w]} {
raise $w
return
}
toplevel $w
wm transient $w .
set finfo [find_ssh_key]
if {$finfo eq {}} {
set sshkey_title [mc "No keys found."]
set gen_state normal
} else {
set sshkey_title [mc "Found a public key in: %s" [lindex $finfo 0]]
set gen_state disabled
}
frame $w.header -relief flat
label $w.header.lbl -textvariable sshkey_title -anchor w
button $w.header.gen -text [mc "Generate Key"] \
-command [list make_ssh_key $w] -state $gen_state
pack $w.header.lbl -side left -expand 1 -fill x
pack $w.header.gen -side right
pack $w.header -fill x -pady 5 -padx 5
text $w.contents -width 60 -height 10 -wrap char -relief sunken
pack $w.contents -fill both -expand 1
if {$have_tk85} {
$w.contents configure -inactiveselectbackground darkblue
}
frame $w.buttons
button $w.buttons.close -text [mc Close] \
-default active -command [list destroy $w]
pack $w.buttons.close -side right
button $w.buttons.copy -text [mc "Copy To Clipboard"] \
-command [list tk_textCopy $w.contents]
pack $w.buttons.copy -side left
pack $w.buttons -side bottom -fill x -pady 5 -padx 5
if {$finfo ne {}} {
$w.contents insert end [lindex $finfo 1] sel
}
$w.contents configure -state disabled
bind $w <Visibility> "grab $w; focus $w.buttons.close"
bind $w <Key-Escape> "destroy $w"
bind $w <Key-Return> "destroy $w"
bind $w <Destroy> kill_sshkey
wm title $w [mc "Your OpenSSH Public Key"]
tk::PlaceWindow $w widget .
tkwait window $w
}
proc make_ssh_key {w} {
global sshkey_title sshkey_output sshkey_fd
set sshkey_title [mc "Generating..."]
$w.header.gen configure -state disabled
set cmdline [list sh -c {echo | ssh-keygen -q -t rsa -f ~/.ssh/id_rsa 2>&1}]
if {[catch { set sshkey_fd [_open_stdout_stderr $cmdline] } err]} {
error_popup [mc "Could not start ssh-keygen:\n\n%s" $err]
return
}
set sshkey_output {}
fconfigure $sshkey_fd -blocking 0
fileevent $sshkey_fd readable [list read_sshkey_output $sshkey_fd $w]
}
proc kill_sshkey {} {
global sshkey_fd
if {![info exists sshkey_fd]} return
catch { kill_file_process $sshkey_fd }
catch { close $sshkey_fd }
}
proc read_sshkey_output {fd w} {
global sshkey_fd sshkey_output sshkey_title
set sshkey_output "$sshkey_output[read $fd]"
if {![eof $fd]} return
fconfigure $fd -blocking 1
unset sshkey_fd
$w.contents configure -state normal
if {[catch {close $fd} err]} {
set sshkey_title [mc "Generation failed."]
$w.contents insert end $err
$w.contents insert end "\n"
$w.contents insert end $sshkey_output
} else {
set finfo [find_ssh_key]
if {$finfo eq {}} {
set sshkey_title [mc "Generation succeded, but no keys found."]
$w.contents insert end $sshkey_output
} else {
set sshkey_title [mc "Your key is in: %s" [lindex $finfo 0]]
$w.contents insert end [lindex $finfo 1] sel
}
}
$w.contents configure -state disable
}

View File

@ -135,7 +135,7 @@ proc do_push_anywhere {} {
set push_urltype url set push_urltype url
} }
radiobutton $w.dest.url_r \ radiobutton $w.dest.url_r \
-text [mc "Arbitrary URL:"] \ -text [mc "Arbitrary Location:"] \
-value url \ -value url \
-variable push_urltype -variable push_urltype
entry $w.dest.url_t \ entry $w.dest.url_t \

View File

@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: git-gui\n" "Project-Id-Version: git-gui\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2008-09-13 10:20+0200\n" "POT-Creation-Date: 2008-10-25 13:32+0200\n"
"PO-Revision-Date: 2008-09-13 10:24+0200\n" "PO-Revision-Date: 2008-10-25 22:47+0200\n"
"Last-Translator: Christian Stimming <stimming@tuhh.de>\n" "Last-Translator: Christian Stimming <stimming@tuhh.de>\n"
"Language-Team: German\n" "Language-Team: German\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -86,7 +86,17 @@ msgstr "Dateistatus aktualisieren..."
msgid "Scanning for modified files ..." msgid "Scanning for modified files ..."
msgstr "Nach geänderten Dateien suchen..." msgstr "Nach geänderten Dateien suchen..."
#: git-gui.sh:1324 lib/browser.tcl:246 #: git-gui.sh:1325
#, fuzzy
msgid "Calling prepare-commit-msg hook..."
msgstr "Aufrufen der Vor-Eintragen-Kontrolle..."
#: git-gui.sh:1342
#, fuzzy
msgid "Commit declined by prepare-commit-msg hook."
msgstr "Eintragen abgelehnt durch Vor-Eintragen-Kontrolle (»pre-commit hook«)."
#: git-gui.sh:1502 lib/browser.tcl:246
msgid "Ready." msgid "Ready."
msgstr "Bereit." msgstr "Bereit."
@ -170,7 +180,11 @@ msgstr "Zusammenführen"
msgid "Remote" msgid "Remote"
msgstr "Andere Archive" msgstr "Andere Archive"
#: git-gui.sh:1879 #: git-gui.sh:2242
msgid "Explore Working Copy"
msgstr "Arbeitskopie im Dateimanager"
#: git-gui.sh:2247
msgid "Browse Current Branch's Files" msgid "Browse Current Branch's Files"
msgstr "Aktuellen Zweig durchblättern" msgstr "Aktuellen Zweig durchblättern"
@ -267,7 +281,15 @@ msgstr "Löschen..."
msgid "Reset..." msgid "Reset..."
msgstr "Zurücksetzen..." msgstr "Zurücksetzen..."
#: git-gui.sh:2002 git-gui.sh:2389 #: git-gui.sh:2372
msgid "Done"
msgstr "Fertig"
#: git-gui.sh:2374
msgid "Commit@@verb"
msgstr "Eintragen"
#: git-gui.sh:2383 git-gui.sh:2786
msgid "New Commit" msgid "New Commit"
msgstr "Neue Version" msgstr "Neue Version"
@ -307,11 +329,7 @@ msgstr "Mehr Zeilen anzeigen"
msgid "Sign Off" msgid "Sign Off"
msgstr "Abzeichnen" msgstr "Abzeichnen"
#: git-gui.sh:2053 git-gui.sh:2372 #: git-gui.sh:2458
msgid "Commit@@verb"
msgstr "Eintragen"
#: git-gui.sh:2064
msgid "Local Merge..." msgid "Local Merge..."
msgstr "Lokales Zusammenführen..." msgstr "Lokales Zusammenführen..."
@ -319,11 +337,19 @@ msgstr "Lokales Zusammenführen..."
msgid "Abort Merge..." msgid "Abort Merge..."
msgstr "Zusammenführen abbrechen..." msgstr "Zusammenführen abbrechen..."
#: git-gui.sh:2081 #: git-gui.sh:2475
msgid "Add..."
msgstr "Hinzufügen..."
#: git-gui.sh:2479
msgid "Push..." msgid "Push..."
msgstr "Versenden..." msgstr "Versenden..."
#: git-gui.sh:2197 git-gui.sh:2219 lib/about.tcl:14 #: git-gui.sh:2483
msgid "Delete Branch..."
msgstr "Zweig löschen..."
#: git-gui.sh:2493 git-gui.sh:2515 lib/about.tcl:14
#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50 #: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50
#, tcl-format #, tcl-format
msgid "About %s" msgid "About %s"
@ -416,7 +442,11 @@ msgstr "Schriftgröße verkleinern"
msgid "Increase Font Size" msgid "Increase Font Size"
msgstr "Schriftgröße vergrößern" msgstr "Schriftgröße vergrößern"
#: git-gui.sh:2870 #: git-gui.sh:3033 lib/blame.tcl:281
msgid "Encoding"
msgstr "Zeichenkodierung"
#: git-gui.sh:3044
msgid "Apply/Reverse Hunk" msgid "Apply/Reverse Hunk"
msgstr "Kontext anwenden/umkehren" msgstr "Kontext anwenden/umkehren"
@ -440,11 +470,7 @@ msgstr "Lokale Version benutzen"
msgid "Revert To Base" msgid "Revert To Base"
msgstr "Ursprüngliche Version benutzen" msgstr "Ursprüngliche Version benutzen"
#: git-gui.sh:2906 #: git-gui.sh:3091
msgid "Stage Working Copy"
msgstr "Arbeitskopie bereitstellen"
#: git-gui.sh:2925
msgid "Unstage Hunk From Commit" msgid "Unstage Hunk From Commit"
msgstr "Kontext aus Bereitstellung herausnehmen" msgstr "Kontext aus Bereitstellung herausnehmen"
@ -583,7 +609,12 @@ msgstr "Eintragender:"
msgid "Original File:" msgid "Original File:"
msgstr "Ursprüngliche Datei:" msgstr "Ursprüngliche Datei:"
#: lib/blame.tcl:990 #: lib/blame.tcl:1013
#, fuzzy
msgid "Cannot find HEAD commit:"
msgstr "Elternversion kann nicht gefunden werden:"
#: lib/blame.tcl:1068
msgid "Cannot find parent commit:" msgid "Cannot find parent commit:"
msgstr "Elternversion kann nicht gefunden werden:" msgstr "Elternversion kann nicht gefunden werden:"
@ -1041,11 +1072,15 @@ msgstr "Datei »%s« existiert bereits."
msgid "Clone" msgid "Clone"
msgstr "Klonen" msgstr "Klonen"
#: lib/choose_repository.tcl:468 #: lib/choose_repository.tcl:467
msgid "URL:" msgid "Source Location:"
msgstr "URL:" msgstr ""
#: lib/choose_repository.tcl:489 #: lib/choose_repository.tcl:478
msgid "Target Directory:"
msgstr "Zielverzeichnis:"
#: lib/choose_repository.tcl:490
msgid "Clone Type:" msgid "Clone Type:"
msgstr "Art des Klonens:" msgstr "Art des Klonens:"
@ -1525,7 +1560,27 @@ msgstr ""
msgid "Loading diff of %s..." msgid "Loading diff of %s..."
msgstr "Vergleich von »%s« laden..." msgstr "Vergleich von »%s« laden..."
#: lib/diff.tcl:114 lib/diff.tcl:184 #: lib/diff.tcl:120
msgid ""
"LOCAL: deleted\n"
"REMOTE:\n"
msgstr ""
#: lib/diff.tcl:125
msgid ""
"REMOTE: deleted\n"
"LOCAL:\n"
msgstr ""
#: lib/diff.tcl:132
msgid "LOCAL:\n"
msgstr ""
#: lib/diff.tcl:135
msgid "REMOTE:\n"
msgstr ""
#: lib/diff.tcl:197 lib/diff.tcl:296
#, tcl-format #, tcl-format
msgid "Unable to display %s" msgid "Unable to display %s"
msgstr "Datei »%s« kann nicht angezeigt werden" msgstr "Datei »%s« kann nicht angezeigt werden"
@ -1542,7 +1597,22 @@ msgstr "Git-Projektarchiv (Unterprojekt)"
msgid "* Binary file (not showing content)." msgid "* Binary file (not showing content)."
msgstr "* Binärdatei (Inhalt wird nicht angezeigt)" msgstr "* Binärdatei (Inhalt wird nicht angezeigt)"
#: lib/diff.tcl:313 #: lib/diff.tcl:222
#, tcl-format
msgid ""
"* Untracked file is %d bytes.\n"
"* Showing only first %d bytes.\n"
msgstr ""
#: lib/diff.tcl:228
#, tcl-format
msgid ""
"\n"
"* Untracked file clipped here by %s.\n"
"* To see the entire file, use an external editor.\n"
msgstr ""
#: lib/diff.tcl:437
msgid "Failed to unstage selected hunk." msgid "Failed to unstage selected hunk."
msgstr "" msgstr ""
"Fehler beim Herausnehmen des gewählten Kontexts aus der Bereitstellung." "Fehler beim Herausnehmen des gewählten Kontexts aus der Bereitstellung."
@ -1559,6 +1629,19 @@ msgstr "Fehler beim Herausnehmen der gewählten Zeile aus der Bereitstellung."
msgid "Failed to stage selected line." msgid "Failed to stage selected line."
msgstr "Fehler beim Bereitstellen der gewählten Zeile." msgstr "Fehler beim Bereitstellen der gewählten Zeile."
#: lib/encoding.tcl:443
msgid "Default"
msgstr "Voreinstellung"
#: lib/encoding.tcl:448
#, tcl-format
msgid "System (%s)"
msgstr "Systemweit (%s)"
#: lib/encoding.tcl:459 lib/encoding.tcl:465
msgid "Other"
msgstr "Andere"
#: lib/error.tcl:20 lib/error.tcl:114 #: lib/error.tcl:20 lib/error.tcl:114
msgid "error" msgid "error"
msgstr "Fehler" msgstr "Fehler"
@ -1811,7 +1894,12 @@ msgstr ""
"Diese Operation kann nur rückgängig gemacht werden, wenn die\n" "Diese Operation kann nur rückgängig gemacht werden, wenn die\n"
"Zusammenführung erneut gestartet wird." "Zusammenführung erneut gestartet wird."
#: lib/mergetool.tcl:32 #: lib/mergetool.tcl:45
#, tcl-format
msgid "File %s seems to have unresolved conflicts, still stage?"
msgstr "Datei »%s« hat nicht aufgelöste Konflikte. Trotzdem bereitstellen?"
#: lib/mergetool.tcl:60
#, tcl-format #, tcl-format
msgid "Adding resolution for %s" msgid "Adding resolution for %s"
msgstr "Auflösung hinzugefügt für %s" msgstr "Auflösung hinzugefügt für %s"
@ -1868,12 +1956,17 @@ msgstr "Zusammenführungswerkzeug starten..."
msgid "Merge tool failed." msgid "Merge tool failed."
msgstr "Zusammenführungswerkzeug fehlgeschlagen." msgstr "Zusammenführungswerkzeug fehlgeschlagen."
#: lib/mergetool.tcl:353 #: lib/option.tcl:11
#, tcl-format #, tcl-format
msgid "File %s unchanged, still accept as resolved?" msgid "Invalid global encoding '%s'"
msgstr "Datei »%s« unverändert. Trotzdem Konflikt als gelöst akzeptieren?" msgstr "Ungültige globale Zeichenkodierung »%s«"
#: lib/option.tcl:95 #: lib/option.tcl:19
#, tcl-format
msgid "Invalid repo encoding '%s'"
msgstr "Ungültige Archiv-Zeichenkodierung »%s«"
#: lib/option.tcl:117
msgid "Restore Defaults" msgid "Restore Defaults"
msgstr "Voreinstellungen wiederherstellen" msgstr "Voreinstellungen wiederherstellen"
@ -1950,7 +2043,15 @@ msgstr "Textbreite der Versionsbeschreibung"
msgid "New Branch Name Template" msgid "New Branch Name Template"
msgstr "Namensvorschlag für neue Zweige" msgstr "Namensvorschlag für neue Zweige"
#: lib/option.tcl:192 #: lib/option.tcl:155
msgid "Default File Contents Encoding"
msgstr "Vorgestellte Zeichenkodierung"
#: lib/option.tcl:203
msgid "Change"
msgstr "Ändern"
#: lib/option.tcl:230
msgid "Spelling Dictionary:" msgid "Spelling Dictionary:"
msgstr "Wörterbuch Rechtschreibprüfung:" msgstr "Wörterbuch Rechtschreibprüfung:"
@ -1975,9 +2076,85 @@ msgstr "Einstellungen"
msgid "Failed to completely save options:" msgid "Failed to completely save options:"
msgstr "Optionen konnten nicht gespeichert werden:" msgstr "Optionen konnten nicht gespeichert werden:"
#: lib/remote_add.tcl:19
msgid "Add Remote"
msgstr "Anderes Archiv hinzufügen"
#: lib/remote_add.tcl:24
msgid "Add New Remote"
msgstr "Neues anderes Archiv hinzufügen"
#: lib/remote_add.tcl:28
msgid "Add"
msgstr "Hinzufügen"
#: lib/remote_add.tcl:37
msgid "Remote Details"
msgstr "Einzelheiten des anderen Archivs"
#: lib/remote_add.tcl:50
msgid "Location:"
msgstr "Adresse:"
#: lib/remote_add.tcl:62
msgid "Further Action"
msgstr "Weitere Aktion jetzt"
#: lib/remote_add.tcl:65
msgid "Fetch Immediately"
msgstr "Gleich anfordern"
#: lib/remote_add.tcl:71
msgid "Initialize Remote Repository and Push"
msgstr "Anderes Archiv initialisieren und dahin versenden"
#: lib/remote_add.tcl:77
msgid "Do Nothing Else Now"
msgstr "Nichts tun"
#: lib/remote_add.tcl:101
#, fuzzy
msgid "Please supply a remote name."
msgstr "Bitte geben Sie einen Zweignamen an."
#: lib/remote_add.tcl:114
#, fuzzy, tcl-format
msgid "'%s' is not an acceptable remote name."
msgstr "»%s« ist kein zulässiger Zweigname."
#: lib/remote_add.tcl:125
#, fuzzy, tcl-format
msgid "Failed to add remote '%s' of location '%s'."
msgstr "Fehler beim Umbenennen von »%s«."
#: lib/remote_add.tcl:133 lib/transport.tcl:6
#, tcl-format
msgid "fetch %s"
msgstr "»%s« anfordern"
#: lib/remote_add.tcl:134
#, fuzzy, tcl-format
msgid "Fetching the %s"
msgstr "Änderungen »%s« von »%s« anfordern"
#: lib/remote_add.tcl:157
#, tcl-format
msgid "Do not know how to initialize repository at location '%s'."
msgstr "Initialisieren eines anderen Archivs an Adresse »%s« ist nicht möglich."
#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:71
#, tcl-format
msgid "push %s"
msgstr "»%s« versenden..."
#: lib/remote_add.tcl:164
#, tcl-format
msgid "Setting up the %s (at %s)"
msgstr "Einrichten von »%s« an »%s«"
#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34 #: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
msgid "Delete Remote Branch" msgid "Delete Branch Remotely"
msgstr "Zweig in anderem Projektarchiv löschen" msgstr "Zweig in anderem Archiv löschen"
#: lib/remote_branch_delete.tcl:47 #: lib/remote_branch_delete.tcl:47
msgid "From Repository" msgid "From Repository"
@ -1988,8 +2165,8 @@ msgid "Remote:"
msgstr "Anderes Archiv:" msgstr "Anderes Archiv:"
#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138 #: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
msgid "Arbitrary URL:" msgid "Arbitrary Location:"
msgstr "Archiv-URL:" msgstr "Adresse:"
#: lib/remote_branch_delete.tcl:84 #: lib/remote_branch_delete.tcl:84
msgid "Branches" msgid "Branches"
@ -2061,7 +2238,11 @@ msgstr "Kein Projektarchiv ausgewählt."
msgid "Scanning %s..." msgid "Scanning %s..."
msgstr "»%s« laden..." msgstr "»%s« laden..."
#: lib/remote.tcl:165 #: lib/remote.tcl:163
msgid "Remove Remote"
msgstr "Anderes Archiv entfernen"
#: lib/remote.tcl:168
msgid "Prune from" msgid "Prune from"
msgstr "Aufräumen von" msgstr "Aufräumen von"
@ -2073,6 +2254,22 @@ msgstr "Anfordern von"
msgid "Push to" msgid "Push to"
msgstr "Versenden nach" msgstr "Versenden nach"
#: lib/search.tcl:21
msgid "Find:"
msgstr "Suchen:"
#: lib/search.tcl:22
msgid "Next"
msgstr "Nächster"
#: lib/search.tcl:23
msgid "Prev"
msgstr "Voriger"
#: lib/search.tcl:24
msgid "Case-Sensitive"
msgstr ""
#: lib/shortcut.tcl:20 lib/shortcut.tcl:61 #: lib/shortcut.tcl:20 lib/shortcut.tcl:61
msgid "Cannot write shortcut:" msgid "Cannot write shortcut:"
msgstr "Fehler beim Schreiben der Verknüpfung:" msgstr "Fehler beim Schreiben der Verknüpfung:"
@ -2123,11 +2320,6 @@ msgstr "Rechtschreibprüfung fehlgeschlagen"
msgid "%s ... %*i of %*i %s (%3i%%)" msgid "%s ... %*i of %*i %s (%3i%%)"
msgstr "%s ... %*i von %*i %s (%3i%%)" msgstr "%s ... %*i von %*i %s (%3i%%)"
#: lib/transport.tcl:6
#, tcl-format
msgid "fetch %s"
msgstr "»%s« anfordern"
#: lib/transport.tcl:7 #: lib/transport.tcl:7
#, tcl-format #, tcl-format
msgid "Fetching new changes from %s" msgid "Fetching new changes from %s"
@ -2143,11 +2335,6 @@ msgstr "Aufräumen von »%s«"
msgid "Pruning tracking branches deleted from %s" msgid "Pruning tracking branches deleted from %s"
msgstr "Übernahmezweige aufräumen und entfernen, die in »%s« gelöscht wurden" msgstr "Übernahmezweige aufräumen und entfernen, die in »%s« gelöscht wurden"
#: lib/transport.tcl:25 lib/transport.tcl:71
#, tcl-format
msgid "push %s"
msgstr "»%s« versenden..."
#: lib/transport.tcl:26 #: lib/transport.tcl:26
#, tcl-format #, tcl-format
msgid "Pushing changes to %s" msgid "Pushing changes to %s"