fordon_greeman / voidfiles

Branch: main
Switch branches/tags
main
theidioticdev add emacs 2079ec5 23h ago
203 lines · 7.2 KB Raw Blame History
1 ;;; magit-subtree.el --- Subtree support for Magit -*- lexical-binding:t -*-
2
3 ;; Copyright (C) 2008-2026 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 ;;; Commentary:
24
25 ;; This library implements support for "git subtree".
26 ;; The entry point is the `magit-subtree' menu command.
27
28 ;; See (info "(magit)Subtree").
29
30 ;;; Code:
31
32 (require 'magit)
33
34 ;;; Commands
35
36 ;;;###autoload(autoload 'magit-subtree "magit-subtree" nil t)
37 (transient-define-prefix magit-subtree ()
38 "Import or export subtrees."
39 :man-page "git-subtree"
40 ["Subtree actions"
41 ("i" "Import" magit-subtree-import)
42 ("e" "Export" magit-subtree-export)])
43
44 ;;;###autoload(autoload 'magit-subtree-import "magit-subtree" nil t)
45 (transient-define-prefix magit-subtree-import ()
46 "Import subtrees."
47 :man-page "git-subtree"
48 ["Arguments"
49 (magit-subtree:--prefix)
50 (magit-subtree:--message)
51 ("-s" "Squash" "--squash")]
52 ["Subtree import actions"
53 [("a" "Add" magit-subtree-add)
54 ("c" "Add commit" magit-subtree-add-commit)]
55 [("m" "Merge" magit-subtree-merge)
56 ("f" "Pull" magit-subtree-pull)]])
57
58 ;;;###autoload(autoload 'magit-subtree-export "magit-subtree" nil t)
59 (transient-define-prefix magit-subtree-export ()
60 "Export subtrees."
61 :man-page "git-subtree"
62 ["Arguments"
63 (magit-subtree:--prefix)
64 (magit-subtree:--annotate)
65 (magit-subtree:--branch)
66 (magit-subtree:--onto)
67 ("-i" "Ignore joins" "--ignore-joins")
68 ("-j" "Rejoin" "--rejoin")]
69 ["Subtree export actions"
70 ("p" "Push" magit-subtree-push)
71 ("s" "Split" magit-subtree-split)])
72
73 (transient-define-argument magit-subtree:--prefix ()
74 :description "Prefix"
75 :class 'transient-option
76 :shortarg "-P"
77 :argument "--prefix="
78 :reader #'magit-subtree-read-prefix)
79
80 (defun magit-subtree-read-prefix (prompt &optional default _history)
81 (let* ((insert-default-directory nil)
82 (topdir (magit-toplevel))
83 (prefix (read-directory-name (concat prompt ": ") topdir default)))
84 (if (file-name-absolute-p prefix)
85 (if (string-prefix-p topdir prefix)
86 (file-relative-name prefix topdir)
87 (user-error "%s isn't inside the repository at %s" prefix topdir))
88 prefix)))
89
90 (transient-define-argument magit-subtree:--message ()
91 :description "Message"
92 :class 'transient-option
93 :shortarg "-m"
94 :argument "--message=")
95
96 (transient-define-argument magit-subtree:--annotate ()
97 :description "Annotate"
98 :class 'transient-option
99 :key "-a"
100 :argument "--annotate=")
101
102 (transient-define-argument magit-subtree:--branch ()
103 :description "Branch"
104 :class 'transient-option
105 :shortarg "-b"
106 :argument "--branch=")
107
108 (transient-define-argument magit-subtree:--onto ()
109 :description "Onto"
110 :class 'transient-option
111 :key "-o"
112 :argument "--onto="
113 :reader #'magit-transient-read-revision)
114
115 (defun magit-subtree-prefix (transient prompt)
116 (if-let ((arg (seq-find (##string-prefix-p "--prefix=" %)
117 (transient-args transient))))
118 (substring arg 9)
119 (magit-subtree-read-prefix prompt)))
120
121 (defun magit-subtree-arguments (transient)
122 (seq-remove (##string-prefix-p "--prefix=" %)
123 (transient-args transient)))
124
125 (defun magit-git-subtree (subcmd prefix &rest args)
126 (magit-run-git-async "subtree" subcmd (concat "--prefix=" prefix) args))
127
128 ;;;###autoload
129 (defun magit-subtree-add (prefix repository ref args)
130 "Add REF from REPOSITORY as a new subtree at PREFIX."
131 (interactive
132 (cons (magit-subtree-prefix 'magit-subtree-import "Add subtree")
133 (let ((remote (magit-read-remote-or-url "From repository")))
134 (list remote
135 (magit-read-refspec "Ref" remote)
136 (magit-subtree-arguments 'magit-subtree-import)))))
137 (magit-git-subtree "add" prefix args repository ref))
138
139 ;;;###autoload
140 (defun magit-subtree-add-commit (prefix commit args)
141 "Add COMMIT as a new subtree at PREFIX."
142 (interactive
143 (list (magit-subtree-prefix 'magit-subtree-import "Add subtree")
144 (magit-read-string-ns "Commit")
145 (magit-subtree-arguments 'magit-subtree-import)))
146 (magit-git-subtree "add" prefix args commit))
147
148 ;;;###autoload
149 (defun magit-subtree-merge (prefix commit args)
150 "Merge COMMIT into the PREFIX subtree."
151 (interactive
152 (list (magit-subtree-prefix 'magit-subtree-import "Merge into subtree")
153 (magit-read-string-ns "Commit")
154 (magit-subtree-arguments 'magit-subtree-import)))
155 (magit-git-subtree "merge" prefix args commit))
156
157 ;;;###autoload
158 (defun magit-subtree-pull (prefix repository ref args)
159 "Pull REF from REPOSITORY into the PREFIX subtree."
160 (interactive
161 (cons (magit-subtree-prefix 'magit-subtree-import "Pull into subtree")
162 (let ((remote (magit-read-remote-or-url "From repository")))
163 (list remote
164 (magit-read-refspec "Ref" remote)
165 (magit-subtree-arguments 'magit-subtree-import)))))
166 (magit-git-subtree "pull" prefix args repository ref))
167
168 ;;;###autoload
169 (defun magit-subtree-push (prefix repository ref args)
170 "Extract the history of the subtree PREFIX and push it to REF on REPOSITORY."
171 (interactive (list (magit-subtree-prefix 'magit-subtree-export "Push subtree")
172 (magit-read-remote-or-url "To repository")
173 (magit-read-string-ns "To reference")
174 (magit-subtree-arguments 'magit-subtree-export)))
175 (magit-git-subtree "push" prefix args repository ref))
176
177 ;;;###autoload
178 (defun magit-subtree-split (prefix commit args)
179 "Extract the history of the subtree PREFIX."
180 (interactive (list (magit-subtree-prefix 'magit-subtree-export "Split subtree")
181 (magit-read-string-ns "Commit")
182 (magit-subtree-arguments 'magit-subtree-export)))
183 (magit-git-subtree "split" prefix args commit))
184
185 ;;; _
186 (provide 'magit-subtree)
187 ;; Local Variables:
188 ;; read-symbol-shorthands: (
189 ;; ("and$" . "cond-let--and$")
190 ;; ("thread$" . "cond-let--thread$")
191 ;; ("when$" . "cond-let--when$")
192 ;; ("and-let*" . "cond-let--and-let*")
193 ;; ("and-let" . "cond-let--and-let")
194 ;; ("if-let*" . "cond-let--if-let*")
195 ;; ("if-let" . "cond-let--if-let")
196 ;; ("when-let*" . "cond-let--when-let*")
197 ;; ("when-let" . "cond-let--when-let")
198 ;; ("while-let*" . "cond-let--while-let*")
199 ;; ("while-let" . "cond-let--while-let")
200 ;; ("match-string" . "match-string")
201 ;; ("match-str" . "match-string-no-properties"))
202 ;; End:
203 ;;; magit-subtree.el ends here