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 @@GITGUI_
*@@
$oguilib]} {
29 set oguilib
[file join [file dirname [file normalize
$argv0]] lib
]
31 set idx
[file join $oguilib tclIndex
]
34 if {[gets
$fd] eq
{# Autogenerated by git-gui Makefile}} {
36 while {[gets
$fd n
] >= 0} {
37 if {$n ne
{} && ![string match
#* $n]} {
49 if {[lsearch
-exact $loaded $p] >= 0} continue
51 source [file join $oguilib $p]
56 set auto_path
[concat
[list
$oguilib] $auto_path]
58 unset -nocomplain fd idx
60 if {![catch
{set _verbose
$env(GITGUI_VERBOSE
)}]} {
62 rename auto_load real__auto_load
63 proc auto_load
{name args
} {
64 puts stderr
"auto_load $name"
65 return [uplevel
1 real__auto_load
$name $args]
67 rename
source real__source
69 puts stderr
"source $name"
70 uplevel
1 real__source
$name
74 ######################################################################
78 set _appname
[lindex
[file split $argv0] end
]
94 return [eval [concat
[list
file join $_gitdir] $args]]
99 if {$_gitexec eq
{}} {
100 if {[catch
{set _gitexec
[git
--exec-path]} err
]} {
101 error
"Git not installed?\n\n$err"
107 return [eval [concat
[list
file join $_gitexec] $args]]
116 global tcl_platform tk_library
117 if {[tk windowingsystem
] eq
{aqua
}} {
125 if {$tcl_platform(platform
) eq
{windows
}} {
132 global tcl_platform _iscygwin
133 if {$_iscygwin eq
{}} {
134 if {$tcl_platform(platform
) eq
{windows
}} {
135 if {[catch
{set p
[exec cygpath
--windir]} err
]} {
147 proc is_enabled
{option
} {
148 global enabled_options
149 if {[catch
{set on
$enabled_options($option)}]} {return 0}
153 proc enable_option
{option
} {
154 global enabled_options
155 set enabled_options
($option) 1
158 proc disable_option
{option
} {
159 global enabled_options
160 set enabled_options
($option) 0
163 ######################################################################
167 proc is_many_config
{name
} {
168 switch
-glob -- $name {
177 proc is_config_true
{name
} {
179 if {[catch
{set v
$repo_config($name)}]} {
181 } elseif
{$v eq
{true
} ||
$v eq
{1} ||
$v eq
{yes}} {
188 proc load_config
{include_global
} {
189 global repo_config global_config default_config
191 array
unset global_config
192 if {$include_global} {
194 set fd_rc
[open
"| git config --global --list" r
]
195 while {[gets
$fd_rc line
] >= 0} {
196 if {[regexp
{^
([^
=]+)=(.
*)$
} $line line name value
]} {
197 if {[is_many_config
$name]} {
198 lappend global_config
($name) $value
200 set global_config
($name) $value
208 array
unset repo_config
210 set fd_rc
[open
"| git config --list" r
]
211 while {[gets
$fd_rc line
] >= 0} {
212 if {[regexp
{^
([^
=]+)=(.
*)$
} $line line name value
]} {
213 if {[is_many_config
$name]} {
214 lappend repo_config
($name) $value
216 set repo_config
($name) $value
223 foreach name
[array names default_config
] {
224 if {[catch
{set v
$global_config($name)}]} {
225 set global_config
($name) $default_config($name)
227 if {[catch
{set v
$repo_config($name)}]} {
228 set repo_config
($name) $default_config($name)
233 ######################################################################
238 return [eval exec git
$args]
241 auto_load tk_optionMenu
242 rename tk_optionMenu real__tkOptionMenu
243 proc tk_optionMenu
{w varName args
} {
244 set m
[eval real__tkOptionMenu
$w $varName $args]
245 $m configure
-font font_ui
246 $w configure
-font font_ui
250 ######################################################################
254 if {{--version} eq
$argv ||
{version
} eq
$argv} {
255 puts
"git-gui version $appvers"
262 if {[catch
{set v
[git
--version]} err
]} {
263 catch
{wm withdraw .
}
264 error_popup
"Cannot determine Git version:
268 [appname] requires Git $req_maj.$req_min or later."
271 if {[regexp
{^git version
(\d
+)\.
(\d
+)} $v _junk act_maj act_min
]} {
272 if {$act_maj < $req_maj
273 ||
($act_maj == $req_maj && $act_min < $req_min)} {
274 catch
{wm withdraw .
}
275 error_popup
"[appname] requires Git $req_maj.$req_min or later.
281 catch
{wm withdraw .
}
282 error_popup
"Cannot parse Git version string:\n\n$v"
285 unset -nocomplain v _junk act_maj act_min req_maj req_min
287 ######################################################################
292 set _gitdir
$env(GIT_DIR
)
296 set _gitdir
[git rev-parse
--git-dir]
297 set _prefix
[git rev-parse
--show-prefix]
299 catch
{wm withdraw .
}
300 error_popup
"Cannot find the git directory:\n\n$err"
303 if {![file isdirectory
$_gitdir] && [is_Cygwin
]} {
304 catch
{set _gitdir
[exec cygpath
--unix $_gitdir]}
306 if {![file isdirectory
$_gitdir]} {
307 catch
{wm withdraw .
}
308 error_popup
"Git directory not found:\n\n$_gitdir"
311 if {[lindex
[file split $_gitdir] end
] ne
{.git
}} {
312 catch
{wm withdraw .
}
313 error_popup
"Cannot use funny .git directory:\n\n$_gitdir"
316 if {[catch
{cd [file dirname $_gitdir]} err
]} {
317 catch
{wm withdraw .
}
318 error_popup
"No working directory [file dirname $_gitdir]:\n\n$err"
321 set _reponame
[lindex
[file split \
322 [file normalize
[file dirname $_gitdir]]] \
325 ######################################################################
329 set current_diff_path
{}
330 set current_diff_side
{}
331 set diff_actions
[list
]
332 set ui_status_value
{Initializing...
}
336 set MERGE_HEAD
[list
]
339 set current_branch
{}
340 set current_diff_path
{}
341 set selected_commit_type new
343 ######################################################################
351 set disable_on_lock
[list
]
352 set index_lock_type none
354 proc lock_index
{type} {
355 global index_lock_type disable_on_lock
357 if {$index_lock_type eq
{none
}} {
358 set index_lock_type
$type
359 foreach w
$disable_on_lock {
360 uplevel
#0 $w disabled
363 } elseif
{$index_lock_type eq
"begin-$type"} {
364 set index_lock_type
$type
370 proc unlock_index
{} {
371 global index_lock_type disable_on_lock
373 set index_lock_type none
374 foreach w
$disable_on_lock {
379 ######################################################################
383 proc repository_state
{ctvar hdvar mhvar
} {
384 global current_branch
385 upvar
$ctvar ct
$hdvar hd
$mhvar mh
389 if {[catch
{set current_branch
[git symbolic-ref HEAD
]}]} {
390 set current_branch
{}
392 regsub ^refs
/((heads|tags|remotes
)/)? \
398 if {[catch
{set hd
[git rev-parse
--verify HEAD
]}]} {
404 set merge_head
[gitdir MERGE_HEAD
]
405 if {[file exists
$merge_head]} {
407 set fd_mh
[open
$merge_head r
]
408 while {[gets
$fd_mh line
] >= 0} {
419 global PARENT empty_tree
421 set p
[lindex
$PARENT 0]
425 if {$empty_tree eq
{}} {
426 set empty_tree
[git mktree
<< {}]
431 proc rescan
{after
{honor_trustmtime
1}} {
432 global HEAD PARENT MERGE_HEAD commit_type
433 global ui_index ui_workdir ui_status_value ui_comm
434 global rescan_active file_states
437 if {$rescan_active > 0 ||
![lock_index
read]} return
439 repository_state newType newHEAD newMERGE_HEAD
440 if {[string match amend
* $commit_type]
441 && $newType eq
{normal
}
442 && $newHEAD eq
$HEAD} {
446 set MERGE_HEAD
$newMERGE_HEAD
447 set commit_type
$newType
450 array
unset file_states
452 if {![$ui_comm edit modified
]
453 ||
[string trim
[$ui_comm get
0.0 end
]] eq
{}} {
454 if {[load_message GITGUI_MSG
]} {
455 } elseif
{[load_message MERGE_MSG
]} {
456 } elseif
{[load_message SQUASH_MSG
]} {
459 $ui_comm edit modified false
462 if {[is_enabled branch
]} {
467 if {$honor_trustmtime && $repo_config(gui.trustmtime
) eq
{true
}} {
468 rescan_stage2
{} $after
471 set ui_status_value
{Refreshing
file status...
}
472 set cmd
[list git update-index
]
474 lappend cmd
--unmerged
475 lappend cmd
--ignore-missing
476 lappend cmd
--refresh
477 set fd_rf
[open
"| $cmd" r
]
478 fconfigure
$fd_rf -blocking 0 -translation binary
479 fileevent
$fd_rf readable \
480 [list rescan_stage2
$fd_rf $after]
484 proc rescan_stage2
{fd after
} {
485 global ui_status_value
486 global rescan_active buf_rdi buf_rdf buf_rlo
490 if {![eof
$fd]} return
494 set ls_others
[list | git ls-files
--others -z \
495 --exclude-per-directory=.gitignore
]
496 set info_exclude
[gitdir info exclude
]
497 if {[file readable
$info_exclude]} {
498 lappend ls_others
"--exclude-from=$info_exclude"
506 set ui_status_value
{Scanning
for modified files ...
}
507 set fd_di
[open
"| git diff-index --cached -z [PARENT]" r
]
508 set fd_df
[open
"| git diff-files -z" r
]
509 set fd_lo
[open
$ls_others r
]
511 fconfigure
$fd_di -blocking 0 -translation binary
-encoding binary
512 fconfigure
$fd_df -blocking 0 -translation binary
-encoding binary
513 fconfigure
$fd_lo -blocking 0 -translation binary
-encoding binary
514 fileevent
$fd_di readable
[list read_diff_index
$fd_di $after]
515 fileevent
$fd_df readable
[list read_diff_files
$fd_df $after]
516 fileevent
$fd_lo readable
[list read_ls_others
$fd_lo $after]
519 proc load_message
{file} {
523 if {[file isfile
$f]} {
524 if {[catch
{set fd
[open
$f r
]}]} {
527 set content
[string trim
[read $fd]]
529 regsub
-all -line {[ \r\t]+$
} $content {} content
530 $ui_comm delete
0.0 end
531 $ui_comm insert end
$content
537 proc read_diff_index
{fd after
} {
540 append buf_rdi
[read $fd]
542 set n
[string length
$buf_rdi]
544 set z1
[string first
"\0" $buf_rdi $c]
547 set z2
[string first
"\0" $buf_rdi $z1]
551 set i
[split [string range
$buf_rdi $c [expr {$z1 - 2}]] { }]
552 set p
[string range
$buf_rdi $z1 [expr {$z2 - 1}]]
554 [encoding convertfrom
$p] \
556 [list
[lindex
$i 0] [lindex
$i 2]] \
562 set buf_rdi
[string range
$buf_rdi $c end
]
567 rescan_done
$fd buf_rdi
$after
570 proc read_diff_files
{fd after
} {
573 append buf_rdf
[read $fd]
575 set n
[string length
$buf_rdf]
577 set z1
[string first
"\0" $buf_rdf $c]
580 set z2
[string first
"\0" $buf_rdf $z1]
584 set i
[split [string range
$buf_rdf $c [expr {$z1 - 2}]] { }]
585 set p
[string range
$buf_rdf $z1 [expr {$z2 - 1}]]
587 [encoding convertfrom
$p] \
590 [list
[lindex
$i 0] [lindex
$i 2]]
595 set buf_rdf
[string range
$buf_rdf $c end
]
600 rescan_done
$fd buf_rdf
$after
603 proc read_ls_others
{fd after
} {
606 append buf_rlo
[read $fd]
607 set pck
[split $buf_rlo "\0"]
608 set buf_rlo
[lindex
$pck end
]
609 foreach p
[lrange
$pck 0 end-1
] {
610 merge_state
[encoding convertfrom
$p] ?O
612 rescan_done
$fd buf_rlo
$after
615 proc rescan_done
{fd buf after
} {
616 global rescan_active current_diff_path
617 global file_states repo_config
620 if {![eof
$fd]} return
623 if {[incr rescan_active
-1] > 0} return
628 if {$current_diff_path ne
{}} reshow_diff
632 proc prune_selection
{} {
633 global file_states selected_paths
635 foreach path
[array names selected_paths
] {
636 if {[catch
{set still_here
$file_states($path)}]} {
637 unset selected_paths
($path)
642 ######################################################################
646 proc mapicon
{w state path
} {
649 if {[catch
{set r
$all_icons($state$w)}]} {
650 puts
"error: no icon for $w state={$state} $path"
656 proc mapdesc
{state path
} {
659 if {[catch
{set r
$all_descs($state)}]} {
660 puts
"error: no desc for state={$state} $path"
666 proc escape_path
{path
} {
667 regsub
-all {\\} $path "\\\\" path
668 regsub
-all "\n" $path "\\n" path
672 proc short_path
{path
} {
673 return [escape_path
[lindex
[file split $path] end
]]
677 set null_sha1
[string repeat
0 40]
679 proc merge_state
{path new_state
{head_info
{}} {index_info
{}}} {
680 global file_states next_icon_id null_sha1
682 set s0
[string index
$new_state 0]
683 set s1
[string index
$new_state 1]
685 if {[catch
{set info
$file_states($path)}]} {
687 set icon n
[incr next_icon_id
]
689 set state
[lindex
$info 0]
690 set icon
[lindex
$info 1]
691 if {$head_info eq
{}} {set head_info
[lindex
$info 2]}
692 if {$index_info eq
{}} {set index_info
[lindex
$info 3]}
695 if {$s0 eq
{?
}} {set s0
[string index
$state 0]} \
696 elseif
{$s0 eq
{_
}} {set s0 _
}
698 if {$s1 eq
{?
}} {set s1
[string index
$state 1]} \
699 elseif
{$s1 eq
{_
}} {set s1 _
}
701 if {$s0 eq
{A
} && $s1 eq
{_
} && $head_info eq
{}} {
702 set head_info
[list
0 $null_sha1]
703 } elseif
{$s0 ne
{_
} && [string index
$state 0] eq
{_
}
704 && $head_info eq
{}} {
705 set head_info
$index_info
708 set file_states
($path) [list
$s0$s1 $icon \
709 $head_info $index_info \
714 proc display_file_helper
{w path icon_name old_m new_m
} {
718 set lno
[lsearch
-sorted -exact $file_lists($w) $path]
720 set file_lists
($w) [lreplace
$file_lists($w) $lno $lno]
722 $w conf
-state normal
723 $w delete
$lno.0 [expr {$lno + 1}].0
724 $w conf
-state disabled
726 } elseif
{$old_m eq
{_
} && $new_m ne
{_
}} {
727 lappend file_lists
($w) $path
728 set file_lists
($w) [lsort
-unique $file_lists($w)]
729 set lno
[lsearch
-sorted -exact $file_lists($w) $path]
731 $w conf
-state normal
732 $w image create
$lno.0 \
733 -align center
-padx 5 -pady 1 \
735 -image [mapicon
$w $new_m $path]
736 $w insert
$lno.1 "[escape_path $path]\n"
737 $w conf
-state disabled
738 } elseif
{$old_m ne
$new_m} {
739 $w conf
-state normal
740 $w image conf
$icon_name -image [mapicon
$w $new_m $path]
741 $w conf
-state disabled
745 proc display_file
{path state
} {
746 global file_states selected_paths
747 global ui_index ui_workdir
749 set old_m
[merge_state
$path $state]
750 set s
$file_states($path)
751 set new_m
[lindex
$s 0]
752 set icon_name
[lindex
$s 1]
754 set o
[string index
$old_m 0]
755 set n
[string index
$new_m 0]
762 display_file_helper
$ui_index $path $icon_name $o $n
764 if {[string index
$old_m 0] eq
{U
}} {
767 set o
[string index
$old_m 1]
769 if {[string index
$new_m 0] eq
{U
}} {
772 set n
[string index
$new_m 1]
774 display_file_helper
$ui_workdir $path $icon_name $o $n
776 if {$new_m eq
{__
}} {
777 unset file_states
($path)
778 catch
{unset selected_paths
($path)}
782 proc display_all_files_helper
{w path icon_name m
} {
785 lappend file_lists
($w) $path
786 set lno
[expr {[lindex
[split [$w index end
] .
] 0] - 1}]
787 $w image create end \
788 -align center
-padx 5 -pady 1 \
790 -image [mapicon
$w $m $path]
791 $w insert end
"[escape_path $path]\n"
794 proc display_all_files
{} {
795 global ui_index ui_workdir
796 global file_states file_lists
799 $ui_index conf
-state normal
800 $ui_workdir conf
-state normal
802 $ui_index delete
0.0 end
803 $ui_workdir delete
0.0 end
806 set file_lists
($ui_index) [list
]
807 set file_lists
($ui_workdir) [list
]
809 foreach path
[lsort
[array names file_states
]] {
810 set s
$file_states($path)
812 set icon_name
[lindex
$s 1]
814 set s
[string index
$m 0]
815 if {$s ne
{U
} && $s ne
{_
}} {
816 display_all_files_helper
$ui_index $path \
820 if {[string index
$m 0] eq
{U
}} {
823 set s
[string index
$m 1]
826 display_all_files_helper
$ui_workdir $path \
831 $ui_index conf
-state disabled
832 $ui_workdir conf
-state disabled
835 ######################################################################
840 #define mask_width 14
841 #define mask_height 15
842 static unsigned char mask_bits
[] = {
843 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
844 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
845 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f};
848 image create bitmap file_plain
-background white
-foreground black
-data {
849 #define plain_width 14
850 #define plain_height 15
851 static unsigned char plain_bits
[] = {
852 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
853 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10,
854 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f};
855 } -maskdata $filemask
857 image create bitmap file_mod
-background white
-foreground blue
-data {
859 #define mod_height 15
860 static unsigned char mod_bits
[] = {
861 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10,
862 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
863 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
864 } -maskdata $filemask
866 image create bitmap file_fulltick
-background white
-foreground "#007000" -data {
867 #define file_fulltick_width 14
868 #define file_fulltick_height 15
869 static unsigned char file_fulltick_bits
[] = {
870 0xfe, 0x01, 0x02, 0x1a, 0x02, 0x0c, 0x02, 0x0c, 0x02, 0x16, 0x02, 0x16,
871 0x02, 0x13, 0x00, 0x13, 0x86, 0x11, 0x8c, 0x11, 0xd8, 0x10, 0xf2, 0x10,
872 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
873 } -maskdata $filemask
875 image create bitmap file_parttick
-background white
-foreground "#005050" -data {
876 #define parttick_width 14
877 #define parttick_height 15
878 static unsigned char parttick_bits
[] = {
879 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10,
880 0x7a, 0x14, 0x02, 0x16, 0x02, 0x13, 0x8a, 0x11, 0xda, 0x10, 0x72, 0x10,
881 0x22, 0x10, 0x02, 0x10, 0xfe, 0x1f};
882 } -maskdata $filemask
884 image create bitmap file_question
-background white
-foreground black
-data {
885 #define file_question_width 14
886 #define file_question_height 15
887 static unsigned char file_question_bits
[] = {
888 0xfe, 0x01, 0x02, 0x02, 0xe2, 0x04, 0xf2, 0x09, 0x1a, 0x1b, 0x0a, 0x13,
889 0x82, 0x11, 0xc2, 0x10, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, 0x62, 0x10,
890 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
891 } -maskdata $filemask
893 image create bitmap file_removed
-background white
-foreground red
-data {
894 #define file_removed_width 14
895 #define file_removed_height 15
896 static unsigned char file_removed_bits
[] = {
897 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
898 0x1a, 0x16, 0x32, 0x13, 0xe2, 0x11, 0xc2, 0x10, 0xe2, 0x11, 0x32, 0x13,
899 0x1a, 0x16, 0x02, 0x10, 0xfe, 0x1f};
900 } -maskdata $filemask
902 image create bitmap file_merge
-background white
-foreground blue
-data {
903 #define file_merge_width 14
904 #define file_merge_height 15
905 static unsigned char file_merge_bits
[] = {
906 0xfe, 0x01, 0x02, 0x03, 0x62, 0x05, 0x62, 0x09, 0x62, 0x1f, 0x62, 0x10,
907 0xfa, 0x11, 0xf2, 0x10, 0x62, 0x10, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
908 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
909 } -maskdata $filemask
912 #define file_width 18
913 #define file_height 18
914 static unsigned char file_bits
[] = {
915 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00,
916 0x0c, 0x03, 0x00, 0x04, 0xfe, 0x00, 0x06, 0x80, 0x00, 0xff, 0x9f, 0x00,
917 0x03, 0x98, 0x00, 0x02, 0x90, 0x00, 0x06, 0xb0, 0x00, 0x04, 0xa0, 0x00,
918 0x0c, 0xe0, 0x00, 0x08, 0xc0, 0x00, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00,
919 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
921 image create bitmap file_dir
-background white
-foreground blue \
922 -data $file_dir_data -maskdata $file_dir_data
925 set file_uplevel_data
{
928 static unsigned char up_bits
[] = {
929 0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,
930 0xfe, 0x3f, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
931 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00};
933 image create bitmap file_uplevel
-background white
-foreground red \
934 -data $file_uplevel_data -maskdata $file_uplevel_data
935 unset file_uplevel_data
937 set ui_index .vpane.files.index.list
938 set ui_workdir .vpane.files.workdir.list
940 set all_icons
(_
$ui_index) file_plain
941 set all_icons
(A
$ui_index) file_fulltick
942 set all_icons
(M
$ui_index) file_fulltick
943 set all_icons
(D
$ui_index) file_removed
944 set all_icons
(U
$ui_index) file_merge
946 set all_icons
(_
$ui_workdir) file_plain
947 set all_icons
(M
$ui_workdir) file_mod
948 set all_icons
(D
$ui_workdir) file_question
949 set all_icons
(U
$ui_workdir) file_merge
950 set all_icons
(O
$ui_workdir) file_plain
952 set max_status_desc
0
956 {_M
"Modified, not staged"}
957 {M_
"Staged for commit"}
958 {MM
"Portions staged for commit"}
959 {MD
"Staged for commit, missing"}
961 {_O
"Untracked, not staged"}
962 {A_
"Staged for commit"}
963 {AM
"Portions staged for commit"}
964 {AD
"Staged for commit, missing"}
967 {D_
"Staged for removal"}
968 {DO
"Staged for removal, still present"}
970 {U_
"Requires merge resolution"}
971 {UU
"Requires merge resolution"}
972 {UM
"Requires merge resolution"}
973 {UD
"Requires merge resolution"}
975 if {$max_status_desc < [string length
[lindex
$i 1]]} {
976 set max_status_desc
[string length
[lindex
$i 1]]
978 set all_descs
([lindex
$i 0]) [lindex
$i 1]
982 ######################################################################
986 proc bind_button3
{w cmd
} {
987 bind $w <Any-Button-3
> $cmd
989 bind $w <Control-Button-1
> $cmd
993 proc scrollbar2many
{list mode args
} {
994 foreach w
$list {eval $w $mode $args}
997 proc many2scrollbar
{list mode sb top bottom
} {
999 foreach w
$list {$w $mode moveto
$top}
1002 proc incr_font_size
{font
{amt
1}} {
1003 set sz
[font configure
$font -size]
1005 font configure
$font -size $sz
1006 font configure
${font}bold
-size $sz
1009 ######################################################################
1013 set starting_gitk_msg
{Starting gitk... please
wait...
}
1015 proc do_gitk
{revs
} {
1016 global env ui_status_value starting_gitk_msg
1018 # -- Always start gitk through whatever we were loaded with. This
1019 # lets us bypass using shell process on Windows systems.
1021 set cmd
[list
[info nameofexecutable
]]
1022 lappend cmd
[gitexec gitk
]
1028 if {[catch
{eval exec $cmd &} err
]} {
1029 error_popup
"Failed to start gitk:\n\n$err"
1031 set ui_status_value
$starting_gitk_msg
1033 if {$ui_status_value eq
$starting_gitk_msg} {
1034 set ui_status_value
{Ready.
}
1043 global ui_comm is_quitting repo_config commit_type
1045 if {$is_quitting} return
1048 if {[winfo exists
$ui_comm]} {
1049 # -- Stash our current commit buffer.
1051 set save
[gitdir GITGUI_MSG
]
1052 set msg
[string trim
[$ui_comm get
0.0 end
]]
1053 regsub
-all -line {[ \r\t]+$
} $msg {} msg
1054 if {(![string match amend
* $commit_type]
1055 ||
[$ui_comm edit modified
])
1058 set fd
[open
$save w
]
1059 puts
-nonewline $fd $msg
1063 catch
{file delete
$save}
1066 # -- Stash our current window geometry into this repository.
1068 set cfg_geometry
[list
]
1069 lappend cfg_geometry
[wm geometry .
]
1070 lappend cfg_geometry
[lindex
[.vpane sash coord
0] 1]
1071 lappend cfg_geometry
[lindex
[.vpane.files sash coord
0] 0]
1072 if {[catch
{set rc_geometry
$repo_config(gui.geometry
)}]} {
1075 if {$cfg_geometry ne
$rc_geometry} {
1076 catch
{git config gui.geometry
$cfg_geometry}
1084 rescan
{set ui_status_value
{Ready.
}}
1091 proc toggle_or_diff
{w x y
} {
1092 global file_states file_lists current_diff_path ui_index ui_workdir
1093 global last_clicked selected_paths
1095 set pos
[split [$w index @
$x,$y] .
]
1096 set lno
[lindex
$pos 0]
1097 set col [lindex
$pos 1]
1098 set path
[lindex
$file_lists($w) [expr {$lno - 1}]]
1104 set last_clicked
[list
$w $lno]
1105 array
unset selected_paths
1106 $ui_index tag remove in_sel
0.0 end
1107 $ui_workdir tag remove in_sel
0.0 end
1110 if {$current_diff_path eq
$path} {
1111 set after
{reshow_diff
;}
1115 if {$w eq
$ui_index} {
1117 "Unstaging [short_path $path] from commit" \
1119 [concat
$after {set ui_status_value
{Ready.
}}]
1120 } elseif
{$w eq
$ui_workdir} {
1122 "Adding [short_path $path]" \
1124 [concat
$after {set ui_status_value
{Ready.
}}]
1127 show_diff
$path $w $lno
1131 proc add_one_to_selection
{w x y
} {
1132 global file_lists last_clicked selected_paths
1134 set lno
[lindex
[split [$w index @
$x,$y] .
] 0]
1135 set path
[lindex
$file_lists($w) [expr {$lno - 1}]]
1141 if {$last_clicked ne
{}
1142 && [lindex
$last_clicked 0] ne
$w} {
1143 array
unset selected_paths
1144 [lindex
$last_clicked 0] tag remove in_sel
0.0 end
1147 set last_clicked
[list
$w $lno]
1148 if {[catch
{set in_sel
$selected_paths($path)}]} {
1152 unset selected_paths
($path)
1153 $w tag remove in_sel
$lno.0 [expr {$lno + 1}].0
1155 set selected_paths
($path) 1
1156 $w tag add in_sel
$lno.0 [expr {$lno + 1}].0
1160 proc add_range_to_selection
{w x y
} {
1161 global file_lists last_clicked selected_paths
1163 if {[lindex
$last_clicked 0] ne
$w} {
1164 toggle_or_diff
$w $x $y
1168 set lno
[lindex
[split [$w index @
$x,$y] .
] 0]
1169 set lc
[lindex
$last_clicked 1]
1178 foreach path
[lrange
$file_lists($w) \
1179 [expr {$begin - 1}] \
1180 [expr {$end - 1}]] {
1181 set selected_paths
($path) 1
1183 $w tag add in_sel
$begin.0 [expr {$end + 1}].0
1186 ######################################################################
1190 set cursor_ptr arrow
1191 font create font_diff
-family Courier
-size 10
1195 eval font configure font_ui
[font actual
[.dummy cget
-font]]
1199 font create font_uibold
1200 font create font_diffbold
1202 foreach class
{Button Checkbutton Entry Label
1203 Labelframe Listbox Menu Message
1205 option add
*$class.font font_ui
1217 proc apply_config
{} {
1218 global repo_config font_descs
1220 foreach option
$font_descs {
1221 set name
[lindex
$option 0]
1222 set font
[lindex
$option 1]
1224 foreach
{cn cv
} $repo_config(gui.
$name) {
1225 font configure
$font $cn $cv
1228 error_popup
"Invalid font specified in gui.$name:\n\n$err"
1230 foreach
{cn cv
} [font configure
$font] {
1231 font configure
${font}bold
$cn $cv
1233 font configure
${font}bold
-weight bold
1237 set default_config
(merge.summary
) false
1238 set default_config
(merge.verbosity
) 2
1239 set default_config
(user.name
) {}
1240 set default_config
(user.email
) {}
1242 set default_config
(gui.trustmtime
) false
1243 set default_config
(gui.diffcontext
) 5
1244 set default_config
(gui.newbranchtemplate
) {}
1245 set default_config
(gui.fontui
) [font configure font_ui
]
1246 set default_config
(gui.fontdiff
) [font configure font_diff
]
1248 {fontui font_ui
{Main Font
}}
1249 {fontdiff font_diff
{Diff
/Console Font
}}
1254 ######################################################################
1256 ## feature option selection
1258 if {[regexp
{^git-
(.
+)$
} [appname
] _junk subcommand
]} {
1263 if {$subcommand eq
{gui.sh
}} {
1266 if {$subcommand eq
{gui
} && [llength
$argv] > 0} {
1267 set subcommand
[lindex
$argv 0]
1268 set argv
[lrange
$argv 1 end
]
1271 enable_option multicommit
1272 enable_option branch
1273 enable_option transport
1275 switch
-- $subcommand {
1278 disable_option multicommit
1279 disable_option branch
1280 disable_option transport
1283 enable_option singlecommit
1285 disable_option multicommit
1286 disable_option branch
1287 disable_option transport
1291 ######################################################################
1299 menu .mbar
-tearoff 0
1300 .mbar add cascade
-label Repository
-menu .mbar.repository
1301 .mbar add cascade
-label Edit
-menu .mbar.edit
1302 if {[is_enabled branch
]} {
1303 .mbar add cascade
-label Branch
-menu .mbar.branch
1305 if {[is_enabled multicommit
] ||
[is_enabled singlecommit
]} {
1306 .mbar add cascade
-label Commit
-menu .mbar.commit
1308 if {[is_enabled transport
]} {
1309 .mbar add cascade
-label Merge
-menu .mbar.merge
1310 .mbar add cascade
-label Fetch
-menu .mbar.fetch
1311 .mbar add cascade
-label Push
-menu .mbar.push
1313 . configure
-menu .mbar
1315 # -- Repository Menu
1317 menu .mbar.repository
1319 .mbar.repository add
command \
1320 -label {Browse Current Branch
} \
1321 -command {browser
::new
$current_branch}
1322 trace add variable current_branch
write ".mbar.repository entryconf [.mbar.repository index last] -label \"Browse \$current_branch\" ;#"
1323 .mbar.repository add separator
1325 .mbar.repository add
command \
1326 -label {Visualize Current Branch
} \
1327 -command {do_gitk
$current_branch}
1328 trace add variable current_branch
write ".mbar.repository entryconf [.mbar.repository index last] -label \"Visualize \$current_branch\" ;#"
1329 .mbar.repository add
command \
1330 -label {Visualize All Branches
} \
1331 -command {do_gitk
--all}
1332 .mbar.repository add separator
1334 if {[is_enabled multicommit
]} {
1335 .mbar.repository add
command -label {Database Statistics
} \
1338 .mbar.repository add
command -label {Compress Database
} \
1341 .mbar.repository add
command -label {Verify Database
} \
1342 -command do_fsck_objects
1344 .mbar.repository add separator
1347 .mbar.repository add
command \
1348 -label {Create Desktop Icon
} \
1349 -command do_cygwin_shortcut
1350 } elseif
{[is_Windows
]} {
1351 .mbar.repository add
command \
1352 -label {Create Desktop Icon
} \
1353 -command do_windows_shortcut
1354 } elseif
{[is_MacOSX
]} {
1355 .mbar.repository add
command \
1356 -label {Create Desktop Icon
} \
1357 -command do_macosx_app
1361 .mbar.repository add
command -label Quit \
1368 .mbar.edit add
command -label Undo \
1369 -command {catch
{[focus
] edit undo
}} \
1371 .mbar.edit add
command -label Redo \
1372 -command {catch
{[focus
] edit redo
}} \
1374 .mbar.edit add separator
1375 .mbar.edit add
command -label Cut \
1376 -command {catch
{tk_textCut
[focus
]}} \
1378 .mbar.edit add
command -label Copy \
1379 -command {catch
{tk_textCopy
[focus
]}} \
1381 .mbar.edit add
command -label Paste \
1382 -command {catch
{tk_textPaste
[focus
]; [focus
] see insert
}} \
1384 .mbar.edit add
command -label Delete \
1385 -command {catch
{[focus
] delete sel.first sel.last
}} \
1387 .mbar.edit add separator
1388 .mbar.edit add
command -label {Select All
} \
1389 -command {catch
{[focus
] tag add sel
0.0 end
}} \
1394 if {[is_enabled branch
]} {
1397 .mbar.branch add
command -label {Create...
} \
1398 -command do_create_branch \
1400 lappend disable_on_lock
[list .mbar.branch entryconf \
1401 [.mbar.branch index last
] -state]
1403 .mbar.branch add
command -label {Delete...
} \
1404 -command do_delete_branch
1405 lappend disable_on_lock
[list .mbar.branch entryconf \
1406 [.mbar.branch index last
] -state]
1408 .mbar.branch add
command -label {Reset...
} \
1409 -command merge
::reset_hard
1410 lappend disable_on_lock
[list .mbar.branch entryconf \
1411 [.mbar.branch index last
] -state]
1416 if {[is_enabled multicommit
] ||
[is_enabled singlecommit
]} {
1419 .mbar.commit add radiobutton \
1420 -label {New Commit
} \
1421 -command do_select_commit_type \
1422 -variable selected_commit_type \
1424 lappend disable_on_lock \
1425 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1427 .mbar.commit add radiobutton \
1428 -label {Amend Last Commit
} \
1429 -command do_select_commit_type \
1430 -variable selected_commit_type \
1432 lappend disable_on_lock \
1433 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1435 .mbar.commit add separator
1437 .mbar.commit add
command -label Rescan \
1438 -command do_rescan \
1440 lappend disable_on_lock \
1441 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1443 .mbar.commit add
command -label {Add To Commit
} \
1444 -command do_add_selection
1445 lappend disable_on_lock \
1446 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1448 .mbar.commit add
command -label {Add Existing To Commit
} \
1449 -command do_add_all \
1451 lappend disable_on_lock \
1452 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1454 .mbar.commit add
command -label {Unstage From Commit
} \
1455 -command do_unstage_selection
1456 lappend disable_on_lock \
1457 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1459 .mbar.commit add
command -label {Revert Changes
} \
1460 -command do_revert_selection
1461 lappend disable_on_lock \
1462 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1464 .mbar.commit add separator
1466 .mbar.commit add
command -label {Sign Off
} \
1467 -command do_signoff \
1470 .mbar.commit add
command -label Commit \
1471 -command do_commit \
1472 -accelerator $M1T-Return
1473 lappend disable_on_lock \
1474 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1479 if {[is_enabled branch
]} {
1481 .mbar.merge add
command -label {Local Merge...
} \
1482 -command merge
::dialog
1483 lappend disable_on_lock \
1484 [list .mbar.merge entryconf
[.mbar.merge index last
] -state]
1485 .mbar.merge add
command -label {Abort Merge...
} \
1486 -command merge
::reset_hard
1487 lappend disable_on_lock \
1488 [list .mbar.merge entryconf
[.mbar.merge index last
] -state]
1494 if {[is_enabled transport
]} {
1498 .mbar.push add
command -label {Push...
} \
1499 -command do_push_anywhere
1503 # -- Apple Menu (Mac OS X only)
1505 .mbar add cascade
-label Apple
-menu .mbar.apple
1508 .mbar.apple add
command -label "About [appname]" \
1510 .mbar.apple add
command -label "Options..." \
1515 .mbar.edit add separator
1516 .mbar.edit add
command -label {Options...
} \
1521 if {[file exists
/usr
/local
/miga
/lib
/gui-miga
]
1522 && [file exists .pvcsrc
]} {
1524 global ui_status_value
1525 if {![lock_index update
]} return
1526 set cmd
[list sh
--login -c "/usr/local/miga/lib/gui-miga \"[pwd]\""]
1527 set miga_fd
[open
"|$cmd" r
]
1528 fconfigure
$miga_fd -blocking 0
1529 fileevent
$miga_fd readable
[list miga_done
$miga_fd]
1530 set ui_status_value
{Running miga...
}
1532 proc miga_done
{fd
} {
1537 rescan
[list
set ui_status_value
{Ready.
}]
1540 .mbar add cascade
-label Tools
-menu .mbar.tools
1542 .mbar.tools add
command -label "Migrate" \
1544 lappend disable_on_lock \
1545 [list .mbar.tools entryconf
[.mbar.tools index last
] -state]
1551 .mbar add cascade
-label Help
-menu .mbar.
help
1555 .mbar.
help add
command -label "About [appname]" \
1560 catch
{set browser
$repo_config(instaweb.browser
)}
1561 set doc_path
[file dirname [gitexec
]]
1562 set doc_path
[file join $doc_path Documentation index.html
]
1565 set doc_path
[exec cygpath
--mixed $doc_path]
1568 if {$browser eq
{}} {
1571 } elseif
{[is_Cygwin
]} {
1572 set program_files
[file dirname [exec cygpath
--windir]]
1573 set program_files
[file join $program_files {Program Files
}]
1574 set firefox
[file join $program_files {Mozilla Firefox
} firefox.exe
]
1575 set ie
[file join $program_files {Internet Explorer
} IEXPLORE.EXE
]
1576 if {[file exists
$firefox]} {
1577 set browser
$firefox
1578 } elseif
{[file exists
$ie]} {
1581 unset program_files firefox ie
1585 if {[file isfile
$doc_path]} {
1586 set doc_url
"file:$doc_path"
1588 set doc_url
{http
://www.kernel.org
/pub
/software
/scm
/git
/docs
/}
1591 if {$browser ne
{}} {
1592 .mbar.
help add
command -label {Online Documentation
} \
1593 -command [list
exec $browser $doc_url &]
1595 unset browser doc_path doc_url
1597 # -- Standard bindings
1599 bind .
<Destroy
> do_quit
1600 bind all
<$M1B-Key-q> do_quit
1601 bind all
<$M1B-Key-Q> do_quit
1602 bind all
<$M1B-Key-w> {destroy
[winfo toplevel
%W
]}
1603 bind all
<$M1B-Key-W> {destroy
[winfo toplevel
%W
]}
1605 set subcommand_args
{}
1607 puts stderr
"usage: $::argv0 $::subcommand $::subcommand_args"
1611 # -- Not a normal commit type invocation? Do that instead!
1613 switch
-- $subcommand {
1615 set subcommand_args
{rev?
}
1616 switch
[llength
$argv] {
1618 set current_branch
[git symbolic-ref HEAD
]
1619 regsub ^refs
/((heads|tags|remotes
)/)? \
1620 $current_branch {} current_branch
1623 set current_branch
[lindex
$argv 0]
1627 browser
::new
$current_branch
1631 set subcommand_args
{rev? path?
}
1636 if {$is_path ||
[file exists
$_prefix$a]} {
1637 if {$path ne
{}} usage
1640 } elseif
{$a eq
{--}} {
1642 if {$head ne
{}} usage
1647 } elseif
{$head eq
{}} {
1648 if {$head ne
{}} usage
1657 set current_branch
[git symbolic-ref HEAD
]
1658 regsub ^refs
/((heads|tags|remotes
)/)? \
1659 $current_branch {} current_branch
1661 set current_branch
$head
1664 if {$path eq
{}} usage
1665 blame
::new
$head $path
1670 if {[llength
$argv] != 0} {
1671 puts
-nonewline stderr
"usage: $argv0"
1672 if {$subcommand ne
{gui
} && [appname
] ne
"git-$subcommand"} {
1673 puts
-nonewline stderr
" $subcommand"
1678 # fall through to setup UI for commits
1681 puts stderr
"usage: $argv0 \[{blame|browser|citool}\]"
1692 -text {Current Branch
:} \
1696 -textvariable current_branch \
1699 pack .branch.l1
-side left
1700 pack .branch.cb
-side left
-fill x
1701 pack .branch
-side top
-fill x
1703 # -- Main Window Layout
1705 panedwindow .vpane
-orient vertical
1706 panedwindow .vpane.files
-orient horizontal
1707 .vpane add .vpane.files
-sticky nsew
-height 100 -width 200
1708 pack .vpane
-anchor n
-side top
-fill both
-expand 1
1710 # -- Index File List
1712 frame .vpane.files.index
-height 100 -width 200
1713 label .vpane.files.index.title
-text {Staged Changes
(Will Be Committed
)} \
1715 text
$ui_index -background white
-borderwidth 0 \
1716 -width 20 -height 10 \
1718 -cursor $cursor_ptr \
1719 -xscrollcommand {.vpane.files.index.sx
set} \
1720 -yscrollcommand {.vpane.files.index.sy
set} \
1722 scrollbar .vpane.files.index.sx
-orient h
-command [list
$ui_index xview
]
1723 scrollbar .vpane.files.index.sy
-orient v
-command [list
$ui_index yview
]
1724 pack .vpane.files.index.title
-side top
-fill x
1725 pack .vpane.files.index.sx
-side bottom
-fill x
1726 pack .vpane.files.index.sy
-side right
-fill y
1727 pack
$ui_index -side left
-fill both
-expand 1
1728 .vpane.files add .vpane.files.index
-sticky nsew
1730 # -- Working Directory File List
1732 frame .vpane.files.workdir
-height 100 -width 200
1733 label .vpane.files.workdir.title
-text {Unstaged Changes
(Will Not Be Committed
)} \
1735 text
$ui_workdir -background white
-borderwidth 0 \
1736 -width 20 -height 10 \
1738 -cursor $cursor_ptr \
1739 -xscrollcommand {.vpane.files.workdir.sx
set} \
1740 -yscrollcommand {.vpane.files.workdir.sy
set} \
1742 scrollbar .vpane.files.workdir.sx
-orient h
-command [list
$ui_workdir xview
]
1743 scrollbar .vpane.files.workdir.sy
-orient v
-command [list
$ui_workdir yview
]
1744 pack .vpane.files.workdir.title
-side top
-fill x
1745 pack .vpane.files.workdir.sx
-side bottom
-fill x
1746 pack .vpane.files.workdir.sy
-side right
-fill y
1747 pack
$ui_workdir -side left
-fill both
-expand 1
1748 .vpane.files add .vpane.files.workdir
-sticky nsew
1750 foreach i
[list
$ui_index $ui_workdir] {
1751 $i tag conf in_diff
-font font_uibold
1752 $i tag conf in_sel \
1753 -background [$i cget
-foreground] \
1754 -foreground [$i cget
-background]
1758 # -- Diff and Commit Area
1760 frame .vpane.lower
-height 300 -width 400
1761 frame .vpane.lower.commarea
1762 frame .vpane.lower.
diff -relief sunken
-borderwidth 1
1763 pack .vpane.lower.commarea
-side top
-fill x
1764 pack .vpane.lower.
diff -side bottom
-fill both
-expand 1
1765 .vpane add .vpane.lower
-sticky nsew
1767 # -- Commit Area Buttons
1769 frame .vpane.lower.commarea.buttons
1770 label .vpane.lower.commarea.buttons.l
-text {} \
1773 pack .vpane.lower.commarea.buttons.l
-side top
-fill x
1774 pack .vpane.lower.commarea.buttons
-side left
-fill y
1776 button .vpane.lower.commarea.buttons.rescan
-text {Rescan
} \
1778 pack .vpane.lower.commarea.buttons.rescan
-side top
-fill x
1779 lappend disable_on_lock \
1780 {.vpane.lower.commarea.buttons.rescan conf
-state}
1782 button .vpane.lower.commarea.buttons.incall
-text {Add Existing
} \
1784 pack .vpane.lower.commarea.buttons.incall
-side top
-fill x
1785 lappend disable_on_lock \
1786 {.vpane.lower.commarea.buttons.incall conf
-state}
1788 button .vpane.lower.commarea.buttons.signoff
-text {Sign Off
} \
1790 pack .vpane.lower.commarea.buttons.signoff
-side top
-fill x
1792 button .vpane.lower.commarea.buttons.commit
-text {Commit
} \
1794 pack .vpane.lower.commarea.buttons.commit
-side top
-fill x
1795 lappend disable_on_lock \
1796 {.vpane.lower.commarea.buttons.commit conf
-state}
1798 # -- Commit Message Buffer
1800 frame .vpane.lower.commarea.buffer
1801 frame .vpane.lower.commarea.buffer.header
1802 set ui_comm .vpane.lower.commarea.buffer.t
1803 set ui_coml .vpane.lower.commarea.buffer.header.l
1804 radiobutton .vpane.lower.commarea.buffer.header.new \
1805 -text {New Commit
} \
1806 -command do_select_commit_type \
1807 -variable selected_commit_type \
1809 lappend disable_on_lock \
1810 [list .vpane.lower.commarea.buffer.header.new conf
-state]
1811 radiobutton .vpane.lower.commarea.buffer.header.amend \
1812 -text {Amend Last Commit
} \
1813 -command do_select_commit_type \
1814 -variable selected_commit_type \
1816 lappend disable_on_lock \
1817 [list .vpane.lower.commarea.buffer.header.amend conf
-state]
1821 proc trace_commit_type
{varname args
} {
1822 global ui_coml commit_type
1823 switch
-glob -- $commit_type {
1824 initial
{set txt
{Initial Commit Message
:}}
1825 amend
{set txt
{Amended Commit Message
:}}
1826 amend-initial
{set txt
{Amended Initial Commit Message
:}}
1827 amend-merge
{set txt
{Amended Merge Commit Message
:}}
1828 merge
{set txt
{Merge Commit Message
:}}
1829 * {set txt
{Commit Message
:}}
1831 $ui_coml conf
-text $txt
1833 trace add variable commit_type
write trace_commit_type
1834 pack
$ui_coml -side left
-fill x
1835 pack .vpane.lower.commarea.buffer.header.amend
-side right
1836 pack .vpane.lower.commarea.buffer.header.new
-side right
1838 text
$ui_comm -background white
-borderwidth 1 \
1841 -autoseparators true \
1843 -width 75 -height 9 -wrap none \
1845 -yscrollcommand {.vpane.lower.commarea.buffer.sby
set}
1846 scrollbar .vpane.lower.commarea.buffer.sby \
1847 -command [list
$ui_comm yview
]
1848 pack .vpane.lower.commarea.buffer.header
-side top
-fill x
1849 pack .vpane.lower.commarea.buffer.sby
-side right
-fill y
1850 pack
$ui_comm -side left
-fill y
1851 pack .vpane.lower.commarea.buffer
-side left
-fill y
1853 # -- Commit Message Buffer Context Menu
1855 set ctxm .vpane.lower.commarea.buffer.ctxm
1856 menu
$ctxm -tearoff 0
1859 -command {tk_textCut
$ui_comm}
1862 -command {tk_textCopy
$ui_comm}
1865 -command {tk_textPaste
$ui_comm}
1868 -command {$ui_comm delete sel.first sel.last
}
1871 -label {Select All
} \
1872 -command {focus
$ui_comm;$ui_comm tag add sel
0.0 end
}
1876 $ui_comm tag add sel
0.0 end
1877 tk_textCopy
$ui_comm
1878 $ui_comm tag remove sel
0.0 end
1884 bind_button3
$ui_comm "tk_popup $ctxm %X %Y"
1888 proc trace_current_diff_path
{varname args
} {
1889 global current_diff_path diff_actions file_states
1890 if {$current_diff_path eq
{}} {
1896 set p
$current_diff_path
1897 set s
[mapdesc
[lindex
$file_states($p) 0] $p]
1899 set p
[escape_path
$p]
1903 .vpane.lower.
diff.header.status configure
-text $s
1904 .vpane.lower.
diff.header.
file configure
-text $f
1905 .vpane.lower.
diff.header.path configure
-text $p
1906 foreach w
$diff_actions {
1910 trace add variable current_diff_path
write trace_current_diff_path
1912 frame .vpane.lower.
diff.header
-background orange
1913 label .vpane.lower.
diff.header.status \
1914 -background orange \
1915 -width $max_status_desc \
1918 label .vpane.lower.
diff.header.
file \
1919 -background orange \
1922 label .vpane.lower.
diff.header.path \
1923 -background orange \
1926 pack .vpane.lower.
diff.header.status
-side left
1927 pack .vpane.lower.
diff.header.
file -side left
1928 pack .vpane.lower.
diff.header.path
-fill x
1929 set ctxm .vpane.lower.
diff.header.ctxm
1930 menu
$ctxm -tearoff 0
1938 -- $current_diff_path
1940 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1941 bind_button3 .vpane.lower.
diff.header.path
"tk_popup $ctxm %X %Y"
1945 frame .vpane.lower.
diff.body
1946 set ui_diff .vpane.lower.
diff.body.t
1947 text
$ui_diff -background white
-borderwidth 0 \
1948 -width 80 -height 15 -wrap none \
1950 -xscrollcommand {.vpane.lower.
diff.body.sbx
set} \
1951 -yscrollcommand {.vpane.lower.
diff.body.sby
set} \
1953 scrollbar .vpane.lower.
diff.body.sbx
-orient horizontal \
1954 -command [list
$ui_diff xview
]
1955 scrollbar .vpane.lower.
diff.body.sby
-orient vertical \
1956 -command [list
$ui_diff yview
]
1957 pack .vpane.lower.
diff.body.sbx
-side bottom
-fill x
1958 pack .vpane.lower.
diff.body.sby
-side right
-fill y
1959 pack
$ui_diff -side left
-fill both
-expand 1
1960 pack .vpane.lower.
diff.header
-side top
-fill x
1961 pack .vpane.lower.
diff.body
-side bottom
-fill both
-expand 1
1963 $ui_diff tag conf d_cr
-elide true
1964 $ui_diff tag conf d_@
-foreground blue
-font font_diffbold
1965 $ui_diff tag conf d_
+ -foreground {#00a000}
1966 $ui_diff tag conf d_-
-foreground red
1968 $ui_diff tag conf d_
++ -foreground {#00a000}
1969 $ui_diff tag conf d_--
-foreground red
1970 $ui_diff tag conf d_
+s \
1971 -foreground {#00a000} \
1972 -background {#e2effa}
1973 $ui_diff tag conf d_-s \
1975 -background {#e2effa}
1976 $ui_diff tag conf d_s
+ \
1977 -foreground {#00a000} \
1979 $ui_diff tag conf d_s- \
1983 $ui_diff tag conf d
<<<<<<< \
1984 -foreground orange \
1986 $ui_diff tag conf d
======= \
1987 -foreground orange \
1989 $ui_diff tag conf d
>>>>>>> \
1990 -foreground orange \
1993 $ui_diff tag raise sel
1995 # -- Diff Body Context Menu
1997 set ctxm .vpane.lower.
diff.body.ctxm
1998 menu
$ctxm -tearoff 0
2001 -command reshow_diff
2002 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2005 -command {tk_textCopy
$ui_diff}
2006 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2008 -label {Select All
} \
2009 -command {focus
$ui_diff;$ui_diff tag add sel
0.0 end
}
2010 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2014 $ui_diff tag add sel
0.0 end
2015 tk_textCopy
$ui_diff
2016 $ui_diff tag remove sel
0.0 end
2018 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2021 -label {Apply
/Reverse Hunk
} \
2022 -command {apply_hunk
$cursorX $cursorY}
2023 set ui_diff_applyhunk
[$ctxm index last
]
2024 lappend diff_actions
[list
$ctxm entryconf
$ui_diff_applyhunk -state]
2027 -label {Decrease Font Size
} \
2028 -command {incr_font_size font_diff
-1}
2029 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2031 -label {Increase Font Size
} \
2032 -command {incr_font_size font_diff
1}
2033 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2036 -label {Show Less Context
} \
2037 -command {if {$repo_config(gui.diffcontext
) >= 2} {
2038 incr repo_config
(gui.diffcontext
) -1
2041 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2043 -label {Show More Context
} \
2045 incr repo_config
(gui.diffcontext
)
2048 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2050 $ctxm add
command -label {Options...
} \
2052 bind_button3
$ui_diff "
2055 if {\$ui_index eq \$current_diff_side} {
2056 $ctxm entryconf $ui_diff_applyhunk -label {Unstage Hunk From Commit}
2058 $ctxm entryconf $ui_diff_applyhunk -label {Stage Hunk For Commit}
2060 tk_popup $ctxm %X %Y
2062 unset ui_diff_applyhunk
2066 label .status
-textvariable ui_status_value \
2071 pack .status
-anchor w
-side bottom
-fill x
2076 set gm
$repo_config(gui.geometry
)
2077 wm geometry .
[lindex
$gm 0]
2078 .vpane sash place
0 \
2079 [lindex
[.vpane sash coord
0] 0] \
2081 .vpane.files sash place
0 \
2083 [lindex
[.vpane.files sash coord
0] 1]
2089 bind $ui_comm <$M1B-Key-Return> {do_commit
;break}
2090 bind $ui_comm <$M1B-Key-i> {do_add_all
;break}
2091 bind $ui_comm <$M1B-Key-I> {do_add_all
;break}
2092 bind $ui_comm <$M1B-Key-x> {tk_textCut
%W
;break}
2093 bind $ui_comm <$M1B-Key-X> {tk_textCut
%W
;break}
2094 bind $ui_comm <$M1B-Key-c> {tk_textCopy
%W
;break}
2095 bind $ui_comm <$M1B-Key-C> {tk_textCopy
%W
;break}
2096 bind $ui_comm <$M1B-Key-v> {tk_textPaste
%W
; %W see insert
; break}
2097 bind $ui_comm <$M1B-Key-V> {tk_textPaste
%W
; %W see insert
; break}
2098 bind $ui_comm <$M1B-Key-a> {%W tag add sel
0.0 end
;break}
2099 bind $ui_comm <$M1B-Key-A> {%W tag add sel
0.0 end
;break}
2101 bind $ui_diff <$M1B-Key-x> {tk_textCopy
%W
;break}
2102 bind $ui_diff <$M1B-Key-X> {tk_textCopy
%W
;break}
2103 bind $ui_diff <$M1B-Key-c> {tk_textCopy
%W
;break}
2104 bind $ui_diff <$M1B-Key-C> {tk_textCopy
%W
;break}
2105 bind $ui_diff <$M1B-Key-v> {break}
2106 bind $ui_diff <$M1B-Key-V> {break}
2107 bind $ui_diff <$M1B-Key-a> {%W tag add sel
0.0 end
;break}
2108 bind $ui_diff <$M1B-Key-A> {%W tag add sel
0.0 end
;break}
2109 bind $ui_diff <Key-Up
> {catch
{%W yview scroll
-1 units
};break}
2110 bind $ui_diff <Key-Down
> {catch
{%W yview scroll
1 units
};break}
2111 bind $ui_diff <Key-Left
> {catch
{%W xview scroll
-1 units
};break}
2112 bind $ui_diff <Key-Right
> {catch
{%W xview scroll
1 units
};break}
2113 bind $ui_diff <Key-k
> {catch
{%W yview scroll
-1 units
};break}
2114 bind $ui_diff <Key-j
> {catch
{%W yview scroll
1 units
};break}
2115 bind $ui_diff <Key-h
> {catch
{%W xview scroll
-1 units
};break}
2116 bind $ui_diff <Key-l
> {catch
{%W xview scroll
1 units
};break}
2117 bind $ui_diff <Control-Key-b
> {catch
{%W yview scroll
-1 pages
};break}
2118 bind $ui_diff <Control-Key-f
> {catch
{%W yview scroll
1 pages
};break}
2119 bind $ui_diff <Button-1
> {focus
%W
}
2121 if {[is_enabled branch
]} {
2122 bind .
<$M1B-Key-n> do_create_branch
2123 bind .
<$M1B-Key-N> do_create_branch
2126 bind all
<Key-F5
> do_rescan
2127 bind all
<$M1B-Key-r> do_rescan
2128 bind all
<$M1B-Key-R> do_rescan
2129 bind .
<$M1B-Key-s> do_signoff
2130 bind .
<$M1B-Key-S> do_signoff
2131 bind .
<$M1B-Key-i> do_add_all
2132 bind .
<$M1B-Key-I> do_add_all
2133 bind .
<$M1B-Key-Return> do_commit
2134 foreach i
[list
$ui_index $ui_workdir] {
2135 bind $i <Button-1
> "toggle_or_diff $i %x %y; break"
2136 bind $i <$M1B-Button-1> "add_one_to_selection $i %x %y; break"
2137 bind $i <Shift-Button-1
> "add_range_to_selection $i %x %y; break"
2141 set file_lists
($ui_index) [list
]
2142 set file_lists
($ui_workdir) [list
]
2144 wm title .
"[appname] ([reponame]) [file normalize [file dirname [gitdir]]]"
2145 focus
-force $ui_comm
2147 # -- Warn the user about environmental problems. Cygwin's Tcl
2148 # does *not* pass its env array onto any processes it spawns.
2149 # This means that git processes get none of our environment.
2154 set msg
"Possible environment issues exist.
2156 The following environment variables are probably
2157 going to be ignored by any Git subprocess run
2161 foreach name
[array names env
] {
2162 switch
-regexp -- $name {
2163 {^GIT_INDEX_FILE$
} -
2164 {^GIT_OBJECT_DIRECTORY$
} -
2165 {^GIT_ALTERNATE_OBJECT_DIRECTORIES$
} -
2167 {^GIT_EXTERNAL_DIFF$
} -
2171 {^GIT_CONFIG_LOCAL$
} -
2172 {^GIT_
(AUTHOR|COMMITTER
)_DATE$
} {
2173 append msg
" - $name\n"
2176 {^GIT_
(AUTHOR|COMMITTER
)_
(NAME|EMAIL
)$
} {
2177 append msg
" - $name\n"
2179 set suggest_user
$name
2183 if {$ignored_env > 0} {
2185 This is due to a known issue with the
2186 Tcl binary distributed by Cygwin."
2188 if {$suggest_user ne
{}} {
2191 A good replacement for $suggest_user
2192 is placing values for the user.name and
2193 user.email settings into your personal
2199 unset ignored_env msg suggest_user name
2202 # -- Only initialize complex UI if we are going to stay running.
2204 if {[is_enabled transport
]} {
2208 populate_branch_menu
2213 # -- Only suggest a gc run if we are going to stay running.
2215 if {[is_enabled multicommit
]} {
2216 set object_limit
2000
2217 if {[is_Windows
]} {set object_limit
200}
2218 regexp
{^
([0-9]+) objects
,} [git count-objects
] _junk objects_current
2219 if {$objects_current >= $object_limit} {
2221 "This repository currently has $objects_current loose objects.
2223 To maintain optimal performance it is strongly recommended that you compress the database when more than $object_limit loose objects exist.
2225 Compress the database now?"] eq
yes} {
2229 unset object_limit _junk objects_current
2232 lock_index begin-read