fordon_greeman / voidfiles

Branch: 2079ec5
Switch branches/tags
main
theidioticdev add emacs 2079ec5 22h ago
166 lines · 6.3 KB Raw Blame History
1 ;;; magit-sparse-checkout.el --- Sparse checkout support for Magit -*- lexical-binding:t -*-
2
3 ;; Copyright (C) 2008-2026 The Magit Project Contributors
4
5 ;; Author: Kyle Meyer <kyle@kyleam.com>
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 provides an interface to the "git sparse-checkout"
26 ;; command (operating in cone mode).
27
28 ;;; Code:
29
30 (require 'magit)
31
32 ;;; Utilities
33
34 (defun magit-sparse-checkout-enabled-p ()
35 "Return non-nil if working tree is a sparse checkout."
36 (magit-get-boolean "core.sparsecheckout"))
37
38 (defun magit-sparse-checkout--auto-enable ()
39 (if (magit-sparse-checkout-enabled-p)
40 (unless (magit-get-boolean "core.sparsecheckoutcone")
41 (user-error
42 "Magit's sparse checkout functionality requires cone mode"))
43 ;; Note: Don't use `magit-sparse-checkout-enable' because it's
44 ;; asynchronous.
45 (magit-run-git "sparse-checkout" "init" "--cone")))
46
47 (defun magit-sparse-checkout-directories ()
48 "Return directories that are recursively included in the sparse checkout.
49 See the \"git sparse-checkout\" manpage for details about
50 \"recursive\" versus \"parent\" directories in cone mode."
51 (and (magit-get-boolean "core.sparsecheckoutcone")
52 (mapcar #'file-name-as-directory
53 (magit-git-lines "sparse-checkout" "list"))))
54
55 ;;; Commands
56
57 ;;;###autoload(autoload 'magit-sparse-checkout "magit-sparse-checkout" nil t)
58 (transient-define-prefix magit-sparse-checkout ()
59 "Create and manage sparse checkouts."
60 :man-page "git-sparse-checkout"
61 ["Arguments for enabling"
62 :if-not magit-sparse-checkout-enabled-p
63 ("-i" "Use sparse index" "--sparse-index")]
64 ["Actions"
65 [:if-not magit-sparse-checkout-enabled-p
66 ("e" "Enable sparse checkout" magit-sparse-checkout-enable)]
67 [:if magit-sparse-checkout-enabled-p
68 ("d" "Disable sparse checkout" magit-sparse-checkout-disable)
69 ("r" "Reapply rules" magit-sparse-checkout-reapply)]
70 [("s" "Set directories" magit-sparse-checkout-set)
71 ("a" "Add directories" magit-sparse-checkout-add)]])
72
73 ;;;###autoload
74 (defun magit-sparse-checkout-enable (&optional args)
75 "Convert the working tree to a sparse checkout."
76 (interactive (list (transient-args 'magit-sparse-checkout)))
77 (magit-run-git-async "sparse-checkout" "init" "--cone" args))
78
79 ;;;###autoload
80 (defun magit-sparse-checkout-set (directories)
81 "Restrict working tree to DIRECTORIES.
82 To extend rather than override the currently configured
83 directories, call `magit-sparse-checkout-add' instead."
84 (interactive
85 (list (magit-completing-read-multiple
86 "Include these directories: "
87 ;; Note: Given that the appeal of sparse checkouts is
88 ;; dealing with very large trees, listing all subdirectories
89 ;; may need to be reconsidered.
90 (magit-revision-directories "HEAD"))))
91 (magit-sparse-checkout--auto-enable)
92 (magit-run-git-async "sparse-checkout" "set" directories))
93
94 ;;;###autoload
95 (defun magit-sparse-checkout-add (directories)
96 "Add DIRECTORIES to the working tree.
97 To override rather than extend the currently configured
98 directories, call `magit-sparse-checkout-set' instead."
99 (interactive
100 (list (magit-completing-read-multiple
101 "Add these directories: "
102 ;; Same performance note as in `magit-sparse-checkout-set',
103 ;; but even more so given the additional processing.
104 (seq-remove
105 (let ((re (concat
106 "\\`"
107 (regexp-opt (magit-sparse-checkout-directories)))))
108 (##string-match-p re %))
109 (magit-revision-directories "HEAD")))))
110 (magit-sparse-checkout--auto-enable)
111 (magit-run-git-async "sparse-checkout" "add" directories))
112
113 ;;;###autoload
114 (defun magit-sparse-checkout-reapply ()
115 "Reapply the sparse checkout rules to the working tree.
116 Some operations such as merging or rebasing may need to check out
117 files that aren't included in the sparse checkout. Call this
118 command to reset to the sparse checkout state."
119 (interactive)
120 (magit-run-git-async "sparse-checkout" "reapply"))
121
122 ;;;###autoload
123 (defun magit-sparse-checkout-disable ()
124 "Convert sparse checkout to full checkout.
125 Note that disabling the sparse checkout does not clear the
126 configured directories. Call `magit-sparse-checkout-enable' to
127 restore the previous sparse checkout."
128 (interactive)
129 (magit-run-git-async "sparse-checkout" "disable"))
130
131 ;;; Miscellaneous
132
133 (defun magit-sparse-checkout-insert-header ()
134 "Insert header line with sparse checkout information.
135 This header is not inserted by default. To enable it, add it to
136 `magit-status-headers-hook'."
137 (when (magit-sparse-checkout-enabled-p)
138 (insert (propertize (format "%-10s" "Sparse! ")
139 'font-lock-face 'magit-section-heading))
140 (insert
141 (let ((dirs (magit-sparse-checkout-directories)))
142 (pcase (length dirs)
143 (0 "top-level directory")
144 (1 (car dirs))
145 (n (format "%d directories" n)))))
146 (insert ?\n)))
147
148 ;;; _
149 (provide 'magit-sparse-checkout)
150 ;; Local Variables:
151 ;; read-symbol-shorthands: (
152 ;; ("and$" . "cond-let--and$")
153 ;; ("thread$" . "cond-let--thread$")
154 ;; ("when$" . "cond-let--when$")
155 ;; ("and-let*" . "cond-let--and-let*")
156 ;; ("and-let" . "cond-let--and-let")
157 ;; ("if-let*" . "cond-let--if-let*")
158 ;; ("if-let" . "cond-let--if-let")
159 ;; ("when-let*" . "cond-let--when-let*")
160 ;; ("when-let" . "cond-let--when-let")
161 ;; ("while-let*" . "cond-let--while-let*")
162 ;; ("while-let" . "cond-let--while-let")
163 ;; ("match-string" . "match-string")
164 ;; ("match-str" . "match-string-no-properties"))
165 ;; End:
166 ;;; magit-sparse-checkout.el ends here