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 set $i
147 if {![winfo exists
$w.none_r
]} {
148 radiobutton $w.none_r
\
152 grid $w.none_r
-sticky we
-padx {0 5} -columnspan 2
154 $w.none_r configure
-text $text
162 set i
[$w_list curselection
]
164 return [lindex $cur_specs $i 0]
171 expr { return $c_expr }
173 default { error "unknown type of revision" }
177 method pick_tracking_branch
{} {
181 method focus_filter
{} {
182 if {[$w_filter cget
-state] eq
{normal
}} {
187 method get_local_branch
{} {
188 if {$revtype eq
{head
}} {
195 method get_tracking_branch
{} {
196 set i
[$w_list curselection
]
197 if {$i eq
{} ||
$revtype ne
{trck
}} {
200 return [lrange [lindex $cur_specs $i] 1 end
]
203 method get_commit
{} {
208 return [git rev-parse
--verify "$e^0"]
211 method commit_or_die
{} {
212 if {[catch {set new
[get_commit
$this]} err
]} {
214 # Cleanup the not-so-friendly error from rev-parse.
216 regsub {^fatal
:\s
*} $err {} err
217 if {$err eq
{Needed a single revision
}} {
221 set top
[winfo toplevel $w]
222 set msg
"Invalid revision: [get $this]\n\n$err"
226 -title [wm title
$top] \
239 set i
[$w_list curselection
]
241 return [lindex $cur_specs $i 1]
243 error "No revision selected."
251 error "Revision expression is empty."
256 default { error "unknown type of revision" }
260 method _validate
{d S
} {
262 if {[regexp {\s
} $S]} {
265 if {[string length
$S] > 0} {
273 if {[regexp {\s
} $P]} {
280 method _select
{args
} {
281 _rebuild
$this $filter
285 method _rebuild
{pat
} {
288 head
{ set new
$spec_head }
289 trck
{ set new
$spec_trck }
290 tag
{ set new
$spec_tag }
299 if {[$w_list cget
-state] eq
{disabled
}} {
300 $w_list configure
-state normal
309 set txt
[lindex $spec 0]
310 if {$pat eq
{} ||
[string match
$pat $txt]} {
311 lappend cur_specs
$spec
312 $w_list insert end
$txt
316 if {[$w_filter cget
-state] ne
$ste} {
317 $w_list configure
-state $ste
318 $w_filter configure
-state $ste
322 method _delete
{current
} {
323 if {$current eq
$w} {
328 method _sb_set
{sb orient first last
} {
329 set old_focus
[focus -lastfor $w]
331 if {$first == 0 && $last == 1} {
332 if {[winfo exists
$sb]} {
334 if {$old_focus ne
{}} {
342 if {![winfo exists
$sb]} {
343 if {$orient eq
{h
}} {
344 scrollbar $sb -orient h
-command [list $w_list xview
]
345 pack $sb -fill x
-side bottom
-before $w_list
347 scrollbar $sb -orient v
-command [list $w_list yview
]
348 pack $sb -fill y
-side right
-before $w_list
350 if {$old_focus ne
{}} {