2 # Tcl ignores the next line -*- tcl -*- \
5 set appvers
{@@GITGUI_VERSION@@
}
7 Copyright ©
2006, 2007 Shawn Pearce
, et. al.
9 This program is free software
; you can redistribute it and
/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation
; either version
2 of the License
, or
12 (at your option
) any later version.
14 This program is distributed
in the hope that it will be useful
,
15 but WITHOUT ANY WARRANTY
; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License
for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program
; if not
, write to the Free Software
21 Foundation
, Inc.
, 59 Temple Place
, Suite
330, Boston
, MA
02111-1307 USA
}
23 ######################################################################
25 ## configure our library
27 set oguilib
{@@GITGUI_LIBDIR@@
}
28 if {[string match @@
* $oguilib]} {
29 set oguilib
[file join [file dirname [file normalize
$argv0]] lib
]
31 set auto_path
[concat
[list
$oguilib] $auto_path]
33 if {![catch
{set _verbose
$env(GITGUI_VERBOSE
)}]} {
35 rename auto_load real__auto_load
36 proc auto_load
{name args
} {
37 puts stderr
"auto_load $name"
38 return [uplevel
1 real__auto_load
$name $args]
40 rename
source real__source
42 puts stderr
"source $name"
43 uplevel
1 real__source
$name
47 ######################################################################
51 set _appname
[lindex
[file split $argv0] end
]
67 return [eval [concat
[list
file join $_gitdir] $args]]
72 if {$_gitexec eq
{}} {
73 if {[catch
{set _gitexec
[git
--exec-path]} err
]} {
74 error
"Git not installed?\n\n$err"
80 return [eval [concat
[list
file join $_gitexec] $args]]
89 global tcl_platform tk_library
90 if {[tk windowingsystem
] eq
{aqua
}} {
98 if {$tcl_platform(platform
) eq
{windows
}} {
105 global tcl_platform _iscygwin
106 if {$_iscygwin eq
{}} {
107 if {$tcl_platform(platform
) eq
{windows
}} {
108 if {[catch
{set p
[exec cygpath
--windir]} err
]} {
120 proc is_enabled
{option
} {
121 global enabled_options
122 if {[catch
{set on
$enabled_options($option)}]} {return 0}
126 proc enable_option
{option
} {
127 global enabled_options
128 set enabled_options
($option) 1
131 proc disable_option
{option
} {
132 global enabled_options
133 set enabled_options
($option) 0
136 ######################################################################
140 proc is_many_config
{name
} {
141 switch
-glob -- $name {
150 proc is_config_true
{name
} {
152 if {[catch
{set v
$repo_config($name)}]} {
154 } elseif
{$v eq
{true
} ||
$v eq
{1} ||
$v eq
{yes}} {
161 proc load_config
{include_global
} {
162 global repo_config global_config default_config
164 array
unset global_config
165 if {$include_global} {
167 set fd_rc
[open
"| git config --global --list" r
]
168 while {[gets
$fd_rc line
] >= 0} {
169 if {[regexp
{^
([^
=]+)=(.
*)$
} $line line name value
]} {
170 if {[is_many_config
$name]} {
171 lappend global_config
($name) $value
173 set global_config
($name) $value
181 array
unset repo_config
183 set fd_rc
[open
"| git config --list" r
]
184 while {[gets
$fd_rc line
] >= 0} {
185 if {[regexp
{^
([^
=]+)=(.
*)$
} $line line name value
]} {
186 if {[is_many_config
$name]} {
187 lappend repo_config
($name) $value
189 set repo_config
($name) $value
196 foreach name
[array names default_config
] {
197 if {[catch
{set v
$global_config($name)}]} {
198 set global_config
($name) $default_config($name)
200 if {[catch
{set v
$repo_config($name)}]} {
201 set repo_config
($name) $default_config($name)
206 ######################################################################
211 return [eval exec git
$args]
214 auto_load tk_optionMenu
215 rename tk_optionMenu real__tkOptionMenu
216 proc tk_optionMenu
{w varName args
} {
217 set m
[eval real__tkOptionMenu
$w $varName $args]
218 $m configure
-font font_ui
219 $w configure
-font font_ui
223 ######################################################################
227 if {{--version} eq
$argv ||
{version
} eq
$argv} {
228 puts
"git-gui version $appvers"
235 if {[catch
{set v
[git
--version]} err
]} {
236 catch
{wm withdraw .
}
237 error_popup
"Cannot determine Git version:
241 [appname] requires Git $req_maj.$req_min or later."
244 if {[regexp
{^git version
(\d
+)\.
(\d
+)} $v _junk act_maj act_min
]} {
245 if {$act_maj < $req_maj
246 ||
($act_maj == $req_maj && $act_min < $req_min)} {
247 catch
{wm withdraw .
}
248 error_popup
"[appname] requires Git $req_maj.$req_min or later.
254 catch
{wm withdraw .
}
255 error_popup
"Cannot parse Git version string:\n\n$v"
258 unset -nocomplain v _junk act_maj act_min req_maj req_min
260 ######################################################################
265 set _gitdir
$env(GIT_DIR
)
269 set _gitdir
[git rev-parse
--git-dir]
270 set _prefix
[git rev-parse
--show-prefix]
272 catch
{wm withdraw .
}
273 error_popup
"Cannot find the git directory:\n\n$err"
276 if {![file isdirectory
$_gitdir] && [is_Cygwin
]} {
277 catch
{set _gitdir
[exec cygpath
--unix $_gitdir]}
279 if {![file isdirectory
$_gitdir]} {
280 catch
{wm withdraw .
}
281 error_popup
"Git directory not found:\n\n$_gitdir"
284 if {[lindex
[file split $_gitdir] end
] ne
{.git
}} {
285 catch
{wm withdraw .
}
286 error_popup
"Cannot use funny .git directory:\n\n$_gitdir"
289 if {[catch
{cd [file dirname $_gitdir]} err
]} {
290 catch
{wm withdraw .
}
291 error_popup
"No working directory [file dirname $_gitdir]:\n\n$err"
294 set _reponame
[lindex
[file split \
295 [file normalize
[file dirname $_gitdir]]] \
298 ######################################################################
302 set current_diff_path
{}
303 set current_diff_side
{}
304 set diff_actions
[list
]
305 set ui_status_value
{Initializing...
}
309 set MERGE_HEAD
[list
]
312 set current_branch
{}
313 set current_diff_path
{}
314 set selected_commit_type new
316 ######################################################################
324 set disable_on_lock
[list
]
325 set index_lock_type none
327 proc lock_index
{type} {
328 global index_lock_type disable_on_lock
330 if {$index_lock_type eq
{none
}} {
331 set index_lock_type
$type
332 foreach w
$disable_on_lock {
333 uplevel
#0 $w disabled
336 } elseif
{$index_lock_type eq
"begin-$type"} {
337 set index_lock_type
$type
343 proc unlock_index
{} {
344 global index_lock_type disable_on_lock
346 set index_lock_type none
347 foreach w
$disable_on_lock {
352 ######################################################################
356 proc repository_state
{ctvar hdvar mhvar
} {
357 global current_branch
358 upvar
$ctvar ct
$hdvar hd
$mhvar mh
362 if {[catch
{set current_branch
[git symbolic-ref HEAD
]}]} {
363 set current_branch
{}
365 regsub ^refs
/((heads|tags|remotes
)/)? \
371 if {[catch
{set hd
[git rev-parse
--verify HEAD
]}]} {
377 set merge_head
[gitdir MERGE_HEAD
]
378 if {[file exists
$merge_head]} {
380 set fd_mh
[open
$merge_head r
]
381 while {[gets
$fd_mh line
] >= 0} {
392 global PARENT empty_tree
394 set p
[lindex
$PARENT 0]
398 if {$empty_tree eq
{}} {
399 set empty_tree
[git mktree
<< {}]
404 proc rescan
{after
{honor_trustmtime
1}} {
405 global HEAD PARENT MERGE_HEAD commit_type
406 global ui_index ui_workdir ui_status_value ui_comm
407 global rescan_active file_states
410 if {$rescan_active > 0 ||
![lock_index
read]} return
412 repository_state newType newHEAD newMERGE_HEAD
413 if {[string match amend
* $commit_type]
414 && $newType eq
{normal
}
415 && $newHEAD eq
$HEAD} {
419 set MERGE_HEAD
$newMERGE_HEAD
420 set commit_type
$newType
423 array
unset file_states
425 if {![$ui_comm edit modified
]
426 ||
[string trim
[$ui_comm get
0.0 end
]] eq
{}} {
427 if {[load_message GITGUI_MSG
]} {
428 } elseif
{[load_message MERGE_MSG
]} {
429 } elseif
{[load_message SQUASH_MSG
]} {
432 $ui_comm edit modified false
435 if {[is_enabled branch
]} {
440 if {$honor_trustmtime && $repo_config(gui.trustmtime
) eq
{true
}} {
441 rescan_stage2
{} $after
444 set ui_status_value
{Refreshing
file status...
}
445 set cmd
[list git update-index
]
447 lappend cmd
--unmerged
448 lappend cmd
--ignore-missing
449 lappend cmd
--refresh
450 set fd_rf
[open
"| $cmd" r
]
451 fconfigure
$fd_rf -blocking 0 -translation binary
452 fileevent
$fd_rf readable \
453 [list rescan_stage2
$fd_rf $after]
457 proc rescan_stage2
{fd after
} {
458 global ui_status_value
459 global rescan_active buf_rdi buf_rdf buf_rlo
463 if {![eof
$fd]} return
467 set ls_others
[list | git ls-files
--others -z \
468 --exclude-per-directory=.gitignore
]
469 set info_exclude
[gitdir info exclude
]
470 if {[file readable
$info_exclude]} {
471 lappend ls_others
"--exclude-from=$info_exclude"
479 set ui_status_value
{Scanning
for modified files ...
}
480 set fd_di
[open
"| git diff-index --cached -z [PARENT]" r
]
481 set fd_df
[open
"| git diff-files -z" r
]
482 set fd_lo
[open
$ls_others r
]
484 fconfigure
$fd_di -blocking 0 -translation binary
-encoding binary
485 fconfigure
$fd_df -blocking 0 -translation binary
-encoding binary
486 fconfigure
$fd_lo -blocking 0 -translation binary
-encoding binary
487 fileevent
$fd_di readable
[list read_diff_index
$fd_di $after]
488 fileevent
$fd_df readable
[list read_diff_files
$fd_df $after]
489 fileevent
$fd_lo readable
[list read_ls_others
$fd_lo $after]
492 proc load_message
{file} {
496 if {[file isfile
$f]} {
497 if {[catch
{set fd
[open
$f r
]}]} {
500 set content
[string trim
[read $fd]]
502 regsub
-all -line {[ \r\t]+$
} $content {} content
503 $ui_comm delete
0.0 end
504 $ui_comm insert end
$content
510 proc read_diff_index
{fd after
} {
513 append buf_rdi
[read $fd]
515 set n
[string length
$buf_rdi]
517 set z1
[string first
"\0" $buf_rdi $c]
520 set z2
[string first
"\0" $buf_rdi $z1]
524 set i
[split [string range
$buf_rdi $c [expr {$z1 - 2}]] { }]
525 set p
[string range
$buf_rdi $z1 [expr {$z2 - 1}]]
527 [encoding convertfrom
$p] \
529 [list
[lindex
$i 0] [lindex
$i 2]] \
535 set buf_rdi
[string range
$buf_rdi $c end
]
540 rescan_done
$fd buf_rdi
$after
543 proc read_diff_files
{fd after
} {
546 append buf_rdf
[read $fd]
548 set n
[string length
$buf_rdf]
550 set z1
[string first
"\0" $buf_rdf $c]
553 set z2
[string first
"\0" $buf_rdf $z1]
557 set i
[split [string range
$buf_rdf $c [expr {$z1 - 2}]] { }]
558 set p
[string range
$buf_rdf $z1 [expr {$z2 - 1}]]
560 [encoding convertfrom
$p] \
563 [list
[lindex
$i 0] [lindex
$i 2]]
568 set buf_rdf
[string range
$buf_rdf $c end
]
573 rescan_done
$fd buf_rdf
$after
576 proc read_ls_others
{fd after
} {
579 append buf_rlo
[read $fd]
580 set pck
[split $buf_rlo "\0"]
581 set buf_rlo
[lindex
$pck end
]
582 foreach p
[lrange
$pck 0 end-1
] {
583 merge_state
[encoding convertfrom
$p] ?O
585 rescan_done
$fd buf_rlo
$after
588 proc rescan_done
{fd buf after
} {
589 global rescan_active current_diff_path
590 global file_states repo_config
593 if {![eof
$fd]} return
596 if {[incr rescan_active
-1] > 0} return
601 if {$current_diff_path ne
{}} reshow_diff
605 proc prune_selection
{} {
606 global file_states selected_paths
608 foreach path
[array names selected_paths
] {
609 if {[catch
{set still_here
$file_states($path)}]} {
610 unset selected_paths
($path)
615 ######################################################################
619 proc mapicon
{w state path
} {
622 if {[catch
{set r
$all_icons($state$w)}]} {
623 puts
"error: no icon for $w state={$state} $path"
629 proc mapdesc
{state path
} {
632 if {[catch
{set r
$all_descs($state)}]} {
633 puts
"error: no desc for state={$state} $path"
639 proc escape_path
{path
} {
640 regsub
-all {\\} $path "\\\\" path
641 regsub
-all "\n" $path "\\n" path
645 proc short_path
{path
} {
646 return [escape_path
[lindex
[file split $path] end
]]
650 set null_sha1
[string repeat
0 40]
652 proc merge_state
{path new_state
{head_info
{}} {index_info
{}}} {
653 global file_states next_icon_id null_sha1
655 set s0
[string index
$new_state 0]
656 set s1
[string index
$new_state 1]
658 if {[catch
{set info
$file_states($path)}]} {
660 set icon n
[incr next_icon_id
]
662 set state
[lindex
$info 0]
663 set icon
[lindex
$info 1]
664 if {$head_info eq
{}} {set head_info
[lindex
$info 2]}
665 if {$index_info eq
{}} {set index_info
[lindex
$info 3]}
668 if {$s0 eq
{?
}} {set s0
[string index
$state 0]} \
669 elseif
{$s0 eq
{_
}} {set s0 _
}
671 if {$s1 eq
{?
}} {set s1
[string index
$state 1]} \
672 elseif
{$s1 eq
{_
}} {set s1 _
}
674 if {$s0 eq
{A
} && $s1 eq
{_
} && $head_info eq
{}} {
675 set head_info
[list
0 $null_sha1]
676 } elseif
{$s0 ne
{_
} && [string index
$state 0] eq
{_
}
677 && $head_info eq
{}} {
678 set head_info
$index_info
681 set file_states
($path) [list
$s0$s1 $icon \
682 $head_info $index_info \
687 proc display_file_helper
{w path icon_name old_m new_m
} {
691 set lno
[lsearch
-sorted -exact $file_lists($w) $path]
693 set file_lists
($w) [lreplace
$file_lists($w) $lno $lno]
695 $w conf
-state normal
696 $w delete
$lno.0 [expr {$lno + 1}].0
697 $w conf
-state disabled
699 } elseif
{$old_m eq
{_
} && $new_m ne
{_
}} {
700 lappend file_lists
($w) $path
701 set file_lists
($w) [lsort
-unique $file_lists($w)]
702 set lno
[lsearch
-sorted -exact $file_lists($w) $path]
704 $w conf
-state normal
705 $w image create
$lno.0 \
706 -align center
-padx 5 -pady 1 \
708 -image [mapicon
$w $new_m $path]
709 $w insert
$lno.1 "[escape_path $path]\n"
710 $w conf
-state disabled
711 } elseif
{$old_m ne
$new_m} {
712 $w conf
-state normal
713 $w image conf
$icon_name -image [mapicon
$w $new_m $path]
714 $w conf
-state disabled
718 proc display_file
{path state
} {
719 global file_states selected_paths
720 global ui_index ui_workdir
722 set old_m
[merge_state
$path $state]
723 set s
$file_states($path)
724 set new_m
[lindex
$s 0]
725 set icon_name
[lindex
$s 1]
727 set o
[string index
$old_m 0]
728 set n
[string index
$new_m 0]
735 display_file_helper
$ui_index $path $icon_name $o $n
737 if {[string index
$old_m 0] eq
{U
}} {
740 set o
[string index
$old_m 1]
742 if {[string index
$new_m 0] eq
{U
}} {
745 set n
[string index
$new_m 1]
747 display_file_helper
$ui_workdir $path $icon_name $o $n
749 if {$new_m eq
{__
}} {
750 unset file_states
($path)
751 catch
{unset selected_paths
($path)}
755 proc display_all_files_helper
{w path icon_name m
} {
758 lappend file_lists
($w) $path
759 set lno
[expr {[lindex
[split [$w index end
] .
] 0] - 1}]
760 $w image create end \
761 -align center
-padx 5 -pady 1 \
763 -image [mapicon
$w $m $path]
764 $w insert end
"[escape_path $path]\n"
767 proc display_all_files
{} {
768 global ui_index ui_workdir
769 global file_states file_lists
772 $ui_index conf
-state normal
773 $ui_workdir conf
-state normal
775 $ui_index delete
0.0 end
776 $ui_workdir delete
0.0 end
779 set file_lists
($ui_index) [list
]
780 set file_lists
($ui_workdir) [list
]
782 foreach path
[lsort
[array names file_states
]] {
783 set s
$file_states($path)
785 set icon_name
[lindex
$s 1]
787 set s
[string index
$m 0]
788 if {$s ne
{U
} && $s ne
{_
}} {
789 display_all_files_helper
$ui_index $path \
793 if {[string index
$m 0] eq
{U
}} {
796 set s
[string index
$m 1]
799 display_all_files_helper
$ui_workdir $path \
804 $ui_index conf
-state disabled
805 $ui_workdir conf
-state disabled
808 ######################################################################
813 #define mask_width 14
814 #define mask_height 15
815 static unsigned char mask_bits
[] = {
816 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
817 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
818 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f};
821 image create bitmap file_plain
-background white
-foreground black
-data {
822 #define plain_width 14
823 #define plain_height 15
824 static unsigned char plain_bits
[] = {
825 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
826 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10,
827 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f};
828 } -maskdata $filemask
830 image create bitmap file_mod
-background white
-foreground blue
-data {
832 #define mod_height 15
833 static unsigned char mod_bits
[] = {
834 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10,
835 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
836 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
837 } -maskdata $filemask
839 image create bitmap file_fulltick
-background white
-foreground "#007000" -data {
840 #define file_fulltick_width 14
841 #define file_fulltick_height 15
842 static unsigned char file_fulltick_bits
[] = {
843 0xfe, 0x01, 0x02, 0x1a, 0x02, 0x0c, 0x02, 0x0c, 0x02, 0x16, 0x02, 0x16,
844 0x02, 0x13, 0x00, 0x13, 0x86, 0x11, 0x8c, 0x11, 0xd8, 0x10, 0xf2, 0x10,
845 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
846 } -maskdata $filemask
848 image create bitmap file_parttick
-background white
-foreground "#005050" -data {
849 #define parttick_width 14
850 #define parttick_height 15
851 static unsigned char parttick_bits
[] = {
852 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10,
853 0x7a, 0x14, 0x02, 0x16, 0x02, 0x13, 0x8a, 0x11, 0xda, 0x10, 0x72, 0x10,
854 0x22, 0x10, 0x02, 0x10, 0xfe, 0x1f};
855 } -maskdata $filemask
857 image create bitmap file_question
-background white
-foreground black
-data {
858 #define file_question_width 14
859 #define file_question_height 15
860 static unsigned char file_question_bits
[] = {
861 0xfe, 0x01, 0x02, 0x02, 0xe2, 0x04, 0xf2, 0x09, 0x1a, 0x1b, 0x0a, 0x13,
862 0x82, 0x11, 0xc2, 0x10, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, 0x62, 0x10,
863 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
864 } -maskdata $filemask
866 image create bitmap file_removed
-background white
-foreground red
-data {
867 #define file_removed_width 14
868 #define file_removed_height 15
869 static unsigned char file_removed_bits
[] = {
870 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
871 0x1a, 0x16, 0x32, 0x13, 0xe2, 0x11, 0xc2, 0x10, 0xe2, 0x11, 0x32, 0x13,
872 0x1a, 0x16, 0x02, 0x10, 0xfe, 0x1f};
873 } -maskdata $filemask
875 image create bitmap file_merge
-background white
-foreground blue
-data {
876 #define file_merge_width 14
877 #define file_merge_height 15
878 static unsigned char file_merge_bits
[] = {
879 0xfe, 0x01, 0x02, 0x03, 0x62, 0x05, 0x62, 0x09, 0x62, 0x1f, 0x62, 0x10,
880 0xfa, 0x11, 0xf2, 0x10, 0x62, 0x10, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
881 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
882 } -maskdata $filemask
885 #define file_width 18
886 #define file_height 18
887 static unsigned char file_bits
[] = {
888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00,
889 0x0c, 0x03, 0x00, 0x04, 0xfe, 0x00, 0x06, 0x80, 0x00, 0xff, 0x9f, 0x00,
890 0x03, 0x98, 0x00, 0x02, 0x90, 0x00, 0x06, 0xb0, 0x00, 0x04, 0xa0, 0x00,
891 0x0c, 0xe0, 0x00, 0x08, 0xc0, 0x00, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00,
892 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
894 image create bitmap file_dir
-background white
-foreground blue \
895 -data $file_dir_data -maskdata $file_dir_data
898 set file_uplevel_data
{
901 static unsigned char up_bits
[] = {
902 0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,
903 0xfe, 0x3f, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
904 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00};
906 image create bitmap file_uplevel
-background white
-foreground red \
907 -data $file_uplevel_data -maskdata $file_uplevel_data
908 unset file_uplevel_data
910 set ui_index .vpane.files.index.list
911 set ui_workdir .vpane.files.workdir.list
913 set all_icons
(_
$ui_index) file_plain
914 set all_icons
(A
$ui_index) file_fulltick
915 set all_icons
(M
$ui_index) file_fulltick
916 set all_icons
(D
$ui_index) file_removed
917 set all_icons
(U
$ui_index) file_merge
919 set all_icons
(_
$ui_workdir) file_plain
920 set all_icons
(M
$ui_workdir) file_mod
921 set all_icons
(D
$ui_workdir) file_question
922 set all_icons
(U
$ui_workdir) file_merge
923 set all_icons
(O
$ui_workdir) file_plain
925 set max_status_desc
0
929 {_M
"Modified, not staged"}
930 {M_
"Staged for commit"}
931 {MM
"Portions staged for commit"}
932 {MD
"Staged for commit, missing"}
934 {_O
"Untracked, not staged"}
935 {A_
"Staged for commit"}
936 {AM
"Portions staged for commit"}
937 {AD
"Staged for commit, missing"}
940 {D_
"Staged for removal"}
941 {DO
"Staged for removal, still present"}
943 {U_
"Requires merge resolution"}
944 {UU
"Requires merge resolution"}
945 {UM
"Requires merge resolution"}
946 {UD
"Requires merge resolution"}
948 if {$max_status_desc < [string length
[lindex
$i 1]]} {
949 set max_status_desc
[string length
[lindex
$i 1]]
951 set all_descs
([lindex
$i 0]) [lindex
$i 1]
955 ######################################################################
959 proc bind_button3
{w cmd
} {
960 bind $w <Any-Button-3
> $cmd
962 bind $w <Control-Button-1
> $cmd
966 proc scrollbar2many
{list mode args
} {
967 foreach w
$list {eval $w $mode $args}
970 proc many2scrollbar
{list mode sb top bottom
} {
972 foreach w
$list {$w $mode moveto
$top}
975 proc incr_font_size
{font
{amt
1}} {
976 set sz
[font configure
$font -size]
978 font configure
$font -size $sz
979 font configure
${font}bold
-size $sz
982 ######################################################################
986 set starting_gitk_msg
{Starting gitk... please
wait...
}
988 proc do_gitk
{revs
} {
989 global env ui_status_value starting_gitk_msg
991 # -- Always start gitk through whatever we were loaded with. This
992 # lets us bypass using shell process on Windows systems.
994 set cmd
[list
[info nameofexecutable
]]
995 lappend cmd
[gitexec gitk
]
1001 if {[catch
{eval exec $cmd &} err
]} {
1002 error_popup
"Failed to start gitk:\n\n$err"
1004 set ui_status_value
$starting_gitk_msg
1006 if {$ui_status_value eq
$starting_gitk_msg} {
1007 set ui_status_value
{Ready.
}
1016 global ui_comm is_quitting repo_config commit_type
1018 if {$is_quitting} return
1021 if {[winfo exists
$ui_comm]} {
1022 # -- Stash our current commit buffer.
1024 set save
[gitdir GITGUI_MSG
]
1025 set msg
[string trim
[$ui_comm get
0.0 end
]]
1026 regsub
-all -line {[ \r\t]+$
} $msg {} msg
1027 if {(![string match amend
* $commit_type]
1028 ||
[$ui_comm edit modified
])
1031 set fd
[open
$save w
]
1032 puts
-nonewline $fd $msg
1036 catch
{file delete
$save}
1039 # -- Stash our current window geometry into this repository.
1041 set cfg_geometry
[list
]
1042 lappend cfg_geometry
[wm geometry .
]
1043 lappend cfg_geometry
[lindex
[.vpane sash coord
0] 1]
1044 lappend cfg_geometry
[lindex
[.vpane.files sash coord
0] 0]
1045 if {[catch
{set rc_geometry
$repo_config(gui.geometry
)}]} {
1048 if {$cfg_geometry ne
$rc_geometry} {
1049 catch
{git config gui.geometry
$cfg_geometry}
1057 rescan
{set ui_status_value
{Ready.
}}
1064 proc toggle_or_diff
{w x y
} {
1065 global file_states file_lists current_diff_path ui_index ui_workdir
1066 global last_clicked selected_paths
1068 set pos
[split [$w index @
$x,$y] .
]
1069 set lno
[lindex
$pos 0]
1070 set col [lindex
$pos 1]
1071 set path
[lindex
$file_lists($w) [expr {$lno - 1}]]
1077 set last_clicked
[list
$w $lno]
1078 array
unset selected_paths
1079 $ui_index tag remove in_sel
0.0 end
1080 $ui_workdir tag remove in_sel
0.0 end
1083 if {$current_diff_path eq
$path} {
1084 set after
{reshow_diff
;}
1088 if {$w eq
$ui_index} {
1090 "Unstaging [short_path $path] from commit" \
1092 [concat
$after {set ui_status_value
{Ready.
}}]
1093 } elseif
{$w eq
$ui_workdir} {
1095 "Adding [short_path $path]" \
1097 [concat
$after {set ui_status_value
{Ready.
}}]
1100 show_diff
$path $w $lno
1104 proc add_one_to_selection
{w x y
} {
1105 global file_lists last_clicked selected_paths
1107 set lno
[lindex
[split [$w index @
$x,$y] .
] 0]
1108 set path
[lindex
$file_lists($w) [expr {$lno - 1}]]
1114 if {$last_clicked ne
{}
1115 && [lindex
$last_clicked 0] ne
$w} {
1116 array
unset selected_paths
1117 [lindex
$last_clicked 0] tag remove in_sel
0.0 end
1120 set last_clicked
[list
$w $lno]
1121 if {[catch
{set in_sel
$selected_paths($path)}]} {
1125 unset selected_paths
($path)
1126 $w tag remove in_sel
$lno.0 [expr {$lno + 1}].0
1128 set selected_paths
($path) 1
1129 $w tag add in_sel
$lno.0 [expr {$lno + 1}].0
1133 proc add_range_to_selection
{w x y
} {
1134 global file_lists last_clicked selected_paths
1136 if {[lindex
$last_clicked 0] ne
$w} {
1137 toggle_or_diff
$w $x $y
1141 set lno
[lindex
[split [$w index @
$x,$y] .
] 0]
1142 set lc
[lindex
$last_clicked 1]
1151 foreach path
[lrange
$file_lists($w) \
1152 [expr {$begin - 1}] \
1153 [expr {$end - 1}]] {
1154 set selected_paths
($path) 1
1156 $w tag add in_sel
$begin.0 [expr {$end + 1}].0
1159 ######################################################################
1163 set cursor_ptr arrow
1164 font create font_diff
-family Courier
-size 10
1168 eval font configure font_ui
[font actual
[.dummy cget
-font]]
1172 font create font_uibold
1173 font create font_diffbold
1175 foreach class
{Button Checkbutton Entry Label
1176 Labelframe Listbox Menu Message
1178 option add
*$class.font font_ui
1185 } elseif
{[is_MacOSX
]} {
1193 proc apply_config
{} {
1194 global repo_config font_descs
1196 foreach option
$font_descs {
1197 set name
[lindex
$option 0]
1198 set font
[lindex
$option 1]
1200 foreach
{cn cv
} $repo_config(gui.
$name) {
1201 font configure
$font $cn $cv
1204 error_popup
"Invalid font specified in gui.$name:\n\n$err"
1206 foreach
{cn cv
} [font configure
$font] {
1207 font configure
${font}bold
$cn $cv
1209 font configure
${font}bold
-weight bold
1213 set default_config
(merge.summary
) false
1214 set default_config
(merge.verbosity
) 2
1215 set default_config
(user.name
) {}
1216 set default_config
(user.email
) {}
1218 set default_config
(gui.trustmtime
) false
1219 set default_config
(gui.diffcontext
) 5
1220 set default_config
(gui.newbranchtemplate
) {}
1221 set default_config
(gui.fontui
) [font configure font_ui
]
1222 set default_config
(gui.fontdiff
) [font configure font_diff
]
1224 {fontui font_ui
{Main Font
}}
1225 {fontdiff font_diff
{Diff
/Console Font
}}
1230 ######################################################################
1232 ## feature option selection
1234 if {[regexp
{^git-
(.
+)$
} [appname
] _junk subcommand
]} {
1239 if {$subcommand eq
{gui.sh
}} {
1242 if {$subcommand eq
{gui
} && [llength
$argv] > 0} {
1243 set subcommand
[lindex
$argv 0]
1244 set argv
[lrange
$argv 1 end
]
1247 enable_option multicommit
1248 enable_option branch
1249 enable_option transport
1251 switch
-- $subcommand {
1254 disable_option multicommit
1255 disable_option branch
1256 disable_option transport
1259 enable_option singlecommit
1261 disable_option multicommit
1262 disable_option branch
1263 disable_option transport
1267 ######################################################################
1275 menu .mbar
-tearoff 0
1276 .mbar add cascade
-label Repository
-menu .mbar.repository
1277 .mbar add cascade
-label Edit
-menu .mbar.edit
1278 if {[is_enabled branch
]} {
1279 .mbar add cascade
-label Branch
-menu .mbar.branch
1281 if {[is_enabled multicommit
] ||
[is_enabled singlecommit
]} {
1282 .mbar add cascade
-label Commit
-menu .mbar.commit
1284 if {[is_enabled transport
]} {
1285 .mbar add cascade
-label Merge
-menu .mbar.merge
1286 .mbar add cascade
-label Fetch
-menu .mbar.fetch
1287 .mbar add cascade
-label Push
-menu .mbar.push
1289 . configure
-menu .mbar
1291 # -- Repository Menu
1293 menu .mbar.repository
1295 .mbar.repository add
command \
1296 -label {Browse Current Branch
} \
1297 -command {browser
::new
$current_branch}
1298 trace add variable current_branch
write ".mbar.repository entryconf [.mbar.repository index last] -label \"Browse \$current_branch\" ;#"
1299 .mbar.repository add separator
1301 .mbar.repository add
command \
1302 -label {Visualize Current Branch
} \
1303 -command {do_gitk
$current_branch}
1304 trace add variable current_branch
write ".mbar.repository entryconf [.mbar.repository index last] -label \"Visualize \$current_branch\" ;#"
1305 .mbar.repository add
command \
1306 -label {Visualize All Branches
} \
1307 -command {do_gitk
--all}
1308 .mbar.repository add separator
1310 if {[is_enabled multicommit
]} {
1311 .mbar.repository add
command -label {Database Statistics
} \
1314 .mbar.repository add
command -label {Compress Database
} \
1317 .mbar.repository add
command -label {Verify Database
} \
1318 -command do_fsck_objects
1320 .mbar.repository add separator
1323 .mbar.repository add
command \
1324 -label {Create Desktop Icon
} \
1325 -command do_cygwin_shortcut
1326 } elseif
{[is_Windows
]} {
1327 .mbar.repository add
command \
1328 -label {Create Desktop Icon
} \
1329 -command do_windows_shortcut
1330 } elseif
{[is_MacOSX
]} {
1331 .mbar.repository add
command \
1332 -label {Create Desktop Icon
} \
1333 -command do_macosx_app
1337 .mbar.repository add
command -label Quit \
1344 .mbar.edit add
command -label Undo \
1345 -command {catch
{[focus
] edit undo
}} \
1347 .mbar.edit add
command -label Redo \
1348 -command {catch
{[focus
] edit redo
}} \
1350 .mbar.edit add separator
1351 .mbar.edit add
command -label Cut \
1352 -command {catch
{tk_textCut
[focus
]}} \
1354 .mbar.edit add
command -label Copy \
1355 -command {catch
{tk_textCopy
[focus
]}} \
1357 .mbar.edit add
command -label Paste \
1358 -command {catch
{tk_textPaste
[focus
]; [focus
] see insert
}} \
1360 .mbar.edit add
command -label Delete \
1361 -command {catch
{[focus
] delete sel.first sel.last
}} \
1363 .mbar.edit add separator
1364 .mbar.edit add
command -label {Select All
} \
1365 -command {catch
{[focus
] tag add sel
0.0 end
}} \
1370 if {[is_enabled branch
]} {
1373 .mbar.branch add
command -label {Create...
} \
1374 -command do_create_branch \
1376 lappend disable_on_lock
[list .mbar.branch entryconf \
1377 [.mbar.branch index last
] -state]
1379 .mbar.branch add
command -label {Delete...
} \
1380 -command do_delete_branch
1381 lappend disable_on_lock
[list .mbar.branch entryconf \
1382 [.mbar.branch index last
] -state]
1384 .mbar.branch add
command -label {Reset...
} \
1385 -command merge
::reset_hard
1386 lappend disable_on_lock
[list .mbar.branch entryconf \
1387 [.mbar.branch index last
] -state]
1392 if {[is_enabled multicommit
] ||
[is_enabled singlecommit
]} {
1395 .mbar.commit add radiobutton \
1396 -label {New Commit
} \
1397 -command do_select_commit_type \
1398 -variable selected_commit_type \
1400 lappend disable_on_lock \
1401 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1403 .mbar.commit add radiobutton \
1404 -label {Amend Last Commit
} \
1405 -command do_select_commit_type \
1406 -variable selected_commit_type \
1408 lappend disable_on_lock \
1409 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1411 .mbar.commit add separator
1413 .mbar.commit add
command -label Rescan \
1414 -command do_rescan \
1416 lappend disable_on_lock \
1417 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1419 .mbar.commit add
command -label {Add To Commit
} \
1420 -command do_add_selection
1421 lappend disable_on_lock \
1422 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1424 .mbar.commit add
command -label {Add Existing To Commit
} \
1425 -command do_add_all \
1427 lappend disable_on_lock \
1428 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1430 .mbar.commit add
command -label {Unstage From Commit
} \
1431 -command do_unstage_selection
1432 lappend disable_on_lock \
1433 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1435 .mbar.commit add
command -label {Revert Changes
} \
1436 -command do_revert_selection
1437 lappend disable_on_lock \
1438 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1440 .mbar.commit add separator
1442 .mbar.commit add
command -label {Sign Off
} \
1443 -command do_signoff \
1446 .mbar.commit add
command -label Commit \
1447 -command do_commit \
1448 -accelerator $M1T-Return
1449 lappend disable_on_lock \
1450 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1455 if {[is_enabled branch
]} {
1457 .mbar.merge add
command -label {Local Merge...
} \
1458 -command merge
::dialog
1459 lappend disable_on_lock \
1460 [list .mbar.merge entryconf
[.mbar.merge index last
] -state]
1461 .mbar.merge add
command -label {Abort Merge...
} \
1462 -command merge
::reset_hard
1463 lappend disable_on_lock \
1464 [list .mbar.merge entryconf
[.mbar.merge index last
] -state]
1470 if {[is_enabled transport
]} {
1474 .mbar.push add
command -label {Push...
} \
1475 -command do_push_anywhere
1479 # -- Apple Menu (Mac OS X only)
1481 .mbar add cascade
-label Apple
-menu .mbar.apple
1484 .mbar.apple add
command -label "About [appname]" \
1486 .mbar.apple add
command -label "Options..." \
1491 .mbar.edit add separator
1492 .mbar.edit add
command -label {Options...
} \
1497 if {[file exists
/usr
/local
/miga
/lib
/gui-miga
]
1498 && [file exists .pvcsrc
]} {
1500 global ui_status_value
1501 if {![lock_index update
]} return
1502 set cmd
[list sh
--login -c "/usr/local/miga/lib/gui-miga \"[pwd]\""]
1503 set miga_fd
[open
"|$cmd" r
]
1504 fconfigure
$miga_fd -blocking 0
1505 fileevent
$miga_fd readable
[list miga_done
$miga_fd]
1506 set ui_status_value
{Running miga...
}
1508 proc miga_done
{fd
} {
1513 rescan
[list
set ui_status_value
{Ready.
}]
1516 .mbar add cascade
-label Tools
-menu .mbar.tools
1518 .mbar.tools add
command -label "Migrate" \
1520 lappend disable_on_lock \
1521 [list .mbar.tools entryconf
[.mbar.tools index last
] -state]
1527 .mbar add cascade
-label Help
-menu .mbar.
help
1531 .mbar.
help add
command -label "About [appname]" \
1536 catch
{set browser
$repo_config(instaweb.browser
)}
1537 set doc_path
[file dirname [gitexec
]]
1538 set doc_path
[file join $doc_path Documentation index.html
]
1541 set doc_path
[exec cygpath
--mixed $doc_path]
1544 if {$browser eq
{}} {
1547 } elseif
{[is_Cygwin
]} {
1548 set program_files
[file dirname [exec cygpath
--windir]]
1549 set program_files
[file join $program_files {Program Files
}]
1550 set firefox
[file join $program_files {Mozilla Firefox
} firefox.exe
]
1551 set ie
[file join $program_files {Internet Explorer
} IEXPLORE.EXE
]
1552 if {[file exists
$firefox]} {
1553 set browser
$firefox
1554 } elseif
{[file exists
$ie]} {
1557 unset program_files firefox ie
1561 if {[file isfile
$doc_path]} {
1562 set doc_url
"file:$doc_path"
1564 set doc_url
{http
://www.kernel.org
/pub
/software
/scm
/git
/docs
/}
1567 if {$browser ne
{}} {
1568 .mbar.
help add
command -label {Online Documentation
} \
1569 -command [list
exec $browser $doc_url &]
1571 unset browser doc_path doc_url
1573 # -- Standard bindings
1575 bind .
<Destroy
> do_quit
1576 bind all
<$M1B-Key-q> do_quit
1577 bind all
<$M1B-Key-Q> do_quit
1578 bind all
<$M1B-Key-w> {destroy
[winfo toplevel
%W
]}
1579 bind all
<$M1B-Key-W> {destroy
[winfo toplevel
%W
]}
1581 # -- Not a normal commit type invocation? Do that instead!
1583 switch
-- $subcommand {
1585 if {[llength
$argv] != 1} {
1586 puts stderr
"usage: $argv0 browser commit"
1589 set current_branch
[lindex
$argv 0]
1590 browser
::new
$current_branch
1594 if {[llength
$argv] != 2} {
1595 puts stderr
"usage: $argv0 blame commit path"
1598 set current_branch
[lindex
$argv 0]
1599 blame
::new
$current_branch $_prefix[lindex
$argv 1]
1604 if {[llength
$argv] != 0} {
1605 puts
-nonewline stderr
"usage: $argv0"
1606 if {$subcommand ne
{gui
} && [appname
] ne
"git-$subcommand"} {
1607 puts
-nonewline stderr
" $subcommand"
1612 # fall through to setup UI for commits
1615 puts stderr
"usage: $argv0 \[{blame|browser|citool}\]"
1626 -text {Current Branch
:} \
1630 -textvariable current_branch \
1633 pack .branch.l1
-side left
1634 pack .branch.cb
-side left
-fill x
1635 pack .branch
-side top
-fill x
1637 # -- Main Window Layout
1639 panedwindow .vpane
-orient vertical
1640 panedwindow .vpane.files
-orient horizontal
1641 .vpane add .vpane.files
-sticky nsew
-height 100 -width 200
1642 pack .vpane
-anchor n
-side top
-fill both
-expand 1
1644 # -- Index File List
1646 frame .vpane.files.index
-height 100 -width 200
1647 label .vpane.files.index.title
-text {Staged Changes
(Will Be Committed
)} \
1649 text
$ui_index -background white
-borderwidth 0 \
1650 -width 20 -height 10 \
1652 -cursor $cursor_ptr \
1653 -xscrollcommand {.vpane.files.index.sx
set} \
1654 -yscrollcommand {.vpane.files.index.sy
set} \
1656 scrollbar .vpane.files.index.sx
-orient h
-command [list
$ui_index xview
]
1657 scrollbar .vpane.files.index.sy
-orient v
-command [list
$ui_index yview
]
1658 pack .vpane.files.index.title
-side top
-fill x
1659 pack .vpane.files.index.sx
-side bottom
-fill x
1660 pack .vpane.files.index.sy
-side right
-fill y
1661 pack
$ui_index -side left
-fill both
-expand 1
1662 .vpane.files add .vpane.files.index
-sticky nsew
1664 # -- Working Directory File List
1666 frame .vpane.files.workdir
-height 100 -width 200
1667 label .vpane.files.workdir.title
-text {Unstaged Changes
(Will Not Be Committed
)} \
1669 text
$ui_workdir -background white
-borderwidth 0 \
1670 -width 20 -height 10 \
1672 -cursor $cursor_ptr \
1673 -xscrollcommand {.vpane.files.workdir.sx
set} \
1674 -yscrollcommand {.vpane.files.workdir.sy
set} \
1676 scrollbar .vpane.files.workdir.sx
-orient h
-command [list
$ui_workdir xview
]
1677 scrollbar .vpane.files.workdir.sy
-orient v
-command [list
$ui_workdir yview
]
1678 pack .vpane.files.workdir.title
-side top
-fill x
1679 pack .vpane.files.workdir.sx
-side bottom
-fill x
1680 pack .vpane.files.workdir.sy
-side right
-fill y
1681 pack
$ui_workdir -side left
-fill both
-expand 1
1682 .vpane.files add .vpane.files.workdir
-sticky nsew
1684 foreach i
[list
$ui_index $ui_workdir] {
1685 $i tag conf in_diff
-font font_uibold
1686 $i tag conf in_sel \
1687 -background [$i cget
-foreground] \
1688 -foreground [$i cget
-background]
1692 # -- Diff and Commit Area
1694 frame .vpane.lower
-height 300 -width 400
1695 frame .vpane.lower.commarea
1696 frame .vpane.lower.
diff -relief sunken
-borderwidth 1
1697 pack .vpane.lower.commarea
-side top
-fill x
1698 pack .vpane.lower.
diff -side bottom
-fill both
-expand 1
1699 .vpane add .vpane.lower
-sticky nsew
1701 # -- Commit Area Buttons
1703 frame .vpane.lower.commarea.buttons
1704 label .vpane.lower.commarea.buttons.l
-text {} \
1707 pack .vpane.lower.commarea.buttons.l
-side top
-fill x
1708 pack .vpane.lower.commarea.buttons
-side left
-fill y
1710 button .vpane.lower.commarea.buttons.rescan
-text {Rescan
} \
1712 pack .vpane.lower.commarea.buttons.rescan
-side top
-fill x
1713 lappend disable_on_lock \
1714 {.vpane.lower.commarea.buttons.rescan conf
-state}
1716 button .vpane.lower.commarea.buttons.incall
-text {Add Existing
} \
1718 pack .vpane.lower.commarea.buttons.incall
-side top
-fill x
1719 lappend disable_on_lock \
1720 {.vpane.lower.commarea.buttons.incall conf
-state}
1722 button .vpane.lower.commarea.buttons.signoff
-text {Sign Off
} \
1724 pack .vpane.lower.commarea.buttons.signoff
-side top
-fill x
1726 button .vpane.lower.commarea.buttons.commit
-text {Commit
} \
1728 pack .vpane.lower.commarea.buttons.commit
-side top
-fill x
1729 lappend disable_on_lock \
1730 {.vpane.lower.commarea.buttons.commit conf
-state}
1732 # -- Commit Message Buffer
1734 frame .vpane.lower.commarea.buffer
1735 frame .vpane.lower.commarea.buffer.header
1736 set ui_comm .vpane.lower.commarea.buffer.t
1737 set ui_coml .vpane.lower.commarea.buffer.header.l
1738 radiobutton .vpane.lower.commarea.buffer.header.new \
1739 -text {New Commit
} \
1740 -command do_select_commit_type \
1741 -variable selected_commit_type \
1743 lappend disable_on_lock \
1744 [list .vpane.lower.commarea.buffer.header.new conf
-state]
1745 radiobutton .vpane.lower.commarea.buffer.header.amend \
1746 -text {Amend Last Commit
} \
1747 -command do_select_commit_type \
1748 -variable selected_commit_type \
1750 lappend disable_on_lock \
1751 [list .vpane.lower.commarea.buffer.header.amend conf
-state]
1755 proc trace_commit_type
{varname args
} {
1756 global ui_coml commit_type
1757 switch
-glob -- $commit_type {
1758 initial
{set txt
{Initial Commit Message
:}}
1759 amend
{set txt
{Amended Commit Message
:}}
1760 amend-initial
{set txt
{Amended Initial Commit Message
:}}
1761 amend-merge
{set txt
{Amended Merge Commit Message
:}}
1762 merge
{set txt
{Merge Commit Message
:}}
1763 * {set txt
{Commit Message
:}}
1765 $ui_coml conf
-text $txt
1767 trace add variable commit_type
write trace_commit_type
1768 pack
$ui_coml -side left
-fill x
1769 pack .vpane.lower.commarea.buffer.header.amend
-side right
1770 pack .vpane.lower.commarea.buffer.header.new
-side right
1772 text
$ui_comm -background white
-borderwidth 1 \
1775 -autoseparators true \
1777 -width 75 -height 9 -wrap none \
1779 -yscrollcommand {.vpane.lower.commarea.buffer.sby
set}
1780 scrollbar .vpane.lower.commarea.buffer.sby \
1781 -command [list
$ui_comm yview
]
1782 pack .vpane.lower.commarea.buffer.header
-side top
-fill x
1783 pack .vpane.lower.commarea.buffer.sby
-side right
-fill y
1784 pack
$ui_comm -side left
-fill y
1785 pack .vpane.lower.commarea.buffer
-side left
-fill y
1787 # -- Commit Message Buffer Context Menu
1789 set ctxm .vpane.lower.commarea.buffer.ctxm
1790 menu
$ctxm -tearoff 0
1793 -command {tk_textCut
$ui_comm}
1796 -command {tk_textCopy
$ui_comm}
1799 -command {tk_textPaste
$ui_comm}
1802 -command {$ui_comm delete sel.first sel.last
}
1805 -label {Select All
} \
1806 -command {focus
$ui_comm;$ui_comm tag add sel
0.0 end
}
1810 $ui_comm tag add sel
0.0 end
1811 tk_textCopy
$ui_comm
1812 $ui_comm tag remove sel
0.0 end
1818 bind_button3
$ui_comm "tk_popup $ctxm %X %Y"
1822 proc trace_current_diff_path
{varname args
} {
1823 global current_diff_path diff_actions file_states
1824 if {$current_diff_path eq
{}} {
1830 set p
$current_diff_path
1831 set s
[mapdesc
[lindex
$file_states($p) 0] $p]
1833 set p
[escape_path
$p]
1837 .vpane.lower.
diff.header.status configure
-text $s
1838 .vpane.lower.
diff.header.
file configure
-text $f
1839 .vpane.lower.
diff.header.path configure
-text $p
1840 foreach w
$diff_actions {
1844 trace add variable current_diff_path
write trace_current_diff_path
1846 frame .vpane.lower.
diff.header
-background orange
1847 label .vpane.lower.
diff.header.status \
1848 -background orange \
1849 -width $max_status_desc \
1852 label .vpane.lower.
diff.header.
file \
1853 -background orange \
1856 label .vpane.lower.
diff.header.path \
1857 -background orange \
1860 pack .vpane.lower.
diff.header.status
-side left
1861 pack .vpane.lower.
diff.header.
file -side left
1862 pack .vpane.lower.
diff.header.path
-fill x
1863 set ctxm .vpane.lower.
diff.header.ctxm
1864 menu
$ctxm -tearoff 0
1872 -- $current_diff_path
1874 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1875 bind_button3 .vpane.lower.
diff.header.path
"tk_popup $ctxm %X %Y"
1879 frame .vpane.lower.
diff.body
1880 set ui_diff .vpane.lower.
diff.body.t
1881 text
$ui_diff -background white
-borderwidth 0 \
1882 -width 80 -height 15 -wrap none \
1884 -xscrollcommand {.vpane.lower.
diff.body.sbx
set} \
1885 -yscrollcommand {.vpane.lower.
diff.body.sby
set} \
1887 scrollbar .vpane.lower.
diff.body.sbx
-orient horizontal \
1888 -command [list
$ui_diff xview
]
1889 scrollbar .vpane.lower.
diff.body.sby
-orient vertical \
1890 -command [list
$ui_diff yview
]
1891 pack .vpane.lower.
diff.body.sbx
-side bottom
-fill x
1892 pack .vpane.lower.
diff.body.sby
-side right
-fill y
1893 pack
$ui_diff -side left
-fill both
-expand 1
1894 pack .vpane.lower.
diff.header
-side top
-fill x
1895 pack .vpane.lower.
diff.body
-side bottom
-fill both
-expand 1
1897 $ui_diff tag conf d_cr
-elide true
1898 $ui_diff tag conf d_@
-foreground blue
-font font_diffbold
1899 $ui_diff tag conf d_
+ -foreground {#00a000}
1900 $ui_diff tag conf d_-
-foreground red
1902 $ui_diff tag conf d_
++ -foreground {#00a000}
1903 $ui_diff tag conf d_--
-foreground red
1904 $ui_diff tag conf d_
+s \
1905 -foreground {#00a000} \
1906 -background {#e2effa}
1907 $ui_diff tag conf d_-s \
1909 -background {#e2effa}
1910 $ui_diff tag conf d_s
+ \
1911 -foreground {#00a000} \
1913 $ui_diff tag conf d_s- \
1917 $ui_diff tag conf d
<<<<<<< \
1918 -foreground orange \
1920 $ui_diff tag conf d
======= \
1921 -foreground orange \
1923 $ui_diff tag conf d
>>>>>>> \
1924 -foreground orange \
1927 $ui_diff tag raise sel
1929 # -- Diff Body Context Menu
1931 set ctxm .vpane.lower.
diff.body.ctxm
1932 menu
$ctxm -tearoff 0
1935 -command reshow_diff
1936 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1939 -command {tk_textCopy
$ui_diff}
1940 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1942 -label {Select All
} \
1943 -command {focus
$ui_diff;$ui_diff tag add sel
0.0 end
}
1944 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1948 $ui_diff tag add sel
0.0 end
1949 tk_textCopy
$ui_diff
1950 $ui_diff tag remove sel
0.0 end
1952 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1955 -label {Apply
/Reverse Hunk
} \
1956 -command {apply_hunk
$cursorX $cursorY}
1957 set ui_diff_applyhunk
[$ctxm index last
]
1958 lappend diff_actions
[list
$ctxm entryconf
$ui_diff_applyhunk -state]
1961 -label {Decrease Font Size
} \
1962 -command {incr_font_size font_diff
-1}
1963 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1965 -label {Increase Font Size
} \
1966 -command {incr_font_size font_diff
1}
1967 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1970 -label {Show Less Context
} \
1971 -command {if {$repo_config(gui.diffcontext
) >= 2} {
1972 incr repo_config
(gui.diffcontext
) -1
1975 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1977 -label {Show More Context
} \
1979 incr repo_config
(gui.diffcontext
)
1982 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1984 $ctxm add
command -label {Options...
} \
1986 bind_button3
$ui_diff "
1989 if {\$ui_index eq \$current_diff_side} {
1990 $ctxm entryconf $ui_diff_applyhunk -label {Unstage Hunk From Commit}
1992 $ctxm entryconf $ui_diff_applyhunk -label {Stage Hunk For Commit}
1994 tk_popup $ctxm %X %Y
1996 unset ui_diff_applyhunk
2000 label .status
-textvariable ui_status_value \
2005 pack .status
-anchor w
-side bottom
-fill x
2010 set gm
$repo_config(gui.geometry
)
2011 wm geometry .
[lindex
$gm 0]
2012 .vpane sash place
0 \
2013 [lindex
[.vpane sash coord
0] 0] \
2015 .vpane.files sash place
0 \
2017 [lindex
[.vpane.files sash coord
0] 1]
2023 bind $ui_comm <$M1B-Key-Return> {do_commit
;break}
2024 bind $ui_comm <$M1B-Key-i> {do_add_all
;break}
2025 bind $ui_comm <$M1B-Key-I> {do_add_all
;break}
2026 bind $ui_comm <$M1B-Key-x> {tk_textCut
%W
;break}
2027 bind $ui_comm <$M1B-Key-X> {tk_textCut
%W
;break}
2028 bind $ui_comm <$M1B-Key-c> {tk_textCopy
%W
;break}
2029 bind $ui_comm <$M1B-Key-C> {tk_textCopy
%W
;break}
2030 bind $ui_comm <$M1B-Key-v> {tk_textPaste
%W
; %W see insert
; break}
2031 bind $ui_comm <$M1B-Key-V> {tk_textPaste
%W
; %W see insert
; break}
2032 bind $ui_comm <$M1B-Key-a> {%W tag add sel
0.0 end
;break}
2033 bind $ui_comm <$M1B-Key-A> {%W tag add sel
0.0 end
;break}
2035 bind $ui_diff <$M1B-Key-x> {tk_textCopy
%W
;break}
2036 bind $ui_diff <$M1B-Key-X> {tk_textCopy
%W
;break}
2037 bind $ui_diff <$M1B-Key-c> {tk_textCopy
%W
;break}
2038 bind $ui_diff <$M1B-Key-C> {tk_textCopy
%W
;break}
2039 bind $ui_diff <$M1B-Key-v> {break}
2040 bind $ui_diff <$M1B-Key-V> {break}
2041 bind $ui_diff <$M1B-Key-a> {%W tag add sel
0.0 end
;break}
2042 bind $ui_diff <$M1B-Key-A> {%W tag add sel
0.0 end
;break}
2043 bind $ui_diff <Key-Up
> {catch
{%W yview scroll
-1 units
};break}
2044 bind $ui_diff <Key-Down
> {catch
{%W yview scroll
1 units
};break}
2045 bind $ui_diff <Key-Left
> {catch
{%W xview scroll
-1 units
};break}
2046 bind $ui_diff <Key-Right
> {catch
{%W xview scroll
1 units
};break}
2047 bind $ui_diff <Key-k
> {catch
{%W yview scroll
-1 units
};break}
2048 bind $ui_diff <Key-j
> {catch
{%W yview scroll
1 units
};break}
2049 bind $ui_diff <Key-h
> {catch
{%W xview scroll
-1 units
};break}
2050 bind $ui_diff <Key-l
> {catch
{%W xview scroll
1 units
};break}
2051 bind $ui_diff <Control-Key-b
> {catch
{%W yview scroll
-1 pages
};break}
2052 bind $ui_diff <Control-Key-f
> {catch
{%W yview scroll
1 pages
};break}
2053 bind $ui_diff <Button-1
> {focus
%W
}
2055 if {[is_enabled branch
]} {
2056 bind .
<$M1B-Key-n> do_create_branch
2057 bind .
<$M1B-Key-N> do_create_branch
2060 bind all
<Key-F5
> do_rescan
2061 bind all
<$M1B-Key-r> do_rescan
2062 bind all
<$M1B-Key-R> do_rescan
2063 bind .
<$M1B-Key-s> do_signoff
2064 bind .
<$M1B-Key-S> do_signoff
2065 bind .
<$M1B-Key-i> do_add_all
2066 bind .
<$M1B-Key-I> do_add_all
2067 bind .
<$M1B-Key-Return> do_commit
2068 foreach i
[list
$ui_index $ui_workdir] {
2069 bind $i <Button-1
> "toggle_or_diff $i %x %y; break"
2070 bind $i <$M1B-Button-1> "add_one_to_selection $i %x %y; break"
2071 bind $i <Shift-Button-1
> "add_range_to_selection $i %x %y; break"
2075 set file_lists
($ui_index) [list
]
2076 set file_lists
($ui_workdir) [list
]
2078 wm title .
"[appname] ([reponame]) [file normalize [file dirname [gitdir]]]"
2079 focus
-force $ui_comm
2081 # -- Warn the user about environmental problems. Cygwin's Tcl
2082 # does *not* pass its env array onto any processes it spawns.
2083 # This means that git processes get none of our environment.
2088 set msg
"Possible environment issues exist.
2090 The following environment variables are probably
2091 going to be ignored by any Git subprocess run
2095 foreach name
[array names env
] {
2096 switch
-regexp -- $name {
2097 {^GIT_INDEX_FILE$
} -
2098 {^GIT_OBJECT_DIRECTORY$
} -
2099 {^GIT_ALTERNATE_OBJECT_DIRECTORIES$
} -
2101 {^GIT_EXTERNAL_DIFF$
} -
2105 {^GIT_CONFIG_LOCAL$
} -
2106 {^GIT_
(AUTHOR|COMMITTER
)_DATE$
} {
2107 append msg
" - $name\n"
2110 {^GIT_
(AUTHOR|COMMITTER
)_
(NAME|EMAIL
)$
} {
2111 append msg
" - $name\n"
2113 set suggest_user
$name
2117 if {$ignored_env > 0} {
2119 This is due to a known issue with the
2120 Tcl binary distributed by Cygwin."
2122 if {$suggest_user ne
{}} {
2125 A good replacement for $suggest_user
2126 is placing values for the user.name and
2127 user.email settings into your personal
2133 unset ignored_env msg suggest_user name
2136 # -- Only initialize complex UI if we are going to stay running.
2138 if {[is_enabled transport
]} {
2142 populate_branch_menu
2147 # -- Only suggest a gc run if we are going to stay running.
2149 if {[is_enabled multicommit
]} {
2150 set object_limit
2000
2151 if {[is_Windows
]} {set object_limit
200}
2152 regexp
{^
([0-9]+) objects
,} [git count-objects
] _junk objects_current
2153 if {$objects_current >= $object_limit} {
2155 "This repository currently has $objects_current loose objects.
2157 To maintain optimal performance it is strongly recommended that you compress the database when more than $object_limit loose objects exist.
2159 Compress the database now?"] eq
yes} {
2163 unset object_limit _junk objects_current
2166 lock_index begin-read