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 current_branch is_detached
26 labelframe $w -text $title
30 bind $w <Destroy
> [cb _delete
%W
]
33 radiobutton $w.detachedhead_r
\
35 -text {This Detached Checkout
} \
38 grid $w.detachedhead_r
-sticky we
-padx {0 5} -columnspan 2
41 radiobutton $w.expr_r
\
42 -text {Revision Expression
:} \
49 -textvariable @c_expr
\
51 -validatecommand [cb _validate
%d
%S
]
52 grid $w.expr_r
$w.expr_t
-sticky we
-padx {0 5}
55 radiobutton $w.types.head_r
\
56 -text {Local Branch
} \
59 pack $w.types.head_r
-side left
60 radiobutton $w.types.trck_r
\
61 -text {Tracking Branch
} \
64 pack $w.types.trck_r
-side left
65 radiobutton $w.types.tag_r
\
69 pack $w.types.tag_r
-side left
70 set w_filter
$w.types.filter
75 -textvariable @filter
\
77 -validatecommand [cb _filter
%P
]
78 pack $w_filter -side right
79 pack [label $w.types.filter_icon
\
80 -image ::choose_rev::img_find \
82 grid $w.types
-sticky we
-padx {0 5} -columnspan 2
91 -exportselection false
\
92 -xscrollcommand [cb _sb_set
$w.
list.sbx h
] \
93 -yscrollcommand [cb _sb_set
$w.
list.sby v
]
94 pack $w_list -fill both
-expand 1
95 grid $w.
list -sticky nswe
-padx {20 5} -columnspan 2
97 grid columnconfigure
$w 1 -weight 1
99 grid rowconfigure
$w 3 -weight 1
101 grid rowconfigure
$w 2 -weight 1
104 trace add
variable @revtype write
[cb _select
]
105 bind $w_filter <Key-Return
> [list focus $w_list]\;break
106 bind $w_filter <Key-Down
> [list focus $w_list]
109 foreach name
[load_all_heads
] {
110 lappend spec_head
[list $name refs
/heads
/$name]
114 foreach spec
[all_tracking_branches
] {
115 set name
[lindex $spec 0]
116 regsub ^refs
/(heads|remotes
)/ $name {} name
117 lappend spec_trck
[concat $name $spec]
121 foreach name
[load_all_tags
] {
122 lappend spec_tag
[list $name refs
/tags
/$name]
125 if {$is_detached} { set revtype HEAD
126 } elseif
{[llength $spec_head] > 0} { set revtype head
127 } elseif
{[llength $spec_trck] > 0} { set revtype trck
128 } elseif
{[llength $spec_tag ] > 0} { set revtype tag
129 } else { set revtype
expr
132 if {$revtype eq
{head
} && $current_branch ne
{}} {
134 foreach spec
$spec_head {
135 if {[lindex $spec 0] eq
$current_branch} {
136 $w_list selection clear
0 end
137 $w_list selection set $i
148 if {![winfo exists
$w.none_r
]} {
149 radiobutton $w.none_r
\
153 grid $w.none_r
-sticky we
-padx {0 5} -columnspan 2
155 $w.none_r configure
-text $text
163 set i
[$w_list curselection
]
165 return [lindex $cur_specs $i 0]
172 expr { return $c_expr }
174 default { error "unknown type of revision" }
178 method pick_tracking_branch
{} {
182 method focus_filter
{} {
183 if {[$w_filter cget
-state] eq
{normal
}} {
188 method bind_listbox
{event script
} {
189 bind $w_list $event $script
192 method get_local_branch
{} {
193 if {$revtype eq
{head
}} {
200 method get_tracking_branch
{} {
201 set i
[$w_list curselection
]
202 if {$i eq
{} ||
$revtype ne
{trck
}} {
205 return [lrange [lindex $cur_specs $i] 1 end
]
208 method get_commit
{} {
213 return [git rev-parse
--verify "$e^0"]
216 method commit_or_die
{} {
217 if {[catch {set new
[get_commit
$this]} err
]} {
219 # Cleanup the not-so-friendly error from rev-parse.
221 regsub {^fatal
:\s
*} $err {} err
222 if {$err eq
{Needed a single revision
}} {
226 set top
[winfo toplevel $w]
227 set msg
"Invalid revision: [get $this]\n\n$err"
231 -title [wm title
$top] \
244 set i
[$w_list curselection
]
246 return [lindex $cur_specs $i 1]
248 error "No revision selected."
256 error "Revision expression is empty."
261 default { error "unknown type of revision" }
265 method _validate
{d S
} {
267 if {[regexp {\s
} $S]} {
270 if {[string length
$S] > 0} {
278 if {[regexp {\s
} $P]} {
285 method _select
{args
} {
286 _rebuild
$this $filter
290 method _rebuild
{pat
} {
293 head
{ set new
$spec_head }
294 trck
{ set new
$spec_trck }
295 tag
{ set new
$spec_tag }
304 if {[$w_list cget
-state] eq
{disabled
}} {
305 $w_list configure
-state normal
314 set txt
[lindex $spec 0]
315 if {$pat eq
{} ||
[string match
$pat $txt]} {
316 lappend cur_specs
$spec
317 $w_list insert end
$txt
320 if {$cur_specs ne
{}} {
321 $w_list selection clear
0 end
322 $w_list selection set 0
325 if {[$w_filter cget
-state] ne
$ste} {
326 $w_list configure
-state $ste
327 $w_filter configure
-state $ste
331 method _delete
{current
} {
332 if {$current eq
$w} {
337 method _sb_set
{sb orient first last
} {
338 set old_focus
[focus -lastfor $w]
340 if {$first == 0 && $last == 1} {
341 if {[winfo exists
$sb]} {
343 if {$old_focus ne
{}} {
351 if {![winfo exists
$sb]} {
352 if {$orient eq
{h
}} {
353 scrollbar $sb -orient h
-command [list $w_list xview
]
354 pack $sb -fill x
-side bottom
-before $w_list
356 scrollbar $sb -orient v
-command [list $w_list yview
]
357 pack $sb -fill y
-side right
-before $w_list
359 if {$old_focus ne
{}} {