138e84192c9389e240f1833d2b4223b39e1cc880
   1# git-gui branch delete support
   2# Copyright (C) 2007 Shawn Pearce
   3
   4class branch_delete {
   5
   6field w               ; # widget path
   7field w_heads         ; # listbox of local head names
   8field w_check         ; # revision picker for merge test
   9field w_delete        ; # delete button
  10
  11constructor dialog {} {
  12        global all_heads current_branch
  13
  14        make_toplevel top w
  15        wm title $top "[appname] ([reponame]): Delete Branch"
  16        if {$top ne {.}} {
  17                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
  18        }
  19
  20        label $w.header -text {Delete Local Branch} -font font_uibold
  21        pack $w.header -side top -fill x
  22
  23        frame $w.buttons
  24        set w_delete $w.buttons.delete
  25        button $w_delete \
  26                -text Delete \
  27                -default active \
  28                -state disabled \
  29                -command [cb _delete]
  30        pack $w_delete -side right
  31        button $w.buttons.cancel \
  32                -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.list -text {Local Branches}
  38        set w_heads $w.list.l
  39        listbox $w_heads \
  40                -height 10 \
  41                -width 70 \
  42                -selectmode extended \
  43                -exportselection false \
  44                -yscrollcommand [list $w.list.sby set]
  45        scrollbar $w.list.sby -command [list $w.list.l yview]
  46        pack $w.list.sby -side right -fill y
  47        pack $w.list.l -side left -fill both -expand 1
  48        pack $w.list -fill both -expand 1 -pady 5 -padx 5
  49
  50        set w_check [choose_rev::new \
  51                $w.check \
  52                {Delete Only If Merged Into} \
  53                ]
  54        $w_check none {Always (Do not perform merge test.)}
  55        pack $w.check -anchor nw -fill x -pady 5 -padx 5
  56
  57        foreach h $all_heads {
  58                if {$h ne $current_branch} {
  59                        $w_heads insert end $h
  60                }
  61        }
  62
  63        bind $w_heads <<ListboxSelect>> [cb _select]
  64        bind $w <Visibility> "
  65                grab $w
  66                focus $w
  67        "
  68        bind $w <Key-Escape> [list destroy $w]
  69        bind $w <Key-Return> [cb _delete]\;break
  70        tkwait window $w
  71}
  72
  73method _select {} {
  74        if {[$w_heads curselection] eq {}} {
  75                $w_delete configure -state disabled
  76        } else {
  77                $w_delete configure -state normal
  78        }
  79}
  80
  81method _delete {} {
  82        global all_heads
  83
  84        if {[catch {set check_cmt [$w_check commit_or_die]}]} {
  85                return
  86        }
  87
  88        set to_delete [list]
  89        set not_merged [list]
  90        foreach i [$w_heads curselection] {
  91                set b [$w_heads get $i]
  92                if {[catch {
  93                        set o [git rev-parse --verify "refs/heads/$b"]
  94                }]} continue
  95                if {$check_cmt ne {}} {
  96                        if {[catch {set m [git merge-base $o $check_cmt]}]} continue
  97                        if {$o ne $m} {
  98                                lappend not_merged $b
  99                                continue
 100                        }
 101                }
 102                lappend to_delete [list $b $o]
 103        }
 104        if {$not_merged ne {}} {
 105                set msg "The following branches are not completely merged into [$w_check get]:
 106
 107 - [join $not_merged "\n - "]"
 108                tk_messageBox \
 109                        -icon info \
 110                        -type ok \
 111                        -title [wm title $w] \
 112                        -parent $w \
 113                        -message $msg
 114        }
 115        if {$to_delete eq {}} return
 116        if {$check_cmt eq {}} {
 117                set msg {Recovering deleted branches is difficult.
 118
 119Delete the selected branches?}
 120                if {[tk_messageBox \
 121                        -icon warning \
 122                        -type yesno \
 123                        -title [wm title $w] \
 124                        -parent $w \
 125                        -message $msg] ne yes} {
 126                        return
 127                }
 128        }
 129
 130        set failed {}
 131        foreach i $to_delete {
 132                set b [lindex $i 0]
 133                set o [lindex $i 1]
 134                if {[catch {git update-ref -d "refs/heads/$b" $o} err]} {
 135                        append failed " - $b: $err\n"
 136                } else {
 137                        set x [lsearch -sorted -exact $all_heads $b]
 138                        if {$x >= 0} {
 139                                set all_heads [lreplace $all_heads $x $x]
 140                        }
 141                }
 142        }
 143
 144        if {$failed ne {}} {
 145                tk_messageBox \
 146                        -icon error \
 147                        -type ok \
 148                        -title [wm title $w] \
 149                        -parent $w \
 150                        -message "Failed to delete branches:\n$failed"
 151        }
 152
 153        set all_heads [lsort $all_heads]
 154        populate_branch_menu
 155        destroy $w
 156}
 157
 158}