From 3206c63d0a365b11a430225a31f6a673f7645c25 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 3 Jul 2007 23:33:59 -0400 Subject: [PATCH] git-gui: Refactor the delete branch dialog to use class system A simple refactoring of the delete branch dialog to allow use of the class construct to better organize the code and to reuse the revision selection code of our new choose_rev mega-widget. Signed-off-by: Shawn O. Pearce --- git-gui.sh | 2 +- lib/branch.tcl | 164 ------------------------------------------ lib/branch_delete.tcl | 163 +++++++++++++++++++++++++++++++++++++++++ lib/choose_rev.tcl | 21 ++++++ 4 files changed, 185 insertions(+), 165 deletions(-) create mode 100644 lib/branch_delete.tcl diff --git a/git-gui.sh b/git-gui.sh index e07f4babd..63b2045d9 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1507,7 +1507,7 @@ if {[is_enabled branch]} { [.mbar.branch index last] -state] .mbar.branch add command -label {Delete...} \ - -command do_delete_branch + -command branch_delete::dialog lappend disable_on_lock [list .mbar.branch entryconf \ [.mbar.branch index last] -state] diff --git a/lib/branch.tcl b/lib/branch.tcl index e7559f978..e56f674c6 100644 --- a/lib/branch.tcl +++ b/lib/branch.tcl @@ -66,170 +66,6 @@ proc radio_selector {varname value args} { set var $value } -proc do_delete_branch_action {w} { - global all_heads - global delete_branch_checktype delete_branch_head delete_branch_trackinghead - - set check_rev {} - switch -- $delete_branch_checktype { - head {set check_rev $delete_branch_head} - tracking {set check_rev $delete_branch_trackinghead} - always {set check_rev {:none}} - } - if {$check_rev eq {:none}} { - set check_cmt {} - } elseif {[catch {set check_cmt [git rev-parse --verify "${check_rev}^0"]}]} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Invalid check revision: $check_rev" - return - } - - set to_delete [list] - set not_merged [list] - foreach i [$w.list.l curselection] { - set b [$w.list.l get $i] - if {[catch {set o [git rev-parse --verify $b]}]} continue - if {$check_cmt ne {}} { - if {$b eq $check_rev} continue - if {[catch {set m [git merge-base $o $check_cmt]}]} continue - if {$o ne $m} { - lappend not_merged $b - continue - } - } - lappend to_delete [list $b $o] - } - if {$not_merged ne {}} { - set msg "The following branches are not completely merged into $check_rev: - - - [join $not_merged "\n - "]" - tk_messageBox \ - -icon info \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message $msg - } - if {$to_delete eq {}} return - if {$delete_branch_checktype eq {always}} { - set msg {Recovering deleted branches is difficult. - -Delete the selected branches?} - if {[tk_messageBox \ - -icon warning \ - -type yesno \ - -title [wm title $w] \ - -parent $w \ - -message $msg] ne yes} { - return - } - } - - set failed {} - foreach i $to_delete { - set b [lindex $i 0] - set o [lindex $i 1] - if {[catch {git update-ref -d "refs/heads/$b" $o} err]} { - append failed " - $b: $err\n" - } else { - set x [lsearch -sorted -exact $all_heads $b] - if {$x >= 0} { - set all_heads [lreplace $all_heads $x $x] - } - } - } - - if {$failed ne {}} { - tk_messageBox \ - -icon error \ - -type ok \ - -title [wm title $w] \ - -parent $w \ - -message "Failed to delete branches:\n$failed" - } - - set all_heads [lsort $all_heads] - populate_branch_menu - destroy $w -} - -proc do_delete_branch {} { - global all_heads tracking_branches current_branch - global delete_branch_checktype delete_branch_head delete_branch_trackinghead - - set w .branch_editor - toplevel $w - wm geometry $w "+[winfo rootx .]+[winfo rooty .]" - - label $w.header -text {Delete Local Branch} \ - -font font_uibold - pack $w.header -side top -fill x - - frame $w.buttons - button $w.buttons.create -text Delete \ - -command [list do_delete_branch_action $w] - pack $w.buttons.create -side right - button $w.buttons.cancel -text {Cancel} \ - -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.list -text {Local Branches} - listbox $w.list.l \ - -height 10 \ - -width 70 \ - -selectmode extended \ - -yscrollcommand [list $w.list.sby set] - foreach h $all_heads { - if {$h ne $current_branch} { - $w.list.l insert end $h - } - } - scrollbar $w.list.sby -command [list $w.list.l yview] - pack $w.list.sby -side right -fill y - pack $w.list.l -side left -fill both -expand 1 - pack $w.list -fill both -expand 1 -pady 5 -padx 5 - - labelframe $w.validate -text {Delete Only If} - radiobutton $w.validate.head_r \ - -text {Merged Into Local Branch:} \ - -value head \ - -variable delete_branch_checktype - eval tk_optionMenu $w.validate.head_m delete_branch_head $all_heads - grid $w.validate.head_r $w.validate.head_m -sticky w - set all_trackings [all_tracking_branches] - if {$all_trackings ne {}} { - set delete_branch_trackinghead [lindex $all_trackings 0] - radiobutton $w.validate.tracking_r \ - -text {Merged Into Tracking Branch:} \ - -value tracking \ - -variable delete_branch_checktype - eval tk_optionMenu $w.validate.tracking_m \ - delete_branch_trackinghead \ - $all_trackings - grid $w.validate.tracking_r $w.validate.tracking_m -sticky w - } - radiobutton $w.validate.always_r \ - -text {Always (Do not perform merge checks)} \ - -value always \ - -variable delete_branch_checktype - grid $w.validate.always_r -columnspan 2 -sticky w - grid columnconfigure $w.validate 1 -weight 1 - pack $w.validate -anchor nw -fill x -pady 5 -padx 5 - - set delete_branch_head $current_branch - set delete_branch_checktype head - - bind $w "grab $w; focus $w" - bind $w "destroy $w" - wm title $w "[appname] ([reponame]): Delete Branch" - tkwait window $w -} - proc switch_branch {new_branch} { global HEAD commit_type current_branch repo_config diff --git a/lib/branch_delete.tcl b/lib/branch_delete.tcl new file mode 100644 index 000000000..16ca6938b --- /dev/null +++ b/lib/branch_delete.tcl @@ -0,0 +1,163 @@ +# git-gui branch delete support +# Copyright (C) 2007 Shawn Pearce + +class branch_delete { + +field w ; # widget path +field w_heads ; # listbox of local head names +field w_check ; # revision picker for merge test +field w_delete ; # delete button + +constructor dialog {} { + global all_heads current_branch + + make_toplevel top w + wm title $top "[appname] ([reponame]): Delete Branch" + if {$top ne {.}} { + wm geometry $top "+[winfo rootx .]+[winfo rooty .]" + } + + label $w.header -text {Delete Local Branch} -font font_uibold + pack $w.header -side top -fill x + + frame $w.buttons + set w_delete $w.buttons.delete + button $w_delete \ + -text Delete \ + -default active \ + -state disabled \ + -command [cb _delete] + pack $w_delete -side right + button $w.buttons.cancel \ + -text {Cancel} \ + -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.list -text {Local Branches} + set w_heads $w.list.l + listbox $w_heads \ + -height 10 \ + -width 70 \ + -selectmode extended \ + -yscrollcommand [list $w.list.sby set] + scrollbar $w.list.sby -command [list $w.list.l yview] + pack $w.list.sby -side right -fill y + pack $w.list.l -side left -fill both -expand 1 + pack $w.list -fill both -expand 1 -pady 5 -padx 5 + + set w_check [choose_rev::new \ + $w.check \ + {Delete Only If Merged Into} \ + ] + $w_check none {Always (Do not perform merge test.)} + pack $w.check -anchor nw -fill x -pady 5 -padx 5 + + foreach h $all_heads { + if {$h ne $current_branch} { + $w_heads insert end $h + } + } + + bind $w_heads <> [cb _select] + bind $w " + grab $w + focus $w + " + bind $w [list destroy $w] + bind $w [cb _delete]\;break + tkwait window $w +} + +method _select {} { + if {[$w_heads curselection] eq {}} { + $w_delete configure -state disabled + } else { + $w_delete configure -state normal + } +} + +method _delete {} { + global all_heads + + if {[catch {set check_cmt [$w_check get_commit]} err]} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Invalid revision: [$w_check get]" + return + } + + set to_delete [list] + set not_merged [list] + foreach i [$w_heads curselection] { + set b [$w_heads get $i] + if {[catch { + set o [git rev-parse --verify "refs/heads/$b"] + }]} continue + if {$check_cmt ne {}} { + if {[catch {set m [git merge-base $o $check_cmt]}]} continue + if {$o ne $m} { + lappend not_merged $b + continue + } + } + lappend to_delete [list $b $o] + } + if {$not_merged ne {}} { + set msg "The following branches are not completely merged into [$w_check get]: + + - [join $not_merged "\n - "]" + tk_messageBox \ + -icon info \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message $msg + } + if {$to_delete eq {}} return + if {$check_cmt eq {}} { + set msg {Recovering deleted branches is difficult. + +Delete the selected branches?} + if {[tk_messageBox \ + -icon warning \ + -type yesno \ + -title [wm title $w] \ + -parent $w \ + -message $msg] ne yes} { + return + } + } + + set failed {} + foreach i $to_delete { + set b [lindex $i 0] + set o [lindex $i 1] + if {[catch {git update-ref -d "refs/heads/$b" $o} err]} { + append failed " - $b: $err\n" + } else { + set x [lsearch -sorted -exact $all_heads $b] + if {$x >= 0} { + set all_heads [lreplace $all_heads $x $x] + } + } + } + + if {$failed ne {}} { + tk_messageBox \ + -icon error \ + -type ok \ + -title [wm title $w] \ + -parent $w \ + -message "Failed to delete branches:\n$failed" + } + + set all_heads [lsort $all_heads] + populate_branch_menu + destroy $w +} + +} diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl index 04f77c009..01e8efe99 100644 --- a/lib/choose_rev.tcl +++ b/lib/choose_rev.tcl @@ -87,17 +87,38 @@ constructor new {path {title {}}} { return $this } +method none {text} { + if {[winfo exists $w.none_r]} { + $w.none_r configure -text $text + return + } + + radiobutton $w.none_r \ + -anchor w \ + -text $text \ + -value none \ + -variable @revtype + grid $w.none_r -sticky we -padx {0 5} -columnspan 2 + if {$revtype eq {}} { + set revtype none + } +} + method get {} { switch -- $revtype { head { return $c_head } trck { return $c_trck } tag { return $c_tag } expr { return $c_expr } + none { return {} } default { error "unknown type of revision" } } } method get_commit {} { + if {$revtype eq {none}} { + return {} + } set rev [get $this] return [git rev-parse --verify "${rev}^0"] } -- 2.26.2