lib / choose_rev.tclon commit git-gui: Allow users to match remote branch names locally (dd87efc)
   1# git-gui revision chooser
   2# Copyright (C) 2006, 2007 Shawn Pearce
   3
   4class choose_rev {
   5
   6field w               ; # our megawidget path
   7field revtype       {}; # type of revision chosen
   8
   9field c_head        {}; # selected local branch head
  10field c_trck        {}; # selected tracking branch
  11field c_tag         {}; # selected tag
  12field c_expr        {}; # current revision expression
  13
  14field trck_spec       ; # array of specifications
  15
  16constructor 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
 103method 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
 120method 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
 131method get_tracking_branch {} {
 132        if {$revtype eq {trck}} {
 133                return $trck_spec($c_trck)
 134        } else {
 135                return {}
 136        }
 137}
 138
 139method 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
 150method get_commit {} {
 151        if {$revtype eq {none}} {
 152                return {}
 153        }
 154        return [git rev-parse --verify "[get_expr $this]^0"]
 155}
 156
 157method _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
 169method _select {value args} {
 170        set revtype $value
 171}
 172
 173method _delete {current} {
 174        if {$current eq $w} {
 175                delete_this
 176        }
 177}
 178
 179}