Skip to content

Commit 36a189c

Browse files
committed
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
2 parents ce33288 + 6caaf2d commit 36a189c

File tree

4 files changed

+145
-76
lines changed

4 files changed

+145
-76
lines changed

git-gui/git-gui.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,34 @@ proc git_write {args} {
438438
return [open [concat $opt $cmdp $args] w]
439439
}
440440
441+
proc githook_read {hook_name args} {
442+
set pchook [gitdir hooks $hook_name]
443+
lappend args 2>@1
444+
445+
# On Cygwin [file executable] might lie so we need to ask
446+
# the shell if the hook is executable. Yes that's annoying.
447+
#
448+
if {[is_Cygwin]} {
449+
upvar #0 _sh interp
450+
if {![info exists interp]} {
451+
set interp [_which sh]
452+
}
453+
if {$interp eq {}} {
454+
error "hook execution requires sh (not in PATH)"
455+
}
456+
457+
set scr {if test -x "$1";then exec "$@";fi}
458+
set sh_c [list | $interp -c $scr $interp $pchook]
459+
return [_open_stdout_stderr [concat $sh_c $args]]
460+
}
461+
462+
if {[file executable $pchook]} {
463+
return [_open_stdout_stderr [concat [list | $pchook] $args]]
464+
}
465+
466+
return {}
467+
}
468+
441469
proc sq {value} {
442470
regsub -all ' $value "'\\''" value
443471
return "'$value'"

git-gui/lib/commit.tcl

Lines changed: 94 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -192,60 +192,105 @@ A good commit message has the following format:
192192
return
193193
}
194194

195-
# -- Run the pre-commit hook.
195+
# -- Build the message file.
196196
#
197-
set pchook [gitdir hooks pre-commit]
197+
set msg_p [gitdir GITGUI_EDITMSG]
198+
set msg_wt [open $msg_p w]
199+
fconfigure $msg_wt -translation lf
200+
if {[catch {set enc $repo_config(i18n.commitencoding)}]} {
201+
set enc utf-8
202+
}
203+
set use_enc [tcl_encoding $enc]
204+
if {$use_enc ne {}} {
205+
fconfigure $msg_wt -encoding $use_enc
206+
} else {
207+
puts stderr [mc "warning: Tcl does not support encoding '%s'." $enc]
208+
fconfigure $msg_wt -encoding utf-8
209+
}
210+
puts $msg_wt $msg
211+
close $msg_wt
198212

199-
# On Cygwin [file executable] might lie so we need to ask
200-
# the shell if the hook is executable. Yes that's annoying.
213+
# -- Run the pre-commit hook.
201214
#
202-
if {[is_Cygwin] && [file isfile $pchook]} {
203-
set pchook [list sh -c [concat \
204-
"if test -x \"$pchook\";" \
205-
"then exec \"$pchook\" 2>&1;" \
206-
"fi"]]
207-
} elseif {[file executable $pchook]} {
208-
set pchook [list $pchook |& cat]
209-
} else {
210-
commit_writetree $curHEAD $msg
215+
set fd_ph [githook_read pre-commit]
216+
if {$fd_ph eq {}} {
217+
commit_commitmsg $curHEAD $msg_p
211218
return
212219
}
213220

214221
ui_status {Calling pre-commit hook...}
215222
set pch_error {}
216-
set fd_ph [open "| $pchook" r]
217223
fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
218224
fileevent $fd_ph readable \
219-
[list commit_prehook_wait $fd_ph $curHEAD $msg]
225+
[list commit_prehook_wait $fd_ph $curHEAD $msg_p]
220226
}
221227

