Code

git-gui: Maintain remote and source ref for tracking branches
[git.git] / lib / choose_rev.tcl
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
25         }
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
38                 }
39                 trace add variable @c_head write [cb _select head]
40         }
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]
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
63                 }
64                 trace add variable @c_trck write [cb _select trck]
65                 unset nam spec txt
66         }
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         }
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         }
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
107         }
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         }
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         }
131 method get_expr {} {
132         switch -- $revtype {
133         head { return refs/heads/$c_head             }
134         trck { return [lindex $trck_spec($c_trck) 0] }
135         tag  { return refs/tags/$c_tag               }
136         expr { return $c_expr                        }
137         none { return {}                             }
138         default { error "unknown type of revision"   }
139         }
142 method get_commit {} {
143         if {$revtype eq {none}} {
144                 return {}
145         }
146         return [git rev-parse --verify "[get_expr $this]^0"]
149 method _validate {d S} {
150         if {$d == 1} {
151                 if {[regexp {\s} $S]} {
152                         return 0
153                 }
154                 if {[string length $S] > 0} {
155                         set revtype expr
156                 }
157         }
158         return 1
161 method _select {value args} {
162         set revtype $value
165 method _delete {current} {
166         if {$current eq $w} {
167                 delete_this
168         }