7f82424edace4b473977d5fe9d37ee268cb3148f
   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_checkout  1; # automatically checkout the new branch?
  14
  15constructor dialog {} {
  16        global repo_config
  17
  18        make_toplevel top w
  19        wm title $top "[appname] ([reponame]): Create Branch"
  20        if {$top ne {.}} {
  21                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
  22        }
  23
  24        label $w.header -text {Create New Branch} -font font_uibold
  25        pack $w.header -side top -fill x
  26
  27        frame $w.buttons
  28        button $w.buttons.create -text Create \
  29                -default active \
  30                -command [cb _create]
  31        pack $w.buttons.create -side right
  32        button $w.buttons.cancel -text {Cancel} \
  33                -command [list destroy $w]
  34        pack $w.buttons.cancel -side right -padx 5
  35        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
  36
  37        labelframe $w.desc -text {Branch Name}
  38        radiobutton $w.desc.name_r \
  39                -anchor w \
  40                -text {Name:} \
  41                -value user \
  42                -variable @name_type
  43        set w_name $w.desc.name_t
  44        entry $w_name \
  45                -borderwidth 1 \
  46                -relief sunken \
  47                -width 40 \
  48                -textvariable @name \
  49                -validate key \
  50                -validatecommand [cb _validate %d %S]
  51        grid $w.desc.name_r $w_name -sticky we -padx {0 5}
  52
  53        radiobutton $w.desc.match_r \
  54                -anchor w \
  55                -text {Match Tracking Branch Name} \
  56                -value match \
  57                -variable @name_type
  58        grid $w.desc.match_r -sticky we -padx {0 5} -columnspan 2
  59
  60        grid columnconfigure $w.desc 1 -weight 1
  61        pack $w.desc -anchor nw -fill x -pady 5 -padx 5
  62
  63        set w_rev [::choose_rev::new $w.rev {Starting Revision}]
  64        pack $w.rev -anchor nw -fill x -pady 5 -padx 5
  65
  66        labelframe $w.postActions -text {Post Creation Actions}
  67        checkbutton $w.postActions.checkout \
  68                -text {Checkout after creation} \
  69                -variable @opt_checkout
  70        pack $w.postActions.checkout -anchor nw
  71        pack $w.postActions -anchor nw -fill x -pady 5 -padx 5
  72
  73        set name $repo_config(gui.newbranchtemplate)
  74
  75        bind $w <Visibility> "
  76                grab $w
  77                $w_name icursor end
  78                focus $w_name
  79        "
  80        bind $w <Key-Escape> [list destroy $w]
  81        bind $w <Key-Return> [cb _create]\;break
  82        tkwait window $w
  83}
  84
  85method _create {} {
  86        global null_sha1 repo_config
  87        global all_heads
  88
  89        switch -- $name_type {
  90        user {
  91                set newbranch $name
  92        }
  93        match {
  94                set spec [$w_rev get_tracking_branch]
  95                if {$spec eq {}} {
  96                        tk_messageBox \
  97                                -icon error \
  98                                -type ok \
  99                                -title [wm title $w] \
 100                                -parent $w \
 101                                -message "Please select a tracking branch."
 102                        return
 103                }
 104                if {![regsub ^refs/heads/ [lindex $spec 2] {} newbranch]} {
 105                        tk_messageBox \
 106                                -icon error \
 107                                -type ok \
 108                                -title [wm title $w] \
 109                                -parent $w \
 110                                -message "Tracking branch [$w get] is not a branch in the remote repository."
 111                        return
 112                }
 113        }
 114        }
 115
 116        if {$newbranch eq {}
 117                || $newbranch eq $repo_config(gui.newbranchtemplate)} {
 118                tk_messageBox \
 119                        -icon error \
 120                        -type ok \
 121                        -title [wm title $w] \
 122                        -parent $w \
 123                        -message "Please supply a branch name."
 124                focus $w_name
 125                return
 126        }
 127        if {![catch {git show-ref --verify -- "refs/heads/$newbranch"}]} {
 128                tk_messageBox \
 129                        -icon error \
 130                        -type ok \
 131                        -title [wm title $w] \
 132                        -parent $w \
 133                        -message "Branch '$newbranch' already exists."
 134                focus $w_name
 135                return
 136        }
 137        if {[catch {git check-ref-format "heads/$newbranch"}]} {
 138                tk_messageBox \
 139                        -icon error \
 140                        -type ok \
 141                        -title [wm title $w] \
 142                        -parent $w \
 143                        -message "We do not like '$newbranch' as a branch name."
 144                focus $w_name
 145                return
 146        }
 147
 148        if {[catch {set cmt [$w_rev get_commit]}]} {
 149                tk_messageBox \
 150                        -icon error \
 151                        -type ok \
 152                        -title [wm title $w] \
 153                        -parent $w \
 154                        -message "Invalid starting revision: [$w_rev get]"
 155                return
 156        }
 157        if {[catch {
 158                        git update-ref \
 159                                -m "branch: Created from [$w_rev get]" \
 160                                "refs/heads/$newbranch" \
 161                                $cmt \
 162                                $null_sha1
 163                } err]} {
 164                tk_messageBox \
 165                        -icon error \
 166                        -type ok \
 167                        -title [wm title $w] \
 168                        -parent $w \
 169                        -message "Failed to create '$newbranch'.\n\n$err"
 170                return
 171        }
 172
 173        lappend all_heads $newbranch
 174        set all_heads [lsort $all_heads]
 175        populate_branch_menu
 176        destroy $w
 177        if {$opt_checkout} {
 178                switch_branch $newbranch
 179        }
 180}
 181
 182method _validate {d S} {
 183        if {$d == 1} {
 184                if {[regexp {[~^:?*\[\0- ]} $S]} {
 185                        return 0
 186                }
 187                if {[string length $S] > 0} {
 188                        set name_type user
 189                }
 190        }
 191        return 1
 192}
 193
 194}