summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b1fa2bf)
raw | patch | inline | side by side (parent: b1fa2bf)
author | Shawn O. Pearce <spearce@spearce.org> | |
Wed, 4 Jul 2007 03:33:59 +0000 (23:33 -0400) | ||
committer | Shawn O. Pearce <spearce@spearce.org> | |
Mon, 9 Jul 2007 01:12:47 +0000 (21:12 -0400) |
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>
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>
git-gui.sh | patch | blob | history | |
lib/branch.tcl | patch | blob | history | |
lib/branch_delete.tcl | [new file with mode: 0644] | patch | blob |
lib/choose_rev.tcl | patch | blob | history |
diff --git a/git-gui.sh b/git-gui.sh
index e07f4babd0c6eedb81f0ebd91ace0ab6aa25b0a7..63b2045d96b87b414edfe04dd5f0d951c1f7b233 100755 (executable)
--- a/git-gui.sh
+++ b/git-gui.sh
[.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 e7559f978912c143453391bca98330818cc13394..e56f674c6dc3348d9ee9e23e8424947fa4a321e7 100644 (file)
--- a/lib/branch.tcl
+++ b/lib/branch.tcl
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 <Visibility> "grab $w; focus $w"
- bind $w <Key-Escape> "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
--- /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
+}
+
+}
diff --git a/lib/choose_rev.tcl b/lib/choose_rev.tcl
index 04f77c009296c88093db5eed5ca0b8647440e0c9..01e8efe991599901a5b90b65ec333a3063af635d 100644 (file)
--- a/lib/choose_rev.tcl
+++ b/lib/choose_rev.tcl
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"]
}