magit-subtree.el (6573B)
1 ;;; magit-subtree.el --- Subtree support for Magit -*- lexical-binding:t -*- 2 3 ;; Copyright (C) 2008-2024 The Magit Project Contributors 4 5 ;; Author: Jonas Bernoulli <emacs.magit@jonas.bernoulli.dev> 6 ;; Maintainer: Jonas Bernoulli <emacs.magit@jonas.bernoulli.dev> 7 8 ;; SPDX-License-Identifier: GPL-3.0-or-later 9 10 ;; Magit is free software: you can redistribute it and/or modify it 11 ;; under the terms of the GNU General Public License as published by 12 ;; the Free Software Foundation, either version 3 of the License, or 13 ;; (at your option) any later version. 14 ;; 15 ;; Magit is distributed in the hope that it will be useful, but WITHOUT 16 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 18 ;; License for more details. 19 ;; 20 ;; You should have received a copy of the GNU General Public License 21 ;; along with Magit. If not, see <https://www.gnu.org/licenses/>. 22 23 ;;; Code: 24 25 (require 'magit) 26 27 ;;; Commands 28 29 ;;;###autoload (autoload 'magit-subtree "magit-subtree" nil t) 30 (transient-define-prefix magit-subtree () 31 "Import or export subtrees." 32 :man-page "git-subtree" 33 ["Subtree actions" 34 ("i" "Import" magit-subtree-import) 35 ("e" "Export" magit-subtree-export)]) 36 37 ;;;###autoload (autoload 'magit-subtree-import "magit-subtree" nil t) 38 (transient-define-prefix magit-subtree-import () 39 "Import subtrees." 40 :man-page "git-subtree" 41 ["Arguments" 42 (magit-subtree:--prefix) 43 (magit-subtree:--message) 44 ("-s" "Squash" "--squash")] 45 ["Subtree import actions" 46 [("a" "Add" magit-subtree-add) 47 ("c" "Add commit" magit-subtree-add-commit)] 48 [("m" "Merge" magit-subtree-merge) 49 ("f" "Pull" magit-subtree-pull)]]) 50 51 ;;;###autoload (autoload 'magit-subtree-export "magit-subtree" nil t) 52 (transient-define-prefix magit-subtree-export () 53 "Export subtrees." 54 :man-page "git-subtree" 55 ["Arguments" 56 (magit-subtree:--prefix) 57 (magit-subtree:--annotate) 58 (magit-subtree:--branch) 59 (magit-subtree:--onto) 60 ("-i" "Ignore joins" "--ignore-joins") 61 ("-j" "Rejoin" "--rejoin")] 62 ["Subtree export actions" 63 ("p" "Push" magit-subtree-push) 64 ("s" "Split" magit-subtree-split)]) 65 66 (transient-define-argument magit-subtree:--prefix () 67 :description "Prefix" 68 :class 'transient-option 69 :shortarg "-P" 70 :argument "--prefix=" 71 :reader #'magit-subtree-read-prefix) 72 73 (defun magit-subtree-read-prefix (prompt &optional default _history) 74 (let* ((insert-default-directory nil) 75 (topdir (magit-toplevel)) 76 (prefix (read-directory-name (concat prompt ": ") topdir default))) 77 (if (file-name-absolute-p prefix) 78 ;; At least `ido-mode's variant is not compatible. 79 (if (string-prefix-p topdir prefix) 80 (file-relative-name prefix topdir) 81 (user-error "%s isn't inside the repository at %s" prefix topdir)) 82 prefix))) 83 84 (transient-define-argument magit-subtree:--message () 85 :description "Message" 86 :class 'transient-option 87 :shortarg "-m" 88 :argument "--message=") 89 90 (transient-define-argument magit-subtree:--annotate () 91 :description "Annotate" 92 :class 'transient-option 93 :key "-a" 94 :argument "--annotate=") 95 96 (transient-define-argument magit-subtree:--branch () 97 :description "Branch" 98 :class 'transient-option 99 :shortarg "-b" 100 :argument "--branch=") 101 102 (transient-define-argument magit-subtree:--onto () 103 :description "Onto" 104 :class 'transient-option 105 :key "-o" 106 :argument "--onto=" 107 :reader #'magit-transient-read-revision) 108 109 (defun magit-subtree-prefix (transient prompt) 110 (if-let ((arg (--first (string-prefix-p "--prefix=" it) 111 (transient-args transient)))) 112 (substring arg 9) 113 (magit-subtree-read-prefix prompt))) 114 115 (defun magit-subtree-arguments (transient) 116 (--remove (string-prefix-p "--prefix=" it) 117 (transient-args transient))) 118 119 (defun magit-git-subtree (subcmd prefix &rest args) 120 (magit-run-git-async "subtree" subcmd (concat "--prefix=" prefix) args)) 121 122 ;;;###autoload 123 (defun magit-subtree-add (prefix repository ref args) 124 "Add REF from REPOSITORY as a new subtree at PREFIX." 125 (interactive 126 (cons (magit-subtree-prefix 'magit-subtree-import "Add subtree") 127 (let ((remote (magit-read-remote-or-url "From repository"))) 128 (list remote 129 (magit-read-refspec "Ref" remote) 130 (magit-subtree-arguments 'magit-subtree-import))))) 131 (magit-git-subtree "add" prefix args repository ref)) 132 133 ;;;###autoload 134 (defun magit-subtree-add-commit (prefix commit args) 135 "Add COMMIT as a new subtree at PREFIX." 136 (interactive 137 (list (magit-subtree-prefix 'magit-subtree-import "Add subtree") 138 (magit-read-string-ns "Commit") 139 (magit-subtree-arguments 'magit-subtree-import))) 140 (magit-git-subtree "add" prefix args commit)) 141 142 ;;;###autoload 143 (defun magit-subtree-merge (prefix commit args) 144 "Merge COMMIT into the PREFIX subtree." 145 (interactive 146 (list (magit-subtree-prefix 'magit-subtree-import "Merge into subtree") 147 (magit-read-string-ns "Commit") 148 (magit-subtree-arguments 'magit-subtree-import))) 149 (magit-git-subtree "merge" prefix args commit)) 150 151 ;;;###autoload 152 (defun magit-subtree-pull (prefix repository ref args) 153 "Pull REF from REPOSITORY into the PREFIX subtree." 154 (interactive 155 (cons (magit-subtree-prefix 'magit-subtree-import "Pull into subtree") 156 (let ((remote (magit-read-remote-or-url "From repository"))) 157 (list remote 158 (magit-read-refspec "Ref" remote) 159 (magit-subtree-arguments 'magit-subtree-import))))) 160 (magit-git-subtree "pull" prefix args repository ref)) 161 162 ;;;###autoload 163 (defun magit-subtree-push (prefix repository ref args) 164 "Extract the history of the subtree PREFIX and push it to REF on REPOSITORY." 165 (interactive (list (magit-subtree-prefix 'magit-subtree-export "Push subtree") 166 (magit-read-remote-or-url "To repository") 167 (magit-read-string-ns "To reference") 168 (magit-subtree-arguments 'magit-subtree-export))) 169 (magit-git-subtree "push" prefix args repository ref)) 170 171 ;;;###autoload 172 (defun magit-subtree-split (prefix commit args) 173 "Extract the history of the subtree PREFIX." 174 (interactive (list (magit-subtree-prefix 'magit-subtree-export "Split subtree") 175 (magit-read-string-ns "Commit") 176 (magit-subtree-arguments 'magit-subtree-export))) 177 (magit-git-subtree "split" prefix args commit)) 178 179 ;;; _ 180 (provide 'magit-subtree) 181 ;;; magit-subtree.el ends here