From c5ab47cbe4cf9f2f3068c9bf23a666404b615176 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Sun, 21 Jan 2007 01:31:14 -0500 Subject: [PATCH] git-gui: Implemented create branch GUI. Users may now create new branches by activating the Branch->Create menu item. This opens a dialog which lets the user enter the new branch name and select the starting revision for the new branch. For the starting revision we allow the user to either select from a list of known heads (aka local branches) or to enter an arbitrary SHA1 expression. For either creation technique we run the starting revision through rev-parse to verify it is valid before trying to create the ref with update-ref. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 3 deletions(-) diff --git a/git-gui.sh b/git-gui.sh index 13cd1b9b4a..605fc17dc5 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1622,9 +1622,25 @@ proc load_all_heads {} { set all_heads [lsort $all_heads] } -proc populate_branch_menu {m} { +proc populate_branch_menu {} { global all_heads disable_on_lock + set m .mbar.branch + set last [$m index last] + for {set i 0} {$i <= $last} {incr i} { + if {[$m type $i] eq {separator}} { + $m delete $i last + set new_dol [list] + foreach a $disable_on_lock { + if {[lindex $a 0] ne $m || [lindex $a 2] < $i} { + lappend new_dol $a + } + } + set disable_on_lock $new_dol + break + } + } + $m add separator foreach b $all_heads { $m add radiobutton \ @@ -1638,8 +1654,169 @@ proc populate_branch_menu {m} { } } +proc do_create_branch_action {w} { + global all_heads null_sha1 + global create_branch_checkout create_branch_revtype create_branch_head + + set newbranch [string trim [$w.name.t get 0.0 end]] + if {![catch {exec git show-ref --verify -- "refs/heads/$newbranch"}]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Branch '$newbranch' already exists." + focus $w.name.t + return + } + if {[catch {exec git check-ref-format "heads/$newbranch"}]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "We do not like '$newbranch' as a branch name." + focus $w.name.t + return + } + + set rev {} + switch -- $create_branch_revtype { + head {set rev $create_branch_head} + expression {set rev [string trim [$w.from.exp.t get 0.0 end]]} + } + if {[catch {set cmt [exec git rev-parse --verify "${rev}^0"]}]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Invalid starting revision: $rev" + return + } + set cmd [list git update-ref] + lappend cmd -m + lappend cmd "branch: Created from $rev" + lappend cmd "refs/heads/$newbranch" + lappend cmd $cmt + lappend cmd $null_sha1 + if {[catch {eval exec $cmd} err]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Failed to create '$newbranch'.\n\n$err" + return + } + + lappend all_heads $newbranch + set all_heads [lsort $all_heads] + populate_branch_menu + + destroy $w +} + proc do_create_branch {} { - error "NOT IMPLEMENTED" + global all_heads current_branch + global create_branch_checkout create_branch_revtype create_branch_head + + set create_branch_checkout true + set create_branch_revtype head + set create_branch_head $current_branch + + set w .branch_editor + toplevel $w + wm geometry $w "+[winfo rootx .]+[winfo rooty .]" + + label $w.header -text {Create New Branch} \ + -font font_uibold + pack $w.header -side top -fill x + + frame $w.buttons + button $w.buttons.create -text Create \ + -font font_ui \ + -default active \ + -command [list do_create_branch_action $w] + pack $w.buttons.create -side right + button $w.buttons.cancel -text {Cancel} \ + -font font_ui \ + -command [list destroy $w] + pack $w.buttons.cancel -side right -padx 5 + pack $w.buttons -side bottom -fill x -pady 10 -padx 10 + + labelframe $w.name \ + -text {Branch Description} \ + -font font_ui + label $w.name.l -text {Name:} -font font_ui + text $w.name.t \ + -height 1 \ + -width 40 \ + -font font_ui + bind $w.name.t "focus $w.postActions.checkout;break" + bind $w.name.t "focus $w.from.exp.t;break" + bind $w.name.t "do_create_branch_action $w;break" + bind $w.name.t { + if {{%K} ne {BackSpace} + && {%K} ne {Tab} + && {%K} ne {Escape} + && {%K} ne {Return}} { + if {%k <= 32} break + if {[string first %A {~^:?*[}] >= 0} break + } + } + pack $w.name.l -side left -padx 5 + pack $w.name.t -side left -fill x -expand 1 + pack $w.name -anchor nw -fill x -pady 5 -padx 5 + + labelframe $w.from \ + -text {Starting Revision} \ + -font font_ui + frame $w.from.head + radiobutton $w.from.head.r \ + -text {Local Branch:} \ + -value head \ + -variable create_branch_revtype \ + -font font_ui + eval tk_optionMenu $w.from.head.m create_branch_head $all_heads + pack $w.from.head.r -side left + pack $w.from.head.m -side left + frame $w.from.exp + radiobutton $w.from.exp.r \ + -text {Revision Expression:} \ + -value expression \ + -variable create_branch_revtype \ + -font font_ui + text $w.from.exp.t \ + -height 1 \ + -width 50 \ + -font font_ui + bind $w.from.exp.t "focus $w.name.t;break" + bind $w.from.exp.t "focus $w.postActions.checkout;break" + bind $w.from.exp.t "do_create_branch_action $w;break" + pack $w.from.exp.r -side left + pack $w.from.exp.t -side left -fill x -expand 1 + pack $w.from.head -padx 5 -fill x -expand 1 + pack $w.from.exp -padx 5 -fill x -expand 1 + pack $w.from -anchor nw -fill x -pady 5 -padx 5 + + labelframe $w.postActions \ + -text {Post Creation Actions} \ + -font font_ui + checkbutton $w.postActions.checkout \ + -text {Checkout after creation} \ + -offvalue false \ + -onvalue true \ + -variable create_branch_checkout \ + -font font_ui + pack $w.postActions.checkout -anchor nw + pack $w.postActions -anchor nw -fill x -pady 5 -padx 5 + + bind $w "grab $w; focus $w.name.t" + bind $w "destroy $w" + bind $w "do_create_branch_action $w;break" + wm title $w "[appname] ([reponame]): Create Branch" + tkwait window $w } proc do_delete_branch {} { @@ -3734,7 +3911,7 @@ if {!$single_commit} { load_all_remotes load_all_heads - populate_branch_menu .mbar.branch + populate_branch_menu populate_fetch_menu .mbar.fetch populate_pull_menu .mbar.pull populate_push_menu .mbar.push -- 2.11.4.GIT