Browse Source

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

* git://repo.or.cz/git-gui:
  git-gui: Correct encoding of glossary/fr.po to UTF-8
  git-gui: Consolidate hook execution code into a single function
  git-gui: Correct window title for hook failure dialogs
  git-gui: Honor the standard commit-msg hook
maint
Junio C Hamano 17 years ago
parent
commit
36a189c86e
  1. 28
      git-gui/git-gui.sh
  2. 149
      git-gui/lib/commit.tcl
  3. 18
      git-gui/lib/error.tcl
  4. 26
      git-gui/po/glossary/fr.po

28
git-gui/git-gui.sh

@ -438,6 +438,34 @@ proc git_write {args} {
return [open [concat $opt $cmdp $args] w] return [open [concat $opt $cmdp $args] w]
} }


proc githook_read {hook_name args} {
set pchook [gitdir hooks $hook_name]
lappend args 2>@1

# On Cygwin [file executable] might lie so we need to ask
# the shell if the hook is executable. Yes that's annoying.
#
if {[is_Cygwin]} {
upvar #0 _sh interp
if {![info exists interp]} {
set interp [_which sh]
}
if {$interp eq {}} {
error "hook execution requires sh (not in PATH)"
}

set scr {if test -x "$1";then exec "$@";fi}
set sh_c [list | $interp -c $scr $interp $pchook]
return [_open_stdout_stderr [concat $sh_c $args]]
}

if {[file executable $pchook]} {
return [_open_stdout_stderr [concat [list | $pchook] $args]]
}

return {}
}

proc sq {value} { proc sq {value} {
regsub -all ' $value "'\\''" value regsub -all ' $value "'\\''" value
return "'$value'" return "'$value'"

149
git-gui/lib/commit.tcl

@ -192,45 +192,52 @@ A good commit message has the following format:
return return
} }


# -- Run the pre-commit hook. # -- Build the message file.
# #
set pchook [gitdir hooks pre-commit] set msg_p [gitdir GITGUI_EDITMSG]
set msg_wt [open $msg_p w]
fconfigure $msg_wt -translation lf
if {[catch {set enc $repo_config(i18n.commitencoding)}]} {
set enc utf-8
}
set use_enc [tcl_encoding $enc]
if {$use_enc ne {}} {
fconfigure $msg_wt -encoding $use_enc
} else {
puts stderr [mc "warning: Tcl does not support encoding '%s'." $enc]
fconfigure $msg_wt -encoding utf-8
}
puts $msg_wt $msg
close $msg_wt


# On Cygwin [file executable] might lie so we need to ask # -- Run the pre-commit hook.
# the shell if the hook is executable. Yes that's annoying.
# #
if {[is_Cygwin] && [file isfile $pchook]} { set fd_ph [githook_read pre-commit]
set pchook [list sh -c [concat \ if {$fd_ph eq {}} {
"if test -x \"$pchook\";" \ commit_commitmsg $curHEAD $msg_p
"then exec \"$pchook\" 2>&1;" \
"fi"]]
} elseif {[file executable $pchook]} {
set pchook [list $pchook |& cat]
} else {
commit_writetree $curHEAD $msg
return return
} }


ui_status {Calling pre-commit hook...} ui_status {Calling pre-commit hook...}
set pch_error {} set pch_error {}
set fd_ph [open "| $pchook" r]
fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
fileevent $fd_ph readable \ fileevent $fd_ph readable \
[list commit_prehook_wait $fd_ph $curHEAD $msg] [list commit_prehook_wait $fd_ph $curHEAD $msg_p]
} }