222-
proc commit_prehook_wait {fd_ph curHEAD msg} {
228+
proc commit_prehook_wait {fd_ph curHEAD msg_p} {
223229
global pch_error
224230

225231
append pch_error [read $fd_ph]
226232
fconfigure $fd_ph -blocking 1
227233
if {[eof $fd_ph]} {
228234
if {[catch {close $fd_ph}]} {
235+
catch {file delete $msg_p}
229236
ui_status {Commit declined by pre-commit hook.}
230237
hook_failed_popup pre-commit $pch_error
231238
unlock_index
232239
} else {
233-
commit_writetree $curHEAD $msg
240+
commit_commitmsg $curHEAD $msg_p
234241
}
235242
set pch_error {}
236243
return
237244
}
238245
fconfigure $fd_ph -blocking 0
239246
}
240247

241-
proc commit_writetree {curHEAD msg} {
248+
proc commit_commitmsg {curHEAD msg_p} {
249+
global pch_error
250+
251+
# -- Run the commit-msg hook.
252+
#
253+
set fd_ph [githook_read commit-msg $msg_p]
254+
if {$fd_ph eq {}} {
255+
commit_writetree $curHEAD $msg_p
256+
return
257+
}
258+
259+
ui_status {Calling commit-msg hook...}
260+
set pch_error {}
261+
fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
262+
fileevent $fd_ph readable \
263+
[list commit_commitmsg_wait $fd_ph $curHEAD $msg_p]
264+
}
265+
266+
proc commit_commitmsg_wait {fd_ph curHEAD msg_p} {
267+
global pch_error
268+
269+
append pch_error [read $fd_ph]
270+
fconfigure $fd_ph -blocking 1
271+
if {[eof $fd_ph]} {
272+
if {[catch {close $fd_ph}]} {
273+
catch {file delete $msg_p}
274+
ui_status {Commit declined by commit-msg hook.}
275+
hook_failed_popup commit-msg $pch_error
276+
unlock_index
277+
} else {
278+
commit_writetree $curHEAD $msg_p
279+
}
280+
set pch_error {}
281+
return
282+
}
283+
fconfigure $fd_ph -blocking 0
284+
}
285+
286+
proc commit_writetree {curHEAD msg_p} {
242287
ui_status {Committing changes...}
243288
set fd_wt [git_read write-tree]
244289
fileevent $fd_wt readable \
245-
[list commit_committree $fd_wt $curHEAD $msg]
290+
[list commit_committree $fd_wt $curHEAD $msg_p]
246291
}
247292

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

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

278324
if {$tree_id eq $old_tree} {
325+
catch {file delete $msg_p}
279326
info_popup [mc "No changes to commit.
280327
281328
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.
288335
}
289336
}
290337

291-
# -- Build the message.
292-
#
293-
set msg_p [gitdir COMMIT_EDITMSG]
294-
set msg_wt [open $msg_p w]
295-
fconfigure $msg_wt -translation lf
296-
if {[catch {set enc $repo_config(i18n.commitencoding)}]} {
297-
set enc utf-8
298-
}
299-
set use_enc [tcl_encoding $enc]
300-
if {$use_enc ne {}} {
301-
fconfigure $msg_wt -encoding $use_enc
302-
} else {
303-
puts stderr [mc "warning: Tcl does not support encoding '%s'." $enc]
304-
fconfigure $msg_wt -encoding utf-8
305-
}
306-
puts $msg_wt $msg
307-
close $msg_wt
308-
309338
# -- Create the commit.
310339
#
311340
set cmd [list commit-tree $tree_id]
@@ -314,6 +343,7 @@ A rescan will be automatically started now.
314343
}
315344
lappend cmd <$msg_p
316345
if {[catch {set cmt_id [eval git $cmd]} err]} {
346+
catch {file delete $msg_p}
317347
error_popup [strcat [mc "commit-tree failed:"] "\n\n$err"]
318348
ui_status {Commit failed.}
319349
unlock_index
@@ -326,16 +356,14 @@ A rescan will be automatically started now.
326356
if {$commit_type ne {normal}} {
327357
append reflogm " ($commit_type)"
328358
}
329-
set i [string first "\n" $msg]
330-
if {$i >= 0} {
331-
set subject [string range $msg 0 [expr {$i - 1}]]
332-
} else {
333-
set subject $msg
334-
}
359+
set msg_fd [open $msg_p r]
360+
gets $msg_fd subject
361+
close $msg_fd
335362
append reflogm {: } $subject
336363
if {[catch {
337364
git update-ref -m $reflogm HEAD $cmt_id $curHEAD
338365
} err]} {
366+
catch {file delete $msg_p}
339367
error_popup [strcat [mc "update-ref failed:"] "\n\n$err"]
340368
ui_status {Commit failed.}
341369
unlock_index
@@ -363,17 +391,13 @@ A rescan will be automatically started now.
363391

364392
# -- Run the post-commit hook.
365393
#
366-
set pchook [gitdir hooks post-commit]
367-
if {[is_Cygwin] && [file isfile $pchook]} {
368-
set pchook [list sh -c [concat \
369-
"if test -x \"$pchook\";" \
370-
"then exec \"$pchook\";" \
371-
"fi"]]
372-
} elseif {![file executable $pchook]} {
373-
set pchook {}
374-
}
375-
if {$pchook ne {}} {
376-
catch {exec $pchook &}
394+
set fd_ph [githook_read post-commit]
395+
if {$fd_ph ne {}} {
396+
upvar #0 pch_error$cmt_id pc_err
397+
set pc_err {}
398+
fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
399+
fileevent $fd_ph readable \
400+
[list commit_postcommit_wait $fd_ph $cmt_id]
377401
}
378402

379403
$ui_comm delete 0.0 end
@@ -429,3 +453,18 @@ A rescan will be automatically started now.
429453
reshow_diff
430454
ui_status [mc "Created commit %s: %s" [string range $cmt_id 0 7] $subject]
431455
}
456+
457+
proc commit_postcommit_wait {fd_ph cmt_id} {
458+
upvar #0 pch_error$cmt_id pch_error
459+
460+
append pch_error [read $fd_ph]
461+
fconfigure $fd_ph -blocking 1
462+
if {[eof $fd_ph]} {
463+
if {[catch {close $fd_ph}]} {
464+
hook_failed_popup post-commit $pch_error 0
465+
}
466+
unset pch_error
467+
return
468+
}
469+
fconfigure $fd_ph -blocking 0
470+
}

git-gui/lib/error.tcl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ proc ask_popup {msg} {
6262
eval $cmd
6363
}
6464

65-
proc hook_failed_popup {hook msg} {
65+
proc hook_failed_popup {hook msg {is_fatal 1}} {
6666
set w .hookfail
6767
toplevel $w
6868

@@ -77,14 +77,16 @@ proc hook_failed_popup {hook msg} {
7777
-width 80 -height 10 \
7878
-font font_diff \
7979
-yscrollcommand [list $w.m.sby set]
80-
label $w.m.l2 \
81-
-text [mc "You must correct the above errors before committing."] \
82-
-anchor w \
83-
-justify left \
84-
-font font_uibold
8580
scrollbar $w.m.sby -command [list $w.m.t yview]
8681
pack $w.m.l1 -side top -fill x
87-
pack $w.m.l2 -side bottom -fill x
82+
if {$is_fatal} {
83+
label $w.m.l2 \
84+
-text [mc "You must correct the above errors before committing."] \
85+
-anchor w \
86+
-justify left \
87+
-font font_uibold
88+
pack $w.m.l2 -side bottom -fill x
89+
}
8890
pack $w.m.sby -side right -fill y
8991
pack $w.m.t -side left -fill both -expand 1
9092
pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10
@@ -99,6 +101,6 @@ proc hook_failed_popup {hook msg} {
99101

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

0 commit comments

Comments
 (0)