lib / branch_create.tclon commit git-gui: Automatically backup the user's commit buffer (4578c5c)
   1# git-gui branch create support
   2# Copyright (C) 2006, 2007 Shawn Pearce
   3
   4class branch_create {
   5
   6field w              ; # widget path
   7field w_rev          ; # mega-widget to pick the initial revision
   8field w_name         ; # new branch name widget
   9
  10field name         {}; # name of the branch the user has chosen
  11field name_type  user; # type of branch name to use
  12
  13field opt_merge    ff; # type of merge to apply to existing branch
  14field opt_checkout  1; # automatically checkout the new branch?
  15field opt_fetch     1; # refetch tracking branch if used?
  16field reset_ok      0; # did the user agree to reset?
  17
  18constructor dialog {} {
  19        global repo_config
  20
  21        make_toplevel top w
  22        wm title $top "[appname] ([reponame]): Create Branch"
  23        if {$top ne {.}} {
  24                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
  25        }
  26
  27        label $w.header -text {Create New Branch} -font font_uibold
  28        pack $w.header -side top -fill x
  29
  30        frame $w.buttons
  31        button $w.buttons.create -text Create \
  32                -default active \
  33                -command [cb _create]
  34        pack $w.buttons.create -side right
  35        button $w.buttons.cancel -text {Cancel} \
  36                -command [list destroy $w]
  37        pack $w.buttons.cancel -side right -padx 5
  38        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
  39
  40        labelframe $w.desc -text {Branch Name}
  41        radiobutton $w.desc.name_r \
  42                -anchor w \
  43                -text {Name:} \
  44                -value user \
  45                -variable @name_type
  46        set w_name $w.desc.name_t
  47        entry $w_name \
  48                -borderwidth 1 \
  49                -relief sunken \
  50                -width 40 \
  51                -textvariable @name \
  52                -validate key \
  53                -validatecommand [cb _validate %d %S]
  54        grid $w.desc.name_r $w_name -sticky we -padx {0 5}
  55
  56        radiobutton $w.desc.match_r \
  57                -anchor w \
  58                -text {Match Tracking Branch Name} \
  59                -value match \
  60                -variable @name_type
  61        grid $w.desc.match_r -sticky we -padx {0 5} -columnspan 2
  62
  63        grid columnconfigure $w.desc 1 -weight 1
  64        pack $w.desc -anchor nw -fill x -pady 5 -padx 5
  65
  66        set w_rev [::choose_rev::new $w.rev {Starting Revision}]
  67        pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
  68
  69        labelframe $w.options -text {Options}
  70
  71        frame $w.options.merge
  72        label $w.options.merge.l -text {Update Existing Branch:}
  73        pack $w.options.merge.l -side left
  74        radiobutton $w.options.merge.no \
  75                -text No \
  76                -value none \
  77                -variable @opt_merge
  78        pack $w.options.merge.no -side left
  79        radiobutton $w.options.merge.ff \
  80                -text {Fast Forward Only} \
  81                -value ff \
  82                -variable @opt_merge
  83        pack $w.options.merge.ff -side left
  84        radiobutton $w.options.merge.reset \
  85                -text {Reset} \
  86                -value reset \
  87                -variable @opt_merge
  88        pack $w.options.merge.reset -side left
  89        pack $w.options.merge -anchor nw
  90
  91        checkbutton $w.options.fetch \
  92                -text {Fetch Tracking Branch} \
  93                -variable @opt_fetch
  94        pack $w.options.fetch -anchor nw
  95
  96        checkbutton $w.options.checkout \
  97                -text {Checkout After Creation} \
  98                -variable @opt_checkout
  99        pack $w.options.checkout -anchor nw
 100        pack $w.options -anchor nw -fill x -pady 5 -padx 5
 101
 102        trace add variable @name_type write [cb _select]
 103
 104        set name $repo_config(gui.newbranchtemplate)
 105        if {[is_config_true gui.matchtrackingbranch]} {
 106                set name_type match
 107        }
 108
 109        bind $w <Visibility> [cb _visible]
 110        bind $w <Key-Escape> [list destroy $w]
 111        bind $w <Key-Return> [cb _create]\;break
 112        tkwait window $w
 113}
 114
 115method _create {} {
 116        global repo_config
 117        global M1B
 118
 119        set spec [$w_rev get_tracking_branch]
 120        switch -- $name_type {
 121        user {
 122                set newbranch $name
 123        }
 124        match {
 125                if {$spec eq {}} {
 126                        tk_messageBox \
 127                                -icon error \
 128                                -type ok \
 129                                -title [wm title $w] \
 130                                -parent $w \
 131                                -message "Please select a tracking branch."
 132                        return
 133                }
 134                if {![regsub ^refs/heads/ [lindex $spec 2] {} newbranch]} {
 135                        tk_messageBox \
 136                                -icon error \
 137                                -type ok \
 138                                -title [wm title $w] \
 139                                -parent $w \
 140                                -message "Tracking branch [$w get] is not a branch in the remote repository."
 141                        return
 142                }
 143        }
 144        }
 145
 146        if {$newbranch eq {}
 147                || $newbranch eq $repo_config(gui.newbranchtemplate)} {
 148                tk_messageBox \
 149                        -icon error \
 150                        -type ok \
 151                        -title [wm title $w] \
 152                        -parent $w \
 153                        -message "Please supply a branch name."
 154                focus $w_name
 155                return
 156        }
 157
 158        if {[catch {git check-ref-format "heads/$newbranch"}]} {
 159                tk_messageBox \
 160                        -icon error \
 161                        -type ok \
 162                        -title [wm title $w] \
 163                        -parent $w \
 164                        -message "'$newbranch' is not an acceptable branch name."
 165                focus $w_name
 166                return
 167        }
 168
 169        if {$spec ne {} && $opt_fetch} {
 170                set new {}
 171        } elseif {[catch {set new [$w_rev commit_or_die]}]} {
 172                return
 173        }
 174
 175        set co [::checkout_op::new \
 176                [$w_rev get] \
 177                $new \
 178                refs/heads/$newbranch]
 179        $co parent $w
 180        $co enable_create   1
 181        $co enable_merge    $opt_merge
 182        $co enable_checkout $opt_checkout
 183        if {$spec ne {} && $opt_fetch} {
 184                $co enable_fetch $spec
 185        }
 186
 187        if {[$co run]} {
 188                destroy $w
 189        } else {
 190                focus $w_name
 191        }
 192}
 193
 194method _validate {d S} {
 195        if {$d == 1} {
 196                if {[regexp {[~^:?*\[\0- ]} $S]} {
 197                        return 0
 198                }
 199                if {[string length $S] > 0} {
 200                        set name_type user
 201                }
 202        }
 203        return 1
 204}
 205
 206method _select {args} {
 207        if {$name_type eq {match}} {
 208                $w_rev pick_tracking_branch
 209        }
 210}
 211
 212method _visible {} {
 213        grab $w
 214        if {$name_type eq {user}} {
 215                $w_name icursor end
 216                focus $w_name
 217        }
 218}
 219
 220}