@@ -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
281328No 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+ }
0 commit comments