summaryrefslogtreecommitdiff
path: root/lib/branch_delete.tcl
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2007-07-04 03:33:59 (GMT)
committerShawn O. Pearce <spearce@spearce.org>2007-07-09 01:12:47 (GMT)
commit3206c63d0a365b11a430225a31f6a673f7645c25 (patch)
tree6672c7f03ba361076aac497d131e476711a82317 /lib/branch_delete.tcl
parentb1fa2bfff36933f94dada476ba5b3d3cb894b723 (diff)
downloadgit-3206c63d0a365b11a430225a31f6a673f7645c25.zip
git-3206c63d0a365b11a430225a31f6a673f7645c25.tar.gz
git-3206c63d0a365b11a430225a31f6a673f7645c25.tar.bz2
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 <spearce@spearce.org>
Diffstat (limited to 'lib/branch_delete.tcl')
-rw-r--r--lib/branch_delete.tcl163
1 files changed, 163 insertions, 0 deletions
diff --git a/lib/branch_delete.tcl b/lib/branch_delete.tcl
new file mode 100644
index 0000000..16ca693
--- /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 <<ListboxSelect>> [cb _select]
+ bind $w <Visibility> "
+ grab $w
+ focus $w
+ "
+ bind $w <Key-Escape> [list destroy $w]
+ bind $w <Key-Return> [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
+}
+
+}