Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 1 | # git-gui misc. commit reading/writing support |
| 2 | # Copyright (C) 2006, 2007 Shawn Pearce |
| 3 | |
| 4 | proc load_last_commit {} { |
Pat Thoyts | cfe616b | 2016-10-06 14:04:42 +0100 | [diff] [blame] | 5 | global HEAD PARENT MERGE_HEAD commit_type ui_comm commit_author |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 6 | global repo_config |
| 7 | |
| 8 | if {[llength $PARENT] == 0} { |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 9 | error_popup [mc "There is nothing to amend. |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 10 | |
| 11 | You are about to create the initial commit. There is no commit before this to amend. |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 12 | "] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 13 | return |
| 14 | } |
| 15 | |
| 16 | repository_state curType curHEAD curMERGE_HEAD |
| 17 | if {$curType eq {merge}} { |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 18 | error_popup [mc "Cannot amend while merging. |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 19 | |
| 20 | You are currently in the middle of a merge that has not been fully completed. You cannot amend the prior commit unless you first abort the current merge activity. |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 21 | "] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 22 | return |
| 23 | } |
| 24 | |
| 25 | set msg {} |
| 26 | set parents [list] |
| 27 | if {[catch { |
Łukasz Stelmach | 331450f | 2017-12-05 15:23:26 +0100 | [diff] [blame] | 28 | set name "" |
| 29 | set email "" |
Shawn O. Pearce | 0b81261 | 2007-07-09 01:17:09 -0400 | [diff] [blame] | 30 | set fd [git_read cat-file commit $curHEAD] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 31 | fconfigure $fd -encoding binary -translation lf |
Alexander Gavrilov | 3ac31e4 | 2008-12-06 20:24:35 +0300 | [diff] [blame] | 32 | # By default commits are assumed to be in utf-8 |
| 33 | set enc utf-8 |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 34 | while {[gets $fd line] > 0} { |
| 35 | if {[string match {parent *} $line]} { |
| 36 | lappend parents [string range $line 7 end] |
| 37 | } elseif {[string match {encoding *} $line]} { |
| 38 | set enc [string tolower [string range $line 9 end]] |
Łukasz Stelmach | 331450f | 2017-12-05 15:23:26 +0100 | [diff] [blame] | 39 | } elseif {[regexp "author (.*)\\s<(.*)>\\s(\\d.*$)" $line all name email time]} { } |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 40 | } |
Shawn O. Pearce | c4638f6 | 2007-07-19 01:13:29 -0400 | [diff] [blame] | 41 | set msg [read $fd] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 42 | close $fd |
Shawn O. Pearce | c4638f6 | 2007-07-19 01:13:29 -0400 | [diff] [blame] | 43 | |
| 44 | set enc [tcl_encoding $enc] |
| 45 | if {$enc ne {}} { |
| 46 | set msg [encoding convertfrom $enc $msg] |
Łukasz Stelmach | 331450f | 2017-12-05 15:23:26 +0100 | [diff] [blame] | 47 | set name [encoding convertfrom $enc $name] |
| 48 | set email [encoding convertfrom $enc $email] |
Shawn O. Pearce | c4638f6 | 2007-07-19 01:13:29 -0400 | [diff] [blame] | 49 | } |
Łukasz Stelmach | 331450f | 2017-12-05 15:23:26 +0100 | [diff] [blame] | 50 | if {$name ne {} && $email ne {}} { |
| 51 | set commit_author [list name $name email $email date $time] |
| 52 | } |
| 53 | |
Shawn O. Pearce | c4638f6 | 2007-07-19 01:13:29 -0400 | [diff] [blame] | 54 | set msg [string trim $msg] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 55 | } err]} { |
Shawn O. Pearce | 31bb1d1 | 2007-09-14 01:50:09 -0400 | [diff] [blame] | 56 | error_popup [strcat [mc "Error loading commit data for amend:"] "\n\n$err"] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 57 | return |
| 58 | } |
| 59 | |
| 60 | set HEAD $curHEAD |
| 61 | set PARENT $parents |
| 62 | set MERGE_HEAD [list] |
| 63 | switch -- [llength $parents] { |
| 64 | 0 {set commit_type amend-initial} |
| 65 | 1 {set commit_type amend} |
| 66 | default {set commit_type amend-merge} |
| 67 | } |
| 68 | |
| 69 | $ui_comm delete 0.0 end |
| 70 | $ui_comm insert end $msg |
| 71 | $ui_comm edit reset |
| 72 | $ui_comm edit modified false |
Shawn O. Pearce | 699d560 | 2007-07-05 23:16:13 -0400 | [diff] [blame] | 73 | rescan ui_ready |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | set GIT_COMMITTER_IDENT {} |
| 77 | |
| 78 | proc committer_ident {} { |
| 79 | global GIT_COMMITTER_IDENT |
| 80 | |
| 81 | if {$GIT_COMMITTER_IDENT eq {}} { |
| 82 | if {[catch {set me [git var GIT_COMMITTER_IDENT]} err]} { |
Shawn O. Pearce | 31bb1d1 | 2007-09-14 01:50:09 -0400 | [diff] [blame] | 83 | error_popup [strcat [mc "Unable to obtain your identity:"] "\n\n$err"] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 84 | return {} |
| 85 | } |
| 86 | if {![regexp {^(.*) [0-9]+ [-+0-9]+$} \ |
| 87 | $me me GIT_COMMITTER_IDENT]} { |
Shawn O. Pearce | 31bb1d1 | 2007-09-14 01:50:09 -0400 | [diff] [blame] | 88 | error_popup [strcat [mc "Invalid GIT_COMMITTER_IDENT:"] "\n\n$me"] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 89 | return {} |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | return $GIT_COMMITTER_IDENT |
| 94 | } |
| 95 | |
| 96 | proc do_signoff {} { |
| 97 | global ui_comm |
| 98 | |
| 99 | set me [committer_ident] |
| 100 | if {$me eq {}} return |
| 101 | |
| 102 | set sob "Signed-off-by: $me" |
| 103 | set last [$ui_comm get {end -1c linestart} {end -1c}] |
| 104 | if {$last ne $sob} { |
| 105 | $ui_comm edit separator |
| 106 | if {$last ne {} |
| 107 | && ![regexp {^[A-Z][A-Za-z]*-[A-Za-z-]+: *} $last]} { |
| 108 | $ui_comm insert end "\n" |
| 109 | } |
| 110 | $ui_comm insert end "\n$sob" |
| 111 | $ui_comm edit separator |
| 112 | $ui_comm see end |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | proc create_new_commit {} { |
Pat Thoyts | cfe616b | 2016-10-06 14:04:42 +0100 | [diff] [blame] | 117 | global commit_type ui_comm commit_author |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 118 | |
| 119 | set commit_type normal |
Pat Thoyts | cfe616b | 2016-10-06 14:04:42 +0100 | [diff] [blame] | 120 | unset -nocomplain commit_author |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 121 | $ui_comm delete 0.0 end |
| 122 | $ui_comm edit reset |
| 123 | $ui_comm edit modified false |
Shawn O. Pearce | 699d560 | 2007-07-05 23:16:13 -0400 | [diff] [blame] | 124 | rescan ui_ready |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 125 | } |
| 126 | |
Alexander Gavrilov | 06569cd | 2009-01-24 00:18:13 +0300 | [diff] [blame] | 127 | proc setup_commit_encoding {msg_wt {quiet 0}} { |
| 128 | global repo_config |
| 129 | |
| 130 | if {[catch {set enc $repo_config(i18n.commitencoding)}]} { |
| 131 | set enc utf-8 |
| 132 | } |
| 133 | set use_enc [tcl_encoding $enc] |
| 134 | if {$use_enc ne {}} { |
| 135 | fconfigure $msg_wt -encoding $use_enc |
| 136 | } else { |
| 137 | if {!$quiet} { |
| 138 | error_popup [mc "warning: Tcl does not support encoding '%s'." $enc] |
| 139 | } |
| 140 | fconfigure $msg_wt -encoding utf-8 |
| 141 | } |
| 142 | } |
| 143 | |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 144 | proc commit_tree {} { |
| 145 | global HEAD commit_type file_states ui_comm repo_config |
Shawn O. Pearce | 699d560 | 2007-07-05 23:16:13 -0400 | [diff] [blame] | 146 | global pch_error |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 147 | |
| 148 | if {[committer_ident] eq {}} return |
| 149 | if {![lock_index update]} return |
| 150 | |
| 151 | # -- Our in memory state should match the repository. |
| 152 | # |
| 153 | repository_state curType curHEAD curMERGE_HEAD |
| 154 | if {[string match amend* $commit_type] |
| 155 | && $curType eq {normal} |
| 156 | && $curHEAD eq $HEAD} { |
| 157 | } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} { |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 158 | info_popup [mc "Last scanned state does not match repository state. |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 159 | |
| 160 | Another Git program has modified this repository since the last scan. A rescan must be performed before another commit can be created. |
| 161 | |
| 162 | The rescan will be automatically started now. |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 163 | "] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 164 | unlock_index |
Shawn O. Pearce | 699d560 | 2007-07-05 23:16:13 -0400 | [diff] [blame] | 165 | rescan ui_ready |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 166 | return |
| 167 | } |
| 168 | |
| 169 | # -- At least one file should differ in the index. |
| 170 | # |
| 171 | set files_ready 0 |
| 172 | foreach path [array names file_states] { |
Bert Wesarg | 4a065c8 | 2010-12-09 21:46:22 +0100 | [diff] [blame] | 173 | set s $file_states($path) |
| 174 | switch -glob -- [lindex $s 0] { |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 175 | _? {continue} |
| 176 | A? - |
| 177 | D? - |
Bert Wesarg | 7587f4d | 2010-12-09 21:46:23 +0100 | [diff] [blame] | 178 | T? - |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 179 | M? {set files_ready 1} |
Alexander Gavrilov | ff515d8 | 2008-08-31 01:00:49 +0400 | [diff] [blame] | 180 | _U - |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 181 | U? { |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 182 | error_popup [mc "Unmerged files cannot be committed. |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 183 | |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 184 | File %s has merge conflicts. You must resolve them and stage the file before committing. |
| 185 | " [short_path $path]] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 186 | unlock_index |
| 187 | return |
| 188 | } |
| 189 | default { |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 190 | error_popup [mc "Unknown file state %s detected. |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 191 | |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 192 | File %s cannot be committed by this program. |
| 193 | " [lindex $s 0] [short_path $path]] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 194 | } |
| 195 | } |
| 196 | } |
Alexander Gavrilov | 1e65c62 | 2008-09-12 22:43:49 +0400 | [diff] [blame] | 197 | if {!$files_ready && ![string match *merge $curType] && ![is_enabled nocommit]} { |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 198 | info_popup [mc "No changes to commit. |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 199 | |
Christian Stimming | 360cc10 | 2007-07-28 22:17:10 +0200 | [diff] [blame] | 200 | You must stage at least 1 file before you can commit. |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 201 | "] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 202 | unlock_index |
| 203 | return |
| 204 | } |
| 205 | |
Alexander Gavrilov | 1e65c62 | 2008-09-12 22:43:49 +0400 | [diff] [blame] | 206 | if {[is_enabled nocommitmsg]} { do_quit 0 } |
| 207 | |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 208 | # -- A message is required. |
| 209 | # |
Pratyush Yadav | c0698df | 2021-03-04 13:53:27 +0530 | [diff] [blame] | 210 | set msg [string trim [$ui_comm get 1.0 end]] |
| 211 | regsub -all -line {[ \t\r]+$} $msg {} msg |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 212 | if {$msg eq {}} { |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 213 | error_popup [mc "Please supply a commit message. |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 214 | |
| 215 | A good commit message has the following format: |
| 216 | |
Michele Ballabio | 208320d | 2007-11-22 16:20:08 +0100 | [diff] [blame] | 217 | - First line: Describe in one sentence what you did. |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 218 | - Second line: Blank |
| 219 | - Remaining lines: Describe why this change is good. |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 220 | "] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 221 | unlock_index |
| 222 | return |
| 223 | } |
| 224 | |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 225 | # -- Build the message file. |
| 226 | # |
| 227 | set msg_p [gitdir GITGUI_EDITMSG] |
| 228 | set msg_wt [open $msg_p w] |
| 229 | fconfigure $msg_wt -translation lf |
Alexander Gavrilov | 06569cd | 2009-01-24 00:18:13 +0300 | [diff] [blame] | 230 | setup_commit_encoding $msg_wt |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 231 | puts $msg_wt $msg |
| 232 | close $msg_wt |
| 233 | |
Alexander Gavrilov | 1e65c62 | 2008-09-12 22:43:49 +0400 | [diff] [blame] | 234 | if {[is_enabled nocommit]} { do_quit 0 } |
| 235 | |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 236 | # -- Run the pre-commit hook. |
| 237 | # |
Shawn O. Pearce | ed76cb7 | 2008-01-20 14:46:59 -0500 | [diff] [blame] | 238 | set fd_ph [githook_read pre-commit] |
| 239 | if {$fd_ph eq {}} { |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 240 | commit_commitmsg $curHEAD $msg_p |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 241 | return |
| 242 | } |
| 243 | |
Christian Stimming | 5e6d776 | 2008-02-02 10:20:17 +0100 | [diff] [blame] | 244 | ui_status [mc "Calling pre-commit hook..."] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 245 | set pch_error {} |
Shawn O. Pearce | 6eb420e | 2007-07-17 01:50:10 -0400 | [diff] [blame] | 246 | fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 247 | fileevent $fd_ph readable \ |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 248 | [list commit_prehook_wait $fd_ph $curHEAD $msg_p] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 249 | } |
| 250 | |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 251 | proc commit_prehook_wait {fd_ph curHEAD msg_p} { |
Shawn O. Pearce | 699d560 | 2007-07-05 23:16:13 -0400 | [diff] [blame] | 252 | global pch_error |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 253 | |
| 254 | append pch_error [read $fd_ph] |
| 255 | fconfigure $fd_ph -blocking 1 |
| 256 | if {[eof $fd_ph]} { |
| 257 | if {[catch {close $fd_ph}]} { |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 258 | catch {file delete $msg_p} |
Christian Stimming | 5e6d776 | 2008-02-02 10:20:17 +0100 | [diff] [blame] | 259 | ui_status [mc "Commit declined by pre-commit hook."] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 260 | hook_failed_popup pre-commit $pch_error |
| 261 | unlock_index |
| 262 | } else { |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 263 | commit_commitmsg $curHEAD $msg_p |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 264 | } |
| 265 | set pch_error {} |
| 266 | return |
| 267 | } |
| 268 | fconfigure $fd_ph -blocking 0 |
| 269 | } |
| 270 | |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 271 | proc commit_commitmsg {curHEAD msg_p} { |
Heiko Voigt | e34789c | 2011-02-15 19:43:54 +0000 | [diff] [blame] | 272 | global is_detached repo_config |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 273 | global pch_error |
| 274 | |
Bert Wesarg | d8d166b | 2011-10-22 21:39:40 +0200 | [diff] [blame] | 275 | if {$is_detached |
| 276 | && ![file exists [gitdir rebase-merge head-name]] |
| 277 | && [is_config_true gui.warndetachedcommit]} { |
Heiko Voigt | e34789c | 2011-02-15 19:43:54 +0000 | [diff] [blame] | 278 | set msg [mc "You are about to commit on a detached head.\ |
| 279 | This is a potentially dangerous thing to do because if you switch\ |
Beat Bolli | 9ef7508 | 2012-08-18 13:24:00 -0700 | [diff] [blame] | 280 | to another branch you will lose your changes and it can be difficult\ |
Heiko Voigt | e34789c | 2011-02-15 19:43:54 +0000 | [diff] [blame] | 281 | to retrieve them later from the reflog. You should probably cancel this\ |
| 282 | commit and create a new branch to continue.\n\ |
| 283 | \n\ |
| 284 | Do you really want to proceed with your Commit?"] |
| 285 | if {[ask_popup $msg] ne yes} { |
| 286 | unlock_index |
| 287 | return |
| 288 | } |
| 289 | } |
| 290 | |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 291 | # -- Run the commit-msg hook. |
| 292 | # |
Shawn O. Pearce | ed76cb7 | 2008-01-20 14:46:59 -0500 | [diff] [blame] | 293 | set fd_ph [githook_read commit-msg $msg_p] |
| 294 | if {$fd_ph eq {}} { |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 295 | commit_writetree $curHEAD $msg_p |
| 296 | return |
| 297 | } |
| 298 | |
Christian Stimming | 5e6d776 | 2008-02-02 10:20:17 +0100 | [diff] [blame] | 299 | ui_status [mc "Calling commit-msg hook..."] |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 300 | set pch_error {} |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 301 | fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} |
| 302 | fileevent $fd_ph readable \ |
| 303 | [list commit_commitmsg_wait $fd_ph $curHEAD $msg_p] |
| 304 | } |
| 305 | |
| 306 | proc commit_commitmsg_wait {fd_ph curHEAD msg_p} { |
| 307 | global pch_error |
| 308 | |
| 309 | append pch_error [read $fd_ph] |
| 310 | fconfigure $fd_ph -blocking 1 |
| 311 | if {[eof $fd_ph]} { |
| 312 | if {[catch {close $fd_ph}]} { |
| 313 | catch {file delete $msg_p} |
Christian Stimming | 5e6d776 | 2008-02-02 10:20:17 +0100 | [diff] [blame] | 314 | ui_status [mc "Commit declined by commit-msg hook."] |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 315 | hook_failed_popup commit-msg $pch_error |
| 316 | unlock_index |
| 317 | } else { |
| 318 | commit_writetree $curHEAD $msg_p |
| 319 | } |
| 320 | set pch_error {} |
| 321 | return |
| 322 | } |
| 323 | fconfigure $fd_ph -blocking 0 |
| 324 | } |
| 325 | |
| 326 | proc commit_writetree {curHEAD msg_p} { |
Christian Stimming | 5e6d776 | 2008-02-02 10:20:17 +0100 | [diff] [blame] | 327 | ui_status [mc "Committing changes..."] |
Shawn O. Pearce | 0b81261 | 2007-07-09 01:17:09 -0400 | [diff] [blame] | 328 | set fd_wt [git_read write-tree] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 329 | fileevent $fd_wt readable \ |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 330 | [list commit_committree $fd_wt $curHEAD $msg_p] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 331 | } |
| 332 | |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 333 | proc commit_committree {fd_wt curHEAD msg_p} { |
Pat Thoyts | cfe616b | 2016-10-06 14:04:42 +0100 | [diff] [blame] | 334 | global HEAD PARENT MERGE_HEAD commit_type commit_author |
Shawn O. Pearce | 699d560 | 2007-07-05 23:16:13 -0400 | [diff] [blame] | 335 | global current_branch |
Bert Wesarg | ba41b5b | 2019-09-13 08:02:30 +0200 | [diff] [blame] | 336 | global ui_comm commit_type_is_amend |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 337 | global file_states selected_paths rescan_active |
| 338 | global repo_config |
Pat Thoyts | cfe616b | 2016-10-06 14:04:42 +0100 | [diff] [blame] | 339 | global env |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 340 | |
| 341 | gets $fd_wt tree_id |
Shawn O. Pearce | 8af52d7 | 2007-10-20 01:42:01 -0400 | [diff] [blame] | 342 | if {[catch {close $fd_wt} err]} { |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 343 | catch {file delete $msg_p} |
Shawn O. Pearce | 31bb1d1 | 2007-09-14 01:50:09 -0400 | [diff] [blame] | 344 | error_popup [strcat [mc "write-tree failed:"] "\n\n$err"] |
Christian Stimming | 5e6d776 | 2008-02-02 10:20:17 +0100 | [diff] [blame] | 345 | ui_status [mc "Commit failed."] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 346 | unlock_index |
| 347 | return |
| 348 | } |
| 349 | |
| 350 | # -- Verify this wasn't an empty change. |
| 351 | # |
| 352 | if {$commit_type eq {normal}} { |
Shawn O. Pearce | b215883 | 2007-07-12 02:45:23 -0400 | [diff] [blame] | 353 | set fd_ot [git_read cat-file commit $PARENT] |
Shawn O. Pearce | 20f1a10 | 2007-07-12 02:31:28 -0400 | [diff] [blame] | 354 | fconfigure $fd_ot -encoding binary -translation lf |
| 355 | set old_tree [gets $fd_ot] |
| 356 | close $fd_ot |
| 357 | |
| 358 | if {[string equal -length 5 {tree } $old_tree] |
| 359 | && [string length $old_tree] == 45} { |
| 360 | set old_tree [string range $old_tree 5 end] |
| 361 | } else { |
Michele Ballabio | c8c4854 | 2007-09-13 15:19:05 +0200 | [diff] [blame] | 362 | error [mc "Commit %s appears to be corrupt" $PARENT] |
Shawn O. Pearce | 20f1a10 | 2007-07-12 02:31:28 -0400 | [diff] [blame] | 363 | } |
| 364 | |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 365 | if {$tree_id eq $old_tree} { |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 366 | catch {file delete $msg_p} |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 367 | info_popup [mc "No changes to commit. |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 368 | |
| 369 | No files were modified by this commit and it was not a merge commit. |
| 370 | |
| 371 | A rescan will be automatically started now. |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 372 | "] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 373 | unlock_index |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 374 | rescan {ui_status [mc "No changes to commit."]} |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 375 | return |
| 376 | } |
| 377 | } |
| 378 | |
Pat Thoyts | cfe616b | 2016-10-06 14:04:42 +0100 | [diff] [blame] | 379 | if {[info exists commit_author]} { |
| 380 | set old_author [commit_author_ident $commit_author] |
Orgad Shaneh | 7e71adc | 2016-04-11 09:57:39 +0300 | [diff] [blame] | 381 | } |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 382 | # -- Create the commit. |
| 383 | # |
| 384 | set cmd [list commit-tree $tree_id] |
Johannes Schindelin | 2afe6b7 | 2016-09-09 14:28:24 +0200 | [diff] [blame] | 385 | if {[is_config_true commit.gpgsign]} { |
| 386 | lappend cmd -S |
| 387 | } |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 388 | foreach p [concat $PARENT $MERGE_HEAD] { |
| 389 | lappend cmd -p $p |
| 390 | } |
| 391 | lappend cmd <$msg_p |
| 392 | if {[catch {set cmt_id [eval git $cmd]} err]} { |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 393 | catch {file delete $msg_p} |
Shawn O. Pearce | 31bb1d1 | 2007-09-14 01:50:09 -0400 | [diff] [blame] | 394 | error_popup [strcat [mc "commit-tree failed:"] "\n\n$err"] |
Christian Stimming | 5e6d776 | 2008-02-02 10:20:17 +0100 | [diff] [blame] | 395 | ui_status [mc "Commit failed."] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 396 | unlock_index |
Pat Thoyts | cfe616b | 2016-10-06 14:04:42 +0100 | [diff] [blame] | 397 | unset -nocomplain commit_author |
| 398 | commit_author_reset $old_author |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 399 | return |
| 400 | } |
Pat Thoyts | cfe616b | 2016-10-06 14:04:42 +0100 | [diff] [blame] | 401 | if {[info exists commit_author]} { |
| 402 | unset -nocomplain commit_author |
| 403 | commit_author_reset $old_author |
| 404 | } |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 405 | |
| 406 | # -- Update the HEAD ref. |
| 407 | # |
| 408 | set reflogm commit |
| 409 | if {$commit_type ne {normal}} { |
| 410 | append reflogm " ($commit_type)" |
| 411 | } |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 412 | set msg_fd [open $msg_p r] |
Alexander Gavrilov | 06569cd | 2009-01-24 00:18:13 +0300 | [diff] [blame] | 413 | setup_commit_encoding $msg_fd 1 |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 414 | gets $msg_fd subject |
| 415 | close $msg_fd |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 416 | append reflogm {: } $subject |
| 417 | if {[catch { |
| 418 | git update-ref -m $reflogm HEAD $cmt_id $curHEAD |
| 419 | } err]} { |
Shawn O. Pearce | fb0ca47 | 2008-01-20 14:11:52 -0500 | [diff] [blame] | 420 | catch {file delete $msg_p} |
Shawn O. Pearce | 31bb1d1 | 2007-09-14 01:50:09 -0400 | [diff] [blame] | 421 | error_popup [strcat [mc "update-ref failed:"] "\n\n$err"] |
Christian Stimming | 5e6d776 | 2008-02-02 10:20:17 +0100 | [diff] [blame] | 422 | ui_status [mc "Commit failed."] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 423 | unlock_index |
| 424 | return |
| 425 | } |
| 426 | |
| 427 | # -- Cleanup after ourselves. |
| 428 | # |
| 429 | catch {file delete $msg_p} |
| 430 | catch {file delete [gitdir MERGE_HEAD]} |
| 431 | catch {file delete [gitdir MERGE_MSG]} |
| 432 | catch {file delete [gitdir SQUASH_MSG]} |
| 433 | catch {file delete [gitdir GITGUI_MSG]} |
Beat Bolli | 5a5e4d2 | 2012-08-18 13:28:00 -0700 | [diff] [blame] | 434 | catch {file delete [gitdir CHERRY_PICK_HEAD]} |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 435 | |
| 436 | # -- Let rerere do its thing. |
| 437 | # |
Shawn O. Pearce | d4c5307 | 2007-07-08 17:41:24 -0400 | [diff] [blame] | 438 | if {[get_config rerere.enabled] eq {}} { |
| 439 | set rerere [file isdirectory [gitdir rr-cache]] |
| 440 | } else { |
| 441 | set rerere [is_config_true rerere.enabled] |
| 442 | } |
| 443 | if {$rerere} { |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 444 | catch {git rerere} |
| 445 | } |
| 446 | |
| 447 | # -- Run the post-commit hook. |
| 448 | # |
Shawn O. Pearce | ed76cb7 | 2008-01-20 14:46:59 -0500 | [diff] [blame] | 449 | set fd_ph [githook_read post-commit] |
| 450 | if {$fd_ph ne {}} { |
Jens Lehmann | f0d4eec | 2009-03-30 20:35:57 +0200 | [diff] [blame] | 451 | global pch_error |
| 452 | set pch_error {} |
Shawn O. Pearce | ed76cb7 | 2008-01-20 14:46:59 -0500 | [diff] [blame] | 453 | fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} |
| 454 | fileevent $fd_ph readable \ |
| 455 | [list commit_postcommit_wait $fd_ph $cmt_id] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 456 | } |
| 457 | |
| 458 | $ui_comm delete 0.0 end |
Martin Schön | 627c87f | 2018-07-02 15:28:09 +0200 | [diff] [blame] | 459 | load_message [get_config commit.template] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 460 | $ui_comm edit reset |
| 461 | $ui_comm edit modified false |
Shawn O. Pearce | 4578c5c | 2007-07-21 04:57:57 -0400 | [diff] [blame] | 462 | if {$::GITGUI_BCK_exists} { |
| 463 | catch {file delete [gitdir GITGUI_BCK]} |
Shawn O. Pearce | 9c5a3c7 | 2007-07-23 00:20:04 -0400 | [diff] [blame] | 464 | set ::GITGUI_BCK_exists 0 |
Shawn O. Pearce | 4578c5c | 2007-07-21 04:57:57 -0400 | [diff] [blame] | 465 | } |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 466 | |
Alexander Gavrilov | 1e65c62 | 2008-09-12 22:43:49 +0400 | [diff] [blame] | 467 | if {[is_enabled singlecommit]} { do_quit 0 } |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 468 | |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 469 | # -- Update in memory status |
| 470 | # |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 471 | set commit_type normal |
Bert Wesarg | ba41b5b | 2019-09-13 08:02:30 +0200 | [diff] [blame] | 472 | set commit_type_is_amend 0 |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 473 | set HEAD $cmt_id |
| 474 | set PARENT $cmt_id |
| 475 | set MERGE_HEAD [list] |
| 476 | |
| 477 | foreach path [array names file_states] { |
| 478 | set s $file_states($path) |
| 479 | set m [lindex $s 0] |
| 480 | switch -glob -- $m { |
| 481 | _O - |
| 482 | _M - |
| 483 | _D {continue} |
| 484 | __ - |
| 485 | A_ - |
| 486 | M_ - |
Gustaf Hendeby | e681cb7 | 2008-08-22 22:10:27 +0200 | [diff] [blame] | 487 | T_ - |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 488 | D_ { |
| 489 | unset file_states($path) |
| 490 | catch {unset selected_paths($path)} |
| 491 | } |
| 492 | DO { |
| 493 | set file_states($path) [list _O [lindex $s 1] {} {}] |
| 494 | } |
| 495 | AM - |
| 496 | AD - |
Bert Wesarg | 7587f4d | 2010-12-09 21:46:23 +0100 | [diff] [blame] | 497 | AT - |
| 498 | TM - |
| 499 | TD - |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 500 | MM - |
Bert Wesarg | 7587f4d | 2010-12-09 21:46:23 +0100 | [diff] [blame] | 501 | MT - |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 502 | MD { |
| 503 | set file_states($path) [list \ |
| 504 | _[string index $m 1] \ |
| 505 | [lindex $s 1] \ |
| 506 | [lindex $s 3] \ |
| 507 | {}] |
| 508 | } |
| 509 | } |
| 510 | } |
| 511 | |
| 512 | display_all_files |
| 513 | unlock_index |
| 514 | reshow_diff |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 515 | ui_status [mc "Created commit %s: %s" [string range $cmt_id 0 7] $subject] |
Shawn O. Pearce | f522c9b | 2007-05-07 23:35:48 -0400 | [diff] [blame] | 516 | } |
Shawn O. Pearce | ed76cb7 | 2008-01-20 14:46:59 -0500 | [diff] [blame] | 517 | |
| 518 | proc commit_postcommit_wait {fd_ph cmt_id} { |
Jens Lehmann | f0d4eec | 2009-03-30 20:35:57 +0200 | [diff] [blame] | 519 | global pch_error |
Shawn O. Pearce | ed76cb7 | 2008-01-20 14:46:59 -0500 | [diff] [blame] | 520 | |
| 521 | append pch_error [read $fd_ph] |
| 522 | fconfigure $fd_ph -blocking 1 |
| 523 | if {[eof $fd_ph]} { |
| 524 | if {[catch {close $fd_ph}]} { |
| 525 | hook_failed_popup post-commit $pch_error 0 |
| 526 | } |
| 527 | unset pch_error |
| 528 | return |
| 529 | } |
| 530 | fconfigure $fd_ph -blocking 0 |
| 531 | } |
Pat Thoyts | cfe616b | 2016-10-06 14:04:42 +0100 | [diff] [blame] | 532 | |
| 533 | proc commit_author_ident {details} { |
| 534 | global env |
| 535 | array set author $details |
| 536 | set old [array get env GIT_AUTHOR_*] |
| 537 | set env(GIT_AUTHOR_NAME) $author(name) |
| 538 | set env(GIT_AUTHOR_EMAIL) $author(email) |
| 539 | set env(GIT_AUTHOR_DATE) $author(date) |
| 540 | return $old |
| 541 | } |
| 542 | proc commit_author_reset {details} { |
| 543 | global env |
| 544 | unset env(GIT_AUTHOR_NAME) env(GIT_AUTHOR_EMAIL) env(GIT_AUTHOR_DATE) |
| 545 | if {$details ne {}} { |
| 546 | array set env $details |
| 547 | } |
| 548 | } |