Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 1 | # git-gui remote branch deleting support |
| 2 | # Copyright (C) 2007 Shawn Pearce |
| 3 | |
| 4 | class remote_branch_delete { |
| 5 | |
| 6 | field w |
| 7 | field head_m |
| 8 | |
| 9 | field urltype {url} |
| 10 | field remote {} |
| 11 | field url {} |
| 12 | |
| 13 | field checktype {head} |
| 14 | field check_head {} |
| 15 | |
| 16 | field status {} |
| 17 | field idle_id {} |
| 18 | field full_list {} |
| 19 | field head_list {} |
| 20 | field active_ls {} |
| 21 | field head_cache |
| 22 | field full_cache |
| 23 | field cached |
| 24 | |
| 25 | constructor dialog {} { |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 26 | global all_remotes M1B use_ttk NS |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 27 | |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 28 | make_dialog top w |
Vasco Almeida | a3d97af | 2016-05-08 10:52:57 +0000 | [diff] [blame] | 29 | wm title $top [mc "%s (%s): Delete Branch Remotely" [appname] [reponame]] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 30 | if {$top ne {.}} { |
| 31 | wm geometry $top "+[winfo rootx .]+[winfo rooty .]" |
| 32 | } |
| 33 | |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 34 | ${NS}::label $w.header -text [mc "Delete Branch Remotely"] \ |
| 35 | -font font_uibold -anchor center |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 36 | pack $w.header -side top -fill x |
| 37 | |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 38 | ${NS}::frame $w.buttons |
| 39 | ${NS}::button $w.buttons.delete -text [mc Delete] \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 40 | -default active \ |
| 41 | -command [cb _delete] |
| 42 | pack $w.buttons.delete -side right |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 43 | ${NS}::button $w.buttons.cancel -text [mc "Cancel"] \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 44 | -command [list destroy $w] |
| 45 | pack $w.buttons.cancel -side right -padx 5 |
| 46 | pack $w.buttons -side bottom -fill x -pady 10 -padx 10 |
| 47 | |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 48 | ${NS}::labelframe $w.dest -text [mc "From Repository"] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 49 | if {$all_remotes ne {}} { |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 50 | ${NS}::radiobutton $w.dest.remote_r \ |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 51 | -text [mc "Remote:"] \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 52 | -value remote \ |
| 53 | -variable @urltype |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 54 | if {$use_ttk} { |
| 55 | ttk::combobox $w.dest.remote_m -textvariable @remote \ |
| 56 | -values $all_remotes -state readonly |
| 57 | } else { |
| 58 | eval tk_optionMenu $w.dest.remote_m @remote $all_remotes |
| 59 | } |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 60 | grid $w.dest.remote_r $w.dest.remote_m -sticky w |
| 61 | if {[lsearch -sorted -exact $all_remotes origin] != -1} { |
| 62 | set remote origin |
| 63 | } else { |
| 64 | set remote [lindex $all_remotes 0] |
| 65 | } |
| 66 | set urltype remote |
| 67 | trace add variable @remote write [cb _write_remote] |
| 68 | } else { |
| 69 | set urltype url |
| 70 | } |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 71 | ${NS}::radiobutton $w.dest.url_r \ |
Petr Baudis | 4259568 | 2008-09-25 00:12:50 +0200 | [diff] [blame] | 72 | -text [mc "Arbitrary Location:"] \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 73 | -value url \ |
| 74 | -variable @urltype |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 75 | ${NS}::entry $w.dest.url_t \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 76 | -width 50 \ |
| 77 | -textvariable @url \ |
| 78 | -validate key \ |
| 79 | -validatecommand { |
| 80 | if {%d == 1 && [regexp {\s} %S]} {return 0} |
| 81 | return 1 |
| 82 | } |
| 83 | trace add variable @url write [cb _write_url] |
| 84 | grid $w.dest.url_r $w.dest.url_t -sticky we -padx {0 5} |
| 85 | grid columnconfigure $w.dest 1 -weight 1 |
| 86 | pack $w.dest -anchor nw -fill x -pady 5 -padx 5 |
| 87 | |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 88 | ${NS}::labelframe $w.heads -text [mc "Branches"] |
| 89 | slistbox $w.heads.l \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 90 | -height 10 \ |
| 91 | -width 70 \ |
| 92 | -listvariable @head_list \ |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 93 | -selectmode extended |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 94 | |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 95 | ${NS}::frame $w.heads.footer |
| 96 | ${NS}::label $w.heads.footer.status \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 97 | -textvariable @status \ |
| 98 | -anchor w \ |
| 99 | -justify left |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 100 | ${NS}::button $w.heads.footer.rescan \ |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 101 | -text [mc "Rescan"] \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 102 | -command [cb _rescan] |
Shawn O. Pearce | 1eb96a2 | 2007-07-04 14:06:28 -0400 | [diff] [blame] | 103 | pack $w.heads.footer.status -side left -fill x |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 104 | pack $w.heads.footer.rescan -side right |
| 105 | |
Shawn O. Pearce | 1eb96a2 | 2007-07-04 14:06:28 -0400 | [diff] [blame] | 106 | pack $w.heads.footer -side bottom -fill x |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 107 | pack $w.heads.l -side left -fill both -expand 1 |
| 108 | pack $w.heads -fill both -expand 1 -pady 5 -padx 5 |
| 109 | |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 110 | ${NS}::labelframe $w.validate -text [mc "Delete Only If"] |
| 111 | ${NS}::radiobutton $w.validate.head_r \ |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 112 | -text [mc "Merged Into:"] \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 113 | -value head \ |
| 114 | -variable @checktype |
| 115 | set head_m [tk_optionMenu $w.validate.head_m @check_head {}] |
| 116 | trace add variable @head_list write [cb _write_head_list] |
| 117 | trace add variable @check_head write [cb _write_check_head] |
| 118 | grid $w.validate.head_r $w.validate.head_m -sticky w |
Pat Thoyts | c80d7be | 2010-01-26 00:05:31 +0000 | [diff] [blame] | 119 | ${NS}::radiobutton $w.validate.always_r \ |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 120 | -text [mc "Always (Do not perform merge checks)"] \ |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 121 | -value always \ |
| 122 | -variable @checktype |
| 123 | grid $w.validate.always_r -columnspan 2 -sticky w |
| 124 | grid columnconfigure $w.validate 1 -weight 1 |
| 125 | pack $w.validate -anchor nw -fill x -pady 5 -padx 5 |
| 126 | |
| 127 | trace add variable @urltype write [cb _write_urltype] |
| 128 | _rescan $this |
| 129 | |
| 130 | bind $w <Key-F5> [cb _rescan] |
| 131 | bind $w <$M1B-Key-r> [cb _rescan] |
| 132 | bind $w <$M1B-Key-R> [cb _rescan] |
| 133 | bind $w <Key-Return> [cb _delete] |
| 134 | bind $w <Key-Escape> [list destroy $w] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 135 | return $w |
| 136 | } |
| 137 | |
| 138 | method _delete {} { |
| 139 | switch $urltype { |
| 140 | remote {set uri $remote} |
| 141 | url {set uri $url} |
| 142 | } |
| 143 | |
| 144 | set cache $urltype:$uri |
| 145 | set crev {} |
| 146 | if {$checktype eq {head}} { |
| 147 | if {$check_head eq {}} { |
| 148 | tk_messageBox \ |
| 149 | -icon error \ |
| 150 | -type ok \ |
| 151 | -title [wm title $w] \ |
| 152 | -parent $w \ |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 153 | -message [mc "A branch is required for 'Merged Into'."] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 154 | return |
| 155 | } |
| 156 | set crev $full_cache("$cache\nrefs/heads/$check_head") |
| 157 | } |
| 158 | |
| 159 | set not_merged [list] |
| 160 | set need_fetch 0 |
| 161 | set have_selection 0 |
| 162 | set push_cmd [list git push] |
| 163 | lappend push_cmd -v |
| 164 | lappend push_cmd $uri |
| 165 | |
| 166 | foreach i [$w.heads.l curselection] { |
| 167 | set ref [lindex $full_list $i] |
| 168 | if {$crev ne {}} { |
| 169 | set obj $full_cache("$cache\n$ref") |
| 170 | if {[catch {set m [git merge-base $obj $crev]}]} { |
| 171 | set need_fetch 1 |
| 172 | set m {} |
| 173 | } |
| 174 | if {$obj ne $m} { |
| 175 | lappend not_merged [lindex $head_list $i] |
| 176 | continue |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | lappend push_cmd :$ref |
| 181 | set have_selection 1 |
| 182 | } |
| 183 | |
| 184 | if {$not_merged ne {}} { |
Michele Ballabio | c8c4854 | 2007-09-13 15:19:05 +0200 | [diff] [blame] | 185 | set msg [mc "The following branches are not completely merged into %s: |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 186 | |
Michele Ballabio | c8c4854 | 2007-09-13 15:19:05 +0200 | [diff] [blame] | 187 | - %s" $check_head [join $not_merged "\n - "]] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 188 | |
| 189 | if {$need_fetch} { |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 190 | append msg "\n\n" [mc "One or more of the merge tests failed because you have not fetched the necessary commits. Try fetching from %s first." $uri] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 191 | } |
| 192 | |
| 193 | tk_messageBox \ |
| 194 | -icon info \ |
| 195 | -type ok \ |
| 196 | -title [wm title $w] \ |
| 197 | -parent $w \ |
| 198 | -message $msg |
| 199 | if {!$have_selection} return |
| 200 | } |
| 201 | |
| 202 | if {!$have_selection} { |
| 203 | tk_messageBox \ |
| 204 | -icon error \ |
| 205 | -type ok \ |
| 206 | -title [wm title $w] \ |
| 207 | -parent $w \ |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 208 | -message [mc "Please select one or more branches to delete."] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 209 | return |
| 210 | } |
| 211 | |
Heiko Voigt | 2112be7 | 2009-06-15 23:19:56 +0200 | [diff] [blame] | 212 | if {$checktype ne {head}} { |
| 213 | if {[tk_messageBox \ |
| 214 | -icon warning \ |
| 215 | -type yesno \ |
| 216 | -title [wm title $w] \ |
| 217 | -parent $w \ |
| 218 | -message [mc "Recovering deleted branches is difficult.\n\nDelete the selected branches?"]] ne yes} { |
| 219 | return |
| 220 | } |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 221 | } |
| 222 | |
| 223 | destroy $w |
| 224 | |
| 225 | set cons [console::new \ |
| 226 | "push $uri" \ |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 227 | [mc "Deleting branches from %s" $uri]] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 228 | console::exec $cons $push_cmd |
| 229 | } |
| 230 | |
| 231 | method _rescan {{force 1}} { |
| 232 | switch $urltype { |
| 233 | remote {set uri $remote} |
| 234 | url {set uri $url} |
| 235 | } |
| 236 | |
| 237 | if {$force} { |
| 238 | unset -nocomplain cached($urltype:$uri) |
| 239 | } |
| 240 | |
| 241 | if {$idle_id ne {}} { |
| 242 | after cancel $idle_id |
| 243 | set idle_id {} |
| 244 | } |
| 245 | |
| 246 | _load $this $urltype:$uri $uri |
| 247 | } |
| 248 | |
| 249 | method _write_remote {args} { set urltype remote } |
| 250 | method _write_url {args} { set urltype url } |
| 251 | method _write_check_head {args} { set checktype head } |
| 252 | |
| 253 | method _write_head_list {args} { |
Heiko Voigt | 9d04278 | 2011-02-12 17:44:58 +0100 | [diff] [blame] | 254 | global current_branch _last_merged_branch |
Heiko Voigt | c0d1532 | 2009-12-04 22:26:48 +0100 | [diff] [blame] | 255 | |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 256 | $head_m delete 0 end |
| 257 | foreach abr $head_list { |
| 258 | $head_m insert end radiobutton \ |
| 259 | -label $abr \ |
| 260 | -value $abr \ |
| 261 | -variable @check_head |
| 262 | } |
| 263 | if {[lsearch -exact -sorted $head_list $check_head] < 0} { |
Heiko Voigt | c0d1532 | 2009-12-04 22:26:48 +0100 | [diff] [blame] | 264 | if {[lsearch -exact -sorted $head_list $current_branch] < 0} { |
| 265 | set check_head {} |
| 266 | } else { |
| 267 | set check_head $current_branch |
| 268 | } |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 269 | } |
Heiko Voigt | 9d04278 | 2011-02-12 17:44:58 +0100 | [diff] [blame] | 270 | set lmb [lsearch -exact -sorted $head_list $_last_merged_branch] |
| 271 | if {$lmb >= 0} { |
| 272 | $w.heads.l conf -state normal |
| 273 | $w.heads.l select set $lmb |
| 274 | $w.heads.l yview $lmb |
| 275 | $w.heads.l conf -state disabled |
| 276 | } |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 277 | } |
| 278 | |
| 279 | method _write_urltype {args} { |
| 280 | if {$urltype eq {url}} { |
| 281 | if {$idle_id ne {}} { |
| 282 | after cancel $idle_id |
| 283 | } |
| 284 | _load $this none: {} |
| 285 | set idle_id [after 1000 [cb _rescan 0]] |
| 286 | } else { |
| 287 | _rescan $this 0 |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | method _load {cache uri} { |
| 292 | if {$active_ls ne {}} { |
| 293 | catch {close $active_ls} |
| 294 | } |
| 295 | |
| 296 | if {$uri eq {}} { |
| 297 | $w.heads.l conf -state disabled |
| 298 | set head_list [list] |
| 299 | set full_list [list] |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 300 | set status [mc "No repository selected."] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 301 | return |
| 302 | } |
| 303 | |
| 304 | if {[catch {set x $cached($cache)}]} { |
Christian Stimming | 1ac1795 | 2007-07-21 14:21:34 +0200 | [diff] [blame] | 305 | set status [mc "Scanning %s..." $uri] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 306 | $w.heads.l conf -state disabled |
| 307 | set head_list [list] |
| 308 | set full_list [list] |
| 309 | set head_cache($cache) [list] |
| 310 | set full_cache($cache) [list] |
Shawn O. Pearce | 0b81261 | 2007-07-09 01:17:09 -0400 | [diff] [blame] | 311 | set active_ls [git_read ls-remote $uri] |
Shawn O. Pearce | aa252f1 | 2007-05-28 15:23:32 -0400 | [diff] [blame] | 312 | fconfigure $active_ls \ |
| 313 | -blocking 0 \ |
| 314 | -translation lf \ |
| 315 | -encoding utf-8 |
| 316 | fileevent $active_ls readable [cb _read $cache $active_ls] |
| 317 | } else { |
| 318 | set status {} |
| 319 | set full_list $full_cache($cache) |
| 320 | set head_list $head_cache($cache) |
| 321 | $w.heads.l conf -state normal |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | method _read {cache fd} { |
| 326 | if {$fd ne $active_ls} { |
| 327 | catch {close $fd} |
| 328 | return |
| 329 | } |
| 330 | |
| 331 | while {[gets $fd line] >= 0} { |
| 332 | if {[string match {*^{}} $line]} continue |
| 333 | if {[regexp {^([0-9a-f]{40}) (.*)$} $line _junk obj ref]} { |
| 334 | if {[regsub ^refs/heads/ $ref {} abr]} { |
| 335 | lappend head_list $abr |
| 336 | lappend head_cache($cache) $abr |
| 337 | lappend full_list $ref |
| 338 | lappend full_cache($cache) $ref |
| 339 | set full_cache("$cache\n$ref") $obj |
| 340 | } |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | if {[eof $fd]} { |
| 345 | if {[catch {close $fd} err]} { |
| 346 | set status $err |
| 347 | set head_list [list] |
| 348 | set full_list [list] |
| 349 | } else { |
| 350 | set status {} |
| 351 | set cached($cache) 1 |
| 352 | $w.heads.l conf -state normal |
| 353 | } |
| 354 | } |
| 355 | } ifdeleted { |
| 356 | catch {close $fd} |
| 357 | } |
| 358 | |
| 359 | } |