git-gui: Allow users to match remote branch names locally
[git-gui/bertw.git] / lib / choose_rev.tcl
blob8b9241294376497abfac618d700e22dd99115f37
1 # git-gui revision chooser
2 # Copyright (C) 2006, 2007 Shawn Pearce
4 class choose_rev {
6 field w ; # our megawidget path
7 field revtype {}; # type of revision chosen
9 field c_head {}; # selected local branch head
10 field c_trck {}; # selected tracking branch
11 field c_tag {}; # selected tag
12 field c_expr {}; # current revision expression
14 field trck_spec ; # array of specifications
16 constructor new {path {title {}}} {
17 global all_heads current_branch
19 set w $path
21 if {$title ne {}} {
22 labelframe $w -text $title
23 } else {
24 frame $w
26 bind $w <Destroy> [cb _delete %W]
28 if {$all_heads ne {}} {
29 set c_head $current_branch
30 radiobutton $w.head_r \
31 -text {Local Branch:} \
32 -value head \
33 -variable @revtype
34 eval tk_optionMenu $w.head_m @c_head $all_heads
35 grid $w.head_r $w.head_m -sticky w
36 if {$revtype eq {}} {
37 set revtype head
39 trace add variable @c_head write [cb _select head]
42 set trck_list [all_tracking_branches]
43 if {$trck_list ne {}} {
44 set nam [list]
45 foreach spec $trck_list {
46 set txt [lindex $spec 0]
47 regsub ^refs/(heads/|remotes/)? $txt {} txt
48 set trck_spec($txt) $spec
49 lappend nam $txt
51 set nam [lsort -unique $nam]
53 radiobutton $w.trck_r \
54 -text {Tracking Branch:} \
55 -value trck \
56 -variable @revtype
57 eval tk_optionMenu $w.trck_m @c_trck $nam
58 grid $w.trck_r $w.trck_m -sticky w
60 set c_trck [lindex $nam 0]
61 if {$revtype eq {}} {
62 set revtype trck
64 trace add variable @c_trck write [cb _select trck]
65 unset nam spec txt
68 set all_tags [load_all_tags]
69 if {$all_tags ne {}} {
70 set c_tag [lindex $all_tags 0]
71 radiobutton $w.tag_r \
72 -text {Tag:} \
73 -value tag \
74 -variable @revtype
75 eval tk_optionMenu $w.tag_m @c_tag $all_tags
76 grid $w.tag_r $w.tag_m -sticky w
77 if {$revtype eq {}} {
78 set revtype tag
80 trace add variable @c_tag write [cb _select tag]
83 radiobutton $w.expr_r \
84 -text {Revision Expression:} \
85 -value expr \
86 -variable @revtype
87 entry $w.expr_t \
88 -borderwidth 1 \
89 -relief sunken \
90 -width 50 \
91 -textvariable @c_expr \
92 -validate key \
93 -validatecommand [cb _validate %d %S]
94 grid $w.expr_r $w.expr_t -sticky we -padx {0 5}
95 if {$revtype eq {}} {
96 set revtype expr
99 grid columnconfigure $w 1 -weight 1
100 return $this
103 method none {text} {
104 if {[winfo exists $w.none_r]} {
105 $w.none_r configure -text $text
106 return
109 radiobutton $w.none_r \
110 -anchor w \
111 -text $text \
112 -value none \
113 -variable @revtype
114 grid $w.none_r -sticky we -padx {0 5} -columnspan 2
115 if {$revtype eq {}} {
116 set revtype none
120 method get {} {
121 switch -- $revtype {
122 head { return $c_head }
123 trck { return $c_trck }
124 tag { return $c_tag }
125 expr { return $c_expr }
126 none { return {} }
127 default { error "unknown type of revision" }
131 method get_tracking_branch {} {
132 if {$revtype eq {trck}} {
133 return $trck_spec($c_trck)
134 } else {
135 return {}
139 method get_expr {} {
140 switch -- $revtype {
141 head { return refs/heads/$c_head }
142 trck { return [lindex $trck_spec($c_trck) 0] }
143 tag { return refs/tags/$c_tag }
144 expr { return $c_expr }
145 none { return {} }
146 default { error "unknown type of revision" }
150 method get_commit {} {
151 if {$revtype eq {none}} {
152 return {}
154 return [git rev-parse --verify "[get_expr $this]^0"]
157 method _validate {d S} {
158 if {$d == 1} {
159 if {[regexp {\s} $S]} {
160 return 0
162 if {[string length $S] > 0} {
163 set revtype expr
166 return 1
169 method _select {value args} {
170 set revtype $value
173 method _delete {current} {
174 if {$current eq $w} {
175 delete_this