git-gui / lib / branch_create.tclon commit Merge branch 'jn/branch-move-to-self' (b2dd021)
   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 use_ttk NS
  20
  21        make_dialog top w
  22        wm withdraw $w
  23        wm title $top [append "[appname] ([reponame]): " [mc "Create Branch"]]
  24        if {$top ne {.}} {
  25                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
  26        }
  27
  28        ${NS}::label $w.header -text [mc "Create New Branch"] \
  29                -font font_uibold -anchor center
  30        pack $w.header -side top -fill x
  31
  32        ${NS}::frame $w.buttons
  33        ${NS}::button $w.buttons.create -text [mc Create] \
  34                -default active \
  35                -command [cb _create]
  36        pack $w.buttons.create -side right
  37        ${NS}::button $w.buttons.cancel -text [mc Cancel] \
  38                -command [list destroy $w]
  39        pack $w.buttons.cancel -side right -padx 5
  40        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
  41
  42        ${NS}::labelframe $w.desc -text [mc "Branch Name"]
  43        ${NS}::radiobutton $w.desc.name_r \
  44                -text [mc "Name:"] \
  45                -value user \
  46                -variable @name_type
  47        if {!$use_ttk} {$w.desc.name_r configure -anchor w}
  48        set w_name $w.desc.name_t
  49        ${NS}::entry $w_name \
  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        ${NS}::radiobutton $w.desc.match_r \
  57                -text [mc "Match Tracking Branch Name"] \
  58                -value match \
  59                -variable @name_type
  60        if {!$use_ttk} {$w.desc.match_r configure -anchor w}
  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 [mc "Starting Revision"]]
  67        pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
  68
  69        ${NS}::labelframe $w.options -text [mc Options]
  70
  71        ${NS}::frame $w.options.merge
  72        ${NS}::label $w.options.merge.l -text [mc "Update Existing Branch:"]
  73        pack $w.options.merge.l -side left
  74        ${NS}::radiobutton $w.options.merge.no \
  75                -text [mc No] \
  76                -value none \
  77                -variable @opt_merge
  78        pack $w.options.merge.no -side left
  79        ${NS}::radiobutton $w.options.merge.ff \
  80                -text [mc "Fast Forward Only"] \
  81                -value ff \
  82                -variable @opt_merge
  83        pack $w.options.merge.ff -side left
  84        ${NS}::radiobutton $w.options.merge.reset \
  85                -text [mc 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        ${NS}::checkbutton $w.options.fetch \
  92                -text [mc "Fetch Tracking Branch"] \
  93                -variable @opt_fetch
  94        pack $w.options.fetch -anchor nw
  95
  96        ${NS}::checkbutton $w.options.checkout \
  97                -text [mc "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        wm deiconify $w
 113        tkwait window $w
 114}
 115
 116method _create {} {
 117        global repo_config
 118        global M1B
 119
 120        set spec [$w_rev get_tracking_branch]
 121        switch -- $name_type {
 122        user {
 123                set newbranch $name
 124        }
 125        match {
 126                if {$spec eq {}} {
 127                        tk_messageBox \
 128                                -icon error \
 129                                -type ok \
 130                                -title [wm title $w] \
 131                                -parent $w \
 132                                -message [mc "Please select a tracking branch."]
 133                        return
 134                }
 135                if {![regsub ^refs/heads/ [lindex $spec 2] {} newbranch]} {
 136                        tk_messageBox \
 137                                -icon error \
 138                                -type ok \
 139                                -title [wm title $w] \
 140                                -parent $w \
 141                                -message [mc "Tracking branch %s is not a branch in the remote repository." [$w get]]
 142                        return
 143                }
 144        }
 145        }
 146
 147        if {$newbranch eq {}
 148                || $newbranch eq $repo_config(gui.newbranchtemplate)} {
 149                tk_messageBox \
 150                        -icon error \
 151                        -type ok \
 152                        -title [wm title $w] \
 153                        -parent $w \
 154                        -message [mc "Please supply a branch name."]
 155                focus $w_name
 156                return
 157        }
 158
 159        if {[catch {git check-ref-format "heads/$newbranch"}]} {
 160                tk_messageBox \
 161                        -icon error \
 162                        -type ok \
 163                        -title [wm title $w] \
 164                        -parent $w \
 165                        -message [mc "'%s' is not an acceptable branch name." $newbranch]
 166                focus $w_name
 167                return
 168        }
 169
 170        if {$spec ne {} && $opt_fetch} {
 171                set new {}
 172        } elseif {[catch {set new [$w_rev commit_or_die]}]} {
 173                return
 174        }
 175
 176        set co [::checkout_op::new \
 177                [$w_rev get] \
 178                $new \
 179                refs/heads/$newbranch]
 180        $co parent $w
 181        $co enable_create   1
 182        $co enable_merge    $opt_merge
 183        $co enable_checkout $opt_checkout
 184        if {$spec ne {} && $opt_fetch} {
 185                $co enable_fetch $spec
 186        }
 187        if {$spec ne {}} {
 188                $co remote_source $spec
 189        }
 190
 191        if {[$co run]} {
 192                destroy $w
 193        } else {
 194                focus $w_name
 195        }
 196}
 197
 198method _validate {d S} {
 199        if {$d == 1} {
 200                if {[regexp {[~^:?*\[\0- ]} $S]} {
 201                        return 0
 202                }
 203                if {[string length $S] > 0} {
 204                        set name_type user
 205                }
 206        }
 207        return 1
 208}
 209
 210method _select {args} {
 211        if {$name_type eq {match}} {
 212                $w_rev pick_tracking_branch
 213        }
 214}
 215
 216method _visible {} {
 217        grab $w
 218        if {$name_type eq {user}} {
 219                $w_name icursor end
 220                focus $w_name
 221        }
 222}
 223
 224}