proc commit_prehook_wait {fd_ph curHEAD msg} { proc commit_prehook_wait {fd_ph curHEAD msg_p} {
global pch_error global pch_error


append pch_error [read $fd_ph] append pch_error [read $fd_ph]
fconfigure $fd_ph -blocking 1 fconfigure $fd_ph -blocking 1
if {[eof $fd_ph]} { if {[eof $fd_ph]} {
if {[catch {close $fd_ph}]} { if {[catch {close $fd_ph}]} {
catch {file delete $msg_p}
ui_status {Commit declined by pre-commit hook.} ui_status {Commit declined by pre-commit hook.}
hook_failed_popup pre-commit $pch_error hook_failed_popup pre-commit $pch_error
unlock_index unlock_index
} else { } else {
commit_writetree $curHEAD $msg commit_commitmsg $curHEAD $msg_p
} }
set pch_error {} set pch_error {}
return return
@ -238,14 +245,52 @@ proc commit_prehook_wait {fd_ph curHEAD msg} {
fconfigure $fd_ph -blocking 0 fconfigure $fd_ph -blocking 0
} }


proc commit_writetree {curHEAD msg} { proc commit_commitmsg {curHEAD msg_p} {
global pch_error

# -- Run the commit-msg hook.
#
set fd_ph [githook_read commit-msg $msg_p]
if {$fd_ph eq {}} {
commit_writetree $curHEAD $msg_p
return
}

ui_status {Calling commit-msg hook...}
set pch_error {}
fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
fileevent $fd_ph readable \
[list commit_commitmsg_wait $fd_ph $curHEAD $msg_p]
}

proc commit_commitmsg_wait {fd_ph curHEAD msg_p} {
global pch_error

append pch_error [read $fd_ph]
fconfigure $fd_ph -blocking 1
if {[eof $fd_ph]} {
if {[catch {close $fd_ph}]} {
catch {file delete $msg_p}
ui_status {Commit declined by commit-msg hook.}
hook_failed_popup commit-msg $pch_error
unlock_index
} else {
commit_writetree $curHEAD $msg_p
}
set pch_error {}
return
}
fconfigure $fd_ph -blocking 0
}

proc commit_writetree {curHEAD msg_p} {
ui_status {Committing changes...} ui_status {Committing changes...}
set fd_wt [git_read write-tree] set fd_wt [git_read write-tree]
fileevent $fd_wt readable \ fileevent $fd_wt readable \
[list commit_committree $fd_wt $curHEAD $msg] [list commit_committree $fd_wt $curHEAD $msg_p]
} }


proc commit_committree {fd_wt curHEAD msg} { proc commit_committree {fd_wt curHEAD msg_p} {
global HEAD PARENT MERGE_HEAD commit_type global HEAD PARENT MERGE_HEAD commit_type
global current_branch global current_branch
global ui_comm selected_commit_type global ui_comm selected_commit_type
@ -254,6 +299,7 @@ proc commit_committree {fd_wt curHEAD msg} {


gets $fd_wt tree_id gets $fd_wt tree_id
if {[catch {close $fd_wt} err]} { if {[catch {close $fd_wt} err]} {
catch {file delete $msg_p}
error_popup [strcat [mc "write-tree failed:"] "\n\n$err"] error_popup [strcat [mc "write-tree failed:"] "\n\n$err"]
ui_status {Commit failed.} ui_status {Commit failed.}
unlock_index unlock_index
@ -276,6 +322,7 @@ proc commit_committree {fd_wt curHEAD msg} {
} }


if {$tree_id eq $old_tree} { if {$tree_id eq $old_tree} {
catch {file delete $msg_p}
info_popup [mc "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. No files were modified by this commit and it was not a merge commit.
@ -288,24 +335,6 @@ A rescan will be automatically started now.
} }
} }


# -- Build the message.
#
set msg_p [gitdir COMMIT_EDITMSG]
set msg_wt [open $msg_p w]
fconfigure $msg_wt -translation lf
if {[catch {set enc $repo_config(i18n.commitencoding)}]} {
set enc utf-8
}
set use_enc [tcl_encoding $enc]
if {$use_enc ne {}} {
fconfigure $msg_wt -encoding $use_enc
} else {
puts stderr [mc "warning: Tcl does not support encoding '%s'." $enc]
fconfigure $msg_wt -encoding utf-8
}
puts $msg_wt $msg
close $msg_wt

# -- Create the commit. # -- Create the commit.
# #
set cmd [list commit-tree $tree_id] set cmd [list commit-tree $tree_id]
@ -314,6 +343,7 @@ A rescan will be automatically started now.
} }
lappend cmd <$msg_p lappend cmd <$msg_p
if {[catch {set cmt_id [eval git $cmd]} err]} { if {[catch {set cmt_id [eval git $cmd]} err]} {
catch {file delete $msg_p}
error_popup [strcat [mc "commit-tree failed:"] "\n\n$err"] error_popup [strcat [mc "commit-tree failed:"] "\n\n$err"]
ui_status {Commit failed.} ui_status {Commit failed.}
unlock_index unlock_index
@ -326,16 +356,14 @@ A rescan will be automatically started now.
if {$commit_type ne {normal}} { if {$commit_type ne {normal}} {
append reflogm " ($commit_type)" append reflogm " ($commit_type)"
} }
set i [string first "\n" $msg] set msg_fd [open $msg_p r]
if {$i >= 0} { gets $msg_fd subject
set subject [string range $msg 0 [expr {$i - 1}]] close $msg_fd
} else {
set subject $msg
}
append reflogm {: } $subject append reflogm {: } $subject
if {[catch { if {[catch {
git update-ref -m $reflogm HEAD $cmt_id $curHEAD git update-ref -m $reflogm HEAD $cmt_id $curHEAD
} err]} { } err]} {
catch {file delete $msg_p}
error_popup [strcat [mc "update-ref failed:"] "\n\n$err"] error_popup [strcat [mc "update-ref failed:"] "\n\n$err"]
ui_status {Commit failed.} ui_status {Commit failed.}
unlock_index unlock_index
@ -363,17 +391,13 @@ A rescan will be automatically started now.


# -- Run the post-commit hook. # -- Run the post-commit hook.
# #
set pchook [gitdir hooks post-commit] set fd_ph [githook_read post-commit]
if {[is_Cygwin] && [file isfile $pchook]} { if {$fd_ph ne {}} {
set pchook [list sh -c [concat \ upvar #0 pch_error$cmt_id pc_err
"if test -x \"$pchook\";" \ set pc_err {}
"then exec \"$pchook\";" \ fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
"fi"]] fileevent $fd_ph readable \
} elseif {![file executable $pchook]} { [list commit_postcommit_wait $fd_ph $cmt_id]
set pchook {}
}
if {$pchook ne {}} {
catch {exec $pchook &}
} }


$ui_comm delete 0.0 end $ui_comm delete 0.0 end
@ -429,3 +453,18 @@ A rescan will be automatically started now.
reshow_diff reshow_diff
ui_status [mc "Created commit %s: %s" [string range $cmt_id 0 7] $subject] ui_status [mc "Created commit %s: %s" [string range $cmt_id 0 7] $subject]
} }

proc commit_postcommit_wait {fd_ph cmt_id} {
upvar #0 pch_error$cmt_id pch_error

append pch_error [read $fd_ph]
fconfigure $fd_ph -blocking 1
if {[eof $fd_ph]} {
if {[catch {close $fd_ph}]} {
hook_failed_popup post-commit $pch_error 0
}
unset pch_error
return
}
fconfigure $fd_ph -blocking 0
}

18
git-gui/lib/error.tcl

@ -62,7 +62,7 @@ proc ask_popup {msg} {
eval $cmd eval $cmd
} }


proc hook_failed_popup {hook msg} { proc hook_failed_popup {hook msg {is_fatal 1}} {
set w .hookfail set w .hookfail
toplevel $w toplevel $w


@ -77,14 +77,16 @@ proc hook_failed_popup {hook msg} {
-width 80 -height 10 \ -width 80 -height 10 \
-font font_diff \ -font font_diff \
-yscrollcommand [list $w.m.sby set] -yscrollcommand [list $w.m.sby set]
label $w.m.l2 \
-text [mc "You must correct the above errors before committing."] \
-anchor w \
-justify left \
-font font_uibold
scrollbar $w.m.sby -command [list $w.m.t yview] scrollbar $w.m.sby -command [list $w.m.t yview]
pack $w.m.l1 -side top -fill x pack $w.m.l1 -side top -fill x
pack $w.m.l2 -side bottom -fill x if {$is_fatal} {
label $w.m.l2 \
-text [mc "You must correct the above errors before committing."] \
-anchor w \
-justify left \
-font font_uibold
pack $w.m.l2 -side bottom -fill x
}
pack $w.m.sby -side right -fill y pack $w.m.sby -side right -fill y
pack $w.m.t -side left -fill both -expand 1 pack $w.m.t -side left -fill both -expand 1
pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10 pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10
@ -99,6 +101,6 @@ proc hook_failed_popup {hook msg} {


bind $w <Visibility> "grab $w; focus $w" bind $w <Visibility> "grab $w; focus $w"
bind $w <Key-Return> "destroy $w" bind $w <Key-Return> "destroy $w"
wm title $w [append "[appname] ([reponame]): " [mc "error"]] wm title $w [strcat "[appname] ([reponame]): " [mc "error"]]
tkwait window $w tkwait window $w
} }

26
git-gui/po/glossary/fr.po

@ -34,7 +34,7 @@ msgstr "branche"


#. "" #. ""
msgid "branch [verb]" msgid "branch [verb]"
msgstr "créer une branche" msgstr "créer une branche"


#. "" #. ""
msgid "checkout [noun]" msgid "checkout [noun]"
@ -58,7 +58,7 @@ msgstr "commiter"


#. "" #. ""
msgid "diff [noun]" msgid "diff [noun]"
msgstr "différence" msgstr "différence"


#. "" #. ""
msgid "diff [verb]" msgid "diff [verb]"
@ -70,11 +70,11 @@ msgstr "fusion par avance rapide"


#. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too." #. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
msgid "fetch" msgid "fetch"
msgstr "récupérer" msgstr "récupérer"


#. "A collection of files. The index is a stored version of your working tree." #. "A collection of files. The index is a stored version of your working tree."
msgid "index (in git-gui: staging area)" msgid "index (in git-gui: staging area)"
msgstr "pré-commit" msgstr "pré-commit"


#. "A successful merge results in the creation of a new commit representing the result of the merge." #. "A successful merge results in the creation of a new commit representing the result of the merge."
msgid "merge [noun]" msgid "merge [noun]"
@ -106,15 +106,15 @@ msgstr "refaire"


#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks." #. "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
msgid "remote" msgid "remote"
msgstr "référentiel distant" msgstr "référentiel distant"


#. "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)" #. "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)"
msgid "repository" msgid "repository"
msgstr "référentiel" msgstr "référentiel"


#. "" #. ""
msgid "reset" msgid "reset"
msgstr "réinitialiser" msgstr "réinitialiser"


#. "" #. ""
msgid "revert" msgid "revert"
@ -122,7 +122,7 @@ msgstr "inverser"


#. "A particular state of files and directories which was stored in the object database." #. "A particular state of files and directories which was stored in the object database."
msgid "revision" msgid "revision"
msgstr "révision" msgstr "révision"


#. "" #. ""
msgid "sign off" msgid "sign off"
@ -130,11 +130,11 @@ msgstr "signer"


#. "" #. ""
msgid "staging area" msgid "staging area"
msgstr "pré-commit" msgstr "pré-commit"


#. "" #. ""
msgid "status" msgid "status"
msgstr "état" msgstr "état"


#. "A ref pointing to a tag or commit object" #. "A ref pointing to a tag or commit object"
msgid "tag [noun]" msgid "tag [noun]"
@ -150,15 +150,15 @@ msgstr "branche de suivi"


#. "" #. ""
msgid "undo" msgid "undo"
msgstr "défaire" msgstr "défaire"


#. "" #. ""
msgid "update" msgid "update"
msgstr "mise à jour" msgstr "mise à jour"


#. "" #. ""
msgid "verify" msgid "verify"
msgstr "vérifier" msgstr "vérifier"


#. "The tree of actual checked out files." #. "The tree of actual checked out files."
msgid "working copy, working tree" msgid "working copy, working tree"

Loading…
Cancel
Save