blob: 2aa82781e95fa742f4b6526f8e251d0e2f2f9ee8 [file] [log] [blame]
Shawn O. Pearcebd11b822006-11-19 02:57:58 -05001#!/bin/sh
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002# Tcl ignores the next line -*- tcl -*- \
3exec wish "$0" -- "$@"
4
5# Copyright (C) 2006 Shawn Pearce, Paul Mackerras. All rights reserved.
6# This program is free software; it may be used, copied, modified
7# and distributed under the terms of the GNU General Public Licence,
8# either version 2, or (at your option) any later version.
9
Shawn O. Pearceda5239d2006-11-11 19:03:06 -050010set appname [lindex [file split $argv0] end]
11set gitdir {}
12
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -050013######################################################################
14##
Shawn O. Pearce2d195162006-11-08 23:42:51 -050015## config
16
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050017proc is_many_config {name} {
18 switch -glob -- $name {
19 remote.*.fetch -
20 remote.*.push
21 {return 1}
22 *
23 {return 0}
24 }
25}
26
Shawn O. Pearce6bbd1cb2006-11-12 16:24:52 -050027proc load_config {include_global} {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050028 global repo_config global_config default_config
29
30 array unset global_config
Shawn O. Pearce6bbd1cb2006-11-12 16:24:52 -050031 if {$include_global} {
32 catch {
33 set fd_rc [open "| git repo-config --global --list" r]
34 while {[gets $fd_rc line] >= 0} {
35 if {[regexp {^([^=]+)=(.*)$} $line line name value]} {
36 if {[is_many_config $name]} {
37 lappend global_config($name) $value
38 } else {
39 set global_config($name) $value
40 }
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050041 }
42 }
Shawn O. Pearce6bbd1cb2006-11-12 16:24:52 -050043 close $fd_rc
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050044 }
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050045 }
Shawn O. Pearce6bbd1cb2006-11-12 16:24:52 -050046
47 array unset repo_config
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050048 catch {
Shawn O. Pearce2d195162006-11-08 23:42:51 -050049 set fd_rc [open "| git repo-config --list" r]
50 while {[gets $fd_rc line] >= 0} {
51 if {[regexp {^([^=]+)=(.*)$} $line line name value]} {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050052 if {[is_many_config $name]} {
53 lappend repo_config($name) $value
54 } else {
55 set repo_config($name) $value
56 }
Shawn O. Pearce2d195162006-11-08 23:42:51 -050057 }
58 }
59 close $fd_rc
60 }
61
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050062 foreach name [array names default_config] {
63 if {[catch {set v $global_config($name)}]} {
64 set global_config($name) $default_config($name)
65 }
66 if {[catch {set v $repo_config($name)}]} {
67 set repo_config($name) $default_config($name)
68 }
Shawn O. Pearce2d195162006-11-08 23:42:51 -050069 }
70}
71
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050072proc save_config {} {
Shawn O. Pearce92148d82006-11-12 05:27:00 -050073 global default_config font_descs
74 global repo_config global_config
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050075 global repo_config_new global_config_new
Shawn O. Pearce2d195162006-11-08 23:42:51 -050076
Shawn O. Pearce92148d82006-11-12 05:27:00 -050077 foreach option $font_descs {
78 set name [lindex $option 0]
79 set font [lindex $option 1]
80 font configure $font \
81 -family $global_config_new(gui.$font^^family) \
82 -size $global_config_new(gui.$font^^size)
83 font configure ${font}bold \
84 -family $global_config_new(gui.$font^^family) \
85 -size $global_config_new(gui.$font^^size)
86 set global_config_new(gui.$name) [font configure $font]
87 unset global_config_new(gui.$font^^family)
88 unset global_config_new(gui.$font^^size)
89 }
90
91 foreach name [array names default_config] {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050092 set value $global_config_new($name)
Shawn O. Pearce043f7012006-11-12 18:16:45 -050093 if {$value ne $global_config($name)} {
94 if {$value eq $default_config($name)} {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050095 catch {exec git repo-config --global --unset $name}
96 } else {
Shawn O. Pearce7b64d0b2006-11-12 15:45:35 -050097 regsub -all "\[{}\]" $value {"} value
98 exec git repo-config --global $name $value
Shawn O. Pearce51f4d162006-11-12 03:47:00 -050099 }
100 set global_config($name) $value
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500101 if {$value eq $repo_config($name)} {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -0500102 catch {exec git repo-config --unset $name}
103 set repo_config($name) $value
104 }
105 }
Shawn O. Pearce2d195162006-11-08 23:42:51 -0500106 }
107
Shawn O. Pearce92148d82006-11-12 05:27:00 -0500108 foreach name [array names default_config] {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -0500109 set value $repo_config_new($name)
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500110 if {$value ne $repo_config($name)} {
111 if {$value eq $global_config($name)} {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -0500112 catch {exec git repo-config --unset $name}
113 } else {
Shawn O. Pearce7b64d0b2006-11-12 15:45:35 -0500114 regsub -all "\[{}\]" $value {"} value
115 exec git repo-config $name $value
Shawn O. Pearce51f4d162006-11-12 03:47:00 -0500116 }
117 set repo_config($name) $value
118 }
Shawn O. Pearce2d195162006-11-08 23:42:51 -0500119 }
120}
121
Shawn O. Pearceda5239d2006-11-11 19:03:06 -0500122proc error_popup {msg} {
123 global gitdir appname
124
125 set title $appname
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500126 if {$gitdir ne {}} {
Shawn O. Pearceda5239d2006-11-11 19:03:06 -0500127 append title { (}
128 append title [lindex \
129 [file split [file normalize [file dirname $gitdir]]] \
130 end]
131 append title {)}
132 }
Shawn O. Pearcecbbaa282006-11-18 01:20:37 -0500133 set cmd [list tk_messageBox \
Shawn O. Pearceda5239d2006-11-11 19:03:06 -0500134 -icon error \
135 -type ok \
136 -title "$title: error" \
Shawn O. Pearcecbbaa282006-11-18 01:20:37 -0500137 -message $msg]
138 if {[winfo ismapped .]} {
139 lappend cmd -parent .
140 }
141 eval $cmd
Shawn O. Pearceda5239d2006-11-11 19:03:06 -0500142}
143
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500144proc info_popup {msg} {
145 global gitdir appname
146
147 set title $appname
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500148 if {$gitdir ne {}} {
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500149 append title { (}
150 append title [lindex \
151 [file split [file normalize [file dirname $gitdir]]] \
152 end]
153 append title {)}
154 }
155 tk_messageBox \
156 -parent . \
157 -icon error \
158 -type ok \
159 -title $title \
160 -message $msg
161}
162
Shawn O. Pearce2d195162006-11-08 23:42:51 -0500163######################################################################
164##
165## repository setup
166
Shawn O. Pearcefbee8502006-11-15 22:13:45 -0500167if { [catch {set gitdir $env(GIT_DIR)}]
168 && [catch {set gitdir [exec git rev-parse --git-dir]} err]} {
Shawn O. Pearce44be3402006-11-11 19:10:10 -0500169 catch {wm withdraw .}
170 error_popup "Cannot find the git directory:\n\n$err"
Shawn O. Pearce2d195162006-11-08 23:42:51 -0500171 exit 1
172}
Shawn O. Pearcedbccbbd2006-11-15 22:45:33 -0500173if {![file isdirectory $gitdir]} {
174 catch {wm withdraw .}
175 error_popup "Git directory not found:\n\n$gitdir"
176 exit 1
177}
178if {[lindex [file split $gitdir] end] ne {.git}} {
179 catch {wm withdraw .}
180 error_popup "Cannot use funny .git directory:\n\n$gitdir"
181 exit 1
182}
Shawn O. Pearcefbee8502006-11-15 22:13:45 -0500183if {[catch {cd [file dirname $gitdir]} err]} {
184 catch {wm withdraw .}
185 error_popup "No working directory [file dirname $gitdir]:\n\n$err"
186 exit 1
Shawn O. Pearce2d195162006-11-08 23:42:51 -0500187}
Shawn O. Pearce2d195162006-11-08 23:42:51 -0500188
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -0500189set single_commit 0
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500190if {$appname eq {git-citool}} {
Shawn O. Pearce2d195162006-11-08 23:42:51 -0500191 set single_commit 1
192}
193
Shawn O. Pearce2d195162006-11-08 23:42:51 -0500194######################################################################
195##
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500196## task management
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500197
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500198set rescan_active 0
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500199set diff_active 0
Shawn O. Pearce24263b72006-11-13 16:06:38 -0500200set last_clicked {}
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500201
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500202set disable_on_lock [list]
203set index_lock_type none
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500204
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500205proc lock_index {type} {
206 global index_lock_type disable_on_lock
207
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500208 if {$index_lock_type eq {none}} {
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500209 set index_lock_type $type
210 foreach w $disable_on_lock {
211 uplevel #0 $w disabled
212 }
213 return 1
Shawn O. Pearce53716a72006-11-18 03:31:25 -0500214 } elseif {$index_lock_type eq "begin-$type"} {
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500215 set index_lock_type $type
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500216 return 1
217 }
218 return 0
219}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500220
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500221proc unlock_index {} {
222 global index_lock_type disable_on_lock
223
224 set index_lock_type none
225 foreach w $disable_on_lock {
226 uplevel #0 $w normal
227 }
228}
229
230######################################################################
231##
232## status
233
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500234proc repository_state {ctvar hdvar mhvar} {
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500235 global gitdir
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500236 upvar $ctvar ct $hdvar hd $mhvar mh
237
238 set mh [list]
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500239
240 if {[catch {set hd [exec git rev-parse --verify HEAD]}]} {
Shawn O. Pearce4539eac2006-11-18 02:50:58 -0500241 set hd {}
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500242 set ct initial
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500243 return
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500244 }
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500245
246 set merge_head [file join $gitdir MERGE_HEAD]
247 if {[file exists $merge_head]} {
248 set ct merge
249 set fd_mh [open $merge_head r]
250 while {[gets $fd_mh line] >= 0} {
251 lappend mh $line
252 }
253 close $fd_mh
254 return
255 }
256
257 set ct normal
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500258}
259
Shawn O. Pearce4539eac2006-11-18 02:50:58 -0500260proc PARENT {} {
261 global PARENT empty_tree
262
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500263 set p [lindex $PARENT 0]
264 if {$p ne {}} {
265 return $p
Shawn O. Pearce4539eac2006-11-18 02:50:58 -0500266 }
267 if {$empty_tree eq {}} {
268 set empty_tree [exec git mktree << {}]
269 }
270 return $empty_tree
271}
272
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500273proc rescan {after} {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500274 global HEAD PARENT MERGE_HEAD commit_type
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500275 global ui_index ui_other ui_status_value ui_comm
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500276 global rescan_active file_states
Shawn O. Pearce51f4d162006-11-12 03:47:00 -0500277 global repo_config
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500278
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500279 if {$rescan_active > 0 || ![lock_index read]} return
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500280
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500281 repository_state newType newHEAD newMERGE_HEAD
Shawn O. Pearce4539eac2006-11-18 02:50:58 -0500282 if {[string match amend* $commit_type]
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500283 && $newType eq {normal}
284 && $newHEAD eq $HEAD} {
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500285 } else {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500286 set HEAD $newHEAD
287 set PARENT $newHEAD
288 set MERGE_HEAD $newMERGE_HEAD
289 set commit_type $newType
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500290 }
291
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500292 array unset file_states
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500293
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500294 if {![$ui_comm edit modified]
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500295 || [string trim [$ui_comm get 0.0 end]] eq {}} {
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500296 if {[load_message GITGUI_MSG]} {
297 } elseif {[load_message MERGE_MSG]} {
298 } elseif {[load_message SQUASH_MSG]} {
299 }
300 $ui_comm edit modified false
Shawn O. Pearceb2c6fcf2006-11-11 16:16:25 -0500301 $ui_comm edit reset
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500302 }
303
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500304 if {$repo_config(gui.trustmtime) eq {true}} {
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500305 rescan_stage2 {} $after
Shawn O. Pearcee534f3a2006-11-07 21:27:29 -0500306 } else {
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500307 set rescan_active 1
Shawn O. Pearcee534f3a2006-11-07 21:27:29 -0500308 set ui_status_value {Refreshing file status...}
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500309 set cmd [list git update-index]
310 lappend cmd -q
311 lappend cmd --unmerged
312 lappend cmd --ignore-missing
313 lappend cmd --refresh
314 set fd_rf [open "| $cmd" r]
Shawn O. Pearcee534f3a2006-11-07 21:27:29 -0500315 fconfigure $fd_rf -blocking 0 -translation binary
Shawn O. Pearce390adae2006-11-11 19:40:33 -0500316 fileevent $fd_rf readable \
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500317 [list rescan_stage2 $fd_rf $after]
Shawn O. Pearcee534f3a2006-11-07 21:27:29 -0500318 }
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500319}
320
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500321proc rescan_stage2 {fd after} {
Shawn O. Pearce4539eac2006-11-18 02:50:58 -0500322 global gitdir ui_status_value
323 global rescan_active buf_rdi buf_rdf buf_rlo
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500324
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500325 if {$fd ne {}} {
Shawn O. Pearcee534f3a2006-11-07 21:27:29 -0500326 read $fd
327 if {![eof $fd]} return
328 close $fd
329 }
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500330
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500331 set ls_others [list | git ls-files --others -z \
332 --exclude-per-directory=.gitignore]
333 set info_exclude [file join $gitdir info exclude]
334 if {[file readable $info_exclude]} {
335 lappend ls_others "--exclude-from=$info_exclude"
336 }
337
Shawn O. Pearce868c8752006-11-07 18:34:09 -0500338 set buf_rdi {}
339 set buf_rdf {}
340 set buf_rlo {}
341
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500342 set rescan_active 3
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500343 set ui_status_value {Scanning for modified files ...}
Shawn O. Pearce4539eac2006-11-18 02:50:58 -0500344 set fd_di [open "| git diff-index --cached -z [PARENT]" r]
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500345 set fd_df [open "| git diff-files -z" r]
346 set fd_lo [open $ls_others r]
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500347
348 fconfigure $fd_di -blocking 0 -translation binary
349 fconfigure $fd_df -blocking 0 -translation binary
350 fconfigure $fd_lo -blocking 0 -translation binary
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500351 fileevent $fd_di readable [list read_diff_index $fd_di $after]
352 fileevent $fd_df readable [list read_diff_files $fd_df $after]
353 fileevent $fd_lo readable [list read_ls_others $fd_lo $after]
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500354}
355
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500356proc load_message {file} {
357 global gitdir ui_comm
358
359 set f [file join $gitdir $file]
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500360 if {[file isfile $f]} {
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500361 if {[catch {set fd [open $f r]}]} {
362 return 0
363 }
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500364 set content [string trim [read $fd]]
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500365 close $fd
366 $ui_comm delete 0.0 end
367 $ui_comm insert end $content
368 return 1
369 }
370 return 0
371}
372
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500373proc read_diff_index {fd after} {
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500374 global buf_rdi
375
376 append buf_rdi [read $fd]
Shawn O. Pearce868c8752006-11-07 18:34:09 -0500377 set c 0
378 set n [string length $buf_rdi]
379 while {$c < $n} {
380 set z1 [string first "\0" $buf_rdi $c]
381 if {$z1 == -1} break
382 incr z1
383 set z2 [string first "\0" $buf_rdi $z1]
384 if {$z2 == -1} break
385
Shawn O. Pearce868c8752006-11-07 18:34:09 -0500386 incr c
Shawn O. Pearce86291552006-11-19 01:00:48 -0500387 set i [split [string range $buf_rdi $c [expr {$z1 - 2}]] { }]
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -0500388 merge_state \
389 [string range $buf_rdi $z1 [expr {$z2 - 1}]] \
Shawn O. Pearce86291552006-11-19 01:00:48 -0500390 [lindex $i 4]? \
391 [list [lindex $i 0] [lindex $i 2]] \
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -0500392 [list]
393 set c $z2
Shawn O. Pearce86291552006-11-19 01:00:48 -0500394 incr c
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500395 }
Shawn O. Pearce868c8752006-11-07 18:34:09 -0500396 if {$c < $n} {
397 set buf_rdi [string range $buf_rdi $c end]
398 } else {
399 set buf_rdi {}
400 }
401
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500402 rescan_done $fd buf_rdi $after
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500403}
404
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500405proc read_diff_files {fd after} {
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500406 global buf_rdf
407
408 append buf_rdf [read $fd]
Shawn O. Pearce868c8752006-11-07 18:34:09 -0500409 set c 0
410 set n [string length $buf_rdf]
411 while {$c < $n} {
412 set z1 [string first "\0" $buf_rdf $c]
413 if {$z1 == -1} break
414 incr z1
415 set z2 [string first "\0" $buf_rdf $z1]
416 if {$z2 == -1} break
417
Shawn O. Pearce868c8752006-11-07 18:34:09 -0500418 incr c
Shawn O. Pearce86291552006-11-19 01:00:48 -0500419 set i [split [string range $buf_rdf $c [expr {$z1 - 2}]] { }]
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -0500420 merge_state \
421 [string range $buf_rdf $z1 [expr {$z2 - 1}]] \
Shawn O. Pearce86291552006-11-19 01:00:48 -0500422 ?[lindex $i 4] \
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -0500423 [list] \
Shawn O. Pearce86291552006-11-19 01:00:48 -0500424 [list [lindex $i 0] [lindex $i 2]]
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -0500425 set c $z2
Shawn O. Pearce86291552006-11-19 01:00:48 -0500426 incr c
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500427 }
Shawn O. Pearce868c8752006-11-07 18:34:09 -0500428 if {$c < $n} {
429 set buf_rdf [string range $buf_rdf $c end]
430 } else {
431 set buf_rdf {}
432 }
433
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500434 rescan_done $fd buf_rdf $after
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500435}
436
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500437proc read_ls_others {fd after} {
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500438 global buf_rlo
439
440 append buf_rlo [read $fd]
441 set pck [split $buf_rlo "\0"]
442 set buf_rlo [lindex $pck end]
443 foreach p [lrange $pck 0 end-1] {
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -0500444 merge_state $p ?O
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500445 }
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500446 rescan_done $fd buf_rlo $after
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500447}
448
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500449proc rescan_done {fd buf after} {
450 global rescan_active
Shawn O. Pearcef7f8d322006-11-13 04:22:42 -0500451 global file_states repo_config
Shawn O. Pearce7f1df792006-11-11 18:38:00 -0500452 upvar $buf to_clear
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500453
Shawn O. Pearcef7f8d322006-11-13 04:22:42 -0500454 if {![eof $fd]} return
455 set to_clear {}
456 close $fd
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500457 if {[incr rescan_active -1] > 0} return
Shawn O. Pearce93f654d2006-11-07 19:30:54 -0500458
Shawn O. Pearce24263b72006-11-13 16:06:38 -0500459 prune_selection
Shawn O. Pearcef7f8d322006-11-13 04:22:42 -0500460 unlock_index
461 display_all_files
462
463 if {$repo_config(gui.partialinclude) ne {true}} {
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500464 set pathList [list]
Shawn O. Pearcef7f8d322006-11-13 04:22:42 -0500465 foreach path [array names file_states] {
466 switch -- [lindex $file_states($path) 0] {
467 AM -
468 MM {lappend pathList $path}
469 }
470 }
471 if {$pathList ne {}} {
Shawn O. Pearce04b39382006-11-14 01:42:32 -0500472 update_index \
473 "Updating included files" \
474 $pathList \
475 [concat {reshow_diff;} $after]
Shawn O. Pearcef7f8d322006-11-13 04:22:42 -0500476 return
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500477 }
478 }
Shawn O. Pearcef7f8d322006-11-13 04:22:42 -0500479
480 reshow_diff
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500481 uplevel #0 $after
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500482}
483
Shawn O. Pearce24263b72006-11-13 16:06:38 -0500484proc prune_selection {} {
485 global file_states selected_paths
486
487 foreach path [array names selected_paths] {
488 if {[catch {set still_here $file_states($path)}]} {
489 unset selected_paths($path)
490 }
491 }
492}
493
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500494######################################################################
495##
496## diff
497
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500498proc clear_diff {} {
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -0500499 global ui_diff current_diff ui_index ui_other
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500500
501 $ui_diff conf -state normal
502 $ui_diff delete 0.0 end
503 $ui_diff conf -state disabled
Shawn O. Pearce03e4ec52006-11-11 17:52:16 -0500504
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -0500505 set current_diff {}
Shawn O. Pearce03e4ec52006-11-11 17:52:16 -0500506
507 $ui_index tag remove in_diff 0.0 end
508 $ui_other tag remove in_diff 0.0 end
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500509}
510
Shawn O. Pearce7f1df792006-11-11 18:38:00 -0500511proc reshow_diff {} {
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -0500512 global current_diff ui_status_value file_states
Shawn O. Pearce7f1df792006-11-11 18:38:00 -0500513
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -0500514 if {$current_diff eq {}
515 || [catch {set s $file_states($current_diff)}]} {
Shawn O. Pearce7f1df792006-11-11 18:38:00 -0500516 clear_diff
Shawn O. Pearce73ad1792006-11-11 18:42:42 -0500517 } else {
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -0500518 show_diff $current_diff
Shawn O. Pearce7f1df792006-11-11 18:38:00 -0500519 }
520}
521
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500522proc handle_empty_diff {} {
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -0500523 global current_diff file_states file_lists
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500524
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -0500525 set path $current_diff
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500526 set s $file_states($path)
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500527 if {[lindex $s 0] ne {_M}} return
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500528
529 info_popup "No differences detected.
530
531[short_path $path] has no changes.
532
Shawn O. Pearcea37eee42006-11-13 14:37:41 -0500533The modification date of this file was updated
534by another application and you currently have
535the Trust File Modification Timestamps option
536enabled, so Git did not automatically detect
537that there are no content differences in this
538file.
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500539
Shawn O. Pearcea37eee42006-11-13 14:37:41 -0500540This file will now be removed from the modified
541files list, to prevent possible confusion.
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500542"
543 if {[catch {exec git update-index -- $path} err]} {
544 error_popup "Failed to refresh index:\n\n$err"
545 }
546
547 clear_diff
548 set old_w [mapcol [lindex $file_states($path) 0] $path]
549 set lno [lsearch -sorted $file_lists($old_w) $path]
550 if {$lno >= 0} {
551 set file_lists($old_w) \
552 [lreplace $file_lists($old_w) $lno $lno]
553 incr lno
554 $old_w conf -state normal
Shawn O. Pearce24263b72006-11-13 16:06:38 -0500555 $old_w delete $lno.0 [expr {$lno + 1}].0
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500556 $old_w conf -state disabled
557 }
558}
559
Shawn O. Pearce03e4ec52006-11-11 17:52:16 -0500560proc show_diff {path {w {}} {lno {}}} {
561 global file_states file_lists
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500562 global is_3way_diff diff_active repo_config
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -0500563 global ui_diff current_diff ui_status_value
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500564
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500565 if {$diff_active || ![lock_index read]} return
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500566
567 clear_diff
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500568 if {$w eq {} || $lno == {}} {
Shawn O. Pearce03e4ec52006-11-11 17:52:16 -0500569 foreach w [array names file_lists] {
570 set lno [lsearch -sorted $file_lists($w) $path]
571 if {$lno >= 0} {
572 incr lno
573 break
574 }
575 }
576 }
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500577 if {$w ne {} && $lno >= 1} {
Shawn O. Pearce24263b72006-11-13 16:06:38 -0500578 $w tag add in_diff $lno.0 [expr {$lno + 1}].0
Shawn O. Pearce03e4ec52006-11-11 17:52:16 -0500579 }
580
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500581 set s $file_states($path)
582 set m [lindex $s 0]
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500583 set is_3way_diff 0
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500584 set diff_active 1
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -0500585 set current_diff $path
Shawn O. Pearce68e009d2006-11-11 17:59:34 -0500586 set ui_status_value "Loading diff of [escape_path $path]..."
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500587
Shawn O. Pearcefd2656f2006-11-12 18:51:38 -0500588 set cmd [list | git diff-index]
589 lappend cmd --no-color
Shawn O. Pearce358d8de2006-11-12 19:20:02 -0500590 if {$repo_config(gui.diffcontext) > 0} {
591 lappend cmd "-U$repo_config(gui.diffcontext)"
592 }
Shawn O. Pearcefd2656f2006-11-12 18:51:38 -0500593 lappend cmd -p
594
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500595 switch $m {
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500596 MM {
Shawn O. Pearcefd2656f2006-11-12 18:51:38 -0500597 lappend cmd -c
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500598 }
599 _O {
600 if {[catch {
601 set fd [open $path r]
602 set content [read $fd]
603 close $fd
604 } err ]} {
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500605 set diff_active 0
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500606 unlock_index
Shawn O. Pearce68e009d2006-11-11 17:59:34 -0500607 set ui_status_value "Unable to display [escape_path $path]"
Shawn O. Pearce44be3402006-11-11 19:10:10 -0500608 error_popup "Error loading file:\n\n$err"
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500609 return
610 }
611 $ui_diff conf -state normal
612 $ui_diff insert end $content
613 $ui_diff conf -state disabled
Shawn O. Pearcebd1e2b42006-11-06 22:03:05 -0500614 set diff_active 0
615 unlock_index
616 set ui_status_value {Ready.}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500617 return
618 }
619 }
620
Shawn O. Pearce4539eac2006-11-18 02:50:58 -0500621 lappend cmd [PARENT]
Shawn O. Pearcefd2656f2006-11-12 18:51:38 -0500622 lappend cmd --
623 lappend cmd $path
624
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500625 if {[catch {set fd [open $cmd r]} err]} {
Shawn O. Pearce131f5032006-11-06 16:07:32 -0500626 set diff_active 0
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500627 unlock_index
Shawn O. Pearce68e009d2006-11-11 17:59:34 -0500628 set ui_status_value "Unable to display [escape_path $path]"
Shawn O. Pearce44be3402006-11-11 19:10:10 -0500629 error_popup "Error loading diff:\n\n$err"
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500630 return
631 }
632
Shawn O. Pearce6f6eed22006-11-06 18:22:19 -0500633 fconfigure $fd -blocking 0 -translation auto
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500634 fileevent $fd readable [list read_diff $fd]
635}
636
637proc read_diff {fd} {
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500638 global ui_diff ui_status_value is_3way_diff diff_active
Shawn O. Pearce51f4d162006-11-12 03:47:00 -0500639 global repo_config
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500640
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500641 $ui_diff conf -state normal
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500642 while {[gets $fd line] >= 0} {
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500643 # -- Cleanup uninteresting diff header lines.
644 #
645 if {[string match {diff --git *} $line]} continue
Shawn O. Pearce6f6eed22006-11-06 18:22:19 -0500646 if {[string match {diff --combined *} $line]} continue
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500647 if {[string match {--- *} $line]} continue
648 if {[string match {+++ *} $line]} continue
Shawn O. Pearce0d5709c2006-11-19 01:06:42 -0500649 if {$line eq {deleted file mode 120000}} {
650 set line "deleted symlink"
651 }
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500652
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500653 # -- Automatically detect if this is a 3 way diff.
654 #
655 if {[string match {@@@ *} $line]} {set is_3way_diff 1}
656
657 # -- Reformat a 3 way diff, 'cause its too weird.
658 #
659 if {$is_3way_diff} {
660 set op [string range $line 0 1]
661 switch -- $op {
662 {@@} {set tags d_@}
663 {++} {set tags d_+ ; set op { +}}
664 {--} {set tags d_- ; set op { -}}
665 { +} {set tags d_++; set op {++}}
666 { -} {set tags d_--; set op {--}}
667 {+ } {set tags d_-+; set op {-+}}
668 {- } {set tags d_+-; set op {+-}}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500669 default {set tags {}}
670 }
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500671 set line [string replace $line 0 1 $op]
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500672 } else {
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500673 switch -- [string index $line 0] {
674 @ {set tags d_@}
675 + {set tags d_+}
676 - {set tags d_-}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500677 default {set tags {}}
678 }
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500679 }
680 $ui_diff insert end $line $tags
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500681 $ui_diff insert end "\n" $tags
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500682 }
Shawn O. Pearce38dbe272006-11-19 02:46:52 -0500683 $ui_diff conf -state disabled
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500684
685 if {[eof $fd]} {
686 close $fd
687 set diff_active 0
Shawn O. Pearcee210e672006-11-06 19:12:58 -0500688 unlock_index
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500689 set ui_status_value {Ready.}
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500690
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500691 if {$repo_config(gui.trustmtime) eq {true}
692 && [$ui_diff index end] eq {2.0}} {
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500693 handle_empty_diff
694 }
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -0500695 }
696}
697
698######################################################################
699##
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500700## commit
701
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500702proc load_last_commit {} {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500703 global HEAD PARENT MERGE_HEAD commit_type ui_comm
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500704
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500705 if {[llength $PARENT] == 0} {
706 error_popup {There is nothing to amend.
707
708You are about to create the initial commit.
709There is no commit before this to amend.
710}
711 return
712 }
713
714 repository_state curType curHEAD curMERGE_HEAD
715 if {$curType eq {merge}} {
716 error_popup {Cannot amend while merging.
717
718You are currently in the middle of a merge that
719has not been fully completed. You cannot amend
720the prior commit unless you first abort the
721current merge activity.
722}
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500723 return
724 }
725
726 set msg {}
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500727 set parents [list]
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500728 if {[catch {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500729 set fd [open "| git cat-file commit $curHEAD" r]
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500730 while {[gets $fd line] > 0} {
731 if {[string match {parent *} $line]} {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500732 lappend parents [string range $line 7 end]
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500733 }
734 }
735 set msg [string trim [read $fd]]
736 close $fd
737 } err]} {
Shawn O. Pearce44be3402006-11-11 19:10:10 -0500738 error_popup "Error loading commit data for amend:\n\n$err"
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500739 return
740 }
741
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500742 set HEAD $curHEAD
743 set PARENT $parents
744 set MERGE_HEAD [list]
745 switch -- [llength $parents] {
746 0 {set commit_type amend-initial}
747 1 {set commit_type amend}
748 default {set commit_type amend-merge}
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500749 }
Shawn O. Pearce4539eac2006-11-18 02:50:58 -0500750
751 $ui_comm delete 0.0 end
752 $ui_comm insert end $msg
753 $ui_comm edit modified false
754 $ui_comm edit reset
755 rescan {set ui_status_value {Ready.}}
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500756}
757
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -0500758proc create_new_commit {} {
759 global commit_type ui_comm
760
761 set commit_type normal
762 $ui_comm delete 0.0 end
763 $ui_comm edit modified false
764 $ui_comm edit reset
765 rescan {set ui_status_value {Ready.}}
766}
767
Shawn O. Pearced63efae2006-11-18 21:07:05 -0500768set GIT_COMMITTER_IDENT {}
769
770proc committer_ident {} {
771 global GIT_COMMITTER_IDENT
772
773 if {$GIT_COMMITTER_IDENT eq {}} {
774 if {[catch {set me [exec git var GIT_COMMITTER_IDENT]} err]} {
775 error_popup "Unable to obtain your identity:\n\n$err"
776 return {}
777 }
778 if {![regexp {^(.*) [0-9]+ [-+0-9]+$} \
779 $me me GIT_COMMITTER_IDENT]} {
780 error_popup "Invalid GIT_COMMITTER_IDENT:\n\n$me"
781 return {}
782 }
783 }
784
785 return $GIT_COMMITTER_IDENT
786}
787
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500788proc commit_tree {} {
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500789 global HEAD commit_type file_states ui_comm repo_config
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500790
Shawn O. Pearce333b0c72006-11-12 18:03:19 -0500791 if {![lock_index update]} return
Shawn O. Pearced63efae2006-11-18 21:07:05 -0500792 if {[committer_ident] eq {}} return
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500793
794 # -- Our in memory state should match the repository.
795 #
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500796 repository_state curType curHEAD curMERGE_HEAD
Shawn O. Pearce4539eac2006-11-18 02:50:58 -0500797 if {[string match amend* $commit_type]
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500798 && $curType eq {normal}
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500799 && $curHEAD eq $HEAD} {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500800 } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} {
Shawn O. Pearcebca680b2006-11-18 21:13:16 -0500801 info_popup {Last scanned state does not match repository state.
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500802
Shawn O. Pearcebca680b2006-11-18 21:13:16 -0500803Another Git program has modified this repository
804since the last scan. A rescan must be performed
805before another commit can be created.
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500806
Shawn O. Pearcebca680b2006-11-18 21:13:16 -0500807The rescan will be automatically started now.
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500808}
809 unlock_index
Shawn O. Pearce8f525482006-11-14 01:29:32 -0500810 rescan {set ui_status_value {Ready.}}
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500811 return
812 }
813
814 # -- At least one file should differ in the index.
815 #
816 set files_ready 0
817 foreach path [array names file_states] {
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500818 switch -glob -- [lindex $file_states($path) 0] {
Shawn O. Pearce7f1df792006-11-11 18:38:00 -0500819 _? {continue}
820 A? -
821 D? -
822 M? {set files_ready 1; break}
823 U? {
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500824 error_popup "Unmerged files cannot be committed.
825
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500826File [short_path $path] has merge conflicts.
Shawn O. Pearce7fe7e732006-11-08 22:48:34 -0500827You must resolve them and include the file before committing.
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500828"
829 unlock_index
830 return
831 }
832 default {
833 error_popup "Unknown file state [lindex $s 0] detected.
834
Shawn O. Pearce16403d02006-11-11 21:52:06 -0500835File [short_path $path] cannot be committed by this program.
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500836"
837 }
838 }
839 }
840 if {!$files_ready} {
Shawn O. Pearce7fe7e732006-11-08 22:48:34 -0500841 error_popup {No included files to commit.
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500842
Shawn O. Pearce7fe7e732006-11-08 22:48:34 -0500843You must include at least 1 file before you can commit.
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500844}
845 unlock_index
846 return
847 }
848
849 # -- A message is required.
850 #
851 set msg [string trim [$ui_comm get 1.0 end]]
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500852 if {$msg eq {}} {
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500853 error_popup {Please supply a commit message.
854
855A good commit message has the following format:
856
857- First line: Describe in one sentance what you did.
858- Second line: Blank
859- Remaining lines: Describe why this change is good.
860}
861 unlock_index
862 return
863 }
864
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500865 # -- Update included files if partialincludes are off.
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500866 #
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500867 if {$repo_config(gui.partialinclude) ne {true}} {
868 set pathList [list]
869 foreach path [array names file_states] {
870 switch -glob -- [lindex $file_states($path) 0] {
871 A? -
872 M? {lappend pathList $path}
873 }
874 }
875 if {$pathList ne {}} {
876 unlock_index
877 update_index \
878 "Updating included files" \
879 $pathList \
880 [concat {lock_index update;} \
881 [list commit_prehook $curHEAD $msg]]
882 return
883 }
884 }
885
886 commit_prehook $curHEAD $msg
887}
888
889proc commit_prehook {curHEAD msg} {
890 global tcl_platform gitdir ui_status_value pch_error
891
892 # On Cygwin [file executable] might lie so we need to ask
893 # the shell if the hook is executable. Yes that's annoying.
894
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500895 set pchook [file join $gitdir hooks pre-commit]
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500896 if {$tcl_platform(platform) eq {windows}
897 && [file isfile $pchook]} {
Shawn O. Pearce4658b562006-11-12 17:58:08 -0500898 set pchook [list sh -c [concat \
899 "if test -x \"$pchook\";" \
900 "then exec \"$pchook\" 2>&1;" \
901 "fi"]]
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500902 } elseif {[file executable $pchook]} {
Shawn O. Pearce4658b562006-11-12 17:58:08 -0500903 set pchook [list $pchook |& cat]
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500904 } else {
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500905 commit_writetree $curHEAD $msg
906 return
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500907 }
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500908
909 set ui_status_value {Calling pre-commit hook...}
910 set pch_error {}
911 set fd_ph [open "| $pchook" r]
912 fconfigure $fd_ph -blocking 0 -translation binary
913 fileevent $fd_ph readable \
914 [list commit_prehook_wait $fd_ph $curHEAD $msg]
Shawn O. Pearce4658b562006-11-12 17:58:08 -0500915}
916
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500917proc commit_prehook_wait {fd_ph curHEAD msg} {
Shawn O. Pearce333b0c72006-11-12 18:03:19 -0500918 global pch_error ui_status_value
Shawn O. Pearce4658b562006-11-12 17:58:08 -0500919
920 append pch_error [read $fd_ph]
921 fconfigure $fd_ph -blocking 1
922 if {[eof $fd_ph]} {
923 if {[catch {close $fd_ph}]} {
924 set ui_status_value {Commit declined by pre-commit hook.}
925 hook_failed_popup pre-commit $pch_error
926 unlock_index
Shawn O. Pearce333b0c72006-11-12 18:03:19 -0500927 } else {
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500928 commit_writetree $curHEAD $msg
Shawn O. Pearce4658b562006-11-12 17:58:08 -0500929 }
Shawn O. Pearce333b0c72006-11-12 18:03:19 -0500930 set pch_error {}
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500931 return
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500932 }
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500933 fconfigure $fd_ph -blocking 0
Shawn O. Pearce4658b562006-11-12 17:58:08 -0500934}
935
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500936proc commit_writetree {curHEAD msg} {
Shawn O. Pearce4658b562006-11-12 17:58:08 -0500937 global ui_status_value
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500938
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500939 set ui_status_value {Committing changes...}
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500940 set fd_wt [open "| git write-tree" r]
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500941 fileevent $fd_wt readable \
942 [list commit_committree $fd_wt $curHEAD $msg]
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500943}
944
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -0500945proc commit_committree {fd_wt curHEAD msg} {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500946 global HEAD PARENT MERGE_HEAD commit_type
947 global single_commit gitdir tcl_platform
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -0500948 global ui_status_value ui_comm selected_commit_type
Shawn O. Pearcea29481e2006-11-19 03:38:48 -0500949 global file_states selected_paths rescan_active
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500950
951 gets $fd_wt tree_id
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500952 if {$tree_id eq {} || [catch {close $fd_wt} err]} {
Shawn O. Pearce44be3402006-11-11 19:10:10 -0500953 error_popup "write-tree failed:\n\n$err"
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500954 set ui_status_value {Commit failed.}
955 unlock_index
956 return
957 }
958
959 # -- Create the commit.
960 #
961 set cmd [list git commit-tree $tree_id]
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500962 set parents [concat $PARENT $MERGE_HEAD]
963 if {[llength $parents] > 0} {
964 foreach p $parents {
965 lappend cmd -p $p
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500966 }
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -0500967 } else {
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500968 # git commit-tree writes to stderr during initial commit.
969 lappend cmd 2>/dev/null
970 }
971 lappend cmd << $msg
972 if {[catch {set cmt_id [eval exec $cmd]} err]} {
Shawn O. Pearce44be3402006-11-11 19:10:10 -0500973 error_popup "commit-tree failed:\n\n$err"
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500974 set ui_status_value {Commit failed.}
975 unlock_index
976 return
977 }
978
979 # -- Update the HEAD ref.
980 #
981 set reflogm commit
Shawn O. Pearce043f7012006-11-12 18:16:45 -0500982 if {$commit_type ne {normal}} {
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500983 append reflogm " ($commit_type)"
984 }
985 set i [string first "\n" $msg]
986 if {$i >= 0} {
Shawn O. Pearce24263b72006-11-13 16:06:38 -0500987 append reflogm {: } [string range $msg 0 [expr {$i - 1}]]
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500988 } else {
989 append reflogm {: } $msg
990 }
Shawn O. Pearcee57ca852006-11-06 21:34:10 -0500991 set cmd [list git update-ref -m $reflogm HEAD $cmt_id $curHEAD]
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500992 if {[catch {eval exec $cmd} err]} {
Shawn O. Pearce44be3402006-11-11 19:10:10 -0500993 error_popup "update-ref failed:\n\n$err"
Shawn O. Pearceec6b4242006-11-06 20:50:59 -0500994 set ui_status_value {Commit failed.}
995 unlock_index
996 return
997 }
998
999 # -- Cleanup after ourselves.
1000 #
1001 catch {file delete [file join $gitdir MERGE_HEAD]}
1002 catch {file delete [file join $gitdir MERGE_MSG]}
1003 catch {file delete [file join $gitdir SQUASH_MSG]}
1004 catch {file delete [file join $gitdir GITGUI_MSG]}
1005
1006 # -- Let rerere do its thing.
1007 #
1008 if {[file isdirectory [file join $gitdir rr-cache]]} {
1009 catch {exec git rerere}
1010 }
1011
Shawn O. Pearcec8ebafd2006-11-12 18:08:10 -05001012 # -- Run the post-commit hook.
1013 #
1014 set pchook [file join $gitdir hooks post-commit]
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001015 if {$tcl_platform(platform) eq {windows} && [file isfile $pchook]} {
Shawn O. Pearcec8ebafd2006-11-12 18:08:10 -05001016 set pchook [list sh -c [concat \
1017 "if test -x \"$pchook\";" \
1018 "then exec \"$pchook\";" \
1019 "fi"]]
1020 } elseif {![file executable $pchook]} {
1021 set pchook {}
1022 }
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001023 if {$pchook ne {}} {
Shawn O. Pearcec8ebafd2006-11-12 18:08:10 -05001024 catch {exec $pchook &}
1025 }
1026
Shawn O. Pearcee57ca852006-11-06 21:34:10 -05001027 $ui_comm delete 0.0 end
1028 $ui_comm edit modified false
Shawn O. Pearceb2c6fcf2006-11-11 16:16:25 -05001029 $ui_comm edit reset
Shawn O. Pearceec6b4242006-11-06 20:50:59 -05001030
1031 if {$single_commit} do_quit
1032
Shawn O. Pearcea29481e2006-11-19 03:38:48 -05001033 # -- Update in memory status
Shawn O. Pearce7f1df792006-11-11 18:38:00 -05001034 #
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05001035 set selected_commit_type new
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -05001036 set commit_type normal
Shawn O. Pearcebd1e2b42006-11-06 22:03:05 -05001037 set HEAD $cmt_id
1038 set PARENT $cmt_id
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -05001039 set MERGE_HEAD [list]
Shawn O. Pearce7f1df792006-11-11 18:38:00 -05001040
1041 foreach path [array names file_states] {
1042 set s $file_states($path)
1043 set m [lindex $s 0]
1044 switch -glob -- $m {
Shawn O. Pearcea29481e2006-11-19 03:38:48 -05001045 _O -
1046 _M -
1047 _D {continue}
1048 __ -
1049 A_ -
1050 M_ -
1051 DD {
Shawn O. Pearce7f1df792006-11-11 18:38:00 -05001052 unset file_states($path)
Shawn O. Pearce24263b72006-11-13 16:06:38 -05001053 catch {unset selected_paths($path)}
Shawn O. Pearcea29481e2006-11-19 03:38:48 -05001054 }
1055 DO {
1056 set file_states($path) [list _O [lindex $s 1] {} {}]
1057 }
1058 AM -
1059 AD -
1060 MM -
1061 DM {
1062 set file_states($path) [list \
1063 _[string index $m 1] \
1064 [lindex $s 1] \
1065 [lindex $s 3] \
1066 {}]
1067 }
Shawn O. Pearce7f1df792006-11-11 18:38:00 -05001068 }
1069 }
1070
1071 display_all_files
Shawn O. Pearceec6b4242006-11-06 20:50:59 -05001072 unlock_index
Shawn O. Pearce7f1df792006-11-11 18:38:00 -05001073 reshow_diff
1074 set ui_status_value \
1075 "Changes committed as [string range $cmt_id 0 7]."
Shawn O. Pearceec6b4242006-11-06 20:50:59 -05001076}
1077
1078######################################################################
1079##
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001080## fetch pull push
1081
1082proc fetch_from {remote} {
1083 set w [new_console "fetch $remote" \
1084 "Fetching new changes from $remote"]
Shawn O. Pearcecc4b1c02006-11-06 23:47:05 -05001085 set cmd [list git fetch]
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001086 lappend cmd $remote
Shawn O. Pearcecc4b1c02006-11-06 23:47:05 -05001087 console_exec $w $cmd
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001088}
1089
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001090proc pull_remote {remote branch} {
Shawn O. Pearceebf336b2006-11-12 16:53:19 -05001091 global HEAD commit_type file_states repo_config
Shawn O. Pearceec39d832006-11-07 22:00:38 -05001092
Shawn O. Pearce988b8a72006-11-07 21:30:46 -05001093 if {![lock_index update]} return
Shawn O. Pearceec39d832006-11-07 22:00:38 -05001094
1095 # -- Our in memory state should match the repository.
1096 #
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -05001097 repository_state curType curHEAD curMERGE_HEAD
1098 if {$commit_type ne $curType || $HEAD ne $curHEAD} {
Shawn O. Pearceec39d832006-11-07 22:00:38 -05001099 error_popup {Last scanned state does not match repository state.
1100
1101Its highly likely that another Git program modified the
1102repository since our last scan. A rescan is required
1103before a pull can be started.
1104}
1105 unlock_index
Shawn O. Pearce8f525482006-11-14 01:29:32 -05001106 rescan {set ui_status_value {Ready.}}
Shawn O. Pearceec39d832006-11-07 22:00:38 -05001107 return
1108 }
1109
1110 # -- No differences should exist before a pull.
1111 #
1112 if {[array size file_states] != 0} {
1113 error_popup {Uncommitted but modified files are present.
1114
1115You should not perform a pull with unmodified files in your working
1116directory as Git would be unable to recover from an incorrect merge.
1117
1118Commit or throw away all changes before starting a pull operation.
1119}
1120 unlock_index
1121 return
1122 }
1123
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001124 set w [new_console "pull $remote $branch" \
1125 "Pulling new changes from branch $branch in $remote"]
1126 set cmd [list git pull]
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001127 if {$repo_config(gui.pullsummary) eq {false}} {
Shawn O. Pearceebf336b2006-11-12 16:53:19 -05001128 lappend cmd --no-summary
1129 }
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001130 lappend cmd $remote
1131 lappend cmd $branch
1132 console_exec $w $cmd [list post_pull_remote $remote $branch]
1133}
1134
1135proc post_pull_remote {remote branch success} {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -05001136 global HEAD PARENT MERGE_HEAD commit_type selected_commit_type
Shawn O. Pearceec39d832006-11-07 22:00:38 -05001137 global ui_status_value
1138
Shawn O. Pearce988b8a72006-11-07 21:30:46 -05001139 unlock_index
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001140 if {$success} {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -05001141 repository_state commit_type HEAD MERGE_HEAD
Shawn O. Pearceec39d832006-11-07 22:00:38 -05001142 set PARENT $HEAD
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05001143 set selected_commit_type new
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -05001144 set ui_status_value "Pulling $branch from $remote complete."
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001145 } else {
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -05001146 rescan [list set ui_status_value \
1147 "Conflicts detected while pulling $branch from $remote."]
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001148 }
1149}
1150
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001151proc push_to {remote} {
1152 set w [new_console "push $remote" \
1153 "Pushing changes to $remote"]
Shawn O. Pearcecc4b1c02006-11-06 23:47:05 -05001154 set cmd [list git push]
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001155 lappend cmd $remote
Shawn O. Pearcecc4b1c02006-11-06 23:47:05 -05001156 console_exec $w $cmd
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001157}
1158
1159######################################################################
1160##
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001161## ui helpers
1162
1163proc mapcol {state path} {
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001164 global all_cols ui_other
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001165
1166 if {[catch {set r $all_cols($state)}]} {
1167 puts "error: no column for state={$state} $path"
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001168 return $ui_other
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001169 }
1170 return $r
1171}
1172
1173proc mapicon {state path} {
1174 global all_icons
1175
1176 if {[catch {set r $all_icons($state)}]} {
1177 puts "error: no icon for state={$state} $path"
1178 return file_plain
1179 }
1180 return $r
1181}
1182
1183proc mapdesc {state path} {
1184 global all_descs
1185
1186 if {[catch {set r $all_descs($state)}]} {
1187 puts "error: no desc for state={$state} $path"
1188 return $state
1189 }
1190 return $r
1191}
1192
Shawn O. Pearce68e009d2006-11-11 17:59:34 -05001193proc escape_path {path} {
1194 regsub -all "\n" $path "\\n" path
1195 return $path
1196}
1197
Shawn O. Pearce16403d02006-11-11 21:52:06 -05001198proc short_path {path} {
1199 return [escape_path [lindex [file split $path] end]]
1200}
1201
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001202set next_icon_id 0
Shawn O. Pearce51cc47f2006-11-19 01:20:42 -05001203set null_sha1 [string repeat 0 40]
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001204
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05001205proc merge_state {path new_state {head_info {}} {index_info {}}} {
Shawn O. Pearce51cc47f2006-11-19 01:20:42 -05001206 global file_states next_icon_id null_sha1
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001207
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001208 set s0 [string index $new_state 0]
1209 set s1 [string index $new_state 1]
1210
1211 if {[catch {set info $file_states($path)}]} {
1212 set state __
1213 set icon n[incr next_icon_id]
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001214 } else {
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001215 set state [lindex $info 0]
1216 set icon [lindex $info 1]
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05001217 if {$head_info eq {}} {set head_info [lindex $info 2]}
1218 if {$index_info eq {}} {set index_info [lindex $info 3]}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001219 }
1220
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05001221 if {$s0 eq {?}} {set s0 [string index $state 0]} \
1222 elseif {$s0 eq {_}} {set s0 _}
1223
1224 if {$s1 eq {?}} {set s1 [string index $state 1]} \
1225 elseif {$s1 eq {_}} {set s1 _}
1226
Shawn O. Pearce51cc47f2006-11-19 01:20:42 -05001227 if {$s0 eq {A} && $s1 eq {_} && $head_info eq {}} {
1228 set head_info [list 0 $null_sha1]
1229 } elseif {$s0 ne {_} && [string index $state 0] eq {_}
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05001230 && $head_info eq {}} {
1231 set head_info $index_info
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001232 }
1233
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05001234 set file_states($path) [list $s0$s1 $icon \
1235 $head_info $index_info \
1236 ]
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001237 return $state
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001238}
1239
1240proc display_file {path state} {
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05001241 global file_states file_lists selected_paths
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001242
1243 set old_m [merge_state $path $state]
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001244 set s $file_states($path)
1245 set new_m [lindex $s 0]
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05001246 set new_w [mapcol $new_m $path]
1247 set old_w [mapcol $old_m $path]
1248 set new_icon [mapicon $new_m $path]
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001249
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001250 if {$new_w ne $old_w} {
Shawn O. Pearce03e4ec52006-11-11 17:52:16 -05001251 set lno [lsearch -sorted $file_lists($old_w) $path]
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001252 if {$lno >= 0} {
1253 incr lno
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001254 $old_w conf -state normal
Shawn O. Pearce24263b72006-11-13 16:06:38 -05001255 $old_w delete $lno.0 [expr {$lno + 1}].0
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001256 $old_w conf -state disabled
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001257 }
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001258
Shawn O. Pearce03e4ec52006-11-11 17:52:16 -05001259 lappend file_lists($new_w) $path
1260 set file_lists($new_w) [lsort $file_lists($new_w)]
1261 set lno [lsearch -sorted $file_lists($new_w) $path]
1262 incr lno
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001263 $new_w conf -state normal
1264 $new_w image create $lno.0 \
1265 -align center -padx 5 -pady 1 \
1266 -name [lindex $s 1] \
Shawn O. Pearcee4ee9af2006-11-07 22:09:55 -05001267 -image $new_icon
Shawn O. Pearce68e009d2006-11-11 17:59:34 -05001268 $new_w insert $lno.1 "[escape_path $path]\n"
Shawn O. Pearce24263b72006-11-13 16:06:38 -05001269 if {[catch {set in_sel $selected_paths($path)}]} {
1270 set in_sel 0
1271 }
1272 if {$in_sel} {
1273 $new_w tag add in_sel $lno.0 [expr {$lno + 1}].0
1274 }
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001275 $new_w conf -state disabled
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001276 } elseif {$new_icon ne [mapicon $old_m $path]} {
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001277 $new_w conf -state normal
1278 $new_w image conf [lindex $s 1] -image $new_icon
1279 $new_w conf -state disabled
1280 }
1281}
1282
1283proc display_all_files {} {
Shawn O. Pearce24263b72006-11-13 16:06:38 -05001284 global ui_index ui_other
1285 global file_states file_lists
1286 global last_clicked selected_paths
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001287
1288 $ui_index conf -state normal
1289 $ui_other conf -state normal
1290
Shawn O. Pearce7f1df792006-11-11 18:38:00 -05001291 $ui_index delete 0.0 end
1292 $ui_other delete 0.0 end
Shawn O. Pearce24263b72006-11-13 16:06:38 -05001293 set last_clicked {}
Shawn O. Pearce7f1df792006-11-11 18:38:00 -05001294
Shawn O. Pearce62aac802006-11-11 20:00:35 -05001295 set file_lists($ui_index) [list]
1296 set file_lists($ui_other) [list]
1297
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001298 foreach path [lsort [array names file_states]] {
1299 set s $file_states($path)
1300 set m [lindex $s 0]
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001301 set w [mapcol $m $path]
Shawn O. Pearce03e4ec52006-11-11 17:52:16 -05001302 lappend file_lists($w) $path
Shawn O. Pearce24263b72006-11-13 16:06:38 -05001303 set lno [expr {[lindex [split [$w index end] .] 0] - 1}]
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001304 $w image create end \
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001305 -align center -padx 5 -pady 1 \
1306 -name [lindex $s 1] \
1307 -image [mapicon $m $path]
Shawn O. Pearce68e009d2006-11-11 17:59:34 -05001308 $w insert end "[escape_path $path]\n"
Shawn O. Pearce24263b72006-11-13 16:06:38 -05001309 if {[catch {set in_sel $selected_paths($path)}]} {
1310 set in_sel 0
1311 }
1312 if {$in_sel} {
1313 $w tag add in_sel $lno.0 [expr {$lno + 1}].0
1314 }
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001315 }
1316
Shawn O. Pearce93f654d2006-11-07 19:30:54 -05001317 $ui_index conf -state disabled
1318 $ui_other conf -state disabled
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001319}
1320
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05001321proc update_indexinfo {msg pathList after} {
1322 global update_index_cp ui_status_value
1323
1324 if {![lock_index update]} return
1325
1326 set update_index_cp 0
1327 set pathList [lsort $pathList]
1328 set totalCnt [llength $pathList]
1329 set batch [expr {int($totalCnt * .01) + 1}]
1330 if {$batch > 25} {set batch 25}
1331
1332 set ui_status_value [format \
1333 "$msg... %i/%i files (%.2f%%)" \
1334 $update_index_cp \
1335 $totalCnt \
1336 0.0]
1337 set fd [open "| git update-index -z --index-info" w]
1338 fconfigure $fd \
1339 -blocking 0 \
1340 -buffering full \
1341 -buffersize 512 \
1342 -translation binary
1343 fileevent $fd writable [list \
1344 write_update_indexinfo \
1345 $fd \
1346 $pathList \
1347 $totalCnt \
1348 $batch \
1349 $msg \
1350 $after \
1351 ]
1352}
1353
1354proc write_update_indexinfo {fd pathList totalCnt batch msg after} {
1355 global update_index_cp ui_status_value
1356 global file_states current_diff
1357
1358 if {$update_index_cp >= $totalCnt} {
1359 close $fd
1360 unlock_index
1361 uplevel #0 $after
1362 return
1363 }
1364
1365 for {set i $batch} \
1366 {$update_index_cp < $totalCnt && $i > 0} \
1367 {incr i -1} {
1368 set path [lindex $pathList $update_index_cp]
1369 incr update_index_cp
1370
1371 set s $file_states($path)
1372 switch -glob -- [lindex $s 0] {
1373 A? {set new _O}
1374 M? {set new _M}
1375 D? {set new _?}
1376 ?? {continue}
1377 }
1378 set info [lindex $s 2]
1379 if {$info eq {}} continue
1380
1381 puts -nonewline $fd $info
1382 puts -nonewline $fd "\t"
1383 puts -nonewline $fd $path
1384 puts -nonewline $fd "\0"
1385 display_file $path $new
1386 }
1387
1388 set ui_status_value [format \
1389 "$msg... %i/%i files (%.2f%%)" \
1390 $update_index_cp \
1391 $totalCnt \
1392 [expr {100.0 * $update_index_cp / $totalCnt}]]
1393}
1394
Shawn O. Pearce04b39382006-11-14 01:42:32 -05001395proc update_index {msg pathList after} {
Shawn O. Pearce32e0bca2006-11-18 03:03:16 -05001396 global update_index_cp ui_status_value
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001397
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001398 if {![lock_index update]} return
1399
1400 set update_index_cp 0
Shawn O. Pearceaaf10852006-11-12 19:29:04 -05001401 set pathList [lsort $pathList]
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001402 set totalCnt [llength $pathList]
1403 set batch [expr {int($totalCnt * .01) + 1}]
1404 if {$batch > 25} {set batch 25}
1405
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001406 set ui_status_value [format \
Shawn O. Pearce04b39382006-11-14 01:42:32 -05001407 "$msg... %i/%i files (%.2f%%)" \
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001408 $update_index_cp \
1409 $totalCnt \
1410 0.0]
1411 set fd [open "| git update-index --add --remove -z --stdin" w]
Shawn O. Pearce7f09cfa2006-11-12 19:33:33 -05001412 fconfigure $fd \
1413 -blocking 0 \
1414 -buffering full \
1415 -buffersize 512 \
1416 -translation binary
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001417 fileevent $fd writable [list \
1418 write_update_index \
1419 $fd \
1420 $pathList \
1421 $totalCnt \
1422 $batch \
Shawn O. Pearce04b39382006-11-14 01:42:32 -05001423 $msg \
1424 $after \
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001425 ]
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001426}
1427
Shawn O. Pearce04b39382006-11-14 01:42:32 -05001428proc write_update_index {fd pathList totalCnt batch msg after} {
Shawn O. Pearce32e0bca2006-11-18 03:03:16 -05001429 global update_index_cp ui_status_value
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05001430 global file_states current_diff
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001431
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001432 if {$update_index_cp >= $totalCnt} {
1433 close $fd
1434 unlock_index
Shawn O. Pearce04b39382006-11-14 01:42:32 -05001435 uplevel #0 $after
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001436 return
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001437 }
1438
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001439 for {set i $batch} \
1440 {$update_index_cp < $totalCnt && $i > 0} \
1441 {incr i -1} {
1442 set path [lindex $pathList $update_index_cp]
1443 incr update_index_cp
1444
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -05001445 switch -glob -- [lindex $file_states($path) 0] {
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001446 AD -
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -05001447 MD -
Shawn O. Pearcedde59742006-11-19 00:46:08 -05001448 _D {set new DD}
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -05001449
1450 _M -
1451 MM -
Shawn O. Pearceb6765112006-11-18 03:08:51 -05001452 M_ {set new M_}
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -05001453
1454 _O -
1455 AM -
Shawn O. Pearceb6765112006-11-18 03:08:51 -05001456 A_ {set new A_}
Shawn O. Pearcebbe3b3b2006-11-15 18:06:29 -05001457
1458 ?? {continue}
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001459 }
1460
1461 puts -nonewline $fd $path
1462 puts -nonewline $fd "\0"
1463 display_file $path $new
Shawn O. Pearcebd1e2b42006-11-06 22:03:05 -05001464 }
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001465
1466 set ui_status_value [format \
Shawn O. Pearce04b39382006-11-14 01:42:32 -05001467 "$msg... %i/%i files (%.2f%%)" \
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05001468 $update_index_cp \
1469 $totalCnt \
1470 [expr {100.0 * $update_index_cp / $totalCnt}]]
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001471}
1472
1473######################################################################
1474##
Shawn O. Pearce2d195162006-11-08 23:42:51 -05001475## remote management
Shawn O. Pearce0d4f3eb2006-11-07 04:26:02 -05001476
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001477proc load_all_remotes {} {
Shawn O. Pearce0d4f3eb2006-11-07 04:26:02 -05001478 global gitdir all_remotes repo_config
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001479
1480 set all_remotes [list]
1481 set rm_dir [file join $gitdir remotes]
1482 if {[file isdirectory $rm_dir]} {
Shawn O. Pearced47ae542006-11-07 03:00:20 -05001483 set all_remotes [concat $all_remotes [glob \
1484 -types f \
1485 -tails \
1486 -nocomplain \
1487 -directory $rm_dir *]]
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001488 }
1489
Shawn O. Pearce0d4f3eb2006-11-07 04:26:02 -05001490 foreach line [array names repo_config remote.*.url] {
1491 if {[regexp ^remote\.(.*)\.url\$ $line line name]} {
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001492 lappend all_remotes $name
1493 }
1494 }
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001495
1496 set all_remotes [lsort -unique $all_remotes]
1497}
1498
Shawn O. Pearcec1237ae2006-11-15 23:52:20 -05001499proc populate_fetch_menu {m} {
1500 global gitdir all_remotes repo_config
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001501
Shawn O. Pearcec1237ae2006-11-15 23:52:20 -05001502 foreach r $all_remotes {
1503 set enable 0
1504 if {![catch {set a $repo_config(remote.$r.url)}]} {
1505 if {![catch {set a $repo_config(remote.$r.fetch)}]} {
1506 set enable 1
1507 }
1508 } else {
1509 catch {
1510 set fd [open [file join $gitdir remotes $r] r]
1511 while {[gets $fd n] >= 0} {
1512 if {[regexp {^Pull:[ \t]*([^:]+):} $n]} {
1513 set enable 1
1514 break
1515 }
1516 }
1517 close $fd
1518 }
1519 }
1520
1521 if {$enable} {
1522 $m add command \
1523 -label "Fetch from $r..." \
1524 -command [list fetch_from $r] \
1525 -font font_ui
1526 }
1527 }
1528}
1529
1530proc populate_push_menu {m} {
1531 global gitdir all_remotes repo_config
1532
1533 foreach r $all_remotes {
1534 set enable 0
1535 if {![catch {set a $repo_config(remote.$r.url)}]} {
1536 if {![catch {set a $repo_config(remote.$r.push)}]} {
1537 set enable 1
1538 }
1539 } else {
1540 catch {
1541 set fd [open [file join $gitdir remotes $r] r]
1542 while {[gets $fd n] >= 0} {
1543 if {[regexp {^Push:[ \t]*([^:]+):} $n]} {
1544 set enable 1
1545 break
1546 }
1547 }
1548 close $fd
1549 }
1550 }
1551
1552 if {$enable} {
1553 $m add command \
1554 -label "Push to $r..." \
1555 -command [list push_to $r] \
1556 -font font_ui
1557 }
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001558 }
1559}
1560
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001561proc populate_pull_menu {m} {
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001562 global gitdir repo_config all_remotes disable_on_lock
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001563
1564 foreach remote $all_remotes {
1565 set rb {}
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001566 if {[array get repo_config remote.$remote.url] ne {}} {
1567 if {[array get repo_config remote.$remote.fetch] ne {}} {
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001568 regexp {^([^:]+):} \
1569 [lindex $repo_config(remote.$remote.fetch) 0] \
1570 line rb
1571 }
1572 } else {
1573 catch {
1574 set fd [open [file join $gitdir remotes $remote] r]
1575 while {[gets $fd line] >= 0} {
1576 if {[regexp {^Pull:[ \t]*([^:]+):} $line line rb]} {
1577 break
1578 }
1579 }
1580 close $fd
1581 }
1582 }
1583
1584 set rb_short $rb
1585 regsub ^refs/heads/ $rb {} rb_short
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001586 if {$rb_short ne {}} {
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001587 $m add command \
1588 -label "Branch $rb_short from $remote..." \
1589 -command [list pull_remote $remote $rb] \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001590 -font font_ui
Shawn O. Pearce0a462d62006-11-07 21:43:16 -05001591 lappend disable_on_lock \
1592 [list $m entryconf [$m index last] -state]
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001593 }
1594 }
1595}
1596
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001597######################################################################
1598##
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001599## icons
1600
1601set filemask {
1602#define mask_width 14
1603#define mask_height 15
1604static unsigned char mask_bits[] = {
1605 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
1606 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
1607 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f};
1608}
1609
1610image create bitmap file_plain -background white -foreground black -data {
1611#define plain_width 14
1612#define plain_height 15
1613static unsigned char plain_bits[] = {
1614 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
1615 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10,
1616 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f};
1617} -maskdata $filemask
1618
1619image create bitmap file_mod -background white -foreground blue -data {
1620#define mod_width 14
1621#define mod_height 15
1622static unsigned char mod_bits[] = {
1623 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10,
1624 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
1625 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
1626} -maskdata $filemask
1627
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001628image create bitmap file_fulltick -background white -foreground "#007000" -data {
1629#define file_fulltick_width 14
1630#define file_fulltick_height 15
1631static unsigned char file_fulltick_bits[] = {
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001632 0xfe, 0x01, 0x02, 0x1a, 0x02, 0x0c, 0x02, 0x0c, 0x02, 0x16, 0x02, 0x16,
1633 0x02, 0x13, 0x00, 0x13, 0x86, 0x11, 0x8c, 0x11, 0xd8, 0x10, 0xf2, 0x10,
1634 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
1635} -maskdata $filemask
1636
1637image create bitmap file_parttick -background white -foreground "#005050" -data {
1638#define parttick_width 14
1639#define parttick_height 15
1640static unsigned char parttick_bits[] = {
1641 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10,
1642 0x7a, 0x14, 0x02, 0x16, 0x02, 0x13, 0x8a, 0x11, 0xda, 0x10, 0x72, 0x10,
1643 0x22, 0x10, 0x02, 0x10, 0xfe, 0x1f};
1644} -maskdata $filemask
1645
1646image create bitmap file_question -background white -foreground black -data {
1647#define file_question_width 14
1648#define file_question_height 15
1649static unsigned char file_question_bits[] = {
1650 0xfe, 0x01, 0x02, 0x02, 0xe2, 0x04, 0xf2, 0x09, 0x1a, 0x1b, 0x0a, 0x13,
1651 0x82, 0x11, 0xc2, 0x10, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, 0x62, 0x10,
1652 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
1653} -maskdata $filemask
1654
1655image create bitmap file_removed -background white -foreground red -data {
1656#define file_removed_width 14
1657#define file_removed_height 15
1658static unsigned char file_removed_bits[] = {
1659 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
1660 0x1a, 0x16, 0x32, 0x13, 0xe2, 0x11, 0xc2, 0x10, 0xe2, 0x11, 0x32, 0x13,
1661 0x1a, 0x16, 0x02, 0x10, 0xfe, 0x1f};
1662} -maskdata $filemask
1663
1664image create bitmap file_merge -background white -foreground blue -data {
1665#define file_merge_width 14
1666#define file_merge_height 15
1667static unsigned char file_merge_bits[] = {
1668 0xfe, 0x01, 0x02, 0x03, 0x62, 0x05, 0x62, 0x09, 0x62, 0x1f, 0x62, 0x10,
1669 0xfa, 0x11, 0xf2, 0x10, 0x62, 0x10, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
1670 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
1671} -maskdata $filemask
1672
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001673set ui_index .vpane.files.index.list
1674set ui_other .vpane.files.other.list
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001675set max_status_desc 0
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001676foreach i {
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001677 {__ i plain "Unmodified"}
1678 {_M i mod "Modified"}
Shawn O. Pearce135f76e2006-11-12 21:49:49 -05001679 {M_ i fulltick "Included in commit"}
Shawn O. Pearce7fe7e732006-11-08 22:48:34 -05001680 {MM i parttick "Partially included"}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001681
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001682 {_O o plain "Untracked"}
Shawn O. Pearce135f76e2006-11-12 21:49:49 -05001683 {A_ o fulltick "Added by commit"}
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001684 {AM o parttick "Partially added"}
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001685 {AD o question "Added (but now gone)"}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001686
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001687 {_D i question "Missing"}
Shawn O. Pearce135f76e2006-11-12 21:49:49 -05001688 {DD i removed "Removed by commit"}
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001689 {DO i removed "Removed (still exists)"}
Shawn O. Pearcea29481e2006-11-19 03:38:48 -05001690 {DM i removed "Removed (but modified)"}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001691
Shawn O. Pearce375f3882006-11-19 03:46:29 -05001692 {UD i merge "Merge conflicts"}
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001693 {UM i merge "Merge conflicts"}
1694 {U_ i merge "Merge conflicts"}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001695 } {
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001696 if {$max_status_desc < [string length [lindex $i 3]]} {
1697 set max_status_desc [string length [lindex $i 3]]
1698 }
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001699 if {[lindex $i 1] eq {i}} {
Shawn O. Pearce6b292672006-11-07 19:58:37 -05001700 set all_cols([lindex $i 0]) $ui_index
1701 } else {
1702 set all_cols([lindex $i 0]) $ui_other
1703 }
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001704 set all_icons([lindex $i 0]) file_[lindex $i 2]
1705 set all_descs([lindex $i 0]) [lindex $i 3]
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001706}
1707unset filemask i
1708
1709######################################################################
1710##
1711## util
1712
Shawn O. Pearce16fccd72006-11-12 02:22:21 -05001713proc is_MacOSX {} {
1714 global tcl_platform tk_library
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001715 if {$tcl_platform(platform) eq {unix}
1716 && $tcl_platform(os) eq {Darwin}
Shawn O. Pearce16fccd72006-11-12 02:22:21 -05001717 && [string match /Library/Frameworks/* $tk_library]} {
1718 return 1
1719 }
1720 return 0
1721}
1722
1723proc bind_button3 {w cmd} {
1724 bind $w <Any-Button-3> $cmd
1725 if {[is_MacOSX]} {
1726 bind $w <Control-Button-1> $cmd
1727 }
1728}
1729
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001730proc incr_font_size {font {amt 1}} {
1731 set sz [font configure $font -size]
1732 incr sz $amt
1733 font configure $font -size $sz
1734 font configure ${font}bold -size $sz
1735}
1736
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05001737proc hook_failed_popup {hook msg} {
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001738 global gitdir appname
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05001739
1740 set w .hookfail
1741 toplevel $w
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05001742
1743 frame $w.m
1744 label $w.m.l1 -text "$hook hook failed:" \
1745 -anchor w \
1746 -justify left \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001747 -font font_uibold
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05001748 text $w.m.t \
1749 -background white -borderwidth 1 \
1750 -relief sunken \
1751 -width 80 -height 10 \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001752 -font font_diff \
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05001753 -yscrollcommand [list $w.m.sby set]
1754 label $w.m.l2 \
1755 -text {You must correct the above errors before committing.} \
1756 -anchor w \
1757 -justify left \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001758 -font font_uibold
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05001759 scrollbar $w.m.sby -command [list $w.m.t yview]
1760 pack $w.m.l1 -side top -fill x
1761 pack $w.m.l2 -side bottom -fill x
1762 pack $w.m.sby -side right -fill y
1763 pack $w.m.t -side left -fill both -expand 1
1764 pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10
1765
1766 $w.m.t insert 1.0 $msg
1767 $w.m.t conf -state disabled
1768
1769 button $w.ok -text OK \
1770 -width 15 \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001771 -font font_ui \
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05001772 -command "destroy $w"
Shawn O. Pearce1e5c18f2006-11-12 22:41:34 -05001773 pack $w.ok -side bottom -anchor e -pady 10 -padx 10
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05001774
1775 bind $w <Visibility> "grab $w; focus $w"
1776 bind $w <Key-Return> "destroy $w"
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001777 wm title $w "$appname ([lindex [file split \
1778 [file normalize [file dirname $gitdir]]] \
1779 end]): error"
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05001780 tkwait window $w
1781}
1782
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001783set next_console_id 0
1784
1785proc new_console {short_title long_title} {
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001786 global next_console_id console_data
1787 set w .console[incr next_console_id]
1788 set console_data($w) [list $short_title $long_title]
1789 return [console_init $w]
1790}
1791
1792proc console_init {w} {
1793 global console_cr console_data
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001794 global gitdir appname M1B
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001795
Shawn O. Pearceee3dc932006-11-07 02:18:18 -05001796 set console_cr($w) 1.0
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001797 toplevel $w
1798 frame $w.m
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001799 label $w.m.l1 -text "[lindex $console_data($w) 1]:" \
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001800 -anchor w \
1801 -justify left \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001802 -font font_uibold
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001803 text $w.m.t \
1804 -background white -borderwidth 1 \
1805 -relief sunken \
1806 -width 80 -height 10 \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001807 -font font_diff \
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001808 -state disabled \
1809 -yscrollcommand [list $w.m.sby set]
Shawn O. Pearce1e5c18f2006-11-12 22:41:34 -05001810 label $w.m.s -text {Working... please wait...} \
1811 -anchor w \
Shawn O. Pearce07123f42006-11-07 02:57:46 -05001812 -justify left \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001813 -font font_uibold
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001814 scrollbar $w.m.sby -command [list $w.m.t yview]
1815 pack $w.m.l1 -side top -fill x
Shawn O. Pearce07123f42006-11-07 02:57:46 -05001816 pack $w.m.s -side bottom -fill x
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001817 pack $w.m.sby -side right -fill y
1818 pack $w.m.t -side left -fill both -expand 1
1819 pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10
1820
Shawn O. Pearce0e794312006-11-11 20:24:23 -05001821 menu $w.ctxm -tearoff 0
1822 $w.ctxm add command -label "Copy" \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001823 -font font_ui \
Shawn O. Pearce0e794312006-11-11 20:24:23 -05001824 -command "tk_textCopy $w.m.t"
1825 $w.ctxm add command -label "Select All" \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001826 -font font_ui \
Shawn O. Pearce0e794312006-11-11 20:24:23 -05001827 -command "$w.m.t tag add sel 0.0 end"
1828 $w.ctxm add command -label "Copy All" \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001829 -font font_ui \
Shawn O. Pearce0e794312006-11-11 20:24:23 -05001830 -command "
1831 $w.m.t tag add sel 0.0 end
1832 tk_textCopy $w.m.t
1833 $w.m.t tag remove sel 0.0 end
1834 "
1835
Shawn O. Pearce1e5c18f2006-11-12 22:41:34 -05001836 button $w.ok -text {Close} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05001837 -font font_ui \
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001838 -state disabled \
1839 -command "destroy $w"
Shawn O. Pearce1e5c18f2006-11-12 22:41:34 -05001840 pack $w.ok -side bottom -anchor e -pady 10 -padx 10
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001841
Shawn O. Pearce16fccd72006-11-12 02:22:21 -05001842 bind_button3 $w.m.t "tk_popup $w.ctxm %X %Y"
Shawn O. Pearce62aac802006-11-11 20:00:35 -05001843 bind $w.m.t <$M1B-Key-a> "$w.m.t tag add sel 0.0 end;break"
1844 bind $w.m.t <$M1B-Key-A> "$w.m.t tag add sel 0.0 end;break"
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001845 bind $w <Visibility> "focus $w"
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001846 wm title $w "$appname ([lindex [file split \
1847 [file normalize [file dirname $gitdir]]] \
1848 end]): [lindex $console_data($w) 0]"
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001849 return $w
1850}
1851
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001852proc console_exec {w cmd {after {}}} {
Shawn O. Pearcecc4b1c02006-11-06 23:47:05 -05001853 global tcl_platform
1854
1855 # -- Windows tosses the enviroment when we exec our child.
1856 # But most users need that so we have to relogin. :-(
1857 #
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001858 if {$tcl_platform(platform) eq {windows}} {
Shawn O. Pearcecc4b1c02006-11-06 23:47:05 -05001859 set cmd [list sh --login -c "cd \"[pwd]\" && [join $cmd { }]"]
1860 }
1861
1862 # -- Tcl won't let us redirect both stdout and stderr to
1863 # the same pipe. So pass it through cat...
1864 #
1865 set cmd [concat | $cmd |& cat]
1866
1867 set fd_f [open $cmd r]
Shawn O. Pearceee3dc932006-11-07 02:18:18 -05001868 fconfigure $fd_f -blocking 0 -translation binary
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001869 fileevent $fd_f readable [list console_read $w $fd_f $after]
Shawn O. Pearcecc4b1c02006-11-06 23:47:05 -05001870}
1871
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001872proc console_read {w fd after} {
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001873 global console_cr console_data
Shawn O. Pearceee3dc932006-11-07 02:18:18 -05001874
Shawn O. Pearceee3dc932006-11-07 02:18:18 -05001875 set buf [read $fd]
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001876 if {$buf ne {}} {
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001877 if {![winfo exists $w]} {console_init $w}
1878 $w.m.t conf -state normal
1879 set c 0
1880 set n [string length $buf]
1881 while {$c < $n} {
1882 set cr [string first "\r" $buf $c]
1883 set lf [string first "\n" $buf $c]
Shawn O. Pearce24263b72006-11-13 16:06:38 -05001884 if {$cr < 0} {set cr [expr {$n + 1}]}
1885 if {$lf < 0} {set lf [expr {$n + 1}]}
Shawn O. Pearceee3dc932006-11-07 02:18:18 -05001886
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001887 if {$lf < $cr} {
1888 $w.m.t insert end [string range $buf $c $lf]
1889 set console_cr($w) [$w.m.t index {end -1c}]
1890 set c $lf
1891 incr c
1892 } else {
1893 $w.m.t delete $console_cr($w) end
1894 $w.m.t insert end "\n"
1895 $w.m.t insert end [string range $buf $c $cr]
1896 set c $cr
1897 incr c
1898 }
Shawn O. Pearceee3dc932006-11-07 02:18:18 -05001899 }
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001900 $w.m.t conf -state disabled
1901 $w.m.t see end
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001902 }
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001903
Shawn O. Pearce07123f42006-11-07 02:57:46 -05001904 fconfigure $fd -blocking 1
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001905 if {[eof $fd]} {
Shawn O. Pearce07123f42006-11-07 02:57:46 -05001906 if {[catch {close $fd}]} {
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001907 if {![winfo exists $w]} {console_init $w}
Shawn O. Pearce07123f42006-11-07 02:57:46 -05001908 $w.m.s conf -background red -text {Error: Command Failed}
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001909 $w.ok conf -state normal
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001910 set ok 0
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001911 } elseif {[winfo exists $w]} {
Shawn O. Pearce07123f42006-11-07 02:57:46 -05001912 $w.m.s conf -background green -text {Success}
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001913 $w.ok conf -state normal
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001914 set ok 1
Shawn O. Pearce07123f42006-11-07 02:57:46 -05001915 }
Shawn O. Pearceee3dc932006-11-07 02:18:18 -05001916 array unset console_cr $w
Shawn O. Pearce37af79d2006-11-07 04:19:49 -05001917 array unset console_data $w
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001918 if {$after ne {}} {
Shawn O. Pearced33ba5f2006-11-07 05:02:15 -05001919 uplevel #0 $after $ok
1920 }
Shawn O. Pearce07123f42006-11-07 02:57:46 -05001921 return
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001922 }
Shawn O. Pearce07123f42006-11-07 02:57:46 -05001923 fconfigure $fd -blocking 0
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05001924}
1925
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001926######################################################################
1927##
1928## ui commands
1929
Shawn O. Pearcee210e672006-11-06 19:12:58 -05001930set starting_gitk_msg {Please wait... Starting gitk...}
Shawn O. Pearcecc4b1c02006-11-06 23:47:05 -05001931
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001932proc do_gitk {} {
Shawn O. Pearcee210e672006-11-06 19:12:58 -05001933 global tcl_platform ui_status_value starting_gitk_msg
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001934
Shawn O. Pearcee210e672006-11-06 19:12:58 -05001935 set ui_status_value $starting_gitk_msg
Shawn O. Pearcee57ca852006-11-06 21:34:10 -05001936 after 10000 {
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001937 if {$ui_status_value eq $starting_gitk_msg} {
Shawn O. Pearcee210e672006-11-06 19:12:58 -05001938 set ui_status_value {Ready.}
1939 }
1940 }
1941
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001942 if {$tcl_platform(platform) eq {windows}} {
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001943 exec sh -c gitk &
1944 } else {
1945 exec gitk &
1946 }
1947}
1948
Shawn O. Pearced1536c42006-11-07 20:40:35 -05001949proc do_repack {} {
1950 set w [new_console "repack" "Repacking the object database"]
1951 set cmd [list git repack]
1952 lappend cmd -a
1953 lappend cmd -d
1954 console_exec $w $cmd
1955}
1956
Shawn O. Pearce444f92d2006-11-20 21:43:41 -05001957proc do_fsck_objects {} {
1958 set w [new_console "verify" "Verifying the object database"]
1959 set cmd [list git fsck-objects]
1960 lappend cmd --full
1961 lappend cmd --cache
1962 lappend cmd --strict
1963 console_exec $w $cmd
1964}
1965
Shawn O. Pearceb5834d72006-11-12 02:27:28 -05001966set is_quitting 0
Shawn O. Pearcec4fe7722006-11-11 19:32:24 -05001967
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05001968proc do_quit {} {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05001969 global gitdir ui_comm is_quitting repo_config
Shawn O. Pearcec4fe7722006-11-11 19:32:24 -05001970
Shawn O. Pearceb5834d72006-11-12 02:27:28 -05001971 if {$is_quitting} return
1972 set is_quitting 1
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001973
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05001974 # -- Stash our current commit buffer.
1975 #
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001976 set save [file join $gitdir GITGUI_MSG]
Shawn O. Pearceec6b4242006-11-06 20:50:59 -05001977 set msg [string trim [$ui_comm get 0.0 end]]
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001978 if {[$ui_comm edit modified] && $msg ne {}} {
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001979 catch {
1980 set fd [open $save w]
1981 puts $fd [string trim [$ui_comm get 0.0 end]]
1982 close $fd
1983 }
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001984 } elseif {$msg eq {} && [file exists $save]} {
Shawn O. Pearce131f5032006-11-06 16:07:32 -05001985 file delete $save
1986 }
1987
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05001988 # -- Stash our current window geometry into this repository.
1989 #
1990 set cfg_geometry [list]
1991 lappend cfg_geometry [wm geometry .]
1992 lappend cfg_geometry [lindex [.vpane sash coord 0] 1]
1993 lappend cfg_geometry [lindex [.vpane.files sash coord 0] 0]
1994 if {[catch {set rc_geometry $repo_config(gui.geometry)}]} {
1995 set rc_geometry {}
1996 }
Shawn O. Pearce043f7012006-11-12 18:16:45 -05001997 if {$cfg_geometry ne $rc_geometry} {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05001998 catch {exec git repo-config gui.geometry $cfg_geometry}
1999 }
2000
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002001 destroy .
2002}
2003
2004proc do_rescan {} {
Shawn O. Pearce8f525482006-11-14 01:29:32 -05002005 rescan {set ui_status_value {Ready.}}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002006}
2007
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05002008proc remove_helper {txt paths} {
2009 global file_states current_diff
2010
2011 if {![lock_index begin-update]} return
2012
2013 set pathList [list]
2014 set after {}
2015 foreach path $paths {
2016 switch -glob -- [lindex $file_states($path) 0] {
2017 A? -
2018 M? -
2019 D? {
2020 lappend pathList $path
2021 if {$path eq $current_diff} {
2022 set after {reshow_diff;}
2023 }
2024 }
2025 }
2026 }
2027 if {$pathList eq {}} {
2028 unlock_index
2029 } else {
2030 update_indexinfo \
2031 $txt \
2032 $pathList \
2033 [concat $after {set ui_status_value {Ready.}}]
2034 }
2035}
2036
2037proc do_remove_selection {} {
2038 global current_diff selected_paths
2039
2040 if {[array size selected_paths] > 0} {
2041 remove_helper \
2042 {Removing selected files from commit} \
2043 [array names selected_paths]
2044 } elseif {$current_diff ne {}} {
2045 remove_helper \
2046 "Removing [short_path $current_diff] from commit" \
2047 [list $current_diff]
2048 }
2049}
2050
Shawn O. Pearcec4ed8792006-11-18 03:24:20 -05002051proc include_helper {txt paths} {
Shawn O. Pearce32e0bca2006-11-18 03:03:16 -05002052 global file_states current_diff
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002053
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05002054 if {![lock_index begin-update]} return
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002055
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05002056 set pathList [list]
Shawn O. Pearce32e0bca2006-11-18 03:03:16 -05002057 set after {}
Shawn O. Pearcec4ed8792006-11-18 03:24:20 -05002058 foreach path $paths {
Shawn O. Pearce375f3882006-11-19 03:46:29 -05002059 switch -glob -- [lindex $file_states($path) 0] {
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05002060 AM -
Shawn O. Pearce54896cf2006-11-18 21:33:04 -05002061 AD -
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05002062 MM -
Shawn O. Pearce375f3882006-11-19 03:46:29 -05002063 U? -
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05002064 _M -
Shawn O. Pearce54896cf2006-11-18 21:33:04 -05002065 _D -
2066 _O {
Shawn O. Pearce32e0bca2006-11-18 03:03:16 -05002067 lappend pathList $path
2068 if {$path eq $current_diff} {
2069 set after {reshow_diff;}
2070 }
2071 }
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002072 }
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05002073 }
Shawn O. Pearce043f7012006-11-12 18:16:45 -05002074 if {$pathList eq {}} {
Shawn O. Pearce74e6b122006-11-12 06:35:14 -05002075 unlock_index
2076 } else {
Shawn O. Pearce04b39382006-11-14 01:42:32 -05002077 update_index \
Shawn O. Pearcec4ed8792006-11-18 03:24:20 -05002078 $txt \
Shawn O. Pearce04b39382006-11-14 01:42:32 -05002079 $pathList \
Shawn O. Pearce32e0bca2006-11-18 03:03:16 -05002080 [concat $after {set ui_status_value {Ready to commit.}}]
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002081 }
2082}
2083
Shawn O. Pearcec4ed8792006-11-18 03:24:20 -05002084proc do_include_selection {} {
2085 global current_diff selected_paths
2086
2087 if {[array size selected_paths] > 0} {
2088 include_helper \
2089 {Including selected files} \
2090 [array names selected_paths]
2091 } elseif {$current_diff ne {}} {
2092 include_helper \
2093 "Including [short_path $current_diff]" \
2094 [list $current_diff]
2095 }
2096}
2097
2098proc do_include_all {} {
2099 global file_states
Shawn O. Pearce54896cf2006-11-18 21:33:04 -05002100
2101 set paths [list]
2102 foreach path [array names file_states] {
2103 switch -- [lindex $file_states($path) 0] {
2104 AM -
2105 AD -
2106 MM -
2107 _M -
2108 _D {lappend paths $path}
2109 }
2110 }
Shawn O. Pearcec4ed8792006-11-18 03:24:20 -05002111 include_helper \
2112 {Including all modified files} \
Shawn O. Pearce54896cf2006-11-18 21:33:04 -05002113 $paths
Shawn O. Pearcec4ed8792006-11-18 03:24:20 -05002114}
2115
Shawn O. Pearce97bf01c2006-11-08 23:05:46 -05002116proc do_signoff {} {
Shawn O. Pearced63efae2006-11-18 21:07:05 -05002117 global ui_comm
Shawn O. Pearce97bf01c2006-11-08 23:05:46 -05002118
Shawn O. Pearced63efae2006-11-18 21:07:05 -05002119 set me [committer_ident]
2120 if {$me eq {}} return
Shawn O. Pearce97bf01c2006-11-08 23:05:46 -05002121
Shawn O. Pearced63efae2006-11-18 21:07:05 -05002122 set sob "Signed-off-by: $me"
Shawn O. Pearce1daf1d02006-11-11 20:44:03 -05002123 set last [$ui_comm get {end -1c linestart} {end -1c}]
Shawn O. Pearce043f7012006-11-12 18:16:45 -05002124 if {$last ne $sob} {
Shawn O. Pearceb2c6fcf2006-11-11 16:16:25 -05002125 $ui_comm edit separator
Shawn O. Pearce043f7012006-11-12 18:16:45 -05002126 if {$last ne {}
Shawn O. Pearce1daf1d02006-11-11 20:44:03 -05002127 && ![regexp {^[A-Z][A-Za-z]*-[A-Za-z-]+: *} $last]} {
2128 $ui_comm insert end "\n"
2129 }
2130 $ui_comm insert end "\n$sob"
Shawn O. Pearceb2c6fcf2006-11-11 16:16:25 -05002131 $ui_comm edit separator
Shawn O. Pearce97bf01c2006-11-08 23:05:46 -05002132 $ui_comm see end
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002133 }
2134}
2135
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002136proc do_select_commit_type {} {
2137 global commit_type selected_commit_type
2138
2139 if {$selected_commit_type eq {new}
2140 && [string match amend* $commit_type]} {
2141 create_new_commit
2142 } elseif {$selected_commit_type eq {amend}
2143 && ![string match amend* $commit_type]} {
2144 load_last_commit
2145
2146 # The amend request was rejected...
2147 #
2148 if {![string match amend* $commit_type]} {
Shawn O. Pearce54896cf2006-11-18 21:33:04 -05002149 set selected_commit_type new
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002150 }
2151 }
Shawn O. Pearcee57ca852006-11-06 21:34:10 -05002152}
2153
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05002154proc do_commit {} {
Shawn O. Pearceec6b4242006-11-06 20:50:59 -05002155 commit_tree
Shawn O. Pearce6e27d822006-11-06 20:03:36 -05002156}
2157
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002158proc do_options {} {
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002159 global appname gitdir font_descs
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002160 global repo_config global_config
2161 global repo_config_new global_config_new
2162
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002163 array unset repo_config_new
2164 array unset global_config_new
2165 foreach name [array names repo_config] {
2166 set repo_config_new($name) $repo_config($name)
2167 }
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05002168 load_config 1
2169 foreach name [array names repo_config] {
2170 switch -- $name {
2171 gui.diffcontext {continue}
2172 }
2173 set repo_config_new($name) $repo_config($name)
2174 }
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002175 foreach name [array names global_config] {
2176 set global_config_new($name) $global_config($name)
2177 }
Shawn O. Pearcee01b4222006-11-12 06:46:26 -05002178 set reponame [lindex [file split \
2179 [file normalize [file dirname $gitdir]]] \
2180 end]
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002181
2182 set w .options_editor
2183 toplevel $w
Shawn O. Pearcee01b4222006-11-12 06:46:26 -05002184 wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002185
2186 label $w.header -text "$appname Options" \
2187 -font font_uibold
2188 pack $w.header -side top -fill x
2189
2190 frame $w.buttons
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002191 button $w.buttons.restore -text {Restore Defaults} \
2192 -font font_ui \
2193 -command do_restore_defaults
2194 pack $w.buttons.restore -side left
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002195 button $w.buttons.save -text Save \
2196 -font font_ui \
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002197 -command [list do_save_config $w]
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002198 pack $w.buttons.save -side right
2199 button $w.buttons.cancel -text {Cancel} \
2200 -font font_ui \
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002201 -command [list destroy $w]
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002202 pack $w.buttons.cancel -side right
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002203 pack $w.buttons -side bottom -fill x -pady 10 -padx 10
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002204
Shawn O. Pearcee01b4222006-11-12 06:46:26 -05002205 labelframe $w.repo -text "$reponame Repository" \
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002206 -font font_ui \
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002207 -relief raised -borderwidth 2
2208 labelframe $w.global -text {Global (All Repositories)} \
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002209 -font font_ui \
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002210 -relief raised -borderwidth 2
2211 pack $w.repo -side left -fill both -expand 1 -pady 5 -padx 5
2212 pack $w.global -side right -fill both -expand 1 -pady 5 -padx 5
2213
2214 foreach option {
Shawn O. Pearcef7f8d322006-11-13 04:22:42 -05002215 {b partialinclude {Allow Partially Included Files}}
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05002216 {b pullsummary {Show Pull Summary}}
2217 {b trustmtime {Trust File Modification Timestamps}}
2218 {i diffcontext {Number of Diff Context Lines}}
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002219 } {
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05002220 set type [lindex $option 0]
2221 set name [lindex $option 1]
2222 set text [lindex $option 2]
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002223 foreach f {repo global} {
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05002224 switch $type {
2225 b {
2226 checkbutton $w.$f.$name -text $text \
2227 -variable ${f}_config_new(gui.$name) \
2228 -onvalue true \
2229 -offvalue false \
2230 -font font_ui
2231 pack $w.$f.$name -side top -anchor w
2232 }
2233 i {
2234 frame $w.$f.$name
2235 label $w.$f.$name.l -text "$text:" -font font_ui
2236 pack $w.$f.$name.l -side left -anchor w -fill x
2237 spinbox $w.$f.$name.v \
2238 -textvariable ${f}_config_new(gui.$name) \
2239 -from 1 -to 99 -increment 1 \
2240 -width 3 \
2241 -font font_ui
2242 pack $w.$f.$name.v -side right -anchor e
2243 pack $w.$f.$name -side top -anchor w -fill x
2244 }
2245 }
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002246 }
2247 }
2248
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002249 set all_fonts [lsort [font families]]
2250 foreach option $font_descs {
2251 set name [lindex $option 0]
2252 set font [lindex $option 1]
2253 set text [lindex $option 2]
2254
2255 set global_config_new(gui.$font^^family) \
2256 [font configure $font -family]
2257 set global_config_new(gui.$font^^size) \
2258 [font configure $font -size]
2259
2260 frame $w.global.$name
2261 label $w.global.$name.l -text "$text:" -font font_ui
2262 pack $w.global.$name.l -side left -anchor w -fill x
2263 eval tk_optionMenu $w.global.$name.family \
2264 global_config_new(gui.$font^^family) \
2265 $all_fonts
2266 spinbox $w.global.$name.size \
2267 -textvariable global_config_new(gui.$font^^size) \
2268 -from 2 -to 80 -increment 1 \
2269 -width 3 \
2270 -font font_ui
2271 pack $w.global.$name.size -side right -anchor e
2272 pack $w.global.$name.family -side right -anchor e
2273 pack $w.global.$name -side top -anchor w -fill x
2274 }
2275
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002276 bind $w <Visibility> "grab $w; focus $w"
2277 bind $w <Key-Escape> "destroy $w"
Shawn O. Pearcee01b4222006-11-12 06:46:26 -05002278 wm title $w "$appname ($reponame): Options"
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002279 tkwait window $w
2280}
2281
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002282proc do_restore_defaults {} {
Shawn O. Pearce7b64d0b2006-11-12 15:45:35 -05002283 global font_descs default_config repo_config
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002284 global repo_config_new global_config_new
2285
2286 foreach name [array names default_config] {
2287 set repo_config_new($name) $default_config($name)
2288 set global_config_new($name) $default_config($name)
2289 }
2290
2291 foreach option $font_descs {
2292 set name [lindex $option 0]
Shawn O. Pearce7b64d0b2006-11-12 15:45:35 -05002293 set repo_config(gui.$name) $default_config(gui.$name)
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002294 }
2295 apply_config
2296
2297 foreach option $font_descs {
2298 set name [lindex $option 0]
2299 set font [lindex $option 1]
2300 set global_config_new(gui.$font^^family) \
2301 [font configure $font -family]
2302 set global_config_new(gui.$font^^size) \
2303 [font configure $font -size]
2304 }
2305}
2306
2307proc do_save_config {w} {
2308 if {[catch {save_config} err]} {
2309 error_popup "Failed to completely save options:\n\n$err"
2310 }
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05002311 reshow_diff
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002312 destroy $w
2313}
2314
Shawn O. Pearce4aca7402006-11-15 22:35:26 -05002315proc do_windows_shortcut {} {
2316 global gitdir appname argv0
2317
2318 set reponame [lindex [file split \
2319 [file normalize [file dirname $gitdir]]] \
2320 end]
2321
2322 if {[catch {
2323 set desktop [exec cygpath \
2324 --windows \
2325 --absolute \
2326 --long-name \
2327 --desktop]
2328 }]} {
2329 set desktop .
2330 }
2331 set fn [tk_getSaveFile \
2332 -parent . \
2333 -title "$appname ($reponame): Create Desktop Icon" \
2334 -initialdir $desktop \
2335 -initialfile "Git $reponame.bat"]
2336 if {$fn != {}} {
2337 if {[catch {
2338 set fd [open $fn w]
2339 set sh [exec cygpath \
2340 --windows \
2341 --absolute \
2342 --long-name \
2343 /bin/sh]
2344 set me [exec cygpath \
2345 --unix \
2346 --absolute \
2347 $argv0]
2348 set gd [exec cygpath \
2349 --unix \
2350 --absolute \
2351 $gitdir]
Shawn O. Pearce306500f2006-11-15 22:53:53 -05002352 regsub -all ' $me "'\\''" me
2353 regsub -all ' $gd "'\\''" gd
Shawn O. Pearce4aca7402006-11-15 22:35:26 -05002354 puts -nonewline $fd "\"$sh\" --login -c \""
Shawn O. Pearcedbccbbd2006-11-15 22:45:33 -05002355 puts -nonewline $fd "GIT_DIR='$gd'"
2356 puts -nonewline $fd " '$me'"
Shawn O. Pearce4aca7402006-11-15 22:35:26 -05002357 puts $fd "&\""
2358 close $fd
2359 } err]} {
2360 error_popup "Cannot write script:\n\n$err"
2361 }
2362 }
2363}
2364
Shawn O. Pearce06c31112006-11-18 00:31:00 -05002365proc do_macosx_app {} {
2366 global gitdir appname argv0 env
2367
2368 set reponame [lindex [file split \
2369 [file normalize [file dirname $gitdir]]] \
2370 end]
2371
2372 set fn [tk_getSaveFile \
2373 -parent . \
2374 -title "$appname ($reponame): Create Desktop Icon" \
2375 -initialdir [file join $env(HOME) Desktop] \
2376 -initialfile "Git $reponame.app"]
2377 if {$fn != {}} {
2378 if {[catch {
2379 set Contents [file join $fn Contents]
2380 set MacOS [file join $Contents MacOS]
2381 set exe [file join $MacOS git-gui]
2382
2383 file mkdir $MacOS
2384
Shawn O. Pearce06c31112006-11-18 00:31:00 -05002385 set fd [open [file join $Contents Info.plist] w]
2386 puts $fd {<?xml version="1.0" encoding="UTF-8"?>
2387<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
2388<plist version="1.0">
2389<dict>
2390 <key>CFBundleDevelopmentRegion</key>
2391 <string>English</string>
2392 <key>CFBundleExecutable</key>
2393 <string>git-gui</string>
2394 <key>CFBundleIdentifier</key>
2395 <string>org.spearce.git-gui</string>
2396 <key>CFBundleInfoDictionaryVersion</key>
2397 <string>6.0</string>
2398 <key>CFBundlePackageType</key>
2399 <string>APPL</string>
2400 <key>CFBundleSignature</key>
2401 <string>????</string>
2402 <key>CFBundleVersion</key>
2403 <string>1.0</string>
2404 <key>NSPrincipalClass</key>
2405 <string>NSApplication</string>
2406</dict>
2407</plist>}
2408 close $fd
2409
2410 set fd [open $exe w]
2411 set gd [file normalize $gitdir]
2412 set ep [file normalize [exec git --exec-path]]
2413 regsub -all ' $gd "'\\''" gd
2414 regsub -all ' $ep "'\\''" ep
2415 puts $fd "#!/bin/sh"
2416 foreach name [array names env] {
2417 if {[string match GIT_* $name]} {
2418 regsub -all ' $env($name) "'\\''" v
2419 puts $fd "export $name='$v'"
2420 }
2421 }
2422 puts $fd "export PATH='$ep':\$PATH"
2423 puts $fd "export GIT_DIR='$gd'"
2424 puts $fd "exec [file normalize $argv0]"
2425 close $fd
2426
2427 file attributes $exe -permissions u+x,g+x,o+x
2428 } err]} {
2429 error_popup "Cannot write icon:\n\n$err"
2430 }
2431 }
2432}
2433
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002434proc toggle_or_diff {w x y} {
Shawn O. Pearce74d18d22006-11-19 00:37:49 -05002435 global file_states file_lists current_diff ui_index ui_other
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002436 global last_clicked selected_paths
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002437
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002438 set pos [split [$w index @$x,$y] .]
2439 set lno [lindex $pos 0]
2440 set col [lindex $pos 1]
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002441 set path [lindex $file_lists($w) [expr {$lno - 1}]]
2442 if {$path eq {}} {
2443 set last_clicked {}
2444 return
2445 }
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002446
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002447 set last_clicked [list $w $lno]
2448 array unset selected_paths
2449 $ui_index tag remove in_sel 0.0 end
2450 $ui_other tag remove in_sel 0.0 end
2451
2452 if {$col == 0} {
Shawn O. Pearce32e0bca2006-11-18 03:03:16 -05002453 if {$current_diff eq $path} {
2454 set after {reshow_diff;}
2455 } else {
2456 set after {}
2457 }
Shawn O. Pearce74d18d22006-11-19 00:37:49 -05002458 switch -glob -- [lindex $file_states($path) 0] {
2459 A_ -
Shawn O. Pearce74d18d22006-11-19 00:37:49 -05002460 M_ -
Shawn O. Pearcedde59742006-11-19 00:46:08 -05002461 DD -
Shawn O. Pearce375f3882006-11-19 03:46:29 -05002462 DO -
2463 DM {
Shawn O. Pearce74d18d22006-11-19 00:37:49 -05002464 update_indexinfo \
2465 "Removing [short_path $path] from commit" \
2466 [list $path] \
2467 [concat $after {set ui_status_value {Ready.}}]
2468 }
2469 ?? {
2470 update_index \
2471 "Including [short_path $path]" \
2472 [list $path] \
2473 [concat $after {set ui_status_value {Ready.}}]
2474 }
2475 }
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002476 } else {
Shawn O. Pearce03e4ec52006-11-11 17:52:16 -05002477 show_diff $path $w $lno
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002478 }
2479}
2480
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002481proc add_one_to_selection {w x y} {
Shawn O. Pearce7f1df792006-11-11 18:38:00 -05002482 global file_lists
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002483 global last_clicked selected_paths
Shawn O. Pearce7f1df792006-11-11 18:38:00 -05002484
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002485 set pos [split [$w index @$x,$y] .]
2486 set lno [lindex $pos 0]
2487 set col [lindex $pos 1]
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002488 set path [lindex $file_lists($w) [expr {$lno - 1}]]
2489 if {$path eq {}} {
2490 set last_clicked {}
2491 return
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002492 }
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002493
2494 set last_clicked [list $w $lno]
2495 if {[catch {set in_sel $selected_paths($path)}]} {
2496 set in_sel 0
2497 }
2498 if {$in_sel} {
2499 unset selected_paths($path)
2500 $w tag remove in_sel $lno.0 [expr {$lno + 1}].0
2501 } else {
2502 set selected_paths($path) 1
2503 $w tag add in_sel $lno.0 [expr {$lno + 1}].0
2504 }
2505}
2506
2507proc add_range_to_selection {w x y} {
2508 global file_lists
2509 global last_clicked selected_paths
2510
2511 if {[lindex $last_clicked 0] ne $w} {
2512 toggle_or_diff $w $x $y
2513 return
2514 }
2515
2516 set pos [split [$w index @$x,$y] .]
2517 set lno [lindex $pos 0]
2518 set lc [lindex $last_clicked 1]
2519 if {$lc < $lno} {
2520 set begin $lc
2521 set end $lno
2522 } else {
2523 set begin $lno
2524 set end $lc
2525 }
2526
2527 foreach path [lrange $file_lists($w) \
2528 [expr {$begin - 1}] \
2529 [expr {$end - 1}]] {
2530 set selected_paths($path) 1
2531 }
2532 $w tag add in_sel $begin.0 [expr {$end + 1}].0
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002533}
2534
2535######################################################################
2536##
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002537## config defaults
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002538
Shawn O. Pearce00f949f2006-11-12 02:30:02 -05002539set cursor_ptr arrow
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002540font create font_diff -family Courier -size 10
2541font create font_ui
2542catch {
2543 label .dummy
2544 eval font configure font_ui [font actual [.dummy cget -font]]
2545 destroy .dummy
2546}
2547
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002548font create font_uibold
2549font create font_diffbold
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002550
Shawn O. Pearce16fccd72006-11-12 02:22:21 -05002551set M1B M1
2552set M1T M1
Shawn O. Pearce043f7012006-11-12 18:16:45 -05002553if {$tcl_platform(platform) eq {windows}} {
Shawn O. Pearce16fccd72006-11-12 02:22:21 -05002554 set M1B Control
2555 set M1T Ctrl
2556} elseif {[is_MacOSX]} {
2557 set M1B M1
2558 set M1T Cmd
Shawn O. Pearcee210e672006-11-06 19:12:58 -05002559}
2560
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002561proc apply_config {} {
2562 global repo_config font_descs
2563
2564 foreach option $font_descs {
2565 set name [lindex $option 0]
2566 set font [lindex $option 1]
2567 if {[catch {
2568 foreach {cn cv} $repo_config(gui.$name) {
2569 font configure $font $cn $cv
2570 }
2571 } err]} {
2572 error_popup "Invalid font specified in gui.$name:\n\n$err"
2573 }
2574 foreach {cn cv} [font configure $font] {
2575 font configure ${font}bold $cn $cv
2576 }
2577 font configure ${font}bold -weight bold
2578 }
2579}
2580
2581set default_config(gui.trustmtime) false
Shawn O. Pearceebf336b2006-11-12 16:53:19 -05002582set default_config(gui.pullsummary) true
Shawn O. Pearcef7f8d322006-11-13 04:22:42 -05002583set default_config(gui.partialinclude) false
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05002584set default_config(gui.diffcontext) 5
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002585set default_config(gui.fontui) [font configure font_ui]
2586set default_config(gui.fontdiff) [font configure font_diff]
2587set font_descs {
2588 {fontui font_ui {Main Font}}
2589 {fontdiff font_diff {Diff/Console Font}}
2590}
Shawn O. Pearce6bbd1cb2006-11-12 16:24:52 -05002591load_config 0
Shawn O. Pearce92148d82006-11-12 05:27:00 -05002592apply_config
2593
2594######################################################################
2595##
2596## ui construction
2597
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002598# -- Menu Bar
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002599#
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002600menu .mbar -tearoff 0
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002601.mbar add cascade -label Project -menu .mbar.project
Shawn O. Pearce98616712006-11-11 15:51:41 -05002602.mbar add cascade -label Edit -menu .mbar.edit
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002603.mbar add cascade -label Commit -menu .mbar.commit
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05002604if {!$single_commit} {
2605 .mbar add cascade -label Fetch -menu .mbar.fetch
2606 .mbar add cascade -label Pull -menu .mbar.pull
2607 .mbar add cascade -label Push -menu .mbar.push
2608}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002609. configure -menu .mbar
2610
2611# -- Project Menu
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002612#
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002613menu .mbar.project
Shawn O. Pearce6f6eed22006-11-06 18:22:19 -05002614.mbar.project add command -label Visualize \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002615 -command do_gitk \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002616 -font font_ui
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05002617if {!$single_commit} {
2618 .mbar.project add command -label {Repack Database} \
2619 -command do_repack \
2620 -font font_ui
Shawn O. Pearce4aca7402006-11-15 22:35:26 -05002621
Shawn O. Pearce444f92d2006-11-20 21:43:41 -05002622 .mbar.project add command -label {Verify Database} \
2623 -command do_fsck_objects \
2624 -font font_ui
2625
Shawn O. Pearce4aca7402006-11-15 22:35:26 -05002626 if {$tcl_platform(platform) eq {windows}} {
2627 .mbar.project add command \
2628 -label {Create Desktop Icon} \
2629 -command do_windows_shortcut \
2630 -font font_ui
Shawn O. Pearce06c31112006-11-18 00:31:00 -05002631 } elseif {[is_MacOSX]} {
2632 .mbar.project add command \
2633 -label {Create Desktop Icon} \
2634 -command do_macosx_app \
2635 -font font_ui
Shawn O. Pearce4aca7402006-11-15 22:35:26 -05002636 }
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05002637}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002638.mbar.project add command -label Quit \
2639 -command do_quit \
Shawn O. Pearcee210e672006-11-06 19:12:58 -05002640 -accelerator $M1T-Q \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002641 -font font_ui
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002642
Shawn O. Pearce98616712006-11-11 15:51:41 -05002643# -- Edit Menu
2644#
2645menu .mbar.edit
2646.mbar.edit add command -label Undo \
2647 -command {catch {[focus] edit undo}} \
2648 -accelerator $M1T-Z \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002649 -font font_ui
Shawn O. Pearce98616712006-11-11 15:51:41 -05002650.mbar.edit add command -label Redo \
2651 -command {catch {[focus] edit redo}} \
2652 -accelerator $M1T-Y \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002653 -font font_ui
Shawn O. Pearce98616712006-11-11 15:51:41 -05002654.mbar.edit add separator
2655.mbar.edit add command -label Cut \
2656 -command {catch {tk_textCut [focus]}} \
2657 -accelerator $M1T-X \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002658 -font font_ui
Shawn O. Pearce98616712006-11-11 15:51:41 -05002659.mbar.edit add command -label Copy \
2660 -command {catch {tk_textCopy [focus]}} \
2661 -accelerator $M1T-C \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002662 -font font_ui
Shawn O. Pearce98616712006-11-11 15:51:41 -05002663.mbar.edit add command -label Paste \
2664 -command {catch {tk_textPaste [focus]; [focus] see insert}} \
2665 -accelerator $M1T-V \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002666 -font font_ui
Shawn O. Pearce98616712006-11-11 15:51:41 -05002667.mbar.edit add command -label Delete \
2668 -command {catch {[focus] delete sel.first sel.last}} \
2669 -accelerator Del \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002670 -font font_ui
Shawn O. Pearce98616712006-11-11 15:51:41 -05002671.mbar.edit add separator
2672.mbar.edit add command -label {Select All} \
2673 -command {catch {[focus] tag add sel 0.0 end}} \
2674 -accelerator $M1T-A \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002675 -font font_ui
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05002676.mbar.edit add separator
2677.mbar.edit add command -label {Options...} \
2678 -command do_options \
2679 -font font_ui
Shawn O. Pearce98616712006-11-11 15:51:41 -05002680
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002681# -- Commit Menu
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002682#
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002683menu .mbar.commit
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002684
2685.mbar.commit add radiobutton \
2686 -label {New Commit} \
2687 -command do_select_commit_type \
2688 -variable selected_commit_type \
2689 -value new \
2690 -font font_ui
2691lappend disable_on_lock \
2692 [list .mbar.commit entryconf [.mbar.commit index last] -state]
2693
2694.mbar.commit add radiobutton \
2695 -label {Amend Last Commit} \
2696 -command do_select_commit_type \
2697 -variable selected_commit_type \
2698 -value amend \
2699 -font font_ui
2700lappend disable_on_lock \
2701 [list .mbar.commit entryconf [.mbar.commit index last] -state]
2702
2703.mbar.commit add separator
2704
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002705.mbar.commit add command -label Rescan \
2706 -command do_rescan \
Shawn O. Pearcee210e672006-11-06 19:12:58 -05002707 -accelerator F5 \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002708 -font font_ui
Shawn O. Pearcee210e672006-11-06 19:12:58 -05002709lappend disable_on_lock \
2710 [list .mbar.commit entryconf [.mbar.commit index last] -state]
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002711
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05002712.mbar.commit add command -label {Remove From Commit} \
2713 -command do_remove_selection \
2714 -font font_ui
2715lappend disable_on_lock \
2716 [list .mbar.commit entryconf [.mbar.commit index last] -state]
2717
2718.mbar.commit add command -label {Include In Commit} \
Shawn O. Pearcec4ed8792006-11-18 03:24:20 -05002719 -command do_include_selection \
2720 -font font_ui
2721lappend disable_on_lock \
2722 [list .mbar.commit entryconf [.mbar.commit index last] -state]
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002723
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05002724.mbar.commit add command -label {Include All} \
Shawn O. Pearce7fe7e732006-11-08 22:48:34 -05002725 -command do_include_all \
Shawn O. Pearce49b86f02006-11-11 15:16:01 -05002726 -accelerator $M1T-I \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002727 -font font_ui
Shawn O. Pearcee210e672006-11-06 19:12:58 -05002728lappend disable_on_lock \
2729 [list .mbar.commit entryconf [.mbar.commit index last] -state]
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002730
Shawn O. Pearce1461c5f2006-11-19 00:29:55 -05002731.mbar.commit add separator
2732
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002733.mbar.commit add command -label {Sign Off} \
2734 -command do_signoff \
Shawn O. Pearcee210e672006-11-06 19:12:58 -05002735 -accelerator $M1T-S \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002736 -font font_ui
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002737
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002738.mbar.commit add command -label Commit \
2739 -command do_commit \
Shawn O. Pearcee210e672006-11-06 19:12:58 -05002740 -accelerator $M1T-Return \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002741 -font font_ui
Shawn O. Pearcee210e672006-11-06 19:12:58 -05002742lappend disable_on_lock \
2743 [list .mbar.commit entryconf [.mbar.commit index last] -state]
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002744
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002745# -- Transport menus
2746#
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05002747if {!$single_commit} {
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05002748 menu .mbar.fetch
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05002749 menu .mbar.pull
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05002750 menu .mbar.push
2751}
Shawn O. Pearce8c0ce432006-11-06 23:13:23 -05002752
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002753# -- Main Window Layout
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002754#
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002755panedwindow .vpane -orient vertical
2756panedwindow .vpane.files -orient horizontal
Shawn O. Pearce6f6eed22006-11-06 18:22:19 -05002757.vpane add .vpane.files -sticky nsew -height 100 -width 400
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002758pack .vpane -anchor n -side top -fill both -expand 1
2759
2760# -- Index File List
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002761#
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002762frame .vpane.files.index -height 100 -width 400
2763label .vpane.files.index.title -text {Modified Files} \
2764 -background green \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002765 -font font_ui
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002766text $ui_index -background white -borderwidth 0 \
2767 -width 40 -height 10 \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002768 -font font_ui \
Shawn O. Pearce6c6dd012006-11-11 20:33:30 -05002769 -cursor $cursor_ptr \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002770 -yscrollcommand {.vpane.files.index.sb set} \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002771 -state disabled
2772scrollbar .vpane.files.index.sb -command [list $ui_index yview]
2773pack .vpane.files.index.title -side top -fill x
2774pack .vpane.files.index.sb -side right -fill y
2775pack $ui_index -side left -fill both -expand 1
2776.vpane.files add .vpane.files.index -sticky nsew
2777
2778# -- Other (Add) File List
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002779#
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002780frame .vpane.files.other -height 100 -width 100
2781label .vpane.files.other.title -text {Untracked Files} \
2782 -background red \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002783 -font font_ui
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002784text $ui_other -background white -borderwidth 0 \
2785 -width 40 -height 10 \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002786 -font font_ui \
Shawn O. Pearce6c6dd012006-11-11 20:33:30 -05002787 -cursor $cursor_ptr \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002788 -yscrollcommand {.vpane.files.other.sb set} \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002789 -state disabled
2790scrollbar .vpane.files.other.sb -command [list $ui_other yview]
2791pack .vpane.files.other.title -side top -fill x
2792pack .vpane.files.other.sb -side right -fill y
2793pack $ui_other -side left -fill both -expand 1
2794.vpane.files add .vpane.files.other -sticky nsew
2795
Shawn O. Pearce24263b72006-11-13 16:06:38 -05002796foreach i [list $ui_index $ui_other] {
2797 $i tag conf in_diff -font font_uibold
2798 $i tag conf in_sel \
2799 -background [$i cget -foreground] \
2800 -foreground [$i cget -background]
2801}
2802unset i
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002803
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002804# -- Diff and Commit Area
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002805#
Shawn O. Pearce8009dcd2006-11-12 06:53:56 -05002806frame .vpane.lower -height 300 -width 400
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002807frame .vpane.lower.commarea
2808frame .vpane.lower.diff -relief sunken -borderwidth 1
2809pack .vpane.lower.commarea -side top -fill x
2810pack .vpane.lower.diff -side bottom -fill both -expand 1
2811.vpane add .vpane.lower -stick nsew
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002812
2813# -- Commit Area Buttons
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002814#
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002815frame .vpane.lower.commarea.buttons
2816label .vpane.lower.commarea.buttons.l -text {} \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002817 -anchor w \
2818 -justify left \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002819 -font font_ui
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002820pack .vpane.lower.commarea.buttons.l -side top -fill x
2821pack .vpane.lower.commarea.buttons -side left -fill y
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002822
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002823button .vpane.lower.commarea.buttons.rescan -text {Rescan} \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002824 -command do_rescan \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002825 -font font_ui
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002826pack .vpane.lower.commarea.buttons.rescan -side top -fill x
Shawn O. Pearce390adae2006-11-11 19:40:33 -05002827lappend disable_on_lock \
2828 {.vpane.lower.commarea.buttons.rescan conf -state}
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002829
Shawn O. Pearce7fe7e732006-11-08 22:48:34 -05002830button .vpane.lower.commarea.buttons.incall -text {Include All} \
2831 -command do_include_all \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002832 -font font_ui
Shawn O. Pearce7fe7e732006-11-08 22:48:34 -05002833pack .vpane.lower.commarea.buttons.incall -side top -fill x
Shawn O. Pearce390adae2006-11-11 19:40:33 -05002834lappend disable_on_lock \
2835 {.vpane.lower.commarea.buttons.incall conf -state}
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002836
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002837button .vpane.lower.commarea.buttons.signoff -text {Sign Off} \
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002838 -command do_signoff \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002839 -font font_ui
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002840pack .vpane.lower.commarea.buttons.signoff -side top -fill x
Shawn O. Pearce131f5032006-11-06 16:07:32 -05002841
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002842button .vpane.lower.commarea.buttons.commit -text {Commit} \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002843 -command do_commit \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002844 -font font_ui
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002845pack .vpane.lower.commarea.buttons.commit -side top -fill x
Shawn O. Pearce390adae2006-11-11 19:40:33 -05002846lappend disable_on_lock \
2847 {.vpane.lower.commarea.buttons.commit conf -state}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002848
2849# -- Commit Message Buffer
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002850#
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002851frame .vpane.lower.commarea.buffer
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002852frame .vpane.lower.commarea.buffer.header
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002853set ui_comm .vpane.lower.commarea.buffer.t
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002854set ui_coml .vpane.lower.commarea.buffer.header.l
2855radiobutton .vpane.lower.commarea.buffer.header.new \
2856 -text {New Commit} \
2857 -command do_select_commit_type \
2858 -variable selected_commit_type \
2859 -value new \
2860 -font font_ui
2861lappend disable_on_lock \
2862 [list .vpane.lower.commarea.buffer.header.new conf -state]
2863radiobutton .vpane.lower.commarea.buffer.header.amend \
2864 -text {Amend Last Commit} \
2865 -command do_select_commit_type \
2866 -variable selected_commit_type \
2867 -value amend \
2868 -font font_ui
2869lappend disable_on_lock \
2870 [list .vpane.lower.commarea.buffer.header.amend conf -state]
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002871label $ui_coml \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002872 -anchor w \
2873 -justify left \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002874 -font font_ui
Shawn O. Pearce4539eac2006-11-18 02:50:58 -05002875proc trace_commit_type {varname args} {
2876 global ui_coml commit_type
2877 switch -glob -- $commit_type {
2878 initial {set txt {Initial Commit Message:}}
2879 amend {set txt {Amended Commit Message:}}
2880 amend-initial {set txt {Amended Initial Commit Message:}}
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -05002881 amend-merge {set txt {Amended Merge Commit Message:}}
Shawn O. Pearce4539eac2006-11-18 02:50:58 -05002882 merge {set txt {Merge Commit Message:}}
2883 * {set txt {Commit Message:}}
2884 }
2885 $ui_coml conf -text $txt
2886}
2887trace add variable commit_type write trace_commit_type
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002888pack $ui_coml -side left -fill x
2889pack .vpane.lower.commarea.buffer.header.amend -side right
2890pack .vpane.lower.commarea.buffer.header.new -side right
2891
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002892text $ui_comm -background white -borderwidth 1 \
Shawn O. Pearce98616712006-11-11 15:51:41 -05002893 -undo true \
Shawn O. Pearceb2c6fcf2006-11-11 16:16:25 -05002894 -maxundo 20 \
Shawn O. Pearce98616712006-11-11 15:51:41 -05002895 -autoseparators true \
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002896 -relief sunken \
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002897 -width 75 -height 9 -wrap none \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002898 -font font_diff \
Shawn O. Pearce6c6dd012006-11-11 20:33:30 -05002899 -yscrollcommand {.vpane.lower.commarea.buffer.sby set}
Shawn O. Pearce390adae2006-11-11 19:40:33 -05002900scrollbar .vpane.lower.commarea.buffer.sby \
2901 -command [list $ui_comm yview]
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05002902pack .vpane.lower.commarea.buffer.header -side top -fill x
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002903pack .vpane.lower.commarea.buffer.sby -side right -fill y
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05002904pack $ui_comm -side left -fill y
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002905pack .vpane.lower.commarea.buffer -side left -fill y
2906
Shawn O. Pearce0e794312006-11-11 20:24:23 -05002907# -- Commit Message Buffer Context Menu
2908#
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002909set ctxm .vpane.lower.commarea.buffer.ctxm
2910menu $ctxm -tearoff 0
2911$ctxm add command \
2912 -label {Cut} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002913 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002914 -command {tk_textCut $ui_comm}
2915$ctxm add command \
2916 -label {Copy} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002917 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002918 -command {tk_textCopy $ui_comm}
2919$ctxm add command \
2920 -label {Paste} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002921 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002922 -command {tk_textPaste $ui_comm}
2923$ctxm add command \
2924 -label {Delete} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002925 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002926 -command {$ui_comm delete sel.first sel.last}
2927$ctxm add separator
2928$ctxm add command \
2929 -label {Select All} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002930 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002931 -command {$ui_comm tag add sel 0.0 end}
2932$ctxm add command \
2933 -label {Copy All} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002934 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002935 -command {
Shawn O. Pearce0e794312006-11-11 20:24:23 -05002936 $ui_comm tag add sel 0.0 end
2937 tk_textCopy $ui_comm
2938 $ui_comm tag remove sel 0.0 end
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002939 }
2940$ctxm add separator
2941$ctxm add command \
2942 -label {Sign Off} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002943 -font font_ui \
Shawn O. Pearce0e794312006-11-11 20:24:23 -05002944 -command do_signoff
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002945bind_button3 $ui_comm "tk_popup $ctxm %X %Y"
Shawn O. Pearce0e794312006-11-11 20:24:23 -05002946
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002947# -- Diff Header
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05002948#
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002949set current_diff {}
2950set diff_actions [list]
Shawn O. Pearce32e0bca2006-11-18 03:03:16 -05002951proc trace_current_diff {varname args} {
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002952 global current_diff diff_actions file_states
2953 if {$current_diff eq {}} {
2954 set s {}
2955 set f {}
2956 set p {}
2957 set o disabled
2958 } else {
2959 set p $current_diff
2960 set s [mapdesc [lindex $file_states($p) 0] $p]
2961 set f {File:}
2962 set p [escape_path $p]
2963 set o normal
2964 }
2965
2966 .vpane.lower.diff.header.status configure -text $s
2967 .vpane.lower.diff.header.file configure -text $f
2968 .vpane.lower.diff.header.path configure -text $p
2969 foreach w $diff_actions {
2970 uplevel #0 $w $o
2971 }
2972}
Shawn O. Pearce32e0bca2006-11-18 03:03:16 -05002973trace add variable current_diff write trace_current_diff
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002974
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002975frame .vpane.lower.diff.header -background orange
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002976label .vpane.lower.diff.header.status \
Shawn O. Pearce3e7b0e12006-11-12 22:06:37 -05002977 -background orange \
2978 -width $max_status_desc \
2979 -anchor w \
2980 -justify left \
2981 -font font_ui
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002982label .vpane.lower.diff.header.file \
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05002983 -background orange \
Shawn O. Pearcefce89e42006-11-13 00:48:44 -05002984 -anchor w \
2985 -justify left \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05002986 -font font_ui
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05002987label .vpane.lower.diff.header.path \
2988 -background orange \
2989 -anchor w \
2990 -justify left \
2991 -font font_ui
2992pack .vpane.lower.diff.header.status -side left
2993pack .vpane.lower.diff.header.file -side left
2994pack .vpane.lower.diff.header.path -fill x
2995set ctxm .vpane.lower.diff.header.ctxm
2996menu $ctxm -tearoff 0
2997$ctxm add command \
2998 -label {Copy} \
Shawn O. Pearcec11b5f202006-11-12 21:11:12 -05002999 -font font_ui \
Shawn O. Pearcefce89e42006-11-13 00:48:44 -05003000 -command {
3001 clipboard clear
3002 clipboard append \
3003 -format STRING \
3004 -type STRING \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003005 -- $current_diff
Shawn O. Pearcefce89e42006-11-13 00:48:44 -05003006 }
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003007lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
3008bind_button3 .vpane.lower.diff.header.path "tk_popup $ctxm %X %Y"
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05003009
3010# -- Diff Body
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05003011#
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05003012frame .vpane.lower.diff.body
3013set ui_diff .vpane.lower.diff.body.t
3014text $ui_diff -background white -borderwidth 0 \
3015 -width 80 -height 15 -wrap none \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05003016 -font font_diff \
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05003017 -xscrollcommand {.vpane.lower.diff.body.sbx set} \
3018 -yscrollcommand {.vpane.lower.diff.body.sby set} \
Shawn O. Pearce0fb8f9c2006-11-07 20:27:46 -05003019 -state disabled
3020scrollbar .vpane.lower.diff.body.sbx -orient horizontal \
3021 -command [list $ui_diff xview]
3022scrollbar .vpane.lower.diff.body.sby -orient vertical \
3023 -command [list $ui_diff yview]
3024pack .vpane.lower.diff.body.sbx -side bottom -fill x
3025pack .vpane.lower.diff.body.sby -side right -fill y
3026pack $ui_diff -side left -fill both -expand 1
3027pack .vpane.lower.diff.header -side top -fill x
3028pack .vpane.lower.diff.body -side bottom -fill both -expand 1
3029
Shawn O. Pearce38dbe272006-11-19 02:46:52 -05003030$ui_diff tag conf d_@ -font font_diffbold
3031$ui_diff tag conf d_+ -foreground blue
3032$ui_diff tag conf d_- -foreground red
3033$ui_diff tag conf d_++ -foreground {#00a000}
3034$ui_diff tag conf d_-- -foreground {#a000a0}
3035$ui_diff tag conf d_+- \
3036 -foreground red \
3037 -background {light goldenrod yellow}
3038$ui_diff tag conf d_-+ \
3039 -foreground blue \
3040 -background azure2
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05003041
Shawn O. Pearce0e794312006-11-11 20:24:23 -05003042# -- Diff Body Context Menu
3043#
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003044set ctxm .vpane.lower.diff.body.ctxm
3045menu $ctxm -tearoff 0
3046$ctxm add command \
3047 -label {Copy} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05003048 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003049 -command {tk_textCopy $ui_diff}
3050lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
3051$ctxm add command \
3052 -label {Select All} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05003053 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003054 -command {$ui_diff tag add sel 0.0 end}
3055lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
3056$ctxm add command \
3057 -label {Copy All} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05003058 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003059 -command {
Shawn O. Pearce0e794312006-11-11 20:24:23 -05003060 $ui_diff tag add sel 0.0 end
3061 tk_textCopy $ui_diff
3062 $ui_diff tag remove sel 0.0 end
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003063 }
3064lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
3065$ctxm add separator
3066$ctxm add command \
3067 -label {Decrease Font Size} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05003068 -font font_ui \
3069 -command {incr_font_size font_diff -1}
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003070lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
3071$ctxm add command \
3072 -label {Increase Font Size} \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05003073 -font font_ui \
3074 -command {incr_font_size font_diff 1}
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003075lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
3076$ctxm add separator
3077$ctxm add command \
3078 -label {Show Less Context} \
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05003079 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003080 -command {if {$repo_config(gui.diffcontext) >= 2} {
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05003081 incr repo_config(gui.diffcontext) -1
3082 reshow_diff
3083 }}
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003084lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
3085$ctxm add command \
3086 -label {Show More Context} \
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05003087 -font font_ui \
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003088 -command {
Shawn O. Pearce358d8de2006-11-12 19:20:02 -05003089 incr repo_config(gui.diffcontext)
3090 reshow_diff
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003091 }
3092lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
3093$ctxm add separator
3094$ctxm add command -label {Options...} \
Shawn O. Pearce8009dcd2006-11-12 06:53:56 -05003095 -font font_ui \
3096 -command do_options
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003097bind_button3 $ui_diff "tk_popup $ctxm %X %Y"
Shawn O. Pearce0e794312006-11-11 20:24:23 -05003098
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05003099# -- Status Bar
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003100#
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05003101set ui_status_value {Initializing...}
3102label .status -textvariable ui_status_value \
3103 -anchor w \
3104 -justify left \
3105 -borderwidth 1 \
3106 -relief sunken \
Shawn O. Pearceb4946932006-11-12 00:40:38 -05003107 -font font_ui
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05003108pack .status -anchor w -side bottom -fill x
3109
Shawn O. Pearce2d195162006-11-08 23:42:51 -05003110# -- Load geometry
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003111#
Shawn O. Pearce2d195162006-11-08 23:42:51 -05003112catch {
Shawn O. Pearce51f4d162006-11-12 03:47:00 -05003113set gm $repo_config(gui.geometry)
Shawn O. Pearcec4fe7722006-11-11 19:32:24 -05003114wm geometry . [lindex $gm 0]
3115.vpane sash place 0 \
3116 [lindex [.vpane sash coord 0] 0] \
3117 [lindex $gm 1]
3118.vpane.files sash place 0 \
3119 [lindex $gm 2] \
3120 [lindex [.vpane.files sash coord 0] 1]
Shawn O. Pearcec4fe7722006-11-11 19:32:24 -05003121unset gm
Shawn O. Pearce390adae2006-11-11 19:40:33 -05003122}
Shawn O. Pearce2d195162006-11-08 23:42:51 -05003123
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05003124# -- Key Bindings
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003125#
Shawn O. Pearceec6b4242006-11-06 20:50:59 -05003126bind $ui_comm <$M1B-Key-Return> {do_commit;break}
Shawn O. Pearce49b86f02006-11-11 15:16:01 -05003127bind $ui_comm <$M1B-Key-i> {do_include_all;break}
3128bind $ui_comm <$M1B-Key-I> {do_include_all;break}
Shawn O. Pearce98616712006-11-11 15:51:41 -05003129bind $ui_comm <$M1B-Key-x> {tk_textCut %W;break}
3130bind $ui_comm <$M1B-Key-X> {tk_textCut %W;break}
3131bind $ui_comm <$M1B-Key-c> {tk_textCopy %W;break}
3132bind $ui_comm <$M1B-Key-C> {tk_textCopy %W;break}
3133bind $ui_comm <$M1B-Key-v> {tk_textPaste %W; %W see insert; break}
3134bind $ui_comm <$M1B-Key-V> {tk_textPaste %W; %W see insert; break}
3135bind $ui_comm <$M1B-Key-a> {%W tag add sel 0.0 end;break}
3136bind $ui_comm <$M1B-Key-A> {%W tag add sel 0.0 end;break}
3137
3138bind $ui_diff <$M1B-Key-x> {tk_textCopy %W;break}
3139bind $ui_diff <$M1B-Key-X> {tk_textCopy %W;break}
3140bind $ui_diff <$M1B-Key-c> {tk_textCopy %W;break}
3141bind $ui_diff <$M1B-Key-C> {tk_textCopy %W;break}
3142bind $ui_diff <$M1B-Key-v> {break}
3143bind $ui_diff <$M1B-Key-V> {break}
3144bind $ui_diff <$M1B-Key-a> {%W tag add sel 0.0 end;break}
3145bind $ui_diff <$M1B-Key-A> {%W tag add sel 0.0 end;break}
Shawn O. Pearceb2c6fcf2006-11-11 16:16:25 -05003146bind $ui_diff <Key-Up> {catch {%W yview scroll -1 units};break}
3147bind $ui_diff <Key-Down> {catch {%W yview scroll 1 units};break}
3148bind $ui_diff <Key-Left> {catch {%W xview scroll -1 units};break}
3149bind $ui_diff <Key-Right> {catch {%W xview scroll 1 units};break}
Shawn O. Pearce49b86f02006-11-11 15:16:01 -05003150
Shawn O. Pearce07123f42006-11-07 02:57:46 -05003151bind . <Destroy> do_quit
3152bind all <Key-F5> do_rescan
3153bind all <$M1B-Key-r> do_rescan
3154bind all <$M1B-Key-R> do_rescan
3155bind . <$M1B-Key-s> do_signoff
3156bind . <$M1B-Key-S> do_signoff
Shawn O. Pearce49b86f02006-11-11 15:16:01 -05003157bind . <$M1B-Key-i> do_include_all
3158bind . <$M1B-Key-I> do_include_all
Shawn O. Pearce07123f42006-11-07 02:57:46 -05003159bind . <$M1B-Key-Return> do_commit
3160bind all <$M1B-Key-q> do_quit
3161bind all <$M1B-Key-Q> do_quit
3162bind all <$M1B-Key-w> {destroy [winfo toplevel %W]}
3163bind all <$M1B-Key-W> {destroy [winfo toplevel %W]}
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05003164foreach i [list $ui_index $ui_other] {
Shawn O. Pearce24263b72006-11-13 16:06:38 -05003165 bind $i <Button-1> "toggle_or_diff $i %x %y; break"
3166 bind $i <$M1B-Button-1> "add_one_to_selection $i %x %y; break"
3167 bind $i <Shift-Button-1> "add_range_to_selection $i %x %y; break"
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05003168}
Shawn O. Pearce62aac802006-11-11 20:00:35 -05003169unset i
3170
3171set file_lists($ui_index) [list]
3172set file_lists($ui_other) [list]
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05003173
3174set HEAD {}
3175set PARENT {}
Shawn O. Pearcef18e40a2006-11-20 21:27:22 -05003176set MERGE_HEAD [list]
Shawn O. Pearcea49c67d2006-11-18 03:27:23 -05003177set commit_type {}
3178set empty_tree {}
Shawn O. Pearcee8ab6442006-11-15 18:55:05 -05003179set current_diff {}
Shawn O. Pearce24ac9b72006-11-18 20:59:49 -05003180set selected_commit_type new
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05003181
Shawn O. Pearceec6b4242006-11-06 20:50:59 -05003182wm title . "$appname ([file normalize [file dirname $gitdir]])"
Shawn O. Pearcecb07fc22006-11-06 14:20:27 -05003183focus -force $ui_comm
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05003184if {!$single_commit} {
3185 load_all_remotes
Shawn O. Pearcec1237ae2006-11-15 23:52:20 -05003186 populate_fetch_menu .mbar.fetch
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05003187 populate_pull_menu .mbar.pull
Shawn O. Pearcec1237ae2006-11-15 23:52:20 -05003188 populate_push_menu .mbar.push
Shawn O. Pearce4ccdab02006-11-12 16:20:36 -05003189}
Shawn O. Pearce53716a72006-11-18 03:31:25 -05003190lock_index begin-read
Shawn O. Pearce8f525482006-11-14 01:29:32 -05003191after 1 do_rescan