git-gui: Allow users to match remote branch names locally
[git] / lib / choose_rev.tcl
1 # git-gui revision chooser
2 # Copyright (C) 2006, 2007 Shawn Pearce
3
4 class choose_rev {
5
6 field w               ; # our megawidget path
7 field revtype       {}; # type of revision chosen
8
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
13
14 field trck_spec       ; # array of specifications
15
16 constructor new {path {title {}}} {
17         global all_heads current_branch
18
19         set w $path
20
21         if {$title ne {}} {
22                 labelframe $w -text $title
23         } else {
24                 frame $w
25         }
26         bind $w <Destroy> [cb _delete %W]
27
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
38                 }
39                 trace add variable @c_head write [cb _select head]
40         }
41
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
50                 }
51                 set nam [lsort -unique $nam]
52
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
59
60                 set c_trck [lindex $nam 0]
61                 if {$revtype eq {}} {
62                         set revtype trck
63                 }
64                 trace add variable @c_trck write [cb _select trck]
65                 unset nam spec txt
66         }
67
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
79                 }
80                 trace add variable @c_tag write [cb _select tag]
81         }
82
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
97         }
98
99         grid columnconfigure $w 1 -weight 1
100         return $this
101 }
102
103 method none {text} {
104         if {[winfo exists $w.none_r]} {
105                 $w.none_r configure -text $text
106                 return
107         }
108
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
117         }
118 }
119
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" }
128         }
129 }
130
131 method get_tracking_branch {} {
132         if {$revtype eq {trck}} {
133                 return $trck_spec($c_trck)
134         } else {
135                 return {}
136         }
137 }
138
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"   }
147         }
148 }
149
150 method get_commit {} {
151         if {$revtype eq {none}} {
152                 return {}
153         }
154         return [git rev-parse --verify "[get_expr $this]^0"]
155 }
156
157 method _validate {d S} {
158         if {$d == 1} {
159                 if {[regexp {\s} $S]} {
160                         return 0
161                 }
162                 if {[string length $S] > 0} {
163                         set revtype expr
164                 }
165         }
166         return 1
167 }
168
169 method _select {value args} {
170         set revtype $value
171 }
172
173 method _delete {current} {
174         if {$current eq $w} {
175                 delete_this
176         }
177 }
178
179 }