1 # git-gui revision chooser
2 # Copyright (C) 2006, 2007 Shawn Pearce
6 image create
photo ::choose_rev::img_find -data {R0lGODlhEAAQAIYAAPwCBCQmJDw
+PBQSFAQCBMza3NTm5MTW1HyChOT29Ozq7MTq7Kze5Kzm7Oz6
/NTy9Iza5GzGzKzS1Nzy9Nz29Kzq9HTGzHTK1Lza3AwKDLzu9JTi7HTW5GTCzITO1Mzq7Hza5FTK1ESyvHzKzKzW3DQyNDyqtDw6PIzW5HzGzAT
+/Dw
+RKyurNTOzMTGxMS
+tJSGdATCxHRydLSqpLymnLSijBweHERCRNze3Pz69PTy9Oze1OTSxOTGrMSqlLy
+vPTu5OzSvMymjNTGvNS
+tMy2pMyunMSefAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAe4gACCAAECA4OIiAIEBQYHBAKJgwIICQoLDA0IkZIECQ4PCxARCwSSAxITFA8VEBYXGBmJAQYLGhUbHB0eH7KIGRIMEBAgISIjJKaIJQQLFxERIialkieUGigpKRoIBCqJKyyLBwvJAioEyoICLS4v6QQwMQQyLuqLli8zNDU2BCf1lN3AkUPHDh49fAQAAEnGD1MCCALZEaSHkIUMBQS8wWMIkSJGhBzBmFEGgRsBUqpMiSgdAD
+BAAAh
/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7
}
8 field w
; # our megawidget path
9 field w_list
; # list of currently filtered specs
10 field w_filter
; # filter entry for $w_list
12 field c_expr
{}; # current revision expression
13 field filter
; # current filter string
14 field revtype head
; # type of revision chosen
15 field cur_specs
[list]; # list of specs for $revtype
16 field spec_head
; # list of all head specs
17 field spec_trck
; # list of all tracking branch specs
18 field spec_tag
; # list of all tag specs
20 constructor new
{path
{title
{}}} {
21 global all_heads current_branch
26 labelframe $w -text $title
30 bind $w <Destroy
> [cb _delete
%W
]
32 radiobutton $w.expr_r
\
33 -text {Revision Expression
:} \
40 -textvariable @c_expr
\
42 -validatecommand [cb _validate
%d
%S
]
43 grid $w.expr_r
$w.expr_t
-sticky we
-padx {0 5}
46 radiobutton $w.types.head_r
\
47 -text {Local Branch
} \
50 pack $w.types.head_r
-side left
51 radiobutton $w.types.trck_r
\
52 -text {Tracking Branch
} \
55 pack $w.types.trck_r
-side left
56 radiobutton $w.types.tag_r
\
60 pack $w.types.tag_r
-side left
61 set w_filter
$w.types.filter
66 -textvariable @filter
\
68 -validatecommand [cb _filter
%P
]
69 pack $w_filter -side right
70 pack [label $w.types.filter_icon
\
71 -image ::choose_rev::img_find \
73 grid $w.types
-sticky we
-padx {0 5} -columnspan 2
82 -exportselection false
\
83 -xscrollcommand [cb _sb_set
$w.
list.sbx h
] \
84 -yscrollcommand [cb _sb_set
$w.
list.sby v
]
85 pack $w_list -fill both
-expand 1
86 grid $w.
list -sticky nswe
-padx {20 5} -columnspan 2
88 grid columnconfigure
$w 1 -weight 1
89 grid rowconfigure
$w 2 -weight 1
91 trace add
variable @revtype write
[cb _select
]
92 bind $w_filter <Key-Return
> [list focus $w_list]\;break
93 bind $w_filter <Key-Down
> [list focus $w_list]
96 foreach name
$all_heads {
97 lappend spec_head
[list $name refs
/heads
/$name]
101 foreach spec
[all_tracking_branches
] {
102 set name
[lindex $spec 0]
103 regsub ^refs
/(heads|remotes
)/ $name {} name
104 lappend spec_trck
[concat $name $spec]
108 foreach name
[load_all_tags
] {
109 lappend spec_tag
[list $name refs
/tags
/$name]
112 if {[llength $spec_head] > 0} { set revtype head
113 } elseif
{[llength $spec_trck] > 0} { set revtype trck
114 } elseif
{[llength $spec_tag ] > 0} { set revtype tag
115 } else { set revtype
expr
118 if {$revtype eq
{head
} && $current_branch ne
{}} {
120 foreach spec
$spec_head {
121 if {[lindex $spec 0] eq
$current_branch} {
122 $w_list selection set $i
133 if {![winfo exists
$w.none_r
]} {
134 radiobutton $w.none_r
\
138 grid $w.none_r
-sticky we
-padx {0 5} -columnspan 2
140 $w.none_r configure
-text $text
148 set i
[$w_list curselection
]
150 return [lindex $cur_specs $i 0]
156 expr { return $c_expr }
158 default { error "unknown type of revision" }
162 method get_tracking_branch
{} {
163 set i
[$w_list curselection
]
164 if {$i eq
{} ||
$revtype ne
{trck
}} {
167 return [lrange [lindex $cur_specs $i] 1 end
]
170 method get_commit
{} {
175 return [git rev-parse
--verify "$e^0"]
178 method commit_or_die
{} {
179 if {[catch {set new
[get_commit
$this]} err
]} {
181 # Cleanup the not-so-friendly error from rev-parse.
183 regsub {^fatal
:\s
*} $err {} err
184 if {$err eq
{Needed a single revision
}} {
188 set top
[winfo toplevel $w]
189 set msg
"Invalid revision: [get $this]\n\n$err"
193 -title [wm title
$top] \
206 set i
[$w_list curselection
]
208 return [lindex $cur_specs $i 1]
210 error "No revision selected."
218 error "Revision expression is empty."
222 default { error "unknown type of revision" }
226 method _validate
{d S
} {
228 if {[regexp {\s
} $S]} {
231 if {[string length
$S] > 0} {
239 if {[regexp {\s
} $P]} {
246 method _select
{args
} {
247 _rebuild
$this $filter
248 if {[$w_filter cget
-state] eq
{normal
}} {
253 method _rebuild
{pat
} {
256 head
{ set new
$spec_head }
257 trck
{ set new
$spec_trck }
258 tag
{ set new
$spec_tag }
266 if {[$w_list cget
-state] eq
{disabled
}} {
267 $w_list configure
-state normal
276 set txt
[lindex $spec 0]
277 if {$pat eq
{} ||
[string match
$pat $txt]} {
278 lappend cur_specs
$spec
279 $w_list insert end
$txt
283 if {[$w_filter cget
-state] ne
$ste} {
284 $w_list configure
-state $ste
285 $w_filter configure
-state $ste
289 method _delete
{current
} {
290 if {$current eq
$w} {
295 method _sb_set
{sb orient first last
} {
296 set old_focus
[focus -lastfor $w]
298 if {$first == 0 && $last == 1} {
299 if {[winfo exists
$sb]} {
301 if {$old_focus ne
{}} {
309 if {![winfo exists
$sb]} {
310 if {$orient eq
{h
}} {
311 scrollbar $sb -orient h
-command [list $w_list xview
]
312 pack $sb -fill x
-side bottom
-before $w_list
314 scrollbar $sb -orient v
-command [list $w_list yview
]
315 pack $sb -fill y
-side right
-before $w_list
317 if {$old_focus ne
{}} {