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 ## enable verbose loading?
27 if {![catch
{set _verbose
$env(GITGUI_VERBOSE
)}]} {
29 rename auto_load real__auto_load
30 proc auto_load
{name args
} {
31 puts stderr
"auto_load $name"
32 return [uplevel
1 real__auto_load
$name $args]
34 rename
source real__source
36 puts stderr
"source $name"
37 uplevel
1 real__source
$name
41 ######################################################################
43 ## configure our library
45 set oguilib
{@@GITGUI_LIBDIR@@
}
46 set oguirel
{@@GITGUI_RELATIVE@@
}
47 if {$oguirel eq
{1}} {
48 set oguilib
[file dirname [file dirname [file normalize
$argv0]]]
49 set oguilib
[file join $oguilib share git-gui lib
]
50 } elseif
{[string match @@
* $oguirel]} {
51 set oguilib
[file join [file dirname [file normalize
$argv0]] lib
]
53 set idx
[file join $oguilib tclIndex
]
56 if {[gets
$fd] eq
{# Autogenerated by git-gui Makefile}} {
58 while {[gets
$fd n
] >= 0} {
59 if {$n ne
{} && ![string match
#* $n]} {
71 if {[lsearch
-exact $loaded $p] >= 0} continue
73 source [file join $oguilib $p]
78 set auto_path
[concat
[list
$oguilib] $auto_path]
80 unset -nocomplain oguirel idx fd
82 ######################################################################
86 set _appname
[lindex
[file split $argv0] end
]
102 return [eval [concat
[list
file join $_gitdir] $args]]
105 proc gitexec
{args
} {
107 if {$_gitexec eq
{}} {
108 if {[catch
{set _gitexec
[git
--exec-path]} err
]} {
109 error
"Git not installed?\n\n$err"
115 return [eval [concat
[list
file join $_gitexec] $args]]
124 global tcl_platform tk_library
125 if {[tk windowingsystem
] eq
{aqua
}} {
133 if {$tcl_platform(platform
) eq
{windows
}} {
140 global tcl_platform _iscygwin
141 if {$_iscygwin eq
{}} {
142 if {$tcl_platform(platform
) eq
{windows
}} {
143 if {[catch
{set p
[exec cygpath
--windir]} err
]} {
155 proc is_enabled
{option
} {
156 global enabled_options
157 if {[catch
{set on
$enabled_options($option)}]} {return 0}
161 proc enable_option
{option
} {
162 global enabled_options
163 set enabled_options
($option) 1
166 proc disable_option
{option
} {
167 global enabled_options
168 set enabled_options
($option) 0
171 ######################################################################
175 proc is_many_config
{name
} {
176 switch
-glob -- $name {
185 proc is_config_true
{name
} {
187 if {[catch
{set v
$repo_config($name)}]} {
189 } elseif
{$v eq
{true
} ||
$v eq
{1} ||
$v eq
{yes}} {
196 proc load_config
{include_global
} {
197 global repo_config global_config default_config
199 array
unset global_config
200 if {$include_global} {
202 set fd_rc
[open
"| git config --global --list" r
]
203 while {[gets
$fd_rc line
] >= 0} {
204 if {[regexp
{^
([^
=]+)=(.
*)$
} $line line name value
]} {
205 if {[is_many_config
$name]} {
206 lappend global_config
($name) $value
208 set global_config
($name) $value
216 array
unset repo_config
218 set fd_rc
[open
"| git config --list" r
]
219 while {[gets
$fd_rc line
] >= 0} {
220 if {[regexp
{^
([^
=]+)=(.
*)$
} $line line name value
]} {
221 if {[is_many_config
$name]} {
222 lappend repo_config
($name) $value
224 set repo_config
($name) $value
231 foreach name
[array names default_config
] {
232 if {[catch
{set v
$global_config($name)}]} {
233 set global_config
($name) $default_config($name)
235 if {[catch
{set v
$repo_config($name)}]} {
236 set repo_config
($name) $default_config($name)
241 ######################################################################
246 return [eval exec git
$args]
249 auto_load tk_optionMenu
250 rename tk_optionMenu real__tkOptionMenu
251 proc tk_optionMenu
{w varName args
} {
252 set m
[eval real__tkOptionMenu
$w $varName $args]
253 $m configure
-font font_ui
254 $w configure
-font font_ui
258 ######################################################################
262 if {{--version} eq
$argv ||
{version
} eq
$argv} {
263 puts
"git-gui version $appvers"
270 if {[catch
{set v
[git
--version]} err
]} {
271 catch
{wm withdraw .
}
272 error_popup
"Cannot determine Git version:
276 [appname] requires Git $req_maj.$req_min or later."
279 if {[regexp
{^git version
(\d
+)\.
(\d
+)} $v _junk act_maj act_min
]} {
280 if {$act_maj < $req_maj
281 ||
($act_maj == $req_maj && $act_min < $req_min)} {
282 catch
{wm withdraw .
}
283 error_popup
"[appname] requires Git $req_maj.$req_min or later.
289 catch
{wm withdraw .
}
290 error_popup
"Cannot parse Git version string:\n\n$v"
293 unset -nocomplain v _junk act_maj act_min req_maj req_min
295 ######################################################################
300 set _gitdir
$env(GIT_DIR
)
304 set _gitdir
[git rev-parse
--git-dir]
305 set _prefix
[git rev-parse
--show-prefix]
307 catch
{wm withdraw .
}
308 error_popup
"Cannot find the git directory:\n\n$err"
311 if {![file isdirectory
$_gitdir] && [is_Cygwin
]} {
312 catch
{set _gitdir
[exec cygpath
--unix $_gitdir]}
314 if {![file isdirectory
$_gitdir]} {
315 catch
{wm withdraw .
}
316 error_popup
"Git directory not found:\n\n$_gitdir"
319 if {[lindex
[file split $_gitdir] end
] ne
{.git
}} {
320 catch
{wm withdraw .
}
321 error_popup
"Cannot use funny .git directory:\n\n$_gitdir"
324 if {[catch
{cd [file dirname $_gitdir]} err
]} {
325 catch
{wm withdraw .
}
326 error_popup
"No working directory [file dirname $_gitdir]:\n\n$err"
329 set _reponame
[lindex
[file split \
330 [file normalize
[file dirname $_gitdir]]] \
333 ######################################################################
337 set current_diff_path
{}
338 set current_diff_side
{}
339 set diff_actions
[list
]
340 set ui_status_value
{Initializing...
}
344 set MERGE_HEAD
[list
]
347 set current_branch
{}
348 set current_diff_path
{}
349 set selected_commit_type new
351 ######################################################################
359 set disable_on_lock
[list
]
360 set index_lock_type none
362 proc lock_index
{type} {
363 global index_lock_type disable_on_lock
365 if {$index_lock_type eq
{none
}} {
366 set index_lock_type
$type
367 foreach w
$disable_on_lock {
368 uplevel
#0 $w disabled
371 } elseif
{$index_lock_type eq
"begin-$type"} {
372 set index_lock_type
$type
378 proc unlock_index
{} {
379 global index_lock_type disable_on_lock
381 set index_lock_type none
382 foreach w
$disable_on_lock {
387 ######################################################################
391 proc repository_state
{ctvar hdvar mhvar
} {
392 global current_branch
393 upvar
$ctvar ct
$hdvar hd
$mhvar mh
397 if {[catch
{set current_branch
[git symbolic-ref HEAD
]}]} {
398 set current_branch
{}
400 regsub ^refs
/((heads|tags|remotes
)/)? \
406 if {[catch
{set hd
[git rev-parse
--verify HEAD
]}]} {
412 set merge_head
[gitdir MERGE_HEAD
]
413 if {[file exists
$merge_head]} {
415 set fd_mh
[open
$merge_head r
]
416 while {[gets
$fd_mh line
] >= 0} {
427 global PARENT empty_tree
429 set p
[lindex
$PARENT 0]
433 if {$empty_tree eq
{}} {
434 set empty_tree
[git mktree
<< {}]
439 proc rescan
{after
{honor_trustmtime
1}} {
440 global HEAD PARENT MERGE_HEAD commit_type
441 global ui_index ui_workdir ui_status_value ui_comm
442 global rescan_active file_states
445 if {$rescan_active > 0 ||
![lock_index
read]} return
447 repository_state newType newHEAD newMERGE_HEAD
448 if {[string match amend
* $commit_type]
449 && $newType eq
{normal
}
450 && $newHEAD eq
$HEAD} {
454 set MERGE_HEAD
$newMERGE_HEAD
455 set commit_type
$newType
458 array
unset file_states
460 if {![$ui_comm edit modified
]
461 ||
[string trim
[$ui_comm get
0.0 end
]] eq
{}} {
462 if {[load_message GITGUI_MSG
]} {
463 } elseif
{[load_message MERGE_MSG
]} {
464 } elseif
{[load_message SQUASH_MSG
]} {
467 $ui_comm edit modified false
470 if {[is_enabled branch
]} {
475 if {$honor_trustmtime && $repo_config(gui.trustmtime
) eq
{true
}} {
476 rescan_stage2
{} $after
479 set ui_status_value
{Refreshing
file status...
}
480 set cmd
[list git update-index
]
482 lappend cmd
--unmerged
483 lappend cmd
--ignore-missing
484 lappend cmd
--refresh
485 set fd_rf
[open
"| $cmd" r
]
486 fconfigure
$fd_rf -blocking 0 -translation binary
487 fileevent
$fd_rf readable \
488 [list rescan_stage2
$fd_rf $after]
492 proc rescan_stage2
{fd after
} {
493 global ui_status_value
494 global rescan_active buf_rdi buf_rdf buf_rlo
498 if {![eof
$fd]} return
502 set ls_others
[list | git ls-files
--others -z \
503 --exclude-per-directory=.gitignore
]
504 set info_exclude
[gitdir info exclude
]
505 if {[file readable
$info_exclude]} {
506 lappend ls_others
"--exclude-from=$info_exclude"
514 set ui_status_value
{Scanning
for modified files ...
}
515 set fd_di
[open
"| git diff-index --cached -z [PARENT]" r
]
516 set fd_df
[open
"| git diff-files -z" r
]
517 set fd_lo
[open
$ls_others r
]
519 fconfigure
$fd_di -blocking 0 -translation binary
-encoding binary
520 fconfigure
$fd_df -blocking 0 -translation binary
-encoding binary
521 fconfigure
$fd_lo -blocking 0 -translation binary
-encoding binary
522 fileevent
$fd_di readable
[list read_diff_index
$fd_di $after]
523 fileevent
$fd_df readable
[list read_diff_files
$fd_df $after]
524 fileevent
$fd_lo readable
[list read_ls_others
$fd_lo $after]
527 proc load_message
{file} {
531 if {[file isfile
$f]} {
532 if {[catch
{set fd
[open
$f r
]}]} {
535 set content
[string trim
[read $fd]]
537 regsub
-all -line {[ \r\t]+$
} $content {} content
538 $ui_comm delete
0.0 end
539 $ui_comm insert end
$content
545 proc read_diff_index
{fd after
} {
548 append buf_rdi
[read $fd]
550 set n
[string length
$buf_rdi]
552 set z1
[string first
"\0" $buf_rdi $c]
555 set z2
[string first
"\0" $buf_rdi $z1]
559 set i
[split [string range
$buf_rdi $c [expr {$z1 - 2}]] { }]
560 set p
[string range
$buf_rdi $z1 [expr {$z2 - 1}]]
562 [encoding convertfrom
$p] \
564 [list
[lindex
$i 0] [lindex
$i 2]] \
570 set buf_rdi
[string range
$buf_rdi $c end
]
575 rescan_done
$fd buf_rdi
$after
578 proc read_diff_files
{fd after
} {
581 append buf_rdf
[read $fd]
583 set n
[string length
$buf_rdf]
585 set z1
[string first
"\0" $buf_rdf $c]
588 set z2
[string first
"\0" $buf_rdf $z1]
592 set i
[split [string range
$buf_rdf $c [expr {$z1 - 2}]] { }]
593 set p
[string range
$buf_rdf $z1 [expr {$z2 - 1}]]
595 [encoding convertfrom
$p] \
598 [list
[lindex
$i 0] [lindex
$i 2]]
603 set buf_rdf
[string range
$buf_rdf $c end
]
608 rescan_done
$fd buf_rdf
$after
611 proc read_ls_others
{fd after
} {
614 append buf_rlo
[read $fd]
615 set pck
[split $buf_rlo "\0"]
616 set buf_rlo
[lindex
$pck end
]
617 foreach p
[lrange
$pck 0 end-1
] {
618 merge_state
[encoding convertfrom
$p] ?O
620 rescan_done
$fd buf_rlo
$after
623 proc rescan_done
{fd buf after
} {
624 global rescan_active current_diff_path
625 global file_states repo_config
628 if {![eof
$fd]} return
631 if {[incr rescan_active
-1] > 0} return
636 if {$current_diff_path ne
{}} reshow_diff
640 proc prune_selection
{} {
641 global file_states selected_paths
643 foreach path
[array names selected_paths
] {
644 if {[catch
{set still_here
$file_states($path)}]} {
645 unset selected_paths
($path)
650 ######################################################################
654 proc mapicon
{w state path
} {
657 if {[catch
{set r
$all_icons($state$w)}]} {
658 puts
"error: no icon for $w state={$state} $path"
664 proc mapdesc
{state path
} {
667 if {[catch
{set r
$all_descs($state)}]} {
668 puts
"error: no desc for state={$state} $path"
674 proc escape_path
{path
} {
675 regsub
-all {\\} $path "\\\\" path
676 regsub
-all "\n" $path "\\n" path
680 proc short_path
{path
} {
681 return [escape_path
[lindex
[file split $path] end
]]
685 set null_sha1
[string repeat
0 40]
687 proc merge_state
{path new_state
{head_info
{}} {index_info
{}}} {
688 global file_states next_icon_id null_sha1
690 set s0
[string index
$new_state 0]
691 set s1
[string index
$new_state 1]
693 if {[catch
{set info
$file_states($path)}]} {
695 set icon n
[incr next_icon_id
]
697 set state
[lindex
$info 0]
698 set icon
[lindex
$info 1]
699 if {$head_info eq
{}} {set head_info
[lindex
$info 2]}
700 if {$index_info eq
{}} {set index_info
[lindex
$info 3]}
703 if {$s0 eq
{?
}} {set s0
[string index
$state 0]} \
704 elseif
{$s0 eq
{_
}} {set s0 _
}
706 if {$s1 eq
{?
}} {set s1
[string index
$state 1]} \
707 elseif
{$s1 eq
{_
}} {set s1 _
}
709 if {$s0 eq
{A
} && $s1 eq
{_
} && $head_info eq
{}} {
710 set head_info
[list
0 $null_sha1]
711 } elseif
{$s0 ne
{_
} && [string index
$state 0] eq
{_
}
712 && $head_info eq
{}} {
713 set head_info
$index_info
716 set file_states
($path) [list
$s0$s1 $icon \
717 $head_info $index_info \
722 proc display_file_helper
{w path icon_name old_m new_m
} {
726 set lno
[lsearch
-sorted -exact $file_lists($w) $path]
728 set file_lists
($w) [lreplace
$file_lists($w) $lno $lno]
730 $w conf
-state normal
731 $w delete
$lno.0 [expr {$lno + 1}].0
732 $w conf
-state disabled
734 } elseif
{$old_m eq
{_
} && $new_m ne
{_
}} {
735 lappend file_lists
($w) $path
736 set file_lists
($w) [lsort
-unique $file_lists($w)]
737 set lno
[lsearch
-sorted -exact $file_lists($w) $path]
739 $w conf
-state normal
740 $w image create
$lno.0 \
741 -align center
-padx 5 -pady 1 \
743 -image [mapicon
$w $new_m $path]
744 $w insert
$lno.1 "[escape_path $path]\n"
745 $w conf
-state disabled
746 } elseif
{$old_m ne
$new_m} {
747 $w conf
-state normal
748 $w image conf
$icon_name -image [mapicon
$w $new_m $path]
749 $w conf
-state disabled
753 proc display_file
{path state
} {
754 global file_states selected_paths
755 global ui_index ui_workdir
757 set old_m
[merge_state
$path $state]
758 set s
$file_states($path)
759 set new_m
[lindex
$s 0]
760 set icon_name
[lindex
$s 1]
762 set o
[string index
$old_m 0]
763 set n
[string index
$new_m 0]
770 display_file_helper
$ui_index $path $icon_name $o $n
772 if {[string index
$old_m 0] eq
{U
}} {
775 set o
[string index
$old_m 1]
777 if {[string index
$new_m 0] eq
{U
}} {
780 set n
[string index
$new_m 1]
782 display_file_helper
$ui_workdir $path $icon_name $o $n
784 if {$new_m eq
{__
}} {
785 unset file_states
($path)
786 catch
{unset selected_paths
($path)}
790 proc display_all_files_helper
{w path icon_name m
} {
793 lappend file_lists
($w) $path
794 set lno
[expr {[lindex
[split [$w index end
] .
] 0] - 1}]
795 $w image create end \
796 -align center
-padx 5 -pady 1 \
798 -image [mapicon
$w $m $path]
799 $w insert end
"[escape_path $path]\n"
802 proc display_all_files
{} {
803 global ui_index ui_workdir
804 global file_states file_lists
807 $ui_index conf
-state normal
808 $ui_workdir conf
-state normal
810 $ui_index delete
0.0 end
811 $ui_workdir delete
0.0 end
814 set file_lists
($ui_index) [list
]
815 set file_lists
($ui_workdir) [list
]
817 foreach path
[lsort
[array names file_states
]] {
818 set s
$file_states($path)
820 set icon_name
[lindex
$s 1]
822 set s
[string index
$m 0]
823 if {$s ne
{U
} && $s ne
{_
}} {
824 display_all_files_helper
$ui_index $path \
828 if {[string index
$m 0] eq
{U
}} {
831 set s
[string index
$m 1]
834 display_all_files_helper
$ui_workdir $path \
839 $ui_index conf
-state disabled
840 $ui_workdir conf
-state disabled
843 ######################################################################
848 #define mask_width 14
849 #define mask_height 15
850 static unsigned char mask_bits
[] = {
851 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
852 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
853 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f};
856 image create bitmap file_plain
-background white
-foreground black
-data {
857 #define plain_width 14
858 #define plain_height 15
859 static unsigned char plain_bits
[] = {
860 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
861 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10,
862 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f};
863 } -maskdata $filemask
865 image create bitmap file_mod
-background white
-foreground blue
-data {
867 #define mod_height 15
868 static unsigned char mod_bits
[] = {
869 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10,
870 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
871 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
872 } -maskdata $filemask
874 image create bitmap file_fulltick
-background white
-foreground "#007000" -data {
875 #define file_fulltick_width 14
876 #define file_fulltick_height 15
877 static unsigned char file_fulltick_bits
[] = {
878 0xfe, 0x01, 0x02, 0x1a, 0x02, 0x0c, 0x02, 0x0c, 0x02, 0x16, 0x02, 0x16,
879 0x02, 0x13, 0x00, 0x13, 0x86, 0x11, 0x8c, 0x11, 0xd8, 0x10, 0xf2, 0x10,
880 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
881 } -maskdata $filemask
883 image create bitmap file_parttick
-background white
-foreground "#005050" -data {
884 #define parttick_width 14
885 #define parttick_height 15
886 static unsigned char parttick_bits
[] = {
887 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10,
888 0x7a, 0x14, 0x02, 0x16, 0x02, 0x13, 0x8a, 0x11, 0xda, 0x10, 0x72, 0x10,
889 0x22, 0x10, 0x02, 0x10, 0xfe, 0x1f};
890 } -maskdata $filemask
892 image create bitmap file_question
-background white
-foreground black
-data {
893 #define file_question_width 14
894 #define file_question_height 15
895 static unsigned char file_question_bits
[] = {
896 0xfe, 0x01, 0x02, 0x02, 0xe2, 0x04, 0xf2, 0x09, 0x1a, 0x1b, 0x0a, 0x13,
897 0x82, 0x11, 0xc2, 0x10, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, 0x62, 0x10,
898 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
899 } -maskdata $filemask
901 image create bitmap file_removed
-background white
-foreground red
-data {
902 #define file_removed_width 14
903 #define file_removed_height 15
904 static unsigned char file_removed_bits
[] = {
905 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
906 0x1a, 0x16, 0x32, 0x13, 0xe2, 0x11, 0xc2, 0x10, 0xe2, 0x11, 0x32, 0x13,
907 0x1a, 0x16, 0x02, 0x10, 0xfe, 0x1f};
908 } -maskdata $filemask
910 image create bitmap file_merge
-background white
-foreground blue
-data {
911 #define file_merge_width 14
912 #define file_merge_height 15
913 static unsigned char file_merge_bits
[] = {
914 0xfe, 0x01, 0x02, 0x03, 0x62, 0x05, 0x62, 0x09, 0x62, 0x1f, 0x62, 0x10,
915 0xfa, 0x11, 0xf2, 0x10, 0x62, 0x10, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
916 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
917 } -maskdata $filemask
920 #define file_width 18
921 #define file_height 18
922 static unsigned char file_bits
[] = {
923 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00,
924 0x0c, 0x03, 0x00, 0x04, 0xfe, 0x00, 0x06, 0x80, 0x00, 0xff, 0x9f, 0x00,
925 0x03, 0x98, 0x00, 0x02, 0x90, 0x00, 0x06, 0xb0, 0x00, 0x04, 0xa0, 0x00,
926 0x0c, 0xe0, 0x00, 0x08, 0xc0, 0x00, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00,
927 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
929 image create bitmap file_dir
-background white
-foreground blue \
930 -data $file_dir_data -maskdata $file_dir_data
933 set file_uplevel_data
{
936 static unsigned char up_bits
[] = {
937 0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,
938 0xfe, 0x3f, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01,
939 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00};
941 image create bitmap file_uplevel
-background white
-foreground red \
942 -data $file_uplevel_data -maskdata $file_uplevel_data
943 unset file_uplevel_data
945 set ui_index .vpane.files.index.list
946 set ui_workdir .vpane.files.workdir.list
948 set all_icons
(_
$ui_index) file_plain
949 set all_icons
(A
$ui_index) file_fulltick
950 set all_icons
(M
$ui_index) file_fulltick
951 set all_icons
(D
$ui_index) file_removed
952 set all_icons
(U
$ui_index) file_merge
954 set all_icons
(_
$ui_workdir) file_plain
955 set all_icons
(M
$ui_workdir) file_mod
956 set all_icons
(D
$ui_workdir) file_question
957 set all_icons
(U
$ui_workdir) file_merge
958 set all_icons
(O
$ui_workdir) file_plain
960 set max_status_desc
0
964 {_M
"Modified, not staged"}
965 {M_
"Staged for commit"}
966 {MM
"Portions staged for commit"}
967 {MD
"Staged for commit, missing"}
969 {_O
"Untracked, not staged"}
970 {A_
"Staged for commit"}
971 {AM
"Portions staged for commit"}
972 {AD
"Staged for commit, missing"}
975 {D_
"Staged for removal"}
976 {DO
"Staged for removal, still present"}
978 {U_
"Requires merge resolution"}
979 {UU
"Requires merge resolution"}
980 {UM
"Requires merge resolution"}
981 {UD
"Requires merge resolution"}
983 if {$max_status_desc < [string length
[lindex
$i 1]]} {
984 set max_status_desc
[string length
[lindex
$i 1]]
986 set all_descs
([lindex
$i 0]) [lindex
$i 1]
990 ######################################################################
994 proc bind_button3
{w cmd
} {
995 bind $w <Any-Button-3
> $cmd
997 bind $w <Control-Button-1
> $cmd
1001 proc scrollbar2many
{list mode args
} {
1002 foreach w
$list {eval $w $mode $args}
1005 proc many2scrollbar
{list mode sb top bottom
} {
1006 $sb set $top $bottom
1007 foreach w
$list {$w $mode moveto
$top}
1010 proc incr_font_size
{font
{amt
1}} {
1011 set sz
[font configure
$font -size]
1013 font configure
$font -size $sz
1014 font configure
${font}bold
-size $sz
1017 ######################################################################
1021 set starting_gitk_msg
{Starting gitk... please
wait...
}
1023 proc do_gitk
{revs
} {
1024 global env ui_status_value starting_gitk_msg
1026 # -- Always start gitk through whatever we were loaded with. This
1027 # lets us bypass using shell process on Windows systems.
1029 set cmd
[list
[info nameofexecutable
]]
1030 lappend cmd
[gitexec gitk
]
1036 if {[catch
{eval exec $cmd &} err
]} {
1037 error_popup
"Failed to start gitk:\n\n$err"
1039 set ui_status_value
$starting_gitk_msg
1041 if {$ui_status_value eq
$starting_gitk_msg} {
1042 set ui_status_value
{Ready.
}
1051 global ui_comm is_quitting repo_config commit_type
1053 if {$is_quitting} return
1056 if {[winfo exists
$ui_comm]} {
1057 # -- Stash our current commit buffer.
1059 set save
[gitdir GITGUI_MSG
]
1060 set msg
[string trim
[$ui_comm get
0.0 end
]]
1061 regsub
-all -line {[ \r\t]+$
} $msg {} msg
1062 if {(![string match amend
* $commit_type]
1063 ||
[$ui_comm edit modified
])
1066 set fd
[open
$save w
]
1067 puts
-nonewline $fd $msg
1071 catch
{file delete
$save}
1074 # -- Stash our current window geometry into this repository.
1076 set cfg_geometry
[list
]
1077 lappend cfg_geometry
[wm geometry .
]
1078 lappend cfg_geometry
[lindex
[.vpane sash coord
0] 1]
1079 lappend cfg_geometry
[lindex
[.vpane.files sash coord
0] 0]
1080 if {[catch
{set rc_geometry
$repo_config(gui.geometry
)}]} {
1083 if {$cfg_geometry ne
$rc_geometry} {
1084 catch
{git config gui.geometry
$cfg_geometry}
1092 rescan
{set ui_status_value
{Ready.
}}
1099 proc toggle_or_diff
{w x y
} {
1100 global file_states file_lists current_diff_path ui_index ui_workdir
1101 global last_clicked selected_paths
1103 set pos
[split [$w index @
$x,$y] .
]
1104 set lno
[lindex
$pos 0]
1105 set col [lindex
$pos 1]
1106 set path
[lindex
$file_lists($w) [expr {$lno - 1}]]
1112 set last_clicked
[list
$w $lno]
1113 array
unset selected_paths
1114 $ui_index tag remove in_sel
0.0 end
1115 $ui_workdir tag remove in_sel
0.0 end
1118 if {$current_diff_path eq
$path} {
1119 set after
{reshow_diff
;}
1123 if {$w eq
$ui_index} {
1125 "Unstaging [short_path $path] from commit" \
1127 [concat
$after {set ui_status_value
{Ready.
}}]
1128 } elseif
{$w eq
$ui_workdir} {
1130 "Adding [short_path $path]" \
1132 [concat
$after {set ui_status_value
{Ready.
}}]
1135 show_diff
$path $w $lno
1139 proc add_one_to_selection
{w x y
} {
1140 global file_lists last_clicked selected_paths
1142 set lno
[lindex
[split [$w index @
$x,$y] .
] 0]
1143 set path
[lindex
$file_lists($w) [expr {$lno - 1}]]
1149 if {$last_clicked ne
{}
1150 && [lindex
$last_clicked 0] ne
$w} {
1151 array
unset selected_paths
1152 [lindex
$last_clicked 0] tag remove in_sel
0.0 end
1155 set last_clicked
[list
$w $lno]
1156 if {[catch
{set in_sel
$selected_paths($path)}]} {
1160 unset selected_paths
($path)
1161 $w tag remove in_sel
$lno.0 [expr {$lno + 1}].0
1163 set selected_paths
($path) 1
1164 $w tag add in_sel
$lno.0 [expr {$lno + 1}].0
1168 proc add_range_to_selection
{w x y
} {
1169 global file_lists last_clicked selected_paths
1171 if {[lindex
$last_clicked 0] ne
$w} {
1172 toggle_or_diff
$w $x $y
1176 set lno
[lindex
[split [$w index @
$x,$y] .
] 0]
1177 set lc
[lindex
$last_clicked 1]
1186 foreach path
[lrange
$file_lists($w) \
1187 [expr {$begin - 1}] \
1188 [expr {$end - 1}]] {
1189 set selected_paths
($path) 1
1191 $w tag add in_sel
$begin.0 [expr {$end + 1}].0
1194 ######################################################################
1198 set cursor_ptr arrow
1199 font create font_diff
-family Courier
-size 10
1203 eval font configure font_ui
[font actual
[.dummy cget
-font]]
1207 font create font_uibold
1208 font create font_diffbold
1210 foreach class
{Button Checkbutton Entry Label
1211 Labelframe Listbox Menu Message
1213 option add
*$class.font font_ui
1225 proc apply_config
{} {
1226 global repo_config font_descs
1228 foreach option
$font_descs {
1229 set name
[lindex
$option 0]
1230 set font
[lindex
$option 1]
1232 foreach
{cn cv
} $repo_config(gui.
$name) {
1233 font configure
$font $cn $cv
1236 error_popup
"Invalid font specified in gui.$name:\n\n$err"
1238 foreach
{cn cv
} [font configure
$font] {
1239 font configure
${font}bold
$cn $cv
1241 font configure
${font}bold
-weight bold
1245 set default_config
(merge.summary
) false
1246 set default_config
(merge.verbosity
) 2
1247 set default_config
(user.name
) {}
1248 set default_config
(user.email
) {}
1250 set default_config
(gui.pruneduringfetch
) false
1251 set default_config
(gui.trustmtime
) false
1252 set default_config
(gui.diffcontext
) 5
1253 set default_config
(gui.newbranchtemplate
) {}
1254 set default_config
(gui.fontui
) [font configure font_ui
]
1255 set default_config
(gui.fontdiff
) [font configure font_diff
]
1257 {fontui font_ui
{Main Font
}}
1258 {fontdiff font_diff
{Diff
/Console Font
}}
1263 ######################################################################
1265 ## feature option selection
1267 if {[regexp
{^git-
(.
+)$
} [appname
] _junk subcommand
]} {
1272 if {$subcommand eq
{gui.sh
}} {
1275 if {$subcommand eq
{gui
} && [llength
$argv] > 0} {
1276 set subcommand
[lindex
$argv 0]
1277 set argv
[lrange
$argv 1 end
]
1280 enable_option multicommit
1281 enable_option branch
1282 enable_option transport
1284 switch
-- $subcommand {
1287 disable_option multicommit
1288 disable_option branch
1289 disable_option transport
1292 enable_option singlecommit
1294 disable_option multicommit
1295 disable_option branch
1296 disable_option transport
1300 ######################################################################
1308 menu .mbar
-tearoff 0
1309 .mbar add cascade
-label Repository
-menu .mbar.repository
1310 .mbar add cascade
-label Edit
-menu .mbar.edit
1311 if {[is_enabled branch
]} {
1312 .mbar add cascade
-label Branch
-menu .mbar.branch
1314 if {[is_enabled multicommit
] ||
[is_enabled singlecommit
]} {
1315 .mbar add cascade
-label Commit
-menu .mbar.commit
1317 if {[is_enabled transport
]} {
1318 .mbar add cascade
-label Merge
-menu .mbar.merge
1319 .mbar add cascade
-label Fetch
-menu .mbar.fetch
1320 .mbar add cascade
-label Push
-menu .mbar.push
1322 . configure
-menu .mbar
1324 # -- Repository Menu
1326 menu .mbar.repository
1328 .mbar.repository add
command \
1329 -label {Browse Current Branch
} \
1330 -command {browser
::new
$current_branch}
1331 trace add variable current_branch
write ".mbar.repository entryconf [.mbar.repository index last] -label \"Browse \$current_branch\" ;#"
1332 .mbar.repository add separator
1334 .mbar.repository add
command \
1335 -label {Visualize Current Branch
} \
1336 -command {do_gitk
$current_branch}
1337 trace add variable current_branch
write ".mbar.repository entryconf [.mbar.repository index last] -label \"Visualize \$current_branch\" ;#"
1338 .mbar.repository add
command \
1339 -label {Visualize All Branches
} \
1340 -command {do_gitk
--all}
1341 .mbar.repository add separator
1343 if {[is_enabled multicommit
]} {
1344 .mbar.repository add
command -label {Database Statistics
} \
1347 .mbar.repository add
command -label {Compress Database
} \
1350 .mbar.repository add
command -label {Verify Database
} \
1351 -command do_fsck_objects
1353 .mbar.repository add separator
1356 .mbar.repository add
command \
1357 -label {Create Desktop Icon
} \
1358 -command do_cygwin_shortcut
1359 } elseif
{[is_Windows
]} {
1360 .mbar.repository add
command \
1361 -label {Create Desktop Icon
} \
1362 -command do_windows_shortcut
1363 } elseif
{[is_MacOSX
]} {
1364 .mbar.repository add
command \
1365 -label {Create Desktop Icon
} \
1366 -command do_macosx_app
1370 .mbar.repository add
command -label Quit \
1377 .mbar.edit add
command -label Undo \
1378 -command {catch
{[focus
] edit undo
}} \
1380 .mbar.edit add
command -label Redo \
1381 -command {catch
{[focus
] edit redo
}} \
1383 .mbar.edit add separator
1384 .mbar.edit add
command -label Cut \
1385 -command {catch
{tk_textCut
[focus
]}} \
1387 .mbar.edit add
command -label Copy \
1388 -command {catch
{tk_textCopy
[focus
]}} \
1390 .mbar.edit add
command -label Paste \
1391 -command {catch
{tk_textPaste
[focus
]; [focus
] see insert
}} \
1393 .mbar.edit add
command -label Delete \
1394 -command {catch
{[focus
] delete sel.first sel.last
}} \
1396 .mbar.edit add separator
1397 .mbar.edit add
command -label {Select All
} \
1398 -command {catch
{[focus
] tag add sel
0.0 end
}} \
1403 if {[is_enabled branch
]} {
1406 .mbar.branch add
command -label {Create...
} \
1407 -command do_create_branch \
1409 lappend disable_on_lock
[list .mbar.branch entryconf \
1410 [.mbar.branch index last
] -state]
1412 .mbar.branch add
command -label {Delete...
} \
1413 -command do_delete_branch
1414 lappend disable_on_lock
[list .mbar.branch entryconf \
1415 [.mbar.branch index last
] -state]
1417 .mbar.branch add
command -label {Reset...
} \
1418 -command merge
::reset_hard
1419 lappend disable_on_lock
[list .mbar.branch entryconf \
1420 [.mbar.branch index last
] -state]
1425 if {[is_enabled multicommit
] ||
[is_enabled singlecommit
]} {
1428 .mbar.commit add radiobutton \
1429 -label {New Commit
} \
1430 -command do_select_commit_type \
1431 -variable selected_commit_type \
1433 lappend disable_on_lock \
1434 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1436 .mbar.commit add radiobutton \
1437 -label {Amend Last Commit
} \
1438 -command do_select_commit_type \
1439 -variable selected_commit_type \
1441 lappend disable_on_lock \
1442 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1444 .mbar.commit add separator
1446 .mbar.commit add
command -label Rescan \
1447 -command do_rescan \
1449 lappend disable_on_lock \
1450 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1452 .mbar.commit add
command -label {Add To Commit
} \
1453 -command do_add_selection
1454 lappend disable_on_lock \
1455 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1457 .mbar.commit add
command -label {Add Existing To Commit
} \
1458 -command do_add_all \
1460 lappend disable_on_lock \
1461 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1463 .mbar.commit add
command -label {Unstage From Commit
} \
1464 -command do_unstage_selection
1465 lappend disable_on_lock \
1466 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1468 .mbar.commit add
command -label {Revert Changes
} \
1469 -command do_revert_selection
1470 lappend disable_on_lock \
1471 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1473 .mbar.commit add separator
1475 .mbar.commit add
command -label {Sign Off
} \
1476 -command do_signoff \
1479 .mbar.commit add
command -label Commit \
1480 -command do_commit \
1481 -accelerator $M1T-Return
1482 lappend disable_on_lock \
1483 [list .mbar.commit entryconf
[.mbar.commit index last
] -state]
1488 if {[is_enabled branch
]} {
1490 .mbar.merge add
command -label {Local Merge...
} \
1491 -command merge
::dialog
1492 lappend disable_on_lock \
1493 [list .mbar.merge entryconf
[.mbar.merge index last
] -state]
1494 .mbar.merge add
command -label {Abort Merge...
} \
1495 -command merge
::reset_hard
1496 lappend disable_on_lock \
1497 [list .mbar.merge entryconf
[.mbar.merge index last
] -state]
1503 if {[is_enabled transport
]} {
1507 .mbar.push add
command -label {Push...
} \
1508 -command do_push_anywhere
1512 # -- Apple Menu (Mac OS X only)
1514 .mbar add cascade
-label Apple
-menu .mbar.apple
1517 .mbar.apple add
command -label "About [appname]" \
1519 .mbar.apple add
command -label "Options..." \
1524 .mbar.edit add separator
1525 .mbar.edit add
command -label {Options...
} \
1530 if {[file exists
/usr
/local
/miga
/lib
/gui-miga
]
1531 && [file exists .pvcsrc
]} {
1533 global ui_status_value
1534 if {![lock_index update
]} return
1535 set cmd
[list sh
--login -c "/usr/local/miga/lib/gui-miga \"[pwd]\""]
1536 set miga_fd
[open
"|$cmd" r
]
1537 fconfigure
$miga_fd -blocking 0
1538 fileevent
$miga_fd readable
[list miga_done
$miga_fd]
1539 set ui_status_value
{Running miga...
}
1541 proc miga_done
{fd
} {
1546 rescan
[list
set ui_status_value
{Ready.
}]
1549 .mbar add cascade
-label Tools
-menu .mbar.tools
1551 .mbar.tools add
command -label "Migrate" \
1553 lappend disable_on_lock \
1554 [list .mbar.tools entryconf
[.mbar.tools index last
] -state]
1560 .mbar add cascade
-label Help
-menu .mbar.
help
1564 .mbar.
help add
command -label "About [appname]" \
1569 catch
{set browser
$repo_config(instaweb.browser
)}
1570 set doc_path
[file dirname [gitexec
]]
1571 set doc_path
[file join $doc_path Documentation index.html
]
1574 set doc_path
[exec cygpath
--mixed $doc_path]
1577 if {$browser eq
{}} {
1580 } elseif
{[is_Cygwin
]} {
1581 set program_files
[file dirname [exec cygpath
--windir]]
1582 set program_files
[file join $program_files {Program Files
}]
1583 set firefox
[file join $program_files {Mozilla Firefox
} firefox.exe
]
1584 set ie
[file join $program_files {Internet Explorer
} IEXPLORE.EXE
]
1585 if {[file exists
$firefox]} {
1586 set browser
$firefox
1587 } elseif
{[file exists
$ie]} {
1590 unset program_files firefox ie
1594 if {[file isfile
$doc_path]} {
1595 set doc_url
"file:$doc_path"
1597 set doc_url
{http
://www.kernel.org
/pub
/software
/scm
/git
/docs
/}
1600 if {$browser ne
{}} {
1601 .mbar.
help add
command -label {Online Documentation
} \
1602 -command [list
exec $browser $doc_url &]
1604 unset browser doc_path doc_url
1606 # -- Standard bindings
1608 bind .
<Destroy
> do_quit
1609 bind all
<$M1B-Key-q> do_quit
1610 bind all
<$M1B-Key-Q> do_quit
1611 bind all
<$M1B-Key-w> {destroy
[winfo toplevel
%W
]}
1612 bind all
<$M1B-Key-W> {destroy
[winfo toplevel
%W
]}
1614 set subcommand_args
{}
1616 puts stderr
"usage: $::argv0 $::subcommand $::subcommand_args"
1620 # -- Not a normal commit type invocation? Do that instead!
1622 switch
-- $subcommand {
1624 set subcommand_args
{rev?
}
1625 switch
[llength
$argv] {
1627 set current_branch
[git symbolic-ref HEAD
]
1628 regsub ^refs
/((heads|tags|remotes
)/)? \
1629 $current_branch {} current_branch
1632 set current_branch
[lindex
$argv 0]
1636 browser
::new
$current_branch
1640 set subcommand_args
{rev? path?
}
1645 if {$is_path ||
[file exists
$_prefix$a]} {
1646 if {$path ne
{}} usage
1649 } elseif
{$a eq
{--}} {
1651 if {$head ne
{}} usage
1656 } elseif
{$head eq
{}} {
1657 if {$head ne
{}} usage
1666 set current_branch
[git symbolic-ref HEAD
]
1667 regsub ^refs
/((heads|tags|remotes
)/)? \
1668 $current_branch {} current_branch
1670 set current_branch
$head
1673 if {$path eq
{}} usage
1674 blame
::new
$head $path
1679 if {[llength
$argv] != 0} {
1680 puts
-nonewline stderr
"usage: $argv0"
1681 if {$subcommand ne
{gui
} && [appname
] ne
"git-$subcommand"} {
1682 puts
-nonewline stderr
" $subcommand"
1687 # fall through to setup UI for commits
1690 puts stderr
"usage: $argv0 \[{blame|browser|citool}\]"
1701 -text {Current Branch
:} \
1705 -textvariable current_branch \
1708 pack .branch.l1
-side left
1709 pack .branch.cb
-side left
-fill x
1710 pack .branch
-side top
-fill x
1712 # -- Main Window Layout
1714 panedwindow .vpane
-orient vertical
1715 panedwindow .vpane.files
-orient horizontal
1716 .vpane add .vpane.files
-sticky nsew
-height 100 -width 200
1717 pack .vpane
-anchor n
-side top
-fill both
-expand 1
1719 # -- Index File List
1721 frame .vpane.files.index
-height 100 -width 200
1722 label .vpane.files.index.title
-text {Staged Changes
(Will Be Committed
)} \
1724 text
$ui_index -background white
-borderwidth 0 \
1725 -width 20 -height 10 \
1727 -cursor $cursor_ptr \
1728 -xscrollcommand {.vpane.files.index.sx
set} \
1729 -yscrollcommand {.vpane.files.index.sy
set} \
1731 scrollbar .vpane.files.index.sx
-orient h
-command [list
$ui_index xview
]
1732 scrollbar .vpane.files.index.sy
-orient v
-command [list
$ui_index yview
]
1733 pack .vpane.files.index.title
-side top
-fill x
1734 pack .vpane.files.index.sx
-side bottom
-fill x
1735 pack .vpane.files.index.sy
-side right
-fill y
1736 pack
$ui_index -side left
-fill both
-expand 1
1737 .vpane.files add .vpane.files.index
-sticky nsew
1739 # -- Working Directory File List
1741 frame .vpane.files.workdir
-height 100 -width 200
1742 label .vpane.files.workdir.title
-text {Unstaged Changes
(Will Not Be Committed
)} \
1744 text
$ui_workdir -background white
-borderwidth 0 \
1745 -width 20 -height 10 \
1747 -cursor $cursor_ptr \
1748 -xscrollcommand {.vpane.files.workdir.sx
set} \
1749 -yscrollcommand {.vpane.files.workdir.sy
set} \
1751 scrollbar .vpane.files.workdir.sx
-orient h
-command [list
$ui_workdir xview
]
1752 scrollbar .vpane.files.workdir.sy
-orient v
-command [list
$ui_workdir yview
]
1753 pack .vpane.files.workdir.title
-side top
-fill x
1754 pack .vpane.files.workdir.sx
-side bottom
-fill x
1755 pack .vpane.files.workdir.sy
-side right
-fill y
1756 pack
$ui_workdir -side left
-fill both
-expand 1
1757 .vpane.files add .vpane.files.workdir
-sticky nsew
1759 foreach i
[list
$ui_index $ui_workdir] {
1760 $i tag conf in_diff
-font font_uibold
1761 $i tag conf in_sel \
1762 -background [$i cget
-foreground] \
1763 -foreground [$i cget
-background]
1767 # -- Diff and Commit Area
1769 frame .vpane.lower
-height 300 -width 400
1770 frame .vpane.lower.commarea
1771 frame .vpane.lower.
diff -relief sunken
-borderwidth 1
1772 pack .vpane.lower.commarea
-side top
-fill x
1773 pack .vpane.lower.
diff -side bottom
-fill both
-expand 1
1774 .vpane add .vpane.lower
-sticky nsew
1776 # -- Commit Area Buttons
1778 frame .vpane.lower.commarea.buttons
1779 label .vpane.lower.commarea.buttons.l
-text {} \
1782 pack .vpane.lower.commarea.buttons.l
-side top
-fill x
1783 pack .vpane.lower.commarea.buttons
-side left
-fill y
1785 button .vpane.lower.commarea.buttons.rescan
-text {Rescan
} \
1787 pack .vpane.lower.commarea.buttons.rescan
-side top
-fill x
1788 lappend disable_on_lock \
1789 {.vpane.lower.commarea.buttons.rescan conf
-state}
1791 button .vpane.lower.commarea.buttons.incall
-text {Add Existing
} \
1793 pack .vpane.lower.commarea.buttons.incall
-side top
-fill x
1794 lappend disable_on_lock \
1795 {.vpane.lower.commarea.buttons.incall conf
-state}
1797 button .vpane.lower.commarea.buttons.signoff
-text {Sign Off
} \
1799 pack .vpane.lower.commarea.buttons.signoff
-side top
-fill x
1801 button .vpane.lower.commarea.buttons.commit
-text {Commit
} \
1803 pack .vpane.lower.commarea.buttons.commit
-side top
-fill x
1804 lappend disable_on_lock \
1805 {.vpane.lower.commarea.buttons.commit conf
-state}
1807 # -- Commit Message Buffer
1809 frame .vpane.lower.commarea.buffer
1810 frame .vpane.lower.commarea.buffer.header
1811 set ui_comm .vpane.lower.commarea.buffer.t
1812 set ui_coml .vpane.lower.commarea.buffer.header.l
1813 radiobutton .vpane.lower.commarea.buffer.header.new \
1814 -text {New Commit
} \
1815 -command do_select_commit_type \
1816 -variable selected_commit_type \
1818 lappend disable_on_lock \
1819 [list .vpane.lower.commarea.buffer.header.new conf
-state]
1820 radiobutton .vpane.lower.commarea.buffer.header.amend \
1821 -text {Amend Last Commit
} \
1822 -command do_select_commit_type \
1823 -variable selected_commit_type \
1825 lappend disable_on_lock \
1826 [list .vpane.lower.commarea.buffer.header.amend conf
-state]
1830 proc trace_commit_type
{varname args
} {
1831 global ui_coml commit_type
1832 switch
-glob -- $commit_type {
1833 initial
{set txt
{Initial Commit Message
:}}
1834 amend
{set txt
{Amended Commit Message
:}}
1835 amend-initial
{set txt
{Amended Initial Commit Message
:}}
1836 amend-merge
{set txt
{Amended Merge Commit Message
:}}
1837 merge
{set txt
{Merge Commit Message
:}}
1838 * {set txt
{Commit Message
:}}
1840 $ui_coml conf
-text $txt
1842 trace add variable commit_type
write trace_commit_type
1843 pack
$ui_coml -side left
-fill x
1844 pack .vpane.lower.commarea.buffer.header.amend
-side right
1845 pack .vpane.lower.commarea.buffer.header.new
-side right
1847 text
$ui_comm -background white
-borderwidth 1 \
1850 -autoseparators true \
1852 -width 75 -height 9 -wrap none \
1854 -yscrollcommand {.vpane.lower.commarea.buffer.sby
set}
1855 scrollbar .vpane.lower.commarea.buffer.sby \
1856 -command [list
$ui_comm yview
]
1857 pack .vpane.lower.commarea.buffer.header
-side top
-fill x
1858 pack .vpane.lower.commarea.buffer.sby
-side right
-fill y
1859 pack
$ui_comm -side left
-fill y
1860 pack .vpane.lower.commarea.buffer
-side left
-fill y
1862 # -- Commit Message Buffer Context Menu
1864 set ctxm .vpane.lower.commarea.buffer.ctxm
1865 menu
$ctxm -tearoff 0
1868 -command {tk_textCut
$ui_comm}
1871 -command {tk_textCopy
$ui_comm}
1874 -command {tk_textPaste
$ui_comm}
1877 -command {$ui_comm delete sel.first sel.last
}
1880 -label {Select All
} \
1881 -command {focus
$ui_comm;$ui_comm tag add sel
0.0 end
}
1885 $ui_comm tag add sel
0.0 end
1886 tk_textCopy
$ui_comm
1887 $ui_comm tag remove sel
0.0 end
1893 bind_button3
$ui_comm "tk_popup $ctxm %X %Y"
1897 proc trace_current_diff_path
{varname args
} {
1898 global current_diff_path diff_actions file_states
1899 if {$current_diff_path eq
{}} {
1905 set p
$current_diff_path
1906 set s
[mapdesc
[lindex
$file_states($p) 0] $p]
1908 set p
[escape_path
$p]
1912 .vpane.lower.
diff.header.status configure
-text $s
1913 .vpane.lower.
diff.header.
file configure
-text $f
1914 .vpane.lower.
diff.header.path configure
-text $p
1915 foreach w
$diff_actions {
1919 trace add variable current_diff_path
write trace_current_diff_path
1921 frame .vpane.lower.
diff.header
-background orange
1922 label .vpane.lower.
diff.header.status \
1923 -background orange \
1924 -width $max_status_desc \
1927 label .vpane.lower.
diff.header.
file \
1928 -background orange \
1931 label .vpane.lower.
diff.header.path \
1932 -background orange \
1935 pack .vpane.lower.
diff.header.status
-side left
1936 pack .vpane.lower.
diff.header.
file -side left
1937 pack .vpane.lower.
diff.header.path
-fill x
1938 set ctxm .vpane.lower.
diff.header.ctxm
1939 menu
$ctxm -tearoff 0
1947 -- $current_diff_path
1949 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
1950 bind_button3 .vpane.lower.
diff.header.path
"tk_popup $ctxm %X %Y"
1954 frame .vpane.lower.
diff.body
1955 set ui_diff .vpane.lower.
diff.body.t
1956 text
$ui_diff -background white
-borderwidth 0 \
1957 -width 80 -height 15 -wrap none \
1959 -xscrollcommand {.vpane.lower.
diff.body.sbx
set} \
1960 -yscrollcommand {.vpane.lower.
diff.body.sby
set} \
1962 scrollbar .vpane.lower.
diff.body.sbx
-orient horizontal \
1963 -command [list
$ui_diff xview
]
1964 scrollbar .vpane.lower.
diff.body.sby
-orient vertical \
1965 -command [list
$ui_diff yview
]
1966 pack .vpane.lower.
diff.body.sbx
-side bottom
-fill x
1967 pack .vpane.lower.
diff.body.sby
-side right
-fill y
1968 pack
$ui_diff -side left
-fill both
-expand 1
1969 pack .vpane.lower.
diff.header
-side top
-fill x
1970 pack .vpane.lower.
diff.body
-side bottom
-fill both
-expand 1
1972 $ui_diff tag conf d_cr
-elide true
1973 $ui_diff tag conf d_@
-foreground blue
-font font_diffbold
1974 $ui_diff tag conf d_
+ -foreground {#00a000}
1975 $ui_diff tag conf d_-
-foreground red
1977 $ui_diff tag conf d_
++ -foreground {#00a000}
1978 $ui_diff tag conf d_--
-foreground red
1979 $ui_diff tag conf d_
+s \
1980 -foreground {#00a000} \
1981 -background {#e2effa}
1982 $ui_diff tag conf d_-s \
1984 -background {#e2effa}
1985 $ui_diff tag conf d_s
+ \
1986 -foreground {#00a000} \
1988 $ui_diff tag conf d_s- \
1992 $ui_diff tag conf d
<<<<<<< \
1993 -foreground orange \
1995 $ui_diff tag conf d
======= \
1996 -foreground orange \
1998 $ui_diff tag conf d
>>>>>>> \
1999 -foreground orange \
2002 $ui_diff tag raise sel
2004 # -- Diff Body Context Menu
2006 set ctxm .vpane.lower.
diff.body.ctxm
2007 menu
$ctxm -tearoff 0
2010 -command reshow_diff
2011 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2014 -command {tk_textCopy
$ui_diff}
2015 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2017 -label {Select All
} \
2018 -command {focus
$ui_diff;$ui_diff tag add sel
0.0 end
}
2019 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2023 $ui_diff tag add sel
0.0 end
2024 tk_textCopy
$ui_diff
2025 $ui_diff tag remove sel
0.0 end
2027 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2030 -label {Apply
/Reverse Hunk
} \
2031 -command {apply_hunk
$cursorX $cursorY}
2032 set ui_diff_applyhunk
[$ctxm index last
]
2033 lappend diff_actions
[list
$ctxm entryconf
$ui_diff_applyhunk -state]
2036 -label {Decrease Font Size
} \
2037 -command {incr_font_size font_diff
-1}
2038 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2040 -label {Increase Font Size
} \
2041 -command {incr_font_size font_diff
1}
2042 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2045 -label {Show Less Context
} \
2046 -command {if {$repo_config(gui.diffcontext
) >= 2} {
2047 incr repo_config
(gui.diffcontext
) -1
2050 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2052 -label {Show More Context
} \
2054 incr repo_config
(gui.diffcontext
)
2057 lappend diff_actions
[list
$ctxm entryconf
[$ctxm index last
] -state]
2059 $ctxm add
command -label {Options...
} \
2061 bind_button3
$ui_diff "
2064 if {\$ui_index eq \$current_diff_side} {
2065 $ctxm entryconf $ui_diff_applyhunk -label {Unstage Hunk From Commit}
2067 $ctxm entryconf $ui_diff_applyhunk -label {Stage Hunk For Commit}
2069 tk_popup $ctxm %X %Y
2071 unset ui_diff_applyhunk
2075 label .status
-textvariable ui_status_value \
2080 pack .status
-anchor w
-side bottom
-fill x
2085 set gm
$repo_config(gui.geometry
)
2086 wm geometry .
[lindex
$gm 0]
2087 .vpane sash place
0 \
2088 [lindex
[.vpane sash coord
0] 0] \
2090 .vpane.files sash place
0 \
2092 [lindex
[.vpane.files sash coord
0] 1]
2098 bind $ui_comm <$M1B-Key-Return> {do_commit
;break}
2099 bind $ui_comm <$M1B-Key-i> {do_add_all
;break}
2100 bind $ui_comm <$M1B-Key-I> {do_add_all
;break}
2101 bind $ui_comm <$M1B-Key-x> {tk_textCut
%W
;break}
2102 bind $ui_comm <$M1B-Key-X> {tk_textCut
%W
;break}
2103 bind $ui_comm <$M1B-Key-c> {tk_textCopy
%W
;break}
2104 bind $ui_comm <$M1B-Key-C> {tk_textCopy
%W
;break}
2105 bind $ui_comm <$M1B-Key-v> {tk_textPaste
%W
; %W see insert
; break}
2106 bind $ui_comm <$M1B-Key-V> {tk_textPaste
%W
; %W see insert
; break}
2107 bind $ui_comm <$M1B-Key-a> {%W tag add sel
0.0 end
;break}
2108 bind $ui_comm <$M1B-Key-A> {%W tag add sel
0.0 end
;break}
2110 bind $ui_diff <$M1B-Key-x> {tk_textCopy
%W
;break}
2111 bind $ui_diff <$M1B-Key-X> {tk_textCopy
%W
;break}
2112 bind $ui_diff <$M1B-Key-c> {tk_textCopy
%W
;break}
2113 bind $ui_diff <$M1B-Key-C> {tk_textCopy
%W
;break}
2114 bind $ui_diff <$M1B-Key-v> {break}
2115 bind $ui_diff <$M1B-Key-V> {break}
2116 bind $ui_diff <$M1B-Key-a> {%W tag add sel
0.0 end
;break}
2117 bind $ui_diff <$M1B-Key-A> {%W tag add sel
0.0 end
;break}
2118 bind $ui_diff <Key-Up
> {catch
{%W yview scroll
-1 units
};break}
2119 bind $ui_diff <Key-Down
> {catch
{%W yview scroll
1 units
};break}
2120 bind $ui_diff <Key-Left
> {catch
{%W xview scroll
-1 units
};break}
2121 bind $ui_diff <Key-Right
> {catch
{%W xview scroll
1 units
};break}
2122 bind $ui_diff <Key-k
> {catch
{%W yview scroll
-1 units
};break}
2123 bind $ui_diff <Key-j
> {catch
{%W yview scroll
1 units
};break}
2124 bind $ui_diff <Key-h
> {catch
{%W xview scroll
-1 units
};break}
2125 bind $ui_diff <Key-l
> {catch
{%W xview scroll
1 units
};break}
2126 bind $ui_diff <Control-Key-b
> {catch
{%W yview scroll
-1 pages
};break}
2127 bind $ui_diff <Control-Key-f
> {catch
{%W yview scroll
1 pages
};break}
2128 bind $ui_diff <Button-1
> {focus
%W
}
2130 if {[is_enabled branch
]} {
2131 bind .
<$M1B-Key-n> do_create_branch
2132 bind .
<$M1B-Key-N> do_create_branch
2135 bind all
<Key-F5
> do_rescan
2136 bind all
<$M1B-Key-r> do_rescan
2137 bind all
<$M1B-Key-R> do_rescan
2138 bind .
<$M1B-Key-s> do_signoff
2139 bind .
<$M1B-Key-S> do_signoff
2140 bind .
<$M1B-Key-i> do_add_all
2141 bind .
<$M1B-Key-I> do_add_all
2142 bind .
<$M1B-Key-Return> do_commit
2143 foreach i
[list
$ui_index $ui_workdir] {
2144 bind $i <Button-1
> "toggle_or_diff $i %x %y; break"
2145 bind $i <$M1B-Button-1> "add_one_to_selection $i %x %y; break"
2146 bind $i <Shift-Button-1
> "add_range_to_selection $i %x %y; break"
2150 set file_lists
($ui_index) [list
]
2151 set file_lists
($ui_workdir) [list
]
2153 wm title .
"[appname] ([reponame]) [file normalize [file dirname [gitdir]]]"
2154 focus
-force $ui_comm
2156 # -- Warn the user about environmental problems. Cygwin's Tcl
2157 # does *not* pass its env array onto any processes it spawns.
2158 # This means that git processes get none of our environment.
2163 set msg
"Possible environment issues exist.
2165 The following environment variables are probably
2166 going to be ignored by any Git subprocess run
2170 foreach name
[array names env
] {
2171 switch
-regexp -- $name {
2172 {^GIT_INDEX_FILE$
} -
2173 {^GIT_OBJECT_DIRECTORY$
} -
2174 {^GIT_ALTERNATE_OBJECT_DIRECTORIES$
} -
2176 {^GIT_EXTERNAL_DIFF$
} -
2180 {^GIT_CONFIG_LOCAL$
} -
2181 {^GIT_
(AUTHOR|COMMITTER
)_DATE$
} {
2182 append msg
" - $name\n"
2185 {^GIT_
(AUTHOR|COMMITTER
)_
(NAME|EMAIL
)$
} {
2186 append msg
" - $name\n"
2188 set suggest_user
$name
2192 if {$ignored_env > 0} {
2194 This is due to a known issue with the
2195 Tcl binary distributed by Cygwin."
2197 if {$suggest_user ne
{}} {
2200 A good replacement for $suggest_user
2201 is placing values for the user.name and
2202 user.email settings into your personal
2208 unset ignored_env msg suggest_user name
2211 # -- Only initialize complex UI if we are going to stay running.
2213 if {[is_enabled transport
]} {
2217 populate_branch_menu
2222 # -- Only suggest a gc run if we are going to stay running.
2224 if {[is_enabled multicommit
]} {
2225 set object_limit
2000
2226 if {[is_Windows
]} {set object_limit
200}
2227 regexp
{^
([0-9]+) objects
,} [git count-objects
] _junk objects_current
2228 if {$objects_current >= $object_limit} {
2230 "This repository currently has $objects_current loose objects.
2232 To maintain optimal performance it is strongly recommended that you compress the database when more than $object_limit loose objects exist.
2234 Compress the database now?"] eq
yes} {
2238 unset object_limit _junk objects_current
2241 lock_index begin-read