X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=lib%2Fcommit.tcl;h=2977315624fc5deeecff275d8dc8b3f2e3210a70;hb=b2ca414973c3bcd00f2b94538bd9c755387f30a0;hp=15489c616b76567604a605ce59b8fbb797318678;hpb=1ac17950e93a956d01b042db3de70010195eddcc;p=git.git diff --git a/lib/commit.tcl b/lib/commit.tcl index 15489c616..297731562 100644 --- a/lib/commit.tcl +++ b/lib/commit.tcl @@ -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 [append [mc "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 [append [mc "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 [append [mc "Invalid GIT_COMMITTER_IDENT:"] "\n\n$me"] + error_popup [strcat [mc "Invalid GIT_COMMITTER_IDENT:"] "\n\n$me"] return {} } } @@ -149,7 +149,9 @@ The rescan will be automatically started now. _? {continue} A? - D? - + T_ - M? {set files_ready 1} + _U - U? { error_popup [mc "Unmerged files cannot be committed. @@ -184,7 +186,7 @@ You must stage at least 1 file before you can commit. A good commit message has the following format: -- First line: Describe in one sentance what you did. +- First line: Describe in one sentence what you did. - Second line: Blank - Remaining lines: Describe why this change is good. "] @@ -192,45 +194,52 @@ A good commit message has the following format: 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 - # the shell if the hook is executable. Yes that's annoying. + # -- Run the pre-commit hook. # - if {[is_Cygwin] && [file isfile $pchook]} { - set pchook [list sh -c [concat \ - "if test -x \"$pchook\";" \ - "then exec \"$pchook\" 2>&1;" \ - "fi"]] - } elseif {[file executable $pchook]} { - set pchook [list $pchook |& cat] - } else { - commit_writetree $curHEAD $msg + set fd_ph [githook_read pre-commit] + if {$fd_ph eq {}} { + commit_commitmsg $curHEAD $msg_p return } - ui_status {Calling pre-commit hook...} + ui_status [mc "Calling pre-commit hook..."] set pch_error {} - set fd_ph [open "| $pchook" r] fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} 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 append pch_error [read $fd_ph] fconfigure $fd_ph -blocking 1 if {[eof $fd_ph]} { if {[catch {close $fd_ph}]} { - ui_status {Commit declined by pre-commit hook.} + catch {file delete $msg_p} + ui_status [mc "Commit declined by pre-commit hook."] hook_failed_popup pre-commit $pch_error unlock_index } else { - commit_writetree $curHEAD $msg + commit_commitmsg $curHEAD $msg_p } set pch_error {} return @@ -238,14 +247,52 @@ proc commit_prehook_wait {fd_ph curHEAD msg} { fconfigure $fd_ph -blocking 0 } -proc commit_writetree {curHEAD msg} { - ui_status {Committing changes...} +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 [mc "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 [mc "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 [mc "Committing changes..."] set fd_wt [git_read write-tree] 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 current_branch global ui_comm selected_commit_type @@ -253,9 +300,10 @@ proc commit_committree {fd_wt curHEAD msg} { global repo_config gets $fd_wt tree_id - if {$tree_id eq {} || [catch {close $fd_wt} err]} { - error_popup [append [mc "write-tree failed:"] "\n\n$err"] - ui_status {Commit failed.} + if {[catch {close $fd_wt} err]} { + catch {file delete $msg_p} + error_popup [strcat [mc "write-tree failed:"] "\n\n$err"] + ui_status [mc "Commit failed."] unlock_index return } @@ -272,10 +320,11 @@ 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} { + catch {file delete $msg_p} info_popup [mc "No changes to commit. No files were modified by this commit and it was not a merge commit. @@ -288,24 +337,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 "warning: Tcl does not support encoding '$enc'." - fconfigure $msg_wt -encoding utf-8 - } - puts -nonewline $msg_wt $msg - close $msg_wt - # -- Create the commit. # set cmd [list commit-tree $tree_id] @@ -314,8 +345,9 @@ A rescan will be automatically started now. } lappend cmd <$msg_p if {[catch {set cmt_id [eval git $cmd]} err]} { - error_popup [append [mc "commit-tree failed:"] "\n\n$err"] - ui_status {Commit failed.} + catch {file delete $msg_p} + error_popup [strcat [mc "commit-tree failed:"] "\n\n$err"] + ui_status [mc "Commit failed."] unlock_index return } @@ -326,18 +358,16 @@ A rescan will be automatically started now. if {$commit_type ne {normal}} { append reflogm " ($commit_type)" } - set i [string first "\n" $msg] - if {$i >= 0} { - set subject [string range $msg 0 [expr {$i - 1}]] - } else { - set subject $msg - } + set msg_fd [open $msg_p r] + gets $msg_fd subject + close $msg_fd append reflogm {: } $subject if {[catch { git update-ref -m $reflogm HEAD $cmt_id $curHEAD } err]} { - error_popup [append [mc "update-ref failed:"] "\n\n$err"] - ui_status {Commit failed.} + catch {file delete $msg_p} + error_popup [strcat [mc "update-ref failed:"] "\n\n$err"] + ui_status [mc "Commit failed."] unlock_index return } @@ -363,17 +393,13 @@ A rescan will be automatically started now. # -- Run the post-commit hook. # - set pchook [gitdir hooks post-commit] - if {[is_Cygwin] && [file isfile $pchook]} { - set pchook [list sh -c [concat \ - "if test -x \"$pchook\";" \ - "then exec \"$pchook\";" \ - "fi"]] - } elseif {![file executable $pchook]} { - set pchook {} - } - if {$pchook ne {}} { - catch {exec $pchook &} + set fd_ph [githook_read post-commit] + if {$fd_ph ne {}} { + upvar #0 pch_error$cmt_id pc_err + set pc_err {} + fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fileevent $fd_ph readable \ + [list commit_postcommit_wait $fd_ph $cmt_id] } $ui_comm delete 0.0 end @@ -404,6 +430,7 @@ A rescan will be automatically started now. __ - A_ - M_ - + T_ - D_ { unset file_states($path) catch {unset selected_paths($path)} @@ -429,3 +456,18 @@ A rescan will be automatically started now. reshow_diff 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 +}