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