Function: magit-branch-delete
magit-branch-delete is an autoloaded, interactive and byte-compiled
function defined in magit-branch.el.
Signature
(magit-branch-delete BRANCHES &optional FORCE)
Documentation
Delete one or multiple branches.
If the region marks multiple branches, then offer to delete those, otherwise prompt for a single branch to be deleted, defaulting to the branch at point.
Require confirmation when deleting branches is dangerous in some
way. Option magit-no-confirm can be customized to not require
confirmation in certain cases. See its docstring to learn why
confirmation is required by default in certain cases or if a
prompt is confusing.
Key Bindings
Source Code
;; Defined in ~/.emacs.d/elpa/magit-20260411.1452/magit-branch.el
;;;###autoload
(defun magit-branch-delete (branches &optional force)
"Delete one or multiple branches.
If the region marks multiple branches, then offer to delete
those, otherwise prompt for a single branch to be deleted,
defaulting to the branch at point.
Require confirmation when deleting branches is dangerous in some
way. Option `magit-no-confirm' can be customized to not require
confirmation in certain cases. See its docstring to learn why
confirmation is required by default in certain cases or if a
prompt is confusing."
;; One would expect this to be a command as simple as, for example,
;; `magit-branch-rename'; but it turns out everyone wants to squeeze
;; a bit of extra functionality into this one, including myself.
(interactive
(let ((branches (magit-region-values 'branch t))
(force current-prefix-arg))
(if (length> branches 1)
(magit-confirm t nil "Delete %d branches" nil branches)
(setq branches
(list (magit-read-branch-prefer-other
(if force "Force delete branch" "Delete branch")))))
(cond-let
(force)
[[unmerged (seq-remove #'magit-branch-merged-p branches)]]
((magit-confirm 'delete-unmerged-branch
"Delete unmerged branch %s"
"Delete %d unmerged branches"
'noabort unmerged)
(setq force branches))
((setq branches (cl-set-difference branches unmerged :test #'equal)))
((user-error "Abort")))
(list branches force)))
(let ((refs (mapcar #'magit-ref-fullname branches)))
;; If a member of refs is nil, that means that
;; the respective branch name is ambiguous.
(when-let ((ambiguous (seq-filter #'null refs)))
(user-error
"%s ambiguous; please cleanup using git directly"
(let ((len (length ambiguous)))
(cond
((= len 1)
(format "%s is" (seq-find #'magit-ref-ambiguous-p branches)))
((= len (length refs))
(format "These %s names are" len))
((format "%s of these names are" len))))))
(cond
((string-match "^refs/remotes/\\([^/]+\\)" (car refs))
(let* ((remote (match-str 1 (car refs)))
(offset (1+ (length remote))))
(cond
((magit-confirm 'delete-branch-on-remote
(list "Deleting local %s. Also delete on %s"
(magit-ref-fullname (car branches))
remote)
(list "Deleting %d local refs. Also delete on %s"
(length refs)
remote)
'noabort refs)
;; The ref may actually point at another rev on the remote,
;; but this is better than nothing.
(dolist (ref refs)
(message "Delete %s (was %s)" ref
(magit-rev-parse "--short" ref)))
;; Assume the branches actually still exist on the remote.
(magit-run-git-async
"push" "--delete"
(and (or force magit-branch-delete-never-verify) "--no-verify")
remote
(mapcar (##concat "refs/heads/" (substring % offset)) branches))
;; If that is not the case, then this deletes the tracking branches.
(set-process-sentinel
magit-this-process
(apply-partially #'magit-delete-remote-branch-sentinel remote refs)))
(t
(dolist (ref refs)
(message "Delete %s (was %s)" ref
(magit-rev-parse "--short" ref))
(magit-call-git "update-ref" "-d" ref))
(magit-refresh)))))
((length> branches 1)
(setq branches (delete (magit-get-current-branch) branches))
(mapc #'magit-branch-maybe-delete-pr-remote branches)
(mapc #'magit-branch-unset-pushRemote branches)
(magit-run-git "branch" (if force "-D" "-d") branches))
(t ; And now for something completely different.
(let* ((branch (car branches))
(prompt (format "Branch %s is checked out. " branch))
(target (magit-get-indirect-upstream-branch branch t)))
(when (equal branch (magit-get-current-branch))
(when (or (equal branch target)
(not target))
(setq target (magit-main-branch)))
(pcase (if (or (equal branch target)
(not target))
(magit-read-char-case prompt nil
(?d "[d]etach HEAD & delete" 'detach)
(?a "[a]bort" 'abort))
(magit-read-char-case prompt nil
(?d "[d]etach HEAD & delete" 'detach)
(?c (format "[c]heckout %s & delete" target) 'target)
(?a "[a]bort" 'abort)))
(`detach (unless (or (equal force '(4))
(member branch force)
(magit-branch-merged-p branch t))
(magit-confirm 'delete-unmerged-branch
"Delete unmerged branch %s" ""
nil (list branch)))
(magit-call-git "checkout" "--detach"))
(`target (unless (or (equal force '(4))
(member branch force)
(magit-branch-merged-p branch target))
(magit-confirm 'delete-unmerged-branch
"Delete unmerged branch %s" ""
nil (list branch)))
(magit-call-git "checkout" target))
(`abort (user-error "Abort")))
(setq force t))
(magit-branch-maybe-delete-pr-remote branch)
(magit-branch-unset-pushRemote branch)
(magit-run-git "branch" (if force "-D" "-d") branch))))))