Code

47255261d293432b2094385de89387d401d20a66
[git.git] / lib / index.tcl
1 # git-gui index (add/remove) support
2 # Copyright (C) 2006, 2007 Shawn Pearce
4 proc update_indexinfo {msg pathList after} {
5         global update_index_cp
7         if {![lock_index update]} return
9         set update_index_cp 0
10         set pathList [lsort $pathList]
11         set totalCnt [llength $pathList]
12         set batch [expr {int($totalCnt * .01) + 1}]
13         if {$batch > 25} {set batch 25}
15         ui_status [format \
16                 "%s... %i/%i files (%.2f%%)" \
17                 $msg \
18                 $update_index_cp \
19                 $totalCnt \
20                 0.0]
21         set fd [git_write update-index -z --index-info]
22         fconfigure $fd \
23                 -blocking 0 \
24                 -buffering full \
25                 -buffersize 512 \
26                 -encoding binary \
27                 -translation binary
28         fileevent $fd writable [list \
29                 write_update_indexinfo \
30                 $fd \
31                 $pathList \
32                 $totalCnt \
33                 $batch \
34                 $msg \
35                 $after \
36                 ]
37 }
39 proc write_update_indexinfo {fd pathList totalCnt batch msg after} {
40         global update_index_cp
41         global file_states current_diff_path
43         if {$update_index_cp >= $totalCnt} {
44                 close $fd
45                 unlock_index
46                 uplevel #0 $after
47                 return
48         }
50         for {set i $batch} \
51                 {$update_index_cp < $totalCnt && $i > 0} \
52                 {incr i -1} {
53                 set path [lindex $pathList $update_index_cp]
54                 incr update_index_cp
56                 set s $file_states($path)
57                 switch -glob -- [lindex $s 0] {
58                 A? {set new _O}
59                 M? {set new _M}
60                 D_ {set new _D}
61                 D? {set new _?}
62                 ?? {continue}
63                 }
64                 set info [lindex $s 2]
65                 if {$info eq {}} continue
67                 puts -nonewline $fd "$info\t[encoding convertto $path]\0"
68                 display_file $path $new
69         }
71         ui_status [format \
72                 "%s... %i/%i files (%.2f%%)" \
73                 $msg \
74                 $update_index_cp \
75                 $totalCnt \
76                 [expr {100.0 * $update_index_cp / $totalCnt}]]
77 }
79 proc update_index {msg pathList after} {
80         global update_index_cp
82         if {![lock_index update]} return
84         set update_index_cp 0
85         set pathList [lsort $pathList]
86         set totalCnt [llength $pathList]
87         set batch [expr {int($totalCnt * .01) + 1}]
88         if {$batch > 25} {set batch 25}
90         ui_status [format \
91                 "%s... %i/%i files (%.2f%%)" \
92                 $msg \
93                 $update_index_cp \
94                 $totalCnt \
95                 0.0]
96         set fd [git_write update-index --add --remove -z --stdin]
97         fconfigure $fd \
98                 -blocking 0 \
99                 -buffering full \
100                 -buffersize 512 \
101                 -encoding binary \
102                 -translation binary
103         fileevent $fd writable [list \
104                 write_update_index \
105                 $fd \
106                 $pathList \
107                 $totalCnt \
108                 $batch \
109                 $msg \
110                 $after \
111                 ]
114 proc write_update_index {fd pathList totalCnt batch msg after} {
115         global update_index_cp
116         global file_states current_diff_path
118         if {$update_index_cp >= $totalCnt} {
119                 close $fd
120                 unlock_index
121                 uplevel #0 $after
122                 return
123         }
125         for {set i $batch} \
126                 {$update_index_cp < $totalCnt && $i > 0} \
127                 {incr i -1} {
128                 set path [lindex $pathList $update_index_cp]
129                 incr update_index_cp
131                 switch -glob -- [lindex $file_states($path) 0] {
132                 AD {set new __}
133                 ?D {set new D_}
134                 _O -
135                 AM {set new A_}
136                 U? {
137                         if {[file exists $path]} {
138                                 set new M_
139                         } else {
140                                 set new D_
141                         }
142                 }
143                 ?M {set new M_}
144                 ?? {continue}
145                 }
146                 puts -nonewline $fd "[encoding convertto $path]\0"
147                 display_file $path $new
148         }
150         ui_status [format \
151                 "%s... %i/%i files (%.2f%%)" \
152                 $msg \
153                 $update_index_cp \
154                 $totalCnt \
155                 [expr {100.0 * $update_index_cp / $totalCnt}]]
158 proc checkout_index {msg pathList after} {
159         global update_index_cp
161         if {![lock_index update]} return
163         set update_index_cp 0
164         set pathList [lsort $pathList]
165         set totalCnt [llength $pathList]
166         set batch [expr {int($totalCnt * .01) + 1}]
167         if {$batch > 25} {set batch 25}
169         ui_status [format \
170                 "%s... %i/%i files (%.2f%%)" \
171                 $msg \
172                 $update_index_cp \
173                 $totalCnt \
174                 0.0]
175         set fd [git_write checkout-index \
176                 --index \
177                 --quiet \
178                 --force \
179                 -z \
180                 --stdin \
181                 ]
182         fconfigure $fd \
183                 -blocking 0 \
184                 -buffering full \
185                 -buffersize 512 \
186                 -encoding binary \
187                 -translation binary
188         fileevent $fd writable [list \
189                 write_checkout_index \
190                 $fd \
191                 $pathList \
192                 $totalCnt \
193                 $batch \
194                 $msg \
195                 $after \
196                 ]
199 proc write_checkout_index {fd pathList totalCnt batch msg after} {
200         global update_index_cp
201         global file_states current_diff_path
203         if {$update_index_cp >= $totalCnt} {
204                 close $fd
205                 unlock_index
206                 uplevel #0 $after
207                 return
208         }
210         for {set i $batch} \
211                 {$update_index_cp < $totalCnt && $i > 0} \
212                 {incr i -1} {
213                 set path [lindex $pathList $update_index_cp]
214                 incr update_index_cp
215                 switch -glob -- [lindex $file_states($path) 0] {
216                 U? {continue}
217                 ?M -
218                 ?D {
219                         puts -nonewline $fd "[encoding convertto $path]\0"
220                         display_file $path ?_
221                 }
222                 }
223         }
225         ui_status [format \
226                 "%s... %i/%i files (%.2f%%)" \
227                 $msg \
228                 $update_index_cp \
229                 $totalCnt \
230                 [expr {100.0 * $update_index_cp / $totalCnt}]]
233 proc unstage_helper {txt paths} {
234         global file_states current_diff_path
236         if {![lock_index begin-update]} return
238         set pathList [list]
239         set after {}
240         foreach path $paths {
241                 switch -glob -- [lindex $file_states($path) 0] {
242                 A? -
243                 M? -
244                 D? {
245                         lappend pathList $path
246                         if {$path eq $current_diff_path} {
247                                 set after {reshow_diff;}
248                         }
249                 }
250                 }
251         }
252         if {$pathList eq {}} {
253                 unlock_index
254         } else {
255                 update_indexinfo \
256                         $txt \
257                         $pathList \
258                         [concat $after [list ui_ready]]
259         }
262 proc do_unstage_selection {} {
263         global current_diff_path selected_paths
265         if {[array size selected_paths] > 0} {
266                 unstage_helper \
267                         {Unstaging selected files from commit} \
268                         [array names selected_paths]
269         } elseif {$current_diff_path ne {}} {
270                 unstage_helper \
271                         [mc "Unstaging %s from commit" [short_path $current_diff_path]] \
272                         [list $current_diff_path]
273         }
276 proc add_helper {txt paths} {
277         global file_states current_diff_path
279         if {![lock_index begin-update]} return
281         set pathList [list]
282         set after {}
283         foreach path $paths {
284                 switch -glob -- [lindex $file_states($path) 0] {
285                 _O -
286                 ?M -
287                 ?D -
288                 U? {
289                         lappend pathList $path
290                         if {$path eq $current_diff_path} {
291                                 set after {reshow_diff;}
292                         }
293                 }
294                 }
295         }
296         if {$pathList eq {}} {
297                 unlock_index
298         } else {
299                 update_index \
300                         $txt \
301                         $pathList \
302                         [concat $after {ui_status {Ready to commit.}}]
303         }
306 proc do_add_selection {} {
307         global current_diff_path selected_paths
309         if {[array size selected_paths] > 0} {
310                 add_helper \
311                         {Adding selected files} \
312                         [array names selected_paths]
313         } elseif {$current_diff_path ne {}} {
314                 add_helper \
315                         [mc "Adding %s" [short_path $current_diff_path]] \
316                         [list $current_diff_path]
317         }
320 proc do_add_all {} {
321         global file_states
323         set paths [list]
324         foreach path [array names file_states] {
325                 switch -glob -- [lindex $file_states($path) 0] {
326                 U? {continue}
327                 ?M -
328                 ?D {lappend paths $path}
329                 }
330         }
331         add_helper {Adding all changed files} $paths
334 proc revert_helper {txt paths} {
335         global file_states current_diff_path
337         if {![lock_index begin-update]} return
339         set pathList [list]
340         set after {}
341         foreach path $paths {
342                 switch -glob -- [lindex $file_states($path) 0] {
343                 U? {continue}
344                 ?M -
345                 ?D {
346                         lappend pathList $path
347                         if {$path eq $current_diff_path} {
348                                 set after {reshow_diff;}
349                         }
350                 }
351                 }
352         }
355         # Split question between singular and plural cases, because
356         # such distinction is needed in some languages. Previously, the
357         # code used "Revert changes in" for both, but that can't work
358         # in languages where 'in' must be combined with word from
359         # rest of string (in diffrent way for both cases of course).
360         #
361         # FIXME: Unfortunately, even that isn't enough in some languages
362         # as they have quite complex plural-form rules. Unfortunately,
363         # msgcat doesn't seem to support that kind of string translation.
364         #
365         set n [llength $pathList]
366         if {$n == 0} {
367                 unlock_index
368                 return
369         } elseif {$n == 1} {
370                 set query [mc "Revert changes in file %s?" [short_path [lindex $pathList]]]
371         } else {
372                 set query [mc "Revert changes in these %i files?" $n]
373         }
375         set reply [tk_dialog \
376                 .confirm_revert \
377                 "[appname] ([reponame])" \
378                 [mc "Any unstaged changes will be permanently lost by the revert."] \
379                 question \
380                 1 \
381                 [mc "Do Nothing"] \
382                 [mc "Revert Changes"] \
383                 ]
384         if {$reply == 1} {
385                 checkout_index \
386                         $txt \
387                         $pathList \
388                         [concat $after [list ui_ready]]
389         } else {
390                 unlock_index
391         }
394 proc do_revert_selection {} {
395         global current_diff_path selected_paths
397         if {[array size selected_paths] > 0} {
398                 revert_helper \
399                         {Reverting selected files} \
400                         [array names selected_paths]
401         } elseif {$current_diff_path ne {}} {
402                 revert_helper \
403                         "Reverting [short_path $current_diff_path]" \
404                         [list $current_diff_path]
405         }
408 proc do_select_commit_type {} {
409         global commit_type selected_commit_type
411         if {$selected_commit_type eq {new}
412                 && [string match amend* $commit_type]} {
413                 create_new_commit
414         } elseif {$selected_commit_type eq {amend}
415                 && ![string match amend* $commit_type]} {
416                 load_last_commit
418                 # The amend request was rejected...
419                 #
420                 if {![string match amend* $commit_type]} {
421                         set selected_commit_type new
422                 }
423         }