aboutsummaryrefslogtreecommitdiffstats
path: root/elpa/magit-20220503.1245/magit-sparse-checkout.el
diff options
context:
space:
mode:
Diffstat (limited to 'elpa/magit-20220503.1245/magit-sparse-checkout.el')
-rw-r--r--elpa/magit-20220503.1245/magit-sparse-checkout.el170
1 files changed, 170 insertions, 0 deletions
diff --git a/elpa/magit-20220503.1245/magit-sparse-checkout.el b/elpa/magit-20220503.1245/magit-sparse-checkout.el
new file mode 100644
index 0000000..e9f761d
--- /dev/null
+++ b/elpa/magit-20220503.1245/magit-sparse-checkout.el
@@ -0,0 +1,170 @@
+;;; magit-sparse-checkout.el --- Sparse checkout support for Magit -*- lexical-binding:t -*-
+
+;; Copyright (C) 2008-2022 The Magit Project Contributors
+
+;; Author: Kyle Meyer <kyle@kyleam.com>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; Magit is free software: you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+;;
+;; Magit is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;; License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library provides an interface to the `git sparse-checkout'
+;; command. It's been possible to define sparse checkouts since Git
+;; v1.7.0 by adding patterns to $GIT_DIR/info/sparse-checkout and
+;; calling `git read-tree -mu HEAD' to update the index and working
+;; tree. However, Git v2.25 introduced the `git sparse-checkout'
+;; command along with "cone mode", which restricts the possible
+;; patterns to directories to provide better performance.
+;;
+;; The goal of this library is to support the `git sparse-checkout'
+;; command operating in cone mode.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Utilities
+
+(defun magit-sparse-checkout-enabled-p ()
+ "Return non-nil if working tree is a sparse checkout."
+ (magit-get-boolean "core.sparsecheckout"))
+
+(defun magit-sparse-checkout--assert-version ()
+ ;; Older versions of Git have the ability to define sparse checkout
+ ;; patterns in .git/info/sparse-checkout, but the sparse-checkout
+ ;; command isn't available until 2.25.0.
+ (when (magit-git-version< "2.25.0")
+ (user-error "`git sparse-checkout' not available until Git v2.25")))
+
+(defun magit-sparse-checkout--auto-enable ()
+ (if (magit-sparse-checkout-enabled-p)
+ (unless (magit-get-boolean "core.sparsecheckoutcone")
+ (user-error
+ "Magit's sparse checkout functionality requires cone mode"))
+ ;; Note: Don't use `magit-sparse-checkout-enable' because it's
+ ;; asynchronous.
+ (magit-run-git "sparse-checkout" "init" "--cone")))
+
+(defun magit-sparse-checkout-directories ()
+ "Return directories that are recursively included in the sparse checkout.
+See the `git sparse-checkout' manpage for details about
+\"recursive\" versus \"parent\" directories in cone mode."
+ (and (magit-get-boolean "core.sparsecheckoutcone")
+ (mapcar #'file-name-as-directory
+ (magit-git-lines "sparse-checkout" "list"))))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-sparse-checkout "magit-sparse-checkout" nil t)
+(transient-define-prefix magit-sparse-checkout ()
+ "Create and manage sparse checkouts."
+ :man-page "git-sparse-checkout"
+ ["Arguments for enabling"
+ :if-not magit-sparse-checkout-enabled-p
+ ("-i" "Use sparse index" "--sparse-index")]
+ ["Actions"
+ [:if-not magit-sparse-checkout-enabled-p
+ ("e" "Enable sparse checkout" magit-sparse-checkout-enable)]
+ [:if magit-sparse-checkout-enabled-p
+ ("d" "Disable sparse checkout" magit-sparse-checkout-disable)
+ ("r" "Reapply rules" magit-sparse-checkout-reapply)]
+ [("s" "Set directories" magit-sparse-checkout-set)
+ ("a" "Add directories" magit-sparse-checkout-add)]])
+
+;;;###autoload
+(defun magit-sparse-checkout-enable (&optional args)
+ "Convert the working tree to a sparse checkout."
+ (interactive (list (transient-args 'magit-sparse-checkout)))
+ (magit-sparse-checkout--assert-version)
+ (magit-run-git-async "sparse-checkout" "init" "--cone" args))
+
+;;;###autoload
+(defun magit-sparse-checkout-set (directories)
+ "Restrict working tree to DIRECTORIES.
+To extend rather than override the currently configured
+directories, call `magit-sparse-checkout-add' instead."
+ (interactive
+ (list (magit-completing-read-multiple*
+ "Include these directories: "
+ ;; Note: Given that the appeal of sparse checkouts is
+ ;; dealing with very large trees, listing all subdirectories
+ ;; may need to be reconsidered.
+ (magit-revision-directories "HEAD"))))
+ (magit-sparse-checkout--assert-version)
+ (magit-sparse-checkout--auto-enable)
+ (magit-run-git-async "sparse-checkout" "set" directories))
+
+;;;###autoload
+(defun magit-sparse-checkout-add (directories)
+ "Add DIRECTORIES to the working tree.
+To override rather than extend the currently configured
+directories, call `magit-sparse-checkout-set' instead."
+ (interactive
+ (list (magit-completing-read-multiple*
+ "Add these directories: "
+ ;; Same performance note as in `magit-sparse-checkout-set',
+ ;; but even more so given the additional processing.
+ (seq-remove
+ (let ((re (concat
+ "\\`"
+ (regexp-opt (magit-sparse-checkout-directories)))))
+ (lambda (d) (string-match-p re d)))
+ (magit-revision-directories "HEAD")))))
+ (magit-sparse-checkout--assert-version)
+ (magit-sparse-checkout--auto-enable)
+ (magit-run-git-async "sparse-checkout" "add" directories))
+
+;;;###autoload
+(defun magit-sparse-checkout-reapply ()
+ "Reapply the sparse checkout rules to the working tree.
+Some operations such as merging or rebasing may need to check out
+files that aren't included in the sparse checkout. Call this
+command to reset to the sparse checkout state."
+ (interactive)
+ (magit-sparse-checkout--assert-version)
+ (magit-run-git-async "sparse-checkout" "reapply"))
+
+;;;###autoload
+(defun magit-sparse-checkout-disable ()
+ "Convert sparse checkout to full checkout.
+Note that disabling the sparse checkout does not clear the
+configured directories. Call `magit-sparse-checkout-enable' to
+restore the previous sparse checkout."
+ (interactive)
+ (magit-sparse-checkout--assert-version)
+ (magit-run-git-async "sparse-checkout" "disable"))
+
+;;; Miscellaneous
+
+(defun magit-sparse-checkout-insert-header ()
+ "Insert header line with sparse checkout information.
+This header is not inserted by default. To enable it, add it to
+`magit-status-headers-hook'."
+ (when (magit-sparse-checkout-enabled-p)
+ (insert (propertize (format "%-10s" "Sparse! ")
+ 'font-lock-face 'magit-section-heading))
+ (insert
+ (let ((dirs (magit-sparse-checkout-directories)))
+ (pcase (length dirs)
+ (0 "top-level directory")
+ (1 (car dirs))
+ (n (format "%d directories" n)))))
+ (insert ?\n)))
+
+;;; _
+(provide 'magit-sparse-checkout)
+;;; magit-sparse-checkout.el ends here