update packages

This commit is contained in:
2025-11-25 19:52:03 +01:00
parent 14ba373378
commit dbbae92267
280 changed files with 13451 additions and 11207 deletions

View File

@@ -1,5 +1,5 @@
The following people have contributed to Magit.
For statistics see https://magit.vc/stats/magit/authors.html.
For statistics see https://stats.magit.vc/magit/authors.html.
Authors
-------
@@ -238,6 +238,7 @@ All Contributors
- Lluís Vilanova
- Loic Dachary
- Louis Roché
- Lucius Chen
- Luís Oliveira
- Luke Amdor
- Magnar Sveen
@@ -411,6 +412,7 @@ All Contributors
- Wouter Bolsterlee
- X4lldux
- Xavier Noria
- Xavier Young
- Xu Chunyang
- Yann Herklotz
- Yann Hodique

View File

@@ -235,7 +235,7 @@ Also see `magit-post-commit-hook'."
:type 'hook
:get #'magit-hook-custom-get)
(defcustom git-commit-post-finish-hook-timeout 1
(defcustom git-commit-post-finish-hook-timeout 2
"Time in seconds to wait for git to create a commit.
The hook `git-commit-post-finish-hook' (which see) is run only
@@ -502,7 +502,7 @@ the redundant bindings, then set this to nil, before loading
(not (file-accessible-directory-p
(file-name-directory buffer-file-name)))
(magit-expand-git-file-name (substring buffer-file-name 2))))
((file-accessible-directory-p (file-name-directory file)))
(_(file-accessible-directory-p (file-name-directory file)))
(inhibit-read-only t))
(insert-file-contents file t)
t))
@@ -596,9 +596,7 @@ Used as the local value of `header-line-format', in buffer using
(add-hook 'with-editor-post-finish-hook
(apply-partially #'git-commit-run-post-finish-hook
(magit-rev-parse "HEAD"))
nil t)
(when (fboundp 'magit-wip-maybe-add-commit-hook)
(magit-wip-maybe-add-commit-hook)))
nil t))
(setq with-editor-cancel-message
#'git-commit-cancel-message)
(git-commit-setup-font-lock)
@@ -619,17 +617,14 @@ Used as the local value of `header-line-format', in buffer using
(defun git-commit-run-post-finish-hook (previous)
(when git-commit-post-finish-hook
(cl-block nil
(let ((break (time-add (current-time)
(seconds-to-time
git-commit-post-finish-hook-timeout))))
(while (equal (magit-rev-parse "HEAD") previous)
(if (time-less-p (current-time) break)
(sit-for 0.01)
(message "No commit created after 1 second. Not running %s."
'git-commit-post-finish-hook)
(cl-return))))
(run-hooks 'git-commit-post-finish-hook))))
(if (with-timeout (git-commit-post-finish-hook-timeout)
(while (equal (magit-rev-parse "HEAD") previous)
(sit-for 0.01))
t)
(run-hooks 'git-commit-post-finish-hook)
(message "No commit created after %s second. Not running %s."
git-commit-post-finish-hook-timeout
'git-commit-post-finish-hook))))
(define-minor-mode git-commit-mode
"Auxiliary minor mode used when editing Git commit messages.
@@ -721,15 +716,15 @@ conventions are checked."
(save-excursion
(goto-char (point-min))
(re-search-forward (git-commit-summary-regexp) nil t)
(if (equal (match-string 1) "")
(if (equal (match-str 1) "")
t ; Just try; we don't know whether --allow-empty-message was used.
(and (or (not (memq 'overlong-summary-line
git-commit-style-convention-checks))
(equal (match-string 2) "")
(equal (match-str 2) "")
(y-or-n-p "Summary line is too long. Commit anyway? "))
(or (not (memq 'non-empty-second-line
git-commit-style-convention-checks))
(not (match-string 3))
(not (match-str 3))
(y-or-n-p "Second line is not empty. Commit anyway? ")))))))
(defun git-commit-cancel-message ()
@@ -751,7 +746,7 @@ With a numeric prefix ARG, go back ARG messages."
;; non-empty and newly written comment, because otherwise
;; it would be irreversibly lost.
(when-let* ((message (git-commit-buffer-message))
((not (ring-member log-edit-comment-ring message))))
(_(not (ring-member log-edit-comment-ring message))))
(ring-insert log-edit-comment-ring message)
(cl-incf arg)
(setq len (ring-length log-edit-comment-ring)))
@@ -799,16 +794,16 @@ Save current message first."
(defun git-commit-save-message ()
"Save current message to `log-edit-comment-ring'."
(interactive)
(if-let ((message (git-commit-buffer-message)))
(progn
(when-let ((index (ring-member log-edit-comment-ring message)))
(ring-remove log-edit-comment-ring index))
(ring-insert log-edit-comment-ring message)
(when git-commit-use-local-message-ring
(magit-repository-local-set 'log-edit-comment-ring
log-edit-comment-ring))
(message "Message saved"))
(message "Only whitespace and/or comments; message not saved")))
(cond-let
([message (git-commit-buffer-message)]
(when-let ((index (ring-member log-edit-comment-ring message)))
(ring-remove log-edit-comment-ring index))
(ring-insert log-edit-comment-ring message)
(when git-commit-use-local-message-ring
(magit-repository-local-set 'log-edit-comment-ring
log-edit-comment-ring))
(message "Message saved"))
((message "Only whitespace and/or comments; message not saved"))))
(defun git-commit-prepare-message-ring ()
(make-local-variable 'log-edit-comment-ring-index)
@@ -950,11 +945,11 @@ completion candidates. The input must have the form \"NAME <EMAIL>\"."
(sort (delete-dups
(magit-git-lines "log" "-n9999" "--format=%aN <%ae>"))
#'string<)
nil nil nil 'git-commit-read-ident-history)))
nil 'any nil 'git-commit-read-ident-history)))
(save-match-data
(if (string-match "\\`\\([^<]+\\) *<\\([^>]+\\)>\\'" str)
(list (save-match-data (string-trim (match-string 1 str)))
(string-trim (match-string 2 str)))
(list (save-match-data (string-trim (match-str 1 str)))
(string-trim (match-str 2 str)))
(user-error "Invalid input")))))
(defun git-commit--insert-ident-trailer (trailer name email)
@@ -1174,6 +1169,11 @@ Added to `font-lock-extend-region-functions'."
(delete-region (point) (point-max)))))
(let ((diff-default-read-only nil))
(diff-mode))
;; These won't survive copying to another buffer,
;; so let's not waste any time. See #5483.
(setq-local diff-refine nil)
(setq-local diff-font-lock-syntax nil)
(setq-local diff-font-lock-prettify nil)
(let ((font-lock-verbose nil)
(font-lock-support-mode nil))
(font-lock-ensure))
@@ -1221,4 +1221,15 @@ Elisp doc-strings, including this one. Unlike in doc-strings,
"git-commit 4.0.0")
(provide 'git-commit)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; git-commit.el ends here

View File

@@ -362,26 +362,26 @@ BATCH is non-nil, in which case nil is returned. Non-nil
BATCH also ignores commented lines."
(save-excursion
(goto-char (line-beginning-position))
(if-let ((re-start (if batch
"^"
(format "^\\(?99:%s\\)? *"
(regexp-quote comment-start))))
(type (seq-some (pcase-lambda (`(,type . ,re))
(let ((case-fold-search nil))
(and (looking-at (concat re-start re)) type)))
git-rebase-line-regexps)))
(git-rebase-action
(cond-let*
([re-start (if batch
"^"
(format "^\\(?99:%s\\)? *" (regexp-quote comment-start)))]
[type (seq-some (pcase-lambda (`(,type . ,re))
(let ((case-fold-search nil))
(and (looking-at (concat re-start re)) type)))
git-rebase-line-regexps)]
(git-rebase-action
:action-type type
:action (and-let* ((action (match-string-no-properties 1)))
:action (and-let ((action (match-str 1)))
(or (cdr (assoc action git-rebase-short-options))
action))
:action-options (match-string-no-properties 2)
:target (match-string-no-properties 3)
:trailer (match-string-no-properties 5)
:comment-p (and (match-string 99) t))
(and (not batch)
;; Use empty object rather than nil to ease handling.
(git-rebase-action)))))
:action-options (match-str 2)
:target (match-str 3)
:trailer (match-str 5)
:comment-p (and (match-str 99) t)))
((not batch)
;; Use empty object rather than nil to ease handling.
(git-rebase-action)))))
(defun git-rebase-set-action (action)
"Set action of commit line to ACTION.
@@ -412,15 +412,13 @@ of its action type."
(delete-region beg (+ beg 2))
(insert comment-start " ")))
(forward-line))
(t
;; In the case of --rebase-merges, commit lines may have
;; other lines with other action types, empty lines, and
;; "Branch" comments interspersed. Move along.
(forward-line)))))
(goto-char
(if git-rebase-auto-advance
end-marker
(if pt-below-p (1- end-marker) beg)))
;; In the case of --rebase-merges, commit lines may have
;; other lines with other action types, empty lines, and
;; "Branch" comments interspersed. Move along.
((forward-line)))))
(goto-char (cond (git-rebase-auto-advance end-marker)
(pt-below-p (1- end-marker))
(beg)))
(goto-char (line-beginning-position))))
(_ (ding))))
@@ -591,7 +589,7 @@ remove the label on the current line, if any."
(save-excursion
(goto-char (point-min))
(while (re-search-forward "^\\(?:l\\|label\\) \\([^ \n]+\\)" nil t)
(push (match-string-no-properties 1) labels)))
(push (match-str 1) labels)))
(nreverse labels)))
(defun git-rebase-reset (arg)
@@ -871,11 +869,11 @@ except for the \"pick\" command."
(line (concat git-rebase-comment-re "\\(?:\\( \\.? *\\)\\|"
"\\( +\\)\\([^\n,],\\) \\([^\n ]+\\) \\)")))
(while (re-search-forward line nil t)
(if (match-string 1)
(if (match-str 1)
(if (assq cmd git-rebase-fixup-descriptions)
(delete-line)
(replace-match (make-string 10 ?\s) t t nil 1))
(setq cmd (intern (concat "git-rebase-" (match-string 4))))
(setq cmd (intern (concat "git-rebase-" (match-str 4))))
(cond
((not (fboundp cmd))
(delete-line))
@@ -944,4 +942,15 @@ is used as a value for `imenu-extract-index-name-function'."
;;; _
(provide 'git-rebase)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; git-rebase.el ends here

View File

@@ -33,6 +33,7 @@
(require 'magit-diff)
(require 'magit-wip)
(require 'dired)
(require 'transient) ; See #3732.
;; For `magit-apply'
@@ -161,15 +162,15 @@ and only the second and third are to be applied, they would be
adjusted as \"@@ -10,6 +10,7 @@\" and \"@@ -18,6 +19,7 @@\"."
(let* ((first-hunk (car hunks))
(offset (if (string-match diff-hunk-header-re-unified first-hunk)
(- (string-to-number (match-string 3 first-hunk))
(string-to-number (match-string 1 first-hunk)))
(- (string-to-number (match-str 3 first-hunk))
(string-to-number (match-str 1 first-hunk)))
(error "Header hunks have to be applied individually"))))
(if (= offset 0)
hunks
(mapcar (lambda (hunk)
(if (string-match diff-hunk-header-re-unified hunk)
(replace-match (number-to-string
(- (string-to-number (match-string 3 hunk))
(- (string-to-number (match-str 3 hunk))
offset))
t t hunk 3)
(error "Hunk does not have expected header")))
@@ -218,14 +219,14 @@ adjusted as \"@@ -10,6 +10,7 @@\" and \"@@ -18,6 +19,7 @@\"."
(mapcar (##oref % value) section:s)))
(command (symbol-name this-command))
(command (if (and command (string-match "^magit-\\([^-]+\\)" command))
(match-string 1 command)
(match-str 1 command)
"apply"))
(context (magit-diff-get-context))
(ignore-context (magit-diff-ignore-any-space-p)))
(unless (magit-diff-context-p)
(user-error "Not enough context to apply patch. Increase the context"))
(when (and magit-wip-before-change-mode (not magit-inhibit-refresh))
(magit-wip-commit-before-change files (concat " before " command)))
(unless magit-inhibit-refresh
(magit-run-before-change-functions files command))
(with-temp-buffer
(insert patch)
(let ((magit-inhibit-refresh t))
@@ -234,8 +235,7 @@ adjusted as \"@@ -10,6 +10,7 @@\" and \"@@ -18,6 +19,7 @@\"."
(if ignore-context "-C0" (format "-C%s" context))
"--ignore-space-change" "-")))
(unless magit-inhibit-refresh
(when magit-wip-after-apply-mode
(magit-wip-commit-after-apply files (concat " after " command)))
(magit-run-after-apply-functions files command)
(magit-refresh))))
(defun magit-apply--get-selection ()
@@ -338,11 +338,11 @@ ignored) files."
(magit-stage-1 (if all "--all" "-u") magit-buffer-diff-files)))
(defun magit-stage-1 (arg &optional files)
(magit-wip-commit-before-change files " before stage")
(magit-run-before-change-functions files "stage")
(magit-run-git "add" arg (if files (cons "--" files) "."))
(when magit-auto-revert-mode
(mapc #'magit-turn-on-auto-revert-mode-if-desired files))
(magit-wip-commit-after-apply files " after stage"))
(magit-run-after-apply-functions files "stage"))
(defun magit-stage-untracked (&optional intent)
(let* ((section (magit-current-section))
@@ -356,7 +356,7 @@ ignored) files."
(magit-git-repo-p file t))
(push file repos)
(push file plain)))
(magit-wip-commit-before-change files " before stage")
(magit-run-before-change-functions files "stage")
(when plain
(magit-run-git "add" (and intent "--intent-to-add")
"--" plain)
@@ -388,7 +388,7 @@ ignored) files."
(expand-file-name ".gitmodules" topdir))
(let ((default-directory borg-user-emacs-directory))
(borg--maybe-absorb-gitdir package)))))))))
(magit-wip-commit-after-apply files " after stage")))
(magit-run-after-apply-functions files "stage")))
(defvar magit-post-stage-hook-commands
(list #'magit-stage
@@ -396,6 +396,7 @@ ignored) files."
#'magit-stage-modified
'magit-file-stage))
;;;###autoload
(defun magit-run-post-stage-hook ()
(when (memq this-command magit-post-stage-hook-commands)
(magit-run-hook-with-benchmark 'magit-post-stage-hook)))
@@ -442,15 +443,15 @@ ignored) files."
(magit-unstage-1 files)))
(defun magit-unstage-1 (files)
(magit-wip-commit-before-change files " before unstage")
(magit-run-before-change-functions files "unstage")
(if (magit-no-commit-p)
(magit-run-git "rm" "--cached" "--" files)
(magit-run-git "reset" "HEAD" "--" files))
(magit-wip-commit-after-apply files " after unstage"))
(magit-run-after-apply-functions files "unstage"))
(defun magit-unstage-intent (files)
(if-let ((staged (magit-staged-files))
(intent (seq-filter (##member % staged) files)))
(if-let* ((staged (magit-staged-files))
(intent (seq-filter (##member % staged) files)))
(magit-unstage-1 intent)
(user-error "Already unstaged")))
@@ -463,9 +464,9 @@ ignored) files."
(when (or (magit-anything-unstaged-p)
(magit-untracked-files))
(magit-confirm 'unstage-all-changes))
(magit-wip-commit-before-change nil " before unstage")
(magit-run-before-change-functions nil "unstage")
(magit-run-git "reset" "HEAD" "--" magit-buffer-diff-files)
(magit-wip-commit-after-apply nil " after unstage"))
(magit-run-after-apply-functions nil "unstage"))
(defvar magit-post-unstage-hook-commands
(list #'magit-unstage
@@ -473,6 +474,7 @@ ignored) files."
#'magit-unstage-all
'magit-file-unstage))
;;;###autoload
(defun magit-run-post-unstage-hook ()
(when (memq this-command magit-post-unstage-hook-commands)
(magit-run-hook-with-benchmark 'magit-post-unstage-hook)))
@@ -515,39 +517,26 @@ of a side, then keep that side without prompting."
('(?U ?U) (magit-smerge-keep-current))
(_ (magit-discard-apply section #'magit-apply-hunk)))))
(defun magit-discard-apply (section apply)
(if (eq (magit-diff-type section) 'unstaged)
(funcall apply section "--reverse")
(if (magit-anything-unstaged-p
nil (if (magit-file-section-p section)
(oref section value)
(magit-section-parent-value section)))
(progn (let ((magit-inhibit-refresh t))
(funcall apply section "--reverse" "--cached")
(funcall apply section "--reverse" "--reject"))
(magit-refresh))
(funcall apply section "--reverse" "--index"))))
(defun magit-discard-hunks (sections)
(magit-confirm 'discard
(list "Discard %d hunks from %s"
(length sections)
(magit-section-parent-value (car sections))))
(magit-discard-apply-n sections #'magit-apply-hunks))
(magit-discard-apply sections #'magit-apply-hunks))
(defun magit-discard-apply-n (sections apply)
(let ((section (car sections)))
(if (eq (magit-diff-type section) 'unstaged)
(funcall apply sections "--reverse")
(if (magit-anything-unstaged-p
nil (if (magit-file-section-p section)
(oref section value)
(magit-section-parent-value section)))
(progn (let ((magit-inhibit-refresh t))
(funcall apply sections "--reverse" "--cached")
(funcall apply sections "--reverse" "--reject"))
(magit-refresh))
(funcall apply sections "--reverse" "--index")))))
(defun magit-discard-apply (section:s apply)
(let ((primus (if (atom section:s) section:s (car section:s))))
(cond ((eq (magit-diff-type primus) 'unstaged)
(funcall apply section:s "--reverse"))
((magit-anything-unstaged-p
nil (if (magit-file-section-p primus)
(oref primus value)
(magit-section-parent-value primus)))
(let ((magit-inhibit-refresh t))
(funcall apply section:s "--reverse" "--cached")
(funcall apply section:s "--reverse" "--reject"))
(magit-refresh))
((funcall apply section:s "--reverse" "--index")))))
(defun magit-discard-file (section)
(magit-discard-files (list section)))
@@ -583,7 +572,7 @@ of a side, then keep that side without prompting."
(`(?X ?R ,(or ? ?M ?D)) (push file rename)))))
(unwind-protect
(let ((magit-inhibit-refresh t))
(magit-wip-commit-before-change files " before discard")
(magit-run-before-change-functions files "discard")
(when resolve
(magit-discard-files--resolve (nreverse resolve)))
(when resurrect
@@ -595,7 +584,7 @@ of a side, then keep that side without prompting."
(when (or discard discard-new)
(magit-discard-files--discard (nreverse discard)
(nreverse discard-new)))
(magit-wip-commit-after-apply files " after discard"))
(magit-run-after-apply-functions files "discard"))
(magit-refresh))))
(defun magit-discard-files--resolve (files)
@@ -637,7 +626,7 @@ of a side, then keep that side without prompting."
(?M (let ((temp (magit-git-string "checkout-index" "--temp" file)))
(string-match
(format "\\(.+?\\)\t%s" (regexp-quote file)) temp)
(rename-file (match-string 1 temp)
(rename-file (match-str 1 temp)
(setq temp (concat file ".~{index}~")))
(delete-file temp t))
(magit-call-git "rm" "--cached" "--force" "--" file))
@@ -675,10 +664,8 @@ of a side, then keep that side without prompting."
(setq sections
(seq-remove (##member (oref % value) binaries)
sections)))
(cond ((length= sections 1)
(magit-discard-apply (car sections) 'magit-apply-diff))
(sections
(magit-discard-apply-n sections #'magit-apply-diffs)))
(when sections
(magit-discard-apply sections #'magit-apply-diffs))
(when binaries
(let ((modified (magit-unstaged-files t)))
(setq binaries (magit--separate (##member % modified) binaries)))
@@ -733,8 +720,7 @@ so causes the change to be applied to the index as well."
magit-buffer-range)
((derived-mode-p 'magit-diff-mode)
magit-buffer-range)
(t
"--cached")))))
("--cached")))))
(magit--separate (##member (oref % value) bs)
sections))))
(magit-confirm-files 'reverse (mapcar (##oref % value) sections))
@@ -800,9 +786,8 @@ a separate commit. A typical workflow would be:
(defun magit-call-smerge (fn)
(pcase-let* ((file (magit-file-at-point t t))
(keep (get-file-buffer file))
(`(,buf ,pos)
(let ((magit-diff-visit-jump-to-change nil))
(magit-diff-visit-file--noselect file))))
(`(,buf ,pos) (magit-diff-visit-file--noselect))
(keep (eq keep buf)))
(with-current-buffer buf
(save-excursion
(save-restriction
@@ -831,4 +816,15 @@ a separate commit. A typical workflow would be:
;;; _
(provide 'magit-apply)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-apply.el ends here

View File

@@ -104,6 +104,32 @@ seconds of user inactivity. That is not desirable."
;;; Mode
;;;###autoload
(progn ; magit-custom-initialize-after-init
(defun magit-custom-initialize-after-init (symbol value)
;; Use `apply-partially' instead of the wonders of lexical bindings,
;; because of bugs in the autoload handling of package managers, which
;; cause these variables to be treated as dynamic. See #5476 and #5485.
(internal--define-uninitialized-variable symbol)
(cond ((not after-init-time)
(letrec ((f (apply-partially
(lambda (symbol value)
(ignore-errors
(remove-hook 'after-init-hook f))
(custom-initialize-set symbol value))
symbol value)))
(add-hook 'after-init-hook f)))
((not load-file-name)
(custom-initialize-set symbol value))
((letrec ((f (apply-partially
(lambda (thisfile symbol value file)
(when (equal file thisfile)
(ignore-errors
(remove-hook 'after-load-functions f))
(custom-initialize-set symbol value)))
load-file-name symbol value)))
(add-hook 'after-load-functions f))))))
(defun magit-turn-on-auto-revert-mode-if-desired (&optional file)
(cond (file
(when-let ((buffer (find-buffer-visiting file)))
@@ -128,54 +154,20 @@ seconds of user inactivity. That is not desirable."
:link '(info-link "(magit)Automatic Reverting of File-Visiting Buffers")
:group 'magit-auto-revert
:group 'magit-essentials
;; - When `global-auto-revert-mode' is enabled, then this mode is
;; redundant.
;; - In all other cases enable the mode because if buffers are not
;; automatically reverted that would make many very common tasks
;; much more cumbersome.
:init-value (not (or global-auto-revert-mode
noninteractive)))
;; - Unfortunately `:init-value t' only sets the value of the mode
;; variable but does not cause the mode function to be called.
;; - I don't think it works like this on purpose, but since one usually
;; should not enable global modes by default, it is understandable.
;; - If the user has set the variable `magit-auto-revert-mode' to nil
;; after loading magit (instead of doing so before loading magit or
;; by using the function), then we should still respect that setting.
;; - If the user enables `global-auto-revert-mode' after loading magit
;; and after `after-init-hook' has run, then `magit-auto-revert-mode'
;; remains enabled; and there is nothing we can do about it.
;; - However if the init file causes `magit-autorevert' to be loaded
;; and only later it enables `global-auto-revert-mode', then we can
;; and should leave `magit-auto-revert-mode' disabled.
(defun magit-auto-revert-mode--init-kludge ()
"This is an internal kludge to be used on `after-init-hook'.
Do not use this function elsewhere, and don't remove it from
the `after-init-hook'. For more information see the comments
and code surrounding the definition of this function."
(if (or (not magit-auto-revert-mode)
(and global-auto-revert-mode (not after-init-time)))
(magit-auto-revert-mode -1)
(let ((start (current-time)))
(magit-message "Turning on magit-auto-revert-mode...")
(magit-auto-revert-mode 1)
(magit-message
"Turning on magit-auto-revert-mode...done%s"
(let ((elapsed (float-time (time-since start))))
(if (> elapsed 0.2)
(format " (%.3fs, %s buffers checked)" elapsed
(length (buffer-list)))
""))))))
(if after-init-time
;; Since `after-init-hook' has already been
;; run, turn the mode on or off right now.
(magit-auto-revert-mode--init-kludge)
;; By the time the init file has been fully loaded the
;; values of the relevant variables might have changed.
(add-hook 'after-init-hook #'magit-auto-revert-mode--init-kludge t))
:init-value (not (or global-auto-revert-mode noninteractive))
:initialize #'magit-custom-initialize-after-init)
(defun magit-auto-revert-mode--disable ()
"When enabling `global-auto-revert-mode', disable `magit-auto-revert-mode'."
(when (and global-auto-revert-mode
(bound-and-true-p magit-auto-revert-mode))
(magit-auto-revert-mode -1)))
(add-hook 'global-auto-revert-mode-hook #'magit-auto-revert-mode--disable)
(put 'magit-auto-revert-mode 'function-documentation
"Toggle Magit Auto Revert mode.
If called interactively, enable Magit Auto Revert mode if ARG is
positive, and disable it if ARG is zero or negative. If called
from Lisp, also enable the mode if ARG is omitted or nil, and
@@ -210,8 +202,11 @@ Like nearly every mode, this mode should be enabled or disabled
by calling the respective mode function, the reason being that
changing the state of a mode involves more than merely toggling
a single switch, so setting the mode variable is not enough.
Also, you should not use `after-init-hook' to disable this mode.")
Also, you should not use `after-init-hook' to disable this mode.
\(fn &optional ARG)")
;;;###autoload
(defun magit-auto-revert-buffers ()
(when (and magit-auto-revert-immediately
(or global-auto-revert-mode
@@ -268,4 +263,15 @@ defaults to nil) for any BUFFER."
;;; _
(provide 'magit-autorevert)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-autorevert.el ends here

View File

@@ -33,13 +33,14 @@
;;; Code:
;; Also update EMACS_VERSION in "default.mk".
(defconst magit--minimal-emacs "27.1")
(defconst magit--minimal-emacs "28.1")
(defconst magit--minimal-git "2.25.0")
(require 'cl-lib)
(require 'compat)
(require 'cond-let)
(require 'eieio)
(require 'llama)
(require 'llama) ; For (##these ...) see M-x describe-function RET # # RET.
(require 'subr-x)
;; For older Emacs releases we depend on an updated `seq' release from
@@ -332,11 +333,11 @@ Global settings:
for confirmation for any of these actions, you are still better
of adding all of the respective symbols individually.
When `magit-wip-before-change-mode' is enabled then these actions
can fairly easily be undone: `discard', `reverse',
`stage-all-changes', and `unstage-all-changes'. If and only if
this mode is enabled, then `safe-with-wip' has the same effect
as adding all of these symbols individually."
When `magit-wip-mode' is enabled then these actions can fairly
easily be undone: `discard', `reverse', `stage-all-changes', and
`unstage-all-changes'. If and only if this mode is enabled, then
`safe-with-wip' has the same effect as adding all of these symbols
individually."
:package-version '(magit . "2.1.0")
:group 'magit-essentials
:group 'magit-commands
@@ -425,7 +426,7 @@ the ellipsis definition. Currently the only acceptable values
for WHERE are `margin' or t (representing the default).
Whether collapsed sections are indicated using ellipsis is
controlled by `magit-section-visibility-indicator'."
controlled by option `magit-section-visibility-indicators'."
:package-version '(magit . "4.0.0")
:group 'magit-miscellaneous
:type '(repeat (list (symbol :tag "Where")
@@ -493,6 +494,7 @@ and delay of your graphical environment or operating system."
(defclass magit-hunk-section (magit-diff-section)
((keymap :initform 'magit-hunk-section-map)
(painted :initform nil)
(fontified :initform nil) ;TODO
(refined :initform nil)
(combined :initform nil :initarg :combined)
(from-range :initform nil :initarg :from-range)
@@ -576,6 +578,10 @@ acts similarly to `completing-read', except for the following:
- If REQUIRE-MATCH is nil and the user exits without a choice,
then nil is returned instead of an empty string.
- If REQUIRE-MATCH is `any', then do not require a match but
do require non-empty input (or non-nil DEFAULT, since that
is substituted for empty input).
- If REQUIRE-MATCH is non-nil and the user exits without a
choice, `user-error' is raised.
@@ -591,12 +597,13 @@ acts similarly to `completing-read', except for the following:
`minibuffer-default-prompt-format' and depending on
`magit-completing-read-default-prompt-predicate'."
(setq magit-completing-read--silent-default nil)
(if-let ((dwim (and def
(nth 2 (seq-find (pcase-lambda (`(,cmd ,re ,_))
(and (eq this-command cmd)
(or (not re)
(string-match-p re prompt))))
magit-dwim-selection)))))
(if-let ((_ def)
(dwim (seq-some (pcase-lambda (`(,cmd ,re ,dwim))
(and (eq cmd this-command)
(or (not re)
(string-match-p re prompt))
dwim))
magit-dwim-selection)))
(if (eq dwim 'ask)
(if (y-or-n-p (format "%s %s? " prompt def))
def
@@ -613,7 +620,8 @@ acts similarly to `completing-read', except for the following:
(reply (funcall magit-completing-read-function
(magit--format-prompt prompt def)
collection predicate
require-match initial-input hist def)))
(if (eq require-match 'any) nil require-match)
initial-input hist def)))
(setq this-command command)
;; Note: Avoid `string=' to support `helm-comp-read-use-marked'.
(if (equal reply "")
@@ -681,6 +689,14 @@ third-party completion frameworks."
(equal omit-nulls t))
(setq input string))
(funcall split-string string separators omit-nulls trim)))
;; Add the default to the table if absent, which is necessary
;; because we don't add it to the prompt for some frameworks.
(table (if (and def
(listp table)
(not (listp (car table)))
(not (member def table)))
(cons def table)
table))
;; Prevent `BUILT-IN' completion from messing up our existing
;; order of the completion candidates. aa5f098ab
(table (magit--completion-table table))
@@ -696,8 +712,12 @@ third-party completion frameworks."
;; And now, the moment we have all been waiting for...
(values (completing-read-multiple
(magit--format-prompt prompt def)
table predicate require-match initial-input
hist def inherit-input-method)))
table predicate
(if (eq require-match 'any) nil require-match)
initial-input hist def inherit-input-method)))
(when (and (eq require-match 'any)
(not values))
(user-error "Nothing selected"))
(if no-split input values)))
(defvar-keymap magit-minibuffer-local-ns-map
@@ -748,7 +768,7 @@ This is similar to `read-string', but
(user-error "Need non-empty input"))
((and no-whitespace (string-match-p "[\s\t\n]" val))
(user-error "Input contains whitespace"))
(t val))))
(val))))
(defun magit-read-string-ns ( prompt &optional initial-input history
default-value inherit-input-method)
@@ -779,7 +799,7 @@ ACTION is a member of option `magit-slow-confirm'."
(y-or-n-p prompt)))
(defvar magit--no-confirm-alist
'((safe-with-wip magit-wip-before-change-mode
'((safe-with-wip magit-wip-mode
discard reverse stage-all-changes unstage-all-changes)))
(cl-defun magit-confirm ( action &optional prompt prompt-n noabort
@@ -860,13 +880,14 @@ See info node `(magit)Debugging Tools' for more information."
,@(mapcan
(##list "-L" %)
(delete-dups
(mapcan
(seq-keep
(lambda (lib)
(if-let ((path (locate-library lib)))
(list (file-name-directory path))
(file-name-directory path)
(error "Cannot find mandatory dependency %s" lib)))
'(;; Like `LOAD_PATH' in `default.mk'.
"compat"
"cond-let"
"llama"
"seq"
"transient"
@@ -887,21 +908,20 @@ See info node `(magit)Debugging Tools' for more information."
(defmacro magit-bind-match-strings (varlist string &rest body)
"Bind variables to submatches according to VARLIST then evaluate BODY.
Bind the symbols in VARLIST to submatches of the current match
data, starting with 1 and incrementing by 1 for each symbol. If
the last match was against a string, then that has to be provided
as STRING."
Bind the symbols in VARLIST to submatches of the current match data,
starting with 1 and incrementing by 1 for each symbol. If the last
match was against a string, then that has to be provided as STRING."
(declare (indent 2) (debug (listp form body)))
(let ((s (gensym "string"))
(i 0))
`(let ((,s ,string))
(let ,(save-match-data
(mapcan (lambda (sym)
(cl-incf i)
(and (not (eq (aref (symbol-name sym) 0) ?_))
(list (list sym (list 'match-string i s)))))
varlist))
,@body))))
`(let* ((,s ,string)
,@(save-match-data
(seq-keep (lambda (sym)
(cl-incf i)
(and (not (eq (aref (symbol-name sym) 0) ?_))
`(,sym (match-str ,i ,s))))
varlist)))
,@body)))
(defun magit-delete-line ()
"Delete the rest of the current line."
@@ -948,8 +968,8 @@ Pad the left side of STRING so that it aligns with the text area."
(delete-char 1))
;; Valid format spec.
((looking-at "\\([-0-9.]*\\)\\([a-zA-Z]\\)")
(let* ((num (match-string 1))
(spec (string-to-char (match-string 2)))
(let* ((num (match-str 1))
(spec (string-to-char (match-str 2)))
(val (assq spec specification)))
(unless val
(error "Invalid format character: `%%%c'" spec))
@@ -968,42 +988,11 @@ Pad the left side of STRING so that it aligns with the text area."
;; Delete the percent sign.
(delete-region (1- (match-beginning 0)) (match-beginning 0)))))
;; Signal an error on bogus format strings.
(t
(error "Invalid format string"))))
((error "Invalid format string"))))
(buffer-string)))
;;; Missing from Emacs
(defun magit-kill-this-buffer ()
"Kill the current buffer."
(interactive)
(kill-buffer (current-buffer)))
(defun magit--buffer-string (&optional min max trim)
"Like `buffer-substring-no-properties' but the arguments are optional.
This combines the benefits of `buffer-string', `buffer-substring'
and `buffer-substring-no-properties' into one function that is
not as painful to use as the latter. I.e., you can write
(magit--buffer-string)
instead of
(buffer-substring-no-properties (point-min)
(point-max))
Optional MIN defaults to the value of `point-min'.
Optional MAX defaults to the value of `point-max'.
If optional TRIM is non-nil, then all leading and trailing
whitespace is remove. If it is the newline character, then
one trailing newline is added."
;; Lets write that one last time and be done with it:
(let ((str (buffer-substring-no-properties (or min (point-min))
(or max (point-max)))))
(if trim
(concat (string-trim str)
(and (eq trim ?\n) "\n"))
str)))
(defun magit--separate (pred list)
"Separate elements of LIST that do and don't satisfy PRED.
Return a list of two lists; the first containing the elements that
@@ -1085,6 +1074,8 @@ the value in the symbol's `saved-value' property if any, or
;;;###autoload
(define-advice Info-follow-nearest-node (:around (fn &optional fork) gitman)
;; Do not use `if-let*' (aka `cond-let--if-let*') because this is
;; copied to the autoload file, which does not require `cond-let'.
(let ((node (Info-get-token
(point) "\\*note[ \n\t]+"
"\\*note[ \n\t]+\\([^:]*\\):\\(:\\|[ \n\t]*(\\)?")))
@@ -1092,9 +1083,9 @@ the value in the symbol's `saved-value' property if any, or
(pcase magit-view-git-manual-method
('info (funcall fn fork))
('man (require 'man)
(man (match-string 1 node)))
(man (match-str 1 node)))
('woman (require 'woman)
(woman (match-string 1 node)))
(woman (match-str 1 node)))
(_ (user-error "Invalid value for `magit-view-git-manual-method'")))
(funcall fn fork))))
@@ -1134,7 +1125,7 @@ See <https://github.com/raxod502/straight.el/issues/520>."
(build (pcase manager
('straight (bound-and-true-p straight-build-dir))
('elpaca (bound-and-true-p elpaca-builds-directory))))
((string-prefix-p build filename))
(_(string-prefix-p build filename))
(repo (pcase manager
('straight
(and (bound-and-true-p straight-base-dir)
@@ -1172,19 +1163,19 @@ Like `message', except that `message-log-max' is bound to nil."
(defun magit--ellipsis (&optional where)
"Build an ellipsis always as string, depending on WHERE."
(if (stringp magit-ellipsis)
magit-ellipsis
(if-let ((pair (car (or
(alist-get (or where t) magit-ellipsis)
(alist-get t magit-ellipsis)))))
(pcase-let ((`(,fancy . ,universal) pair))
(let ((ellipsis (if (and fancy (char-displayable-p fancy))
fancy
universal)))
(if (characterp ellipsis)
(char-to-string ellipsis)
ellipsis)))
(user-error "Variable magit-ellipsis is invalid"))))
(cond-let
((stringp magit-ellipsis)
magit-ellipsis)
([pair (car (or (alist-get (or where t) magit-ellipsis)
(alist-get t magit-ellipsis)))]
(pcase-let* ((`(,fancy . ,universal) pair)
(ellipsis (if (and fancy (char-displayable-p fancy))
fancy
universal)))
(if (characterp ellipsis)
(char-to-string ellipsis)
ellipsis)))
((user-error "Variable magit-ellipsis is invalid"))))
(defun magit--ext-regexp-quote (string)
"Like `reqexp-quote', but for Extended Regular Expressions."
@@ -1198,4 +1189,15 @@ Like `message', except that `message-log-max' is bound to nil."
;;; _
(provide 'magit-base)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-base.el ends here

View File

@@ -53,7 +53,7 @@
;;; Commands
;;;###autoload (autoload 'magit-bisect "magit-bisect" nil t)
;;;###autoload(autoload 'magit-bisect "magit-bisect" nil t)
(transient-define-prefix magit-bisect ()
"Narrow in on the commit that introduced a bug."
:man-page "git-bisect"
@@ -258,7 +258,7 @@ bisect run'."
(pop lines))
(seq-find (##string-match done-re %) lines))))
(magit-insert-section ((eval (if bad-line 'commit 'bisect-output))
(and bad-line (match-string 1 bad-line)))
(and bad-line (match-str 1 bad-line)))
(magit-insert-heading
(propertize (or bad-line (pop lines))
'font-lock-face 'magit-section-heading))
@@ -291,7 +291,7 @@ bisect run'."
(while (progn (setq beg (point-marker))
(re-search-forward
"^\\(\\(?:git bisect\\|# status:\\) [^\n]+\n\\)" nil t))
(if (string-prefix-p "# status:" (match-string 1))
(if (string-prefix-p "# status:" (match-str 1))
(magit-delete-match)
(magit-bind-match-strings (heading) nil
(magit-delete-match)
@@ -315,4 +315,15 @@ bisect run'."
;;; _
(provide 'magit-bisect)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-bisect.el ends here

View File

@@ -128,7 +128,8 @@ part of the default value:
(margin-body-face . (magit-blame-dimmed)))"
:package-version '(magit . "2.13.0")
:group 'magit-blame
:type 'string)
:type '(alist :key-type symbol
:value-type (alist :key-type symbol :value-type sexp)))
(defcustom magit-blame-echo-style 'lines
"The blame visualization style used by `magit-blame-echo'.
@@ -265,21 +266,22 @@ Also see option `magit-blame-styles'."
(magit-file-relative-name
nil (not magit-buffer-file-name))))
(line (format "%d,+1" (line-number-at-pos))))
(cond (file (with-temp-buffer
(magit-with-toplevel
(magit-git-insert
"blame" "--porcelain"
(if (memq magit-blame-type '(final removal))
(cons "--reverse" (magit-blame-arguments))
(magit-blame-arguments))
"-L" line rev "--" file)
(goto-char (point-min))
(if (eobp)
(unless noerror
(error "Cannot get blame chunk at eob"))
(car (magit-blame--parse-chunk type))))))
(noerror nil)
((error "Buffer does not visit a tracked file")))))))
(cond (file
(with-temp-buffer
(magit-with-toplevel
(magit-git-insert
"blame" "--porcelain"
(if (memq magit-blame-type '(final removal))
(cons "--reverse" (magit-blame-arguments))
(magit-blame-arguments))
"-L" line rev "--" file)
(goto-char (point-min))
(cond ((not (eobp))
(car (magit-blame--parse-chunk type)))
((not noerror)
(error "Cannot get blame chunk at eob"))))))
((not noerror)
(error "Buffer does not visit a tracked file")))))))
(defun magit-blame-chunk-at (pos)
(seq-some (##overlay-get % 'magit-blame-chunk)
@@ -326,12 +328,6 @@ in `magit-blame-read-only-mode-map' instead."
:lighter magit-blame-mode-lighter
:interactive nil
(cond (magit-blame-mode
(unless arg
;; Emacs < 28.1 doesn't support `:interactive'.
(setq magit-blame-mode nil)
(user-error
(concat "Don't call `magit-blame-mode' directly; "
"instead use `magit-blame'")))
(add-hook 'after-save-hook #'magit-blame--refresh t t)
(add-hook 'post-command-hook #'magit-blame-goto-chunk-hook t t)
(add-hook 'before-revert-hook #'magit-blame--remove-overlays t t)
@@ -422,7 +418,8 @@ modes is toggled, then this mode also gets toggled automatically.
(magit-blame-mode 1))
(message "Blaming...")
(magit-blame-run-process
(or magit-buffer-refname magit-buffer-revision)
(and$ (or magit-buffer-refname magit-buffer-revision)
(and (not (equal $ "{index}")) $))
(magit-file-relative-name nil (not magit-buffer-file-name))
(if (memq magit-blame-type '(final removal))
(cons "--reverse" args)
@@ -464,10 +461,10 @@ modes is toggled, then this mode also gets toggled automatically.
(message "Blaming...done"))
(magit-blame-assert-buffer process)
(with-current-buffer (process-get process 'command-buf)
(if magit-blame-mode
(progn (magit-blame-mode -1)
(message "Blaming...failed"))
(message "Blaming...aborted"))))
(cond (magit-blame-mode
(magit-blame-mode -1)
(message "Blaming...failed"))
((message "Blaming...aborted")))))
(kill-local-variable 'magit-blame-process))))
(defun magit-blame-process-filter (process string)
@@ -501,22 +498,22 @@ modes is toggled, then this mode also gets toggled automatically.
(buffer-substring-no-properties (point) (line-end-position))))
(with-slots (orig-rev orig-file prev-rev prev-file)
(setq chunk (magit-blame-chunk
:orig-rev (match-string 1)
:orig-line (string-to-number (match-string 2))
:final-line (string-to-number (match-string 3))
:num-lines (string-to-number (match-string 4))))
:orig-rev (match-str 1)
:orig-line (string-to-number (match-str 2))
:final-line (string-to-number (match-str 3))
:num-lines (string-to-number (match-str 4))))
(forward-line)
(let (done)
(while (not done)
(cond ((looking-at "^filename \\(.+\\)")
(setq done t)
(setf orig-file (magit-decode-git-path (match-string 1))))
(setf orig-file (magit-decode-git-path (match-str 1))))
((looking-at "^previous \\(.\\{40,\\}\\) \\(.+\\)")
(setf prev-rev (match-string 1))
(setf prev-file (magit-decode-git-path (match-string 2))))
(setf prev-rev (match-str 1))
(setf prev-file (magit-decode-git-path (match-str 2))))
((looking-at "^\\([^ ]+\\) \\(.+\\)")
(push (cons (match-string 1)
(match-string 2))
(push (cons (match-str 1)
(match-str 2))
revinfo)))
(forward-line)))
(when (and (eq type 'removal) prev-rev)
@@ -753,18 +750,18 @@ modes is toggled, then this mode also gets toggled automatically.
(delete-overlay ov)))))
(defun magit-blame-maybe-show-message ()
(when (magit-blame--style-get 'show-message)
(if-let ((msg (cdr (assoc "summary"
(gethash (oref (magit-current-blame-chunk)
orig-rev)
magit-blame-cache)))))
(progn (set-text-properties 0 (length msg) nil msg)
(magit-msg "%S" msg))
(magit-msg "Commit data not available yet. Still blaming."))))
(cond-let
((not (magit-blame--style-get 'show-message)))
([msg (cdr (assoc "summary"
(gethash (oref (magit-current-blame-chunk) orig-rev)
magit-blame-cache)))]
(set-text-properties 0 (length msg) nil msg)
(magit-msg "%S" msg))
((magit-msg "Commit data not available yet. Still blaming."))))
;;; Commands
;;;###autoload (autoload 'magit-blame-echo "magit-blame" nil t)
;;;###autoload(autoload 'magit-blame-echo "magit-blame" nil t)
(transient-define-suffix magit-blame-echo (args)
"For each line show the revision in which it was added.
Show the information about the chunk at point in the echo area
@@ -788,7 +785,7 @@ not turn on `read-only-mode'."
(read-only-mode -1)
(magit-blame--update-overlays)))
;;;###autoload (autoload 'magit-blame-addition "magit-blame" nil t)
;;;###autoload(autoload 'magit-blame-addition "magit-blame" nil t)
(transient-define-suffix magit-blame-addition (args)
"For each line show the revision in which it was added."
(interactive (list (magit-blame-arguments)))
@@ -796,7 +793,7 @@ not turn on `read-only-mode'."
(magit-blame--pre-blame-setup 'addition)
(magit-blame--run args))
;;;###autoload (autoload 'magit-blame-removal "magit-blame" nil t)
;;;###autoload(autoload 'magit-blame-removal "magit-blame" nil t)
(transient-define-suffix magit-blame-removal (args)
"For each line show the revision in which it was removed."
:if-nil 'buffer-file-name
@@ -807,7 +804,7 @@ not turn on `read-only-mode'."
(magit-blame--pre-blame-setup 'removal)
(magit-blame--run args))
;;;###autoload (autoload 'magit-blame-reverse "magit-blame" nil t)
;;;###autoload(autoload 'magit-blame-reverse "magit-blame" nil t)
(transient-define-suffix magit-blame-reverse (args)
"For each line show the last revision in which it still exists."
:if-nil 'buffer-file-name
@@ -907,8 +904,9 @@ then also kill the buffer."
#'previous-single-char-property-change
#'next-single-char-property-change)
pos 'magit-blame-chunk)))
(when-let ((o (magit-blame--overlay-at pos))
((equal (oref (magit-blame-chunk-at pos) orig-rev) rev)))
(when-let
((o (magit-blame--overlay-at pos))
(_(equal (oref (magit-blame-chunk-at pos) orig-rev) rev)))
(setq ov o))))
(if ov
(goto-char (overlay-start ov))
@@ -943,7 +941,7 @@ instead of the hash, like `kill-ring-save' would."
;;; Popup
;;;###autoload (autoload 'magit-blame "magit-blame" nil t)
;;;###autoload(autoload 'magit-blame "magit-blame" nil t)
(transient-define-prefix magit-blame ()
"Show the commits that added or removed lines in the visited file."
:man-page "git-blame"
@@ -1002,4 +1000,15 @@ instead of the hash, like `kill-ring-save' would."
;;; _
(provide 'magit-blame)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-blame.el ends here

View File

@@ -156,4 +156,15 @@
;;; _
(provide 'magit-bookmark)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-bookmark.el ends here

View File

@@ -204,7 +204,7 @@ has to be used to view and change branch related variables."
;;; Commands
;;;###autoload (autoload 'magit-branch "magit" nil t)
;;;###autoload(autoload 'magit-branch "magit" nil t)
(transient-define-prefix magit-branch (branch)
"Add, configure or remove a branch."
:man-page "git-branch"
@@ -263,12 +263,12 @@ changes.
(interactive (list (magit-read-other-branch-or-commit "Checkout")
(magit-branch-arguments)))
(when (string-match "\\`heads/\\(.+\\)" commit)
(setq commit (match-string 1 commit)))
(setq commit (match-str 1 commit)))
(magit-run-git-async "checkout" args commit))
(defun magit--checkout (rev &optional args)
(when (string-match "\\`heads/\\(.+\\)" rev)
(setq rev (match-string 1 rev)))
(setq rev (match-str 1 rev)))
(magit-call-git "checkout" args rev))
;;;###autoload
@@ -319,7 +319,7 @@ does."
(and (not (magit-commit-p arg))
(magit-read-starting-point "Create and checkout branch" arg)))))
(when (string-match "\\`heads/\\(.+\\)" arg)
(setq arg (match-string 1 arg)))
(setq arg (match-str 1 arg)))
(if start-point
(with-suppressed-warnings ((interactive-only magit-branch-and-checkout))
(magit-branch-and-checkout arg start-point))
@@ -374,8 +374,7 @@ when using `magit-branch-and-checkout'."
choice))
((member choice local)
(list choice))
(t
(list choice (magit-read-starting-point "Create" choice))))))
((list choice (magit-read-starting-point "Create" choice))))))
(cond
((not start-point)
(magit--checkout branch (magit-branch-arguments))
@@ -496,37 +495,38 @@ from the source branch's upstream, then an error is raised."
(magit-anything-modified-p))
(message "Staying on HEAD due to uncommitted changes")
(setq checkout t))
(if-let ((current (magit-get-current-branch)))
(let ((tracked (magit-get-upstream-branch current))
base)
(when from
(unless (magit-rev-ancestor-p from current)
(user-error "Cannot spin off %s. %s is not reachable from %s"
branch from current))
(when (and tracked
(magit-rev-ancestor-p from tracked))
(user-error "Cannot spin off %s. %s is ancestor of upstream %s"
branch from tracked)))
(let ((magit-process-raise-error t))
(if checkout
(magit-call-git "checkout" "-b" branch current)
(magit-call-git "branch" branch current)))
(when-let ((upstream (magit-get-indirect-upstream-branch current)))
(magit-call-git "branch" "--set-upstream-to" upstream branch))
(when (and tracked
(setq base
(if from
(concat from "^")
(magit-git-string "merge-base" current tracked)))
(not (magit-rev-eq base current)))
(if checkout
(magit-call-git "update-ref" "-m"
(format "reset: moving to %s" base)
(concat "refs/heads/" current) base)
(magit-call-git "reset" "--hard" base))))
(if checkout
(magit-call-git "checkout" "-b" branch)
(magit-call-git "branch" branch)))
(cond-let
([current (magit-get-current-branch)]
(let ((tracked (magit-get-upstream-branch current))
base)
(when from
(unless (magit-rev-ancestor-p from current)
(user-error "Cannot spin off %s. %s is not reachable from %s"
branch from current))
(when (and tracked
(magit-rev-ancestor-p from tracked))
(user-error "Cannot spin off %s. %s is ancestor of upstream %s"
branch from tracked)))
(let ((magit-process-raise-error t))
(if checkout
(magit-call-git "checkout" "-b" branch current)
(magit-call-git "branch" branch current)))
(when-let ((upstream (magit-get-indirect-upstream-branch current)))
(magit-call-git "branch" "--set-upstream-to" upstream branch))
(when (and tracked
(setq base
(if from
(concat from "^")
(magit-git-string "merge-base" current tracked)))
(not (magit-rev-eq base current)))
(if checkout
(magit-call-git "update-ref" "-m"
(format "reset: moving to %s" base)
(concat "refs/heads/" current) base)
(magit-call-git "reset" "--hard" base)))))
(checkout
(magit-call-git "checkout" "-b" branch))
((magit-call-git "branch" branch)))
(magit-refresh))
;;;###autoload
@@ -595,16 +595,16 @@ prompt is confusing."
(setq branches
(list (magit-read-branch-prefer-other
(if force "Force delete branch" "Delete branch")))))
(when-let (((not force))
(unmerged (seq-remove #'magit-branch-merged-p branches)))
(if (magit-confirm 'delete-unmerged-branch
"Delete unmerged branch %s"
"Delete %d unmerged branches"
'noabort unmerged)
(setq force branches)
(or (setq branches
(cl-set-difference branches unmerged :test #'equal))
(user-error "Abort"))))
(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
@@ -618,11 +618,10 @@ prompt is confusing."
(format "%s is" (seq-find #'magit-ref-ambiguous-p branches)))
((= len (length refs))
(format "These %s names are" len))
(t
(format "%s of these names are" len))))))
((format "%s of these names are" len))))))
(cond
((string-match "^refs/remotes/\\([^/]+\\)" (car refs))
(let* ((remote (match-string 1 (car refs)))
(let* ((remote (match-str 1 (car refs)))
(offset (1+ (length remote))))
(cond
((magit-confirm 'delete-branch-on-remote
@@ -728,25 +727,24 @@ prompt is confusing."
(magit-set nil "branch" branch "pushRemote"))
(defun magit-delete-remote-branch-sentinel (remote refs process event)
(when (memq (process-status process) '(exit signal))
(if (= (process-exit-status process) 1)
(if-let ((on-remote (mapcar (##concat "refs/remotes/" remote "/" %)
(magit-remote-list-branches remote)))
(rest (seq-filter (##and (not (member % on-remote))
(magit-ref-exists-p %))
refs)))
(progn
(process-put process 'inhibit-refresh t)
(magit-process-sentinel process event)
(setq magit-this-error nil)
(message "Some remote branches no longer exist. %s"
"Deleting just the local tracking refs instead...")
(dolist (ref rest)
(magit-call-git "update-ref" "-d" ref))
(magit-refresh)
(message "Deleting local remote-tracking refs...done"))
(magit-process-sentinel process event))
(magit-process-sentinel process event))))
(cond-let*
((not (memq (process-status process) '(exit signal))))
([_(= (process-exit-status process) 1)]
[on-remote (mapcar (##concat "refs/remotes/" remote "/" %)
(magit-remote-list-branches remote))]
[rest (seq-filter (##and (not (member % on-remote))
(magit-ref-exists-p %))
refs)]
(process-put process 'inhibit-refresh t)
(magit-process-sentinel process event)
(setq magit-this-error nil)
(message "Some remote branches no longer exist. %s"
"Deleting just the local tracking refs instead...")
(dolist (ref rest)
(magit-call-git "update-ref" "-d" ref))
(magit-refresh)
(message "Deleting local remote-tracking refs...done"))
((magit-process-sentinel process event))))
;;;###autoload
(defun magit-branch-rename (old new &optional force)
@@ -766,7 +764,7 @@ the remote."
nil 'magit-revision-history)
current-prefix-arg)))
(when (string-match "\\`heads/\\(.+\\)" old)
(setq old (match-string 1 old)))
(setq old (match-str 1 old)))
(when (equal old new)
(user-error "Old and new branch names are the same"))
(magit-call-git "branch" (if force "-M" "-m") old new)
@@ -787,9 +785,8 @@ the remote."
(or (not (eq magit-branch-rename-push-target 'forge-only))
(and (require (quote forge) nil t)
(fboundp 'forge--split-forge-url)
(and-let* ((url (magit-git-string
"remote" "get-url" remote)))
(forge--split-forge-url url)))))
(and$ (magit-git-string "remote" "get-url" remote)
(forge--split-forge-url $)))))
(let ((old-target (magit-get-push-branch old t))
(new-target (magit-get-push-branch new t))
(remote (magit-get-push-remote new)))
@@ -830,12 +827,7 @@ and also rename the respective reflog file."
Rename \"refs/shelved/BRANCH\" to \"refs/heads/BRANCH\". If BRANCH
is prefixed with \"YYYY-MM-DD\", then drop that part of the name.
Also rename the respective reflog file."
(interactive
(list (magit-completing-read
"Unshelve branch"
(mapcar (##substring % 8)
(nreverse (magit-list-refnames "refs/shelved")))
nil t)))
(interactive (list (magit-read-shelved-branch "Unshelve branch")))
(let ((old (concat "refs/shelved/" branch))
(new (concat "refs/heads/"
(if (string-match-p
@@ -856,7 +848,7 @@ Also rename the respective reflog file."
;;; Configure
;;;###autoload (autoload 'magit-branch-configure "magit-branch" nil t)
;;;###autoload(autoload 'magit-branch-configure "magit-branch" nil t)
(transient-define-prefix magit-branch-configure (branch)
"Configure a branch."
:man-page "git-branch"
@@ -979,4 +971,15 @@ Also rename the respective reflog file."
;;; _
(provide 'magit-branch)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-branch.el ends here

View File

@@ -33,7 +33,7 @@
;;; Commands
;;;###autoload (autoload 'magit-bundle "magit-bundle" nil t)
;;;###autoload(autoload 'magit-bundle "magit-bundle" nil t)
(transient-define-prefix magit-bundle ()
"Create or verify Git bundles."
:man-page "git-bundle"
@@ -42,7 +42,7 @@
("v" "verify" magit-bundle-verify)
("l" "list-heads" magit-bundle-list-heads)])
;;;###autoload (autoload 'magit-bundle-import "magit-bundle" nil t)
;;;###autoload(autoload 'magit-bundle-import "magit-bundle" nil t)
(transient-define-prefix magit-bundle-create (&optional file refs args)
"Create a bundle."
:man-page "git-bundle"
@@ -99,7 +99,7 @@
;;;###autoload
(defun magit-bundle-update-tracked (tag)
"Update a bundle that is being tracked using TAG."
(interactive (list (magit-read-tag "Update bundle tracked by tag" t)))
(interactive (list (magit-read-tag "Update bundle tracked by tag")))
(let (msg)
(let-alist (magit--with-temp-process-buffer
(save-excursion
@@ -136,4 +136,15 @@
;;; _
(provide 'magit-bundle)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-bundle.el ends here

View File

@@ -123,7 +123,7 @@ directory where the repository has been cloned."
;;; Commands
;;;###autoload (autoload 'magit-clone "magit-clone" nil t)
;;;###autoload(autoload 'magit-clone "magit-clone" nil t)
(transient-define-prefix magit-clone (&optional transient)
"Clone a repository."
:man-page "git-clone"
@@ -314,13 +314,13 @@ Then show the status buffer for the new repository."
(defun magit-clone--url-to-name (url)
(and (string-match "\\([^/:]+?\\)\\(/?\\.git\\)?$" url)
(match-string 1 url)))
(match-str 1 url)))
(defun magit-clone--name-to-url (name)
(or (seq-some
(pcase-lambda (`(,re ,host ,user))
(and (string-match re name)
(let ((repo (match-string 1 name)))
(let ((repo (match-str 1 name)))
(magit-clone--format-url host user repo))))
magit-clone-name-alist)
(user-error "Not an url and no matching entry in `%s'"
@@ -336,16 +336,27 @@ Then show the status buffer for the new repository."
(format-spec
url-format
`((?h . ,host)
(?n . ,(if (string-search "/" repo)
repo
(if (string-search "." user)
(if-let ((user (magit-get user)))
(concat user "/" repo)
(user-error "Set %S or specify owner explicitly" user))
(concat user "/" repo))))))
(?n . ,(cond
((string-search "/" repo) repo)
((string-search "." user)
(if-let ((user (magit-get user)))
(concat user "/" repo)
(user-error "Set %S or specify owner explicitly" user)))
((concat user "/" repo))))))
(user-error
"Bogus `magit-clone-url-format' (bad type or missing default)")))
;;; _
(provide 'magit-clone)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-clone.el ends here

View File

@@ -115,7 +115,7 @@ Also see https://github.com/magit/magit/issues/4132."
;;; Popup
;;;###autoload (autoload 'magit-commit "magit-commit" nil t)
;;;###autoload(autoload 'magit-commit "magit-commit" nil t)
(transient-define-prefix magit-commit ()
"Create a new commit or replace an existing commit."
:info-manual "(magit)Initiating a Commit"
@@ -539,7 +539,7 @@ is updated:
(magit-commit-absorb-modules 'run commit))
nil nil nil nil commit))))
;;;###autoload (autoload 'magit-commit-absorb "magit-commit" nil t)
;;;###autoload(autoload 'magit-commit-absorb "magit-commit" nil t)
(transient-define-prefix magit-commit-absorb (phase commit args)
"Spread staged changes across recent commits.
With a prefix argument use a transient command to select infix
@@ -572,7 +572,7 @@ See `magit-commit-autofixup' for an alternative implementation."
(when commit
(setq commit (magit-rebase-interactive-assert commit t)))
(if (and commit (eq phase 'run))
(progn (magit-run-git-async "absorb" args "-b" commit) t)
(prog1 t (magit-run-git-async "absorb" args "-b" commit))
(magit-log-select
(lambda (commit)
(with-no-warnings ; about non-interactive use
@@ -581,7 +581,7 @@ See `magit-commit-autofixup' for an alternative implementation."
(transient-augment-suffix magit-commit-absorb :transient 'transient--do-exit)
;;;###autoload (autoload 'magit-commit-autofixup "magit-commit" nil t)
;;;###autoload(autoload 'magit-commit-autofixup "magit-commit" nil t)
(transient-define-prefix magit-commit-autofixup (phase commit args)
"Spread staged or unstaged changes across recent commits.
@@ -614,7 +614,7 @@ an alternative implementation."
(when commit
(setq commit (magit-rebase-interactive-assert commit t)))
(if (and commit (eq phase 'run))
(progn (magit-run-git-async "autofixup" args commit) t)
(prog1 t (magit-run-git-async "autofixup" args commit))
(magit-log-select
(lambda (commit)
(with-no-warnings ; about non-interactive use
@@ -646,6 +646,7 @@ an alternative implementation."
#'magit-commit-instant-fixup
#'magit-commit-instant-squash))
;;;###autoload
(defun magit-run-post-commit-hook ()
(when (and (not this-command)
(memq last-command magit-post-commit-hook-commands))
@@ -707,8 +708,8 @@ an alternative implementation."
(cond
((not
(and (eq this-command 'magit-diff-while-committing)
(and-let* ((buf (magit-get-mode-buffer
'magit-diff-mode nil 'selected)))
(and-let ((buf (magit-get-mode-buffer
'magit-diff-mode nil 'selected)))
(and (equal rev (buffer-local-value 'magit-buffer-range buf))
(equal arg (buffer-local-value 'magit-buffer-typearg buf)))))))
((eq command 'magit-commit-amend)
@@ -784,7 +785,7 @@ actually insert the entry."
(narrow-to-region (point-min) (point))
(cond ((re-search-backward (format "* %s\\(?: (\\([^)]+\\))\\)?: " file)
nil t)
(when (equal (match-string 1) defun)
(when (equal (match-str 1) defun)
(setq defun nil))
(re-search-forward ": "))
(t
@@ -813,4 +814,15 @@ actually insert the entry."
;;; _
(provide 'magit-commit)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-commit.el ends here

View File

@@ -120,4 +120,15 @@ Each of these options falls into one or more of these categories:
;;; _
(provide 'magit-core)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-core.el ends here

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,8 @@
(require 'magit)
(require 'dired)
;; For `magit-do-async-shell-command'.
(declare-function dired-read-shell-command "dired-aux" (prompt arg files))
@@ -40,7 +42,9 @@ With a prefix argument, visit in another window. If there
is no file at point, then instead visit `default-directory'."
(interactive "P")
(dired-jump other-window
(and-let* ((file (magit-file-at-point)))
(and-let ((file (if (derived-mode-p 'magit-repolist-mode)
(tabulated-list-get-id)
(magit-file-at-point))))
(expand-file-name (if (file-directory-p file)
(file-name-as-directory file)
file)))))
@@ -106,4 +110,15 @@ Interactively, open the file at point."
;;; _
(provide 'magit-dired)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-dired.el ends here

View File

@@ -115,7 +115,7 @@ recommend you do not further complicate that by enabling this.")
(defvar magit-ediff-previous-winconf nil)
;;;###autoload (autoload 'magit-ediff "magit-ediff" nil)
;;;###autoload(autoload 'magit-ediff "magit-ediff" nil)
(transient-define-prefix magit-ediff ()
"Show differences using the Ediff package."
:info-manual "(ediff)"
@@ -266,21 +266,21 @@ and alternative commands."
(goto-char (point-min))
(unless (re-search-forward "^<<<<<<< " nil t)
(magit-stage-files (list file)))))))))
(if fileC
(magit-ediff-buffers
((magit-get-revision-buffer revA fileA)
(magit-find-file-noselect revA fileA))
((magit-get-revision-buffer revB fileB)
(magit-find-file-noselect revB fileB))
((magit-get-revision-buffer revC fileC)
(magit-find-file-noselect revC fileC))
setup quit file)
(magit-ediff-buffers
((magit-get-revision-buffer revA fileA)
(magit-find-file-noselect revA fileA))
((magit-get-revision-buffer revB fileB)
(magit-find-file-noselect revB fileB))
nil setup quit file))))))
(cond (fileC
(magit-ediff-buffers
((magit-get-revision-buffer revA fileA)
(magit-find-file-noselect revA fileA))
((magit-get-revision-buffer revB fileB)
(magit-find-file-noselect revB fileB))
((magit-get-revision-buffer revC fileC)
(magit-find-file-noselect revC fileC))
setup quit file))
((magit-ediff-buffers
((magit-get-revision-buffer revA fileA)
(magit-find-file-noselect revA fileA))
((magit-get-revision-buffer revB fileB)
(magit-find-file-noselect revB fileB))
nil setup quit file)))))))
;;;###autoload
(defun magit-ediff-resolve-rest (file)
@@ -332,7 +332,7 @@ FILE has to be relative to the top directory of the repository."
(bufC* (or bufC (find-file-noselect file)))
(coding-system-for-read
(buffer-local-value 'buffer-file-coding-system bufC*))
(bufA* (magit-find-file-noselect-1 "HEAD" file t))
(bufA* (magit-find-file-noselect "HEAD" file t))
(bufB* (magit-find-file-index-noselect file t)))
(with-current-buffer bufB* (setq buffer-read-only nil))
(magit-ediff-buffers
@@ -488,8 +488,7 @@ mind at all, then it asks the user for a command to run."
(magit-ediff-show-stash revB))
(file
(funcall command file))
(t
(call-interactively command)))))))
((call-interactively command)))))))
;;;###autoload
(defun magit-ediff-show-staged (file)
@@ -602,4 +601,15 @@ stash that were staged."
;;; _
(provide 'magit-ediff)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-ediff.el ends here

View File

@@ -42,7 +42,7 @@
;;; Git Tools
;;;; Git-Mergetool
;;;###autoload (autoload 'magit-git-mergetool "magit-extras" nil t)
;;;###autoload(autoload 'magit-git-mergetool "magit-extras" nil t)
(transient-define-prefix magit-git-mergetool (file args &optional transient)
"Resolve conflicts in FILE using \"git mergetool --gui\".
With a prefix argument allow changing ARGS using a transient
@@ -205,9 +205,6 @@ to nil before loading Magit to prevent \"m\" from being bound.")
(with-eval-after-load 'project
(when (and magit-bind-magit-project-status
;; Added in Emacs 28.1.
(boundp 'project-prefix-map)
(boundp 'project-switch-commands)
;; Only modify if it hasn't already been modified.
(equal project-switch-commands
(eval (car (get 'project-switch-commands 'standard-value))
@@ -282,7 +279,7 @@ with two prefix arguments remove ignored files only.
(1 "untracked")
(4 "untracked and ignored")
(_ "ignored"))))
(magit-wip-commit-before-change)
(magit-run-before-change-functions nil "clean")
(magit-run-git "clean" "-f" "-d" (pcase arg (4 "-x") (16 "-X")))))
(put 'magit-clean 'disabled t)
@@ -335,10 +332,7 @@ a position in a file-visiting buffer."
(prompt-for-change-log-name)))
(pcase-let ((`(,buf ,pos) (magit-diff-visit-file--noselect)))
(magit--with-temp-position buf pos
(let ((add-log-buffer-file-name-function
(lambda ()
(or magit-buffer-file-name
(buffer-file-name)))))
(let ((add-log-buffer-file-name-function #'magit-buffer-file-name))
(add-change-log-entry whoami file-name other-window)))))
;;;###autoload
@@ -396,7 +390,7 @@ points at it) otherwise."
(put 'magit-edit-line-commit 'disabled t)
;;;###autoload
(defun magit-diff-edit-hunk-commit (file)
(defun magit-diff-edit-hunk-commit ()
"From a hunk, edit the respective commit and visit the file.
First visit the file being modified by the hunk at the correct
@@ -413,10 +407,10 @@ to be visited.
Neither the blob nor the file buffer are killed when finishing
the rebase. If that is undesirable, then it might be better to
use `magit-rebase-edit-commit' instead of this command."
(interactive (list (magit-file-at-point t t)))
(interactive)
(let ((magit-diff-visit-previous-blob nil))
(with-current-buffer
(magit-diff-visit-file--internal file nil #'pop-to-buffer-same-window)
(magit-diff-visit-file--internal nil #'pop-to-buffer-same-window)
(magit-edit-line-commit))))
(put 'magit-diff-edit-hunk-commit 'disabled t)
@@ -609,47 +603,45 @@ the minibuffer too."
default-directory))
(push (caar magit-revision-stack) magit-revision-history)
(pop magit-revision-stack)))
(if rev
(pcase-let ((`(,pnt-format ,eob-format ,idx-format)
magit-pop-revision-stack-format))
(let ((default-directory toplevel)
(idx (and idx-format
(save-excursion
(if (re-search-backward idx-format nil t)
(number-to-string
(1+ (string-to-number (match-string 1))))
"1"))))
pnt-args eob-args)
(when (listp pnt-format)
(setq pnt-args (cdr pnt-format))
(setq pnt-format (car pnt-format)))
(when (listp eob-format)
(setq eob-args (cdr eob-format))
(setq eob-format (car eob-format)))
(when pnt-format
(when idx-format
(setq pnt-format
(string-replace "%N" idx pnt-format)))
(magit-rev-insert-format pnt-format rev pnt-args)
(delete-char -1))
(when eob-format
(when idx-format
(setq eob-format
(string-replace "%N" idx eob-format)))
(save-excursion
(goto-char (point-max))
(skip-syntax-backward ">-")
(beginning-of-line)
(if (and comment-start (looking-at comment-start))
(while (looking-at comment-start)
(forward-line -1))
(forward-line)
(unless (= (current-column) 0)
(insert ?\n)))
(insert ?\n)
(magit-rev-insert-format eob-format rev eob-args)
(delete-char -1)))))
(user-error "Revision stack is empty")))
(unless rev
(user-error "Revision stack is empty"))
(pcase-let ((`(,pnt-format ,eob-format ,idx-format)
magit-pop-revision-stack-format))
(let ((default-directory toplevel)
(idx (and idx-format
(if (save-excursion
(re-search-backward idx-format nil t))
(number-to-string (1+ (string-to-number (match-str 1))))
"1")))
(pnt-args nil)
(eob-args nil))
(when (listp pnt-format)
(setq pnt-args (cdr pnt-format))
(setq pnt-format (car pnt-format)))
(when (listp eob-format)
(setq eob-args (cdr eob-format))
(setq eob-format (car eob-format)))
(when pnt-format
(when idx-format
(setq pnt-format (string-replace "%N" idx pnt-format)))
(magit-rev-insert-format pnt-format rev pnt-args)
(delete-char -1))
(when eob-format
(when idx-format
(setq eob-format (string-replace "%N" idx eob-format)))
(save-excursion
(goto-char (point-max))
(skip-syntax-backward ">-")
(beginning-of-line)
(if (and comment-start (looking-at comment-start))
(while (looking-at comment-start)
(forward-line -1))
(forward-line)
(unless (= (current-column) 0)
(insert ?\n)))
(insert ?\n)
(magit-rev-insert-format eob-format rev eob-args)
(delete-char -1))))))
;;;###autoload
(defun magit-copy-section-value (arg)
@@ -675,42 +667,41 @@ a hunk, then strip the diff marker column and keep only either
the added or removed lines, depending on the sign of the prefix
argument."
(interactive "P")
(cond
((and arg
(magit-section-internal-region-p)
(magit-section-match 'hunk))
(kill-new
(thread-last (buffer-substring-no-properties
(region-beginning)
(region-end))
(replace-regexp-in-string
(format "^\\%c.*\n?" (if (< (prefix-numeric-value arg) 0) ?+ ?-))
"")
(replace-regexp-in-string "^[ +-]" "")))
(deactivate-mark))
((use-region-p)
(call-interactively #'copy-region-as-kill))
(t
(when-let* ((section (magit-current-section))
(value (oref section value)))
(magit-section-case
((branch commit module-commit tag)
(let ((default-directory default-directory) ref)
(magit-section-case
((branch tag)
(setq ref value))
(module-commit
(setq default-directory
(file-name-as-directory
(expand-file-name (magit-section-parent-value section)
(magit-toplevel))))))
(setq value (magit-rev-parse
(and magit-copy-revision-abbreviated "--short")
value))
(push (list value default-directory) magit-revision-stack)
(kill-new (message "%s" (or (and current-prefix-arg ref)
value)))))
(t (kill-new (message "%s" value))))))))
(cond-let*
((and arg
(magit-section-internal-region-p)
(magit-section-match 'hunk))
(kill-new
(thread-last (buffer-substring-no-properties
(region-beginning)
(region-end))
(replace-regexp-in-string
(format "^\\%c.*\n?" (if (< (prefix-numeric-value arg) 0) ?+ ?-))
"")
(replace-regexp-in-string "^[ +-]" "")))
(deactivate-mark))
((use-region-p)
(call-interactively #'copy-region-as-kill))
([section (magit-current-section)]
[value (oref section value)]
(magit-section-case
((branch commit module-commit tag)
(let ((default-directory default-directory) ref)
(magit-section-case
((branch tag)
(setq ref value))
(module-commit
(setq default-directory
(file-name-as-directory
(expand-file-name (magit-section-parent-value section)
(magit-toplevel))))))
(setq value (magit-rev-parse
(and magit-copy-revision-abbreviated "--short")
value))
(push (list value default-directory) magit-revision-stack)
(kill-new (message "%s" (or (and current-prefix-arg ref)
value)))))
(t (kill-new (message "%s" value)))))))
;;;###autoload
(defun magit-copy-buffer-revision ()
@@ -739,22 +730,23 @@ When `magit-copy-revision-abbreviated' is non-nil, save the
abbreviated revision to the `kill-ring' and the
`magit-revision-stack'."
(interactive)
(if (use-region-p)
(call-interactively #'copy-region-as-kill)
(when-let ((rev (or magit-buffer-revision
(cl-case major-mode
(magit-diff-mode
(if (string-match "\\.\\.\\.?\\(.+\\)"
magit-buffer-range)
(match-string 1 magit-buffer-range)
magit-buffer-range))
(magit-status-mode "HEAD")))))
(when (magit-commit-p rev)
(setq rev (magit-rev-parse
(and magit-copy-revision-abbreviated "--short")
rev))
(push (list rev default-directory) magit-revision-stack)
(kill-new (message "%s" rev))))))
(cond-let*
((use-region-p)
(call-interactively #'copy-region-as-kill))
([rev (or magit-buffer-revision
(cl-case major-mode
(magit-diff-mode
(if (string-match "\\.\\.\\.?\\(.+\\)"
magit-buffer-range)
(match-str 1 magit-buffer-range)
magit-buffer-range))
(magit-status-mode "HEAD")))]
[_(magit-commit-p rev)]
(setq rev (magit-rev-parse
(and magit-copy-revision-abbreviated "--short")
rev))
(push (list rev default-directory) magit-revision-stack)
(kill-new (message "%s" rev)))))
;;; Buffer Switching
@@ -835,4 +827,15 @@ In Magit diffs, also skip over - and + at the beginning of the line."
;;; _
(provide 'magit-extras)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-extras.el ends here

View File

@@ -30,7 +30,7 @@
;;; Commands
;;;###autoload (autoload 'magit-fetch "magit-fetch" nil t)
;;;###autoload(autoload 'magit-fetch "magit-fetch" nil t)
(transient-define-prefix magit-fetch ()
"Fetch from another repository."
:man-page "git-fetch"
@@ -58,7 +58,7 @@
(run-hooks 'magit-credential-hook)
(magit-run-git-async "fetch" remote args))
;;;###autoload (autoload 'magit-fetch-from-pushremote "magit-fetch" nil t)
;;;###autoload(autoload 'magit-fetch-from-pushremote "magit-fetch" nil t)
(transient-define-suffix magit-fetch-from-pushremote (args)
"Fetch from the current push-remote.
@@ -84,10 +84,9 @@ push-remote."
((member remote (magit-list-remotes)) remote)
(remote
(format "%s, replacing invalid" v))
(t
(format "%s, setting that" v)))))
((format "%s, setting that" v)))))
;;;###autoload (autoload 'magit-fetch-from-upstream "magit-fetch" nil t)
;;;###autoload(autoload 'magit-fetch-from-upstream "magit-fetch" nil t)
(transient-define-suffix magit-fetch-from-upstream (remote args)
"Fetch from the \"current\" remote, usually the upstream.
@@ -156,7 +155,7 @@ removed on the respective remote."
(run-hooks 'magit-credential-hook)
(magit-run-git-async "remote" "update"))
;;;###autoload (autoload 'magit-fetch-modules "magit-fetch" nil t)
;;;###autoload(autoload 'magit-fetch-modules "magit-fetch" nil t)
(transient-define-prefix magit-fetch-modules (&optional transient args)
"Fetch all populated submodules.
@@ -183,4 +182,15 @@ with a prefix argument."
;;; _
(provide 'magit-fetch)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-fetch.el ends here

View File

@@ -68,17 +68,15 @@ the line and column corresponding to that location."
(defun magit-find-file-read-args (prompt)
(let ((pseudo-revs '("{worktree}" "{index}")))
(if-let ((rev (magit-completing-read "Find file from revision"
(append pseudo-revs
(magit-list-refnames nil t))
nil nil nil 'magit-revision-history
(or (magit-branch-or-commit-at-point)
(magit-get-current-branch)))))
(list rev (magit-read-file-from-rev (if (member rev pseudo-revs)
"HEAD"
rev)
prompt))
(user-error "Nothing selected"))))
(let ((rev (magit-completing-read "Find file from revision"
(append pseudo-revs
(magit-list-refnames nil t))
nil 'any nil 'magit-revision-history
(or (magit-branch-or-commit-at-point)
(magit-get-current-branch)))))
(list rev
(magit-read-file-from-rev (if (member rev pseudo-revs) "HEAD" rev)
prompt)))))
(defun magit-find-file--internal (rev file fn)
(let ((buf (magit-find-file-noselect rev file))
@@ -96,8 +94,7 @@ the line and column corresponding to that location."
(magit-buffer-revision
(setq line (magit-diff-visit--offset
file (concat magit-buffer-revision ".." rev) line)))
(t
(setq line (magit-diff-visit--offset file (list "-R" rev) line)))))
((setq line (magit-diff-visit--offset file (list "-R" rev) line)))))
(funcall fn buf)
(when line
(with-current-buffer buf
@@ -107,39 +104,35 @@ the line and column corresponding to that location."
(move-to-column col)))
buf))
(defun magit-find-file-noselect (rev file)
(defun magit-find-file-noselect (rev file &optional revert)
"Read FILE from REV into a buffer and return the buffer.
REV is a revision or one of \"{worktree}\" or \"{index}\".
FILE must be relative to the top directory of the repository."
(magit-find-file-noselect-1 rev file))
(defun magit-find-file-noselect-1 (rev file &optional revert)
"Read FILE from REV into a buffer and return the buffer.
REV is a revision or one of \"{worktree}\" or \"{index}\".
FILE must be relative to the top directory of the repository.
Non-nil REVERT means to revert the buffer. If `ask-revert',
then only after asking. A non-nil value for REVERT is ignored if REV is
\"{worktree}\"."
(if (equal rev "{worktree}")
(find-file-noselect (expand-file-name file (magit-toplevel)))
(let ((topdir (magit-toplevel)))
(when (file-name-absolute-p file)
(setq file (file-relative-name file topdir)))
(with-current-buffer (magit-get-revision-buffer-create rev file)
REV is a revision or one of \"{worktree}\" or \"{index}\". FILE must
be relative to the top directory of the repository. Non-nil REVERT
means to revert the buffer. If `ask-revert', then only after asking.
A non-nil value for REVERT is ignored if REV is \"{worktree}\"."
(let* ((topdir (magit-toplevel))
(absolute (file-name-absolute-p file))
(file-abs (if absolute file (expand-file-name file topdir)))
(file-rel (if absolute (file-relative-name file topdir) file))
(defdir (file-name-directory file-abs))
(rev (magit--abbrev-if-hash rev)))
(if (equal rev "{worktree}")
(let ((revert-without-query
(if (and$ (find-buffer-visiting file-abs)
(buffer-local-value 'auto-revert-mode $))
(cons "." revert-without-query)
revert-without-query)))
(find-file-noselect file-abs))
(with-current-buffer (magit-get-revision-buffer-create rev file-rel)
(when (or (not magit-buffer-file-name)
(if (eq revert 'ask-revert)
(y-or-n-p (format "%s already exists; revert it? "
(buffer-name))))
revert)
(setq magit-buffer-revision
(if (equal rev "{index}")
"{index}"
(magit-rev-format "%H" rev)))
(setq magit-buffer-revision rev)
(setq magit-buffer-refname rev)
(setq magit-buffer-file-name (expand-file-name file topdir))
(setq default-directory
(let ((dir (file-name-directory magit-buffer-file-name)))
(if (file-exists-p dir) dir topdir)))
(setq magit-buffer-file-name file-abs)
(setq default-directory (if (file-exists-p defdir) defdir topdir))
(setq-local revert-buffer-function #'magit-revert-rev-file-buffer)
(revert-buffer t t)
(run-hooks (if (equal rev "{index}")
@@ -182,7 +175,10 @@ then only after asking. A non-nil value for REVERT is ignored if REV is
global-diff-hl-mode-enable-in-buffers ; Emacs < 30
eglot--maybe-activate-editing-mode)
#'eq)))
(normal-mode t))
;; We want `normal-mode' to respect nil `enable-local-variables'.
;; The FIND-FILE argument wasn't designed for our use case, so we
;; have to use this strange invocation to achieve that.
(normal-mode (not enable-local-variables)))
(setq buffer-read-only t)
(set-buffer-modified-p nil)
(goto-char (point-min))))
@@ -196,11 +192,12 @@ See also https://github.com/doomemacs/doomemacs/pull/6309."
;;; Find Index
(defvar magit-find-index-hook nil)
(add-hook 'magit-find-index-hook #'magit-blob-mode)
(defun magit-find-file-index-noselect (file &optional revert)
"Read FILE from the index into a buffer and return the buffer.
FILE must to be relative to the top directory of the repository."
(magit-find-file-noselect-1 "{index}" file (or revert 'ask-revert)))
(magit-find-file-noselect "{index}" file (or revert 'ask-revert)))
(defun magit-update-index ()
"Update the index with the contents of the current buffer.
@@ -214,8 +211,7 @@ is done using `magit-find-index-noselect'."
(let ((index (make-temp-name
(expand-file-name "magit-update-index-" (magit-gitdir))))
(buffer (current-buffer)))
(when magit-wip-before-change-mode
(magit-wip-commit-before-change (list file) " before un-/stage"))
(magit-run-before-change-functions file "un-/stage")
(unwind-protect
(progn
(let ((coding-system-for-write buffer-file-coding-system))
@@ -232,8 +228,7 @@ is done using `magit-find-index-noselect'."
file)))
(ignore-errors (delete-file index)))
(set-buffer-modified-p nil)
(when magit-wip-after-apply-mode
(magit-wip-commit-after-apply (list file) " after un-/stage")))
(magit-run-after-apply-functions file "un-/stage"))
(message "Abort")))
(when-let ((buffer (magit-get-mode-buffer 'magit-status-mode)))
(with-current-buffer buffer
@@ -292,7 +287,7 @@ directory, while reading the FILENAME."
;;; File Dispatch
;;;###autoload (autoload 'magit-file-dispatch "magit" nil t)
;;;###autoload(autoload 'magit-file-dispatch "magit" nil t)
(transient-define-prefix magit-file-dispatch ()
"Invoke a Magit command that acts on the visited file.
When invoked outside a file-visiting buffer, then fall back
@@ -355,7 +350,7 @@ to `magit-dispatch'."
"b" #'magit-blame-addition
"r" #'magit-blame-removal
"f" #'magit-blame-reverse
"q" #'magit-kill-this-buffer)
"q" #'magit-bury-or-kill-buffer)
(define-minor-mode magit-blob-mode
"Enable some Magit features in blob-visiting buffers.
@@ -364,26 +359,51 @@ Currently this only adds the following key bindings.
\n\\{magit-blob-mode-map}"
:package-version '(magit . "2.3.0"))
(defun magit-blob-next ()
"Visit the next blob which modified the current file."
(interactive)
(if magit-buffer-file-name
(magit-blob-visit (or (magit-blob-successor magit-buffer-revision
magit-buffer-file-name)
magit-buffer-file-name))
(if (buffer-file-name (buffer-base-buffer))
(user-error "You have reached the end of time")
(user-error "Buffer isn't visiting a file or blob"))))
(defun magit-bury-buffer (&optional kill-buffer)
"Bury the current buffer, or with a prefix argument kill it."
(interactive "P")
(if kill-buffer (kill-buffer) (bury-buffer)))
(defun magit-blob-previous ()
"Visit the previous blob which modified the current file."
(defun magit-bury-or-kill-buffer (&optional bury-buffer)
"Bury the current buffer if displayed in multiple windows, else kill it.
With a prefix argument only bury the buffer even if it is only displayed
in a single window."
(interactive "P")
(if (or bury-buffer (cdr (get-buffer-window-list nil nil t)))
(bury-buffer)
(kill-buffer)))
(defun magit-kill-this-buffer ()
"Kill the current buffer."
(interactive)
(if-let ((file (or magit-buffer-file-name
(buffer-file-name (buffer-base-buffer)))))
(if-let ((ancestor (magit-blob-ancestor magit-buffer-revision file)))
(magit-blob-visit ancestor)
(user-error "You have reached the beginning of time"))
(user-error "Buffer isn't visiting a file or blob")))
(kill-buffer))
(transient-define-suffix magit-blob-previous ()
"Visit the previous blob which modified the current file."
:inapt-if-not (##and$ (magit-buffer-file-name)
(magit-blob-ancestor (magit-buffer-revision) $))
(interactive)
(cond-let
[[rev (or magit-buffer-revision "{worktree}")]
[file (magit-buffer-file-name)]]
((not file)
(user-error "Buffer isn't visiting a file or blob"))
([prev (magit-blob-ancestor rev file)]
(apply #'magit-blob-visit prev))
((user-error "You have reached the beginning of time"))))
(transient-define-suffix magit-blob-next ()
"Visit the next blob which modified the current file."
:inapt-if-nil 'magit-buffer-file-name
(interactive)
(cond-let
[[rev (or magit-buffer-revision "{worktree}")]
[file (magit-buffer-file-name)]]
((not file)
(user-error "Buffer isn't visiting a file or blob"))
([next (magit-blob-successor rev file)]
(apply #'magit-blob-visit next))
((user-error "You have reached the end of time"))))
;;;###autoload
(defun magit-blob-visit-file ()
@@ -395,30 +415,40 @@ the same location in the respective file in the working tree."
(magit-find-file--internal "{worktree}" file #'pop-to-buffer-same-window)
(user-error "Not visiting a blob")))
(defun magit-blob-visit (blob-or-file)
(if (stringp blob-or-file)
(find-file blob-or-file)
(pcase-let ((`(,rev ,file) blob-or-file))
(magit-find-file rev file)
(apply #'message "%s (%s %s ago)"
(magit-rev-format "%s" rev)
(magit--age (magit-rev-format "%ct" rev))))))
(defun magit-blob-visit (rev file)
(magit-find-file rev file)
(unless (member rev '("{worktree}" "{index}"))
(apply #'message "%s (%s %s ago)"
(magit-rev-format "%s" rev)
(magit--age (magit-rev-format "%ct" rev)))))
(defun magit-blob-ancestor (rev file)
(let ((lines (magit-with-toplevel
(magit-git-lines "log" "-2" "--format=%H" "--name-only"
"--follow" (or rev "HEAD") "--" file))))
(if rev (cddr lines) (butlast lines 2))))
(pcase rev
((and "{worktree}" (guard (magit-anything-staged-p nil file)))
(list "{index}" file))
((or "{worktree}" "{index}")
(list (magit-rev-abbrev "HEAD") file))
(_ (nth (if rev 1 0)
(magit-with-toplevel
(seq-partition
(magit-git-lines "log" "-2" "--format=%h" "--name-only"
"--follow" (or rev "HEAD") "--" file)
2))))))
(defun magit-blob-successor (rev file)
(let ((lines (magit-with-toplevel
(magit-git-lines "log" "--format=%H" "--name-only" "--follow"
"HEAD" "--" file))))
(catch 'found
(while lines
(if (equal (nth 2 lines) rev)
(throw 'found (list (nth 0 lines) (nth 1 lines)))
(setq lines (nthcdr 2 lines)))))))
(pcase rev
("{worktree}" nil)
("{index}" (list "{worktree}" file))
(_ (let ((lines (magit-with-toplevel
(magit-git-lines "log" "--format=%h" "--name-only"
"--follow" "HEAD" "--" file))))
(catch 'found
(while lines
(if (equal (nth 2 lines) rev)
(throw 'found (list (nth 0 lines) (nth 1 lines)))
(setq lines (nthcdr 2 lines))))
(list (if (magit-anything-staged-p nil file) "{index}" "{worktree}")
file))))))
;;; File Commands
@@ -591,5 +621,19 @@ If DEFAULT is non-nil, use this as the default value instead of
(define-obsolete-function-alias 'magit-unstage-buffer-file
'magit-file-unstage "Magit 4.3.2")
(define-obsolete-function-alias 'magit-find-file-noselect-1
'magit-find-file-noselect "Magit 4.4.0")
(provide 'magit-files)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-files.el ends here

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,7 @@
;;; Transient
;;;###autoload (autoload 'magit-gitignore "magit-gitignore" nil t)
;;;###autoload(autoload 'magit-gitignore "magit-gitignore" nil t)
(transient-define-prefix magit-gitignore ()
"Instruct Git to ignore a file or pattern."
:man-page "gitignore"
@@ -118,9 +118,9 @@ Rules that are defined in that file affect all local repositories."
(mapcan
(lambda (file)
(cons (concat "/" file)
(and-let* ((ext (file-name-extension file)))
(list (concat "/" (file-name-directory file) "*." ext)
(concat "*." ext)))))
(and$ (file-name-extension file)
(list (concat "/" (file-name-directory file) "*." $)
(concat "*." $)))))
(sort (nconc
(magit-untracked-files nil base)
;; The untracked section of the status buffer lists
@@ -138,7 +138,7 @@ Rules that are defined in that file affect all local repositories."
(unless (member default choices)
(setq default nil))))
(magit-completing-read "File or pattern to ignore"
choices nil nil nil nil default)))
choices nil 'any nil nil default)))
;;; Skip Worktree Commands
@@ -192,4 +192,15 @@ Rules that are defined in that file affect all local repositories."
;;; _
(provide 'magit-gitignore)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-gitignore.el ends here

View File

@@ -31,8 +31,7 @@
(require 'magit-core)
(require 'magit-diff)
(declare-function magit--any-wip-mode-enabled-p "magit-wip" ())
(declare-function magit-blob-visit "magit-files" (blob-or-file))
(declare-function magit-blob-visit "magit-files" (rev file))
(declare-function magit-cherry-apply "magit-sequence" (commit &optional args))
(declare-function magit-insert-head-branch-header "magit-status"
(&optional branch))
@@ -48,9 +47,10 @@
(defvar magit-refs-focus-column-width)
(defvar magit-refs-margin)
(defvar magit-refs-show-commit-count)
(defvar magit-buffer-margin)
(defvar magit--right-margin-config)
(defvar magit-status-margin)
(defvar magit-status-sections-hook)
(defvar magit-status-use-buffer-arguments)
(require 'ansi-color)
(require 'crm)
@@ -170,6 +170,23 @@ want to use the same functions for both hooks."
:options (list #'magit-highlight-squash-markers
#'magit-highlight-bracket-keywords))
(defcustom magit-log-trailer-labels nil
"Whether and how to insert labels, derived from commit message trailers.
If non-nil, the value has the form (FUNCTION . OPTIONS). FUNCTION is
called with one argument, the trailers as an alist, and should return a
string, which is then inserted in between the refnames and the message,
or nil. OPTIONS specifies additional options for \"%(trailers)\". You
should probably use something like \"key=KEY1,key=KEY2,only=true\".
\"unfold=true,separator=^^,key_value_separator=^_\" is always appended
to the options specified here. See the git-log(1) manpage."
:package-version '(magit . "4.4.1")
:group 'magit-log
:type '(choice (const :tag "Ignore trailers" nil)
(cons :tag "Process trailers"
(function :tag "Formatting function")
(string :tag "Options for %%(trailers)"))))
(defcustom magit-log-header-line-function #'magit-log-header-line-sentence
"Function used to generate text shown in header line of log buffers."
:package-version '(magit . "2.12.0")
@@ -370,11 +387,15 @@ commits before and half after."
;;;; Prefix Methods
(cl-defmethod transient-prefix-value ((obj magit-log-prefix))
(let ((args (cl-call-next-method obj)))
(list (seq-filter #'atom args)
(cdr (assoc "--" args)))))
(cl-defmethod transient-init-value ((obj magit-log-prefix))
(pcase-let ((`(,args ,files)
(magit-log--get-value 'magit-log-mode
magit-prefix-use-buffer-arguments)))
(when-let (((not (eq transient-current-command 'magit-dispatch)))
(magit-log--get-value 'magit-log-mode 'prefix)))
(when-let ((_(not (eq transient-current-command 'magit-dispatch)))
(file (magit-file-relative-name)))
(setq files (list file)))
(oset obj value (if files `(("--" ,@files) ,@args) args))))
@@ -396,40 +417,38 @@ commits before and half after."
(defun magit-log-arguments (&optional mode)
"Return the current log arguments."
(if (memq transient-current-command '(magit-log magit-log-refresh))
(magit--transient-args-and-files)
(magit-log--get-value (or mode 'magit-log-mode))))
(transient-args transient-current-command)
(magit-log--get-value (or mode 'magit-log-mode) 'direct)))
(defun magit-log--get-value (mode &optional use-buffer-args)
(unless use-buffer-args
(setq use-buffer-args magit-direct-use-buffer-arguments))
(let (args files)
(cond
((and (memq use-buffer-args '(always selected current))
(eq major-mode mode))
(setq args magit-buffer-log-args)
(setq files magit-buffer-log-files))
((when-let (((memq use-buffer-args '(always selected)))
(buffer (magit-get-mode-buffer
mode nil
(eq use-buffer-args 'selected))))
(setq args (buffer-local-value 'magit-buffer-log-args buffer))
(setq files (buffer-local-value 'magit-buffer-log-files buffer))
t))
((plist-member (symbol-plist mode) 'magit-log-current-arguments)
(setq args (get mode 'magit-log-current-arguments)))
((when-let ((elt (assq (intern (format "magit-log:%s" mode))
transient-values)))
(setq args (cdr elt))
t))
(t
(setq args (get mode 'magit-log-default-arguments))))
(list args files)))
(setq use-buffer-args
(pcase-exhaustive use-buffer-args
('prefix magit-prefix-use-buffer-arguments)
('status magit-status-use-buffer-arguments)
('direct magit-direct-use-buffer-arguments)
('nil magit-direct-use-buffer-arguments)
((or 'always 'selected 'current 'never)
use-buffer-args)))
(cond-let
((and (memq use-buffer-args '(always selected current))
(eq major-mode mode))
(list magit-buffer-log-args
magit-buffer-log-files))
([_(memq use-buffer-args '(always selected))]
[buffer (magit-get-mode-buffer mode nil (eq use-buffer-args 'selected))]
(list (buffer-local-value 'magit-buffer-log-args buffer)
(buffer-local-value 'magit-buffer-log-files buffer)))
((plist-member (symbol-plist mode) 'magit-log-current-arguments)
(list (get mode 'magit-log-current-arguments) nil))
([elt (assq (intern (format "magit-log:%s" mode)) transient-values)]
(list (cdr elt) nil))
((list (get mode 'magit-log-default-arguments) nil))))
(defun magit-log--set-value (obj &optional save)
(pcase-let* ((obj (oref obj prototype))
(mode (or (oref obj major-mode) major-mode))
(key (intern (format "magit-log:%s" mode)))
(`(,args ,files) (magit--transient-args-and-files)))
(`(,args ,files) (transient-args (oref obj command))))
(put mode 'magit-log-current-arguments args)
(when save
(setf (alist-get key transient-values) args)
@@ -494,7 +513,7 @@ commits before and half after."
(eq major-mode 'magit-log-mode)
t))
;;;###autoload (autoload 'magit-log "magit-log" nil t)
;;;###autoload(autoload 'magit-log "magit-log" nil t)
(transient-define-prefix magit-log ()
"Show a commit or reference log."
:man-page "git-log"
@@ -516,14 +535,14 @@ commits before and half after."
("r" "current" magit-reflog-current)
("O" "other" magit-reflog-other)
("H" "HEAD" magit-reflog-head)]
[:if magit--any-wip-mode-enabled-p
[:if-mode magit-wip-mode
:description "Wiplog"
("i" "index" magit-wip-log-index)
("w" "worktree" magit-wip-log-worktree)]
["Other"
("s" "shortlog" magit-shortlog)]])
;;;###autoload (autoload 'magit-log-refresh "magit-log" nil t)
;;;###autoload(autoload 'magit-log-refresh "magit-log" nil t)
(transient-define-prefix magit-log-refresh ()
"Change the arguments used for the log(s) in the current buffer."
:man-page "git-log"
@@ -639,13 +658,13 @@ commits before and half after."
"SPC" #'self-insert-command)
(defun magit-log-read-revs (&optional use-current)
(or (and use-current (and-let* ((buf (magit-get-current-branch))) (list buf)))
(or (and use-current (and$ (magit-get-current-branch) (list $)))
(let ((crm-separator "\\(\\.\\.\\.?\\|[, ]\\)")
(crm-local-completion-map magit-log-read-revs-map))
(split-string (magit-completing-read-multiple
"Log rev,s: "
(magit-list-refnames nil t)
nil nil nil 'magit-revision-history
nil 'any nil 'magit-revision-history
(or (magit-branch-or-commit-at-point)
(and (not use-current)
(magit-get-previous-branch)))
@@ -656,7 +675,7 @@ commits before and half after."
"Read a string from the user to pass as parameter to OPTION."
(magit-read-string (format "Type a pattern to pass to %s" option)))
;;;###autoload (autoload 'magit-log-current "magit-log" nil t)
;;;###autoload(autoload 'magit-log-current "magit-log" nil t)
(transient-define-suffix magit-log-current (&optional args files)
"Show log for the current branch, or `HEAD' if no branch is checked out."
:description (##if (magit-get-current-branch) "current" "HEAD")
@@ -722,18 +741,18 @@ completion candidates."
;;;###autoload
(defun magit-log-matching-branches (pattern &optional args files)
"Show log for all branches matching PATTERN and `HEAD'."
(interactive (cons (magit-log-read-pattern "--branches") (magit-log-arguments)))
(magit-log-setup-buffer
(list "HEAD" (format "--branches=%s" pattern))
args files))
(interactive (cons (magit-log-read-pattern "--branches")
(magit-log-arguments)))
(magit-log-setup-buffer (list "HEAD" (format "--branches=%s" pattern))
args files))
;;;###autoload
(defun magit-log-matching-tags (pattern &optional args files)
"Show log for all tags matching PATTERN and `HEAD'."
(interactive (cons (magit-log-read-pattern "--tags") (magit-log-arguments)))
(magit-log-setup-buffer
(list "HEAD" (format "--tags=%s" pattern))
args files))
(interactive (cons (magit-log-read-pattern "--tags")
(magit-log-arguments)))
(magit-log-setup-buffer (list "HEAD" (format "--tags=%s" pattern))
args files))
;;;###autoload
(defun magit-log-all-branches (&optional args files)
@@ -748,10 +767,7 @@ completion candidates."
(defun magit-log-all (&optional args files)
"Show log for all references and `HEAD'."
(interactive (magit-log-arguments))
(magit-log-setup-buffer (if (magit-get-current-branch)
(list "--all")
(list "HEAD" "--all"))
args files))
(magit-log-setup-buffer (list "--all") args files))
;;;###autoload
(defun magit-log-buffer-file (&optional follow beg end)
@@ -865,6 +881,13 @@ https://github.com/mhagger/git-when-merged."
(user-error "Could not find when %s was merged into %s: %s"
commit branch m)))))
;;;###autoload
(defun magit-delete-shelved-branch (branch)
"Delete the shelved BRANCH.
Delete a ref created by `magit-branch-shelve'."
(interactive (list (magit-read-shelved-branch "Log shelved branch")))
(magit-run-git "update-ref" "-d" (concat "refs/shelved/" branch)))
;;;; Limit Commands
(defun magit-log-toggle-commit-limit ()
@@ -887,7 +910,7 @@ limit. Otherwise set it to 256."
(defun magit-log-set-commit-limit (fn)
(let* ((val magit-buffer-log-args)
(arg (seq-find (##string-match "^-n\\([0-9]+\\)?$" %) val))
(num (and arg (string-to-number (match-string 1 arg))))
(num (and arg (string-to-number (match-str 1 arg))))
(num (if num (funcall fn num 2) 256)))
(setq val (remove arg val))
(setq magit-buffer-log-args
@@ -897,9 +920,9 @@ limit. Otherwise set it to 256."
(magit-refresh))
(defun magit-log-get-commit-limit (&optional args)
(and-let* ((str (seq-find (##string-match "^-n\\([0-9]+\\)?$" %)
(or args magit-buffer-log-args))))
(string-to-number (match-string 1 str))))
(and$ (seq-find (##string-match "^-n\\([0-9]+\\)?$" %)
(or args magit-buffer-log-args))
(string-to-number (match-str 1 $))))
;;;; Mode Commands
@@ -909,15 +932,15 @@ Like `magit-mode-bury-buffer' (which see) but with a negative
prefix argument instead bury the revision buffer, provided it
is displayed in the current frame."
(interactive "p")
(if (< arg 0)
(let* ((buf (magit-get-mode-buffer 'magit-revision-mode))
(win (and buf (get-buffer-window buf (selected-frame)))))
(if win
(with-selected-window win
(with-current-buffer buf
(magit-mode-bury-buffer (> (abs arg) 1))))
(user-error "No revision buffer in this frame")))
(magit-mode-bury-buffer (> arg 1))))
(cond-let*
((>= arg 0)
(magit-mode-bury-buffer (> arg 1)))
([buf (magit-get-mode-buffer 'magit-revision-mode)]
[win (get-buffer-window buf (selected-frame))]
(with-selected-window win
(with-current-buffer buf
(magit-mode-bury-buffer (> (abs arg) 1)))))
((user-error "No revision buffer in this frame"))))
;;;###autoload
(defun magit-log-move-to-parent (&optional n)
@@ -947,27 +970,25 @@ nothing else.
If invoked outside any log buffer, then display the log buffer
of the current repository first; creating it if necessary."
(interactive
(list (or (magit-completing-read
"In log, jump to"
(magit-list-refnames nil t)
nil nil nil 'magit-revision-history
(or (and-let* ((rev (magit-commit-at-point)))
(magit-rev-fixup-target rev))
(magit-get-current-branch)))
(user-error "Nothing selected"))))
(list (magit-completing-read
"In log, jump to"
(magit-list-refnames nil t)
nil 'any nil 'magit-revision-history
(or (and$ (magit-commit-at-point)
(magit-rev-fixup-target $))
(magit-get-current-branch)))))
(with-current-buffer
(cond ((derived-mode-p 'magit-log-mode)
(current-buffer))
((and-let* ((buf (magit-get-mode-buffer 'magit-log-mode)))
(pop-to-buffer-same-window buf)))
(t
(apply #'magit-log-all-branches (magit-log-arguments))))
((and$ (magit-get-mode-buffer 'magit-log-mode)
(pop-to-buffer-same-window $)))
((apply #'magit-log-all-branches (magit-log-arguments))))
(unless (magit-log-goto-commit-section (magit-rev-abbrev commit))
(user-error "%s isn't visible in the current log buffer" commit))))
;;;; Shortlog Commands
;;;###autoload (autoload 'magit-shortlog "magit-log" nil t)
;;;###autoload(autoload 'magit-shortlog "magit-log" nil t)
(transient-define-prefix magit-shortlog ()
"Show a history summary."
:man-page "git-shortlog"
@@ -1203,6 +1224,19 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
(declare (obsolete magit--insert-log "Magit 4.0.0"))
(magit--insert-log nil revs args files))
(defconst magit-log-heading-format
;; See `magit-log-heading-re'.
(concat "--format="
"%s" ; 4 graph --graph
"%%h%%x0c" ; 1 %h hash
"%s%%x0c" ; 3 %D refs --decorate
"%s%%x0c" ; 7 %G? gpg --show-signature
"%%aN%%x0c" ; 5 %aN author
"%s%%x0c" ; 6 %at date magit-log-margin-show-committer-date
"%s%%x0c" ; 12 %() trailers magit-log-trailer-labels
"%%s" ; 2 %s msg
"%s")) ; \n .. headers magit-log-revision-headers-format
(defun magit--insert-log (keep-error revs &optional args files)
"Insert a log section.
Do not add this to a hook variable."
@@ -1212,7 +1246,7 @@ Do not add this to a hook variable."
(remove "--literal-pathspecs" magit-git-global-arguments)))
(magit--git-wash (apply-partially #'magit-log-wash-log 'log) keep-error
"log"
(format "--format=%s%%h%%x0c%s%%x0c%s%%x0c%%aN%%x0c%s%%x0c%%s%s"
(format magit-log-heading-format
(if (and (member "--left-right" args)
(not (member "--graph" args)))
"%m "
@@ -1235,6 +1269,13 @@ Do not add this to a hook variable."
"")
("%G?"))))
(if magit-log-margin-show-committer-date "%ct" "%at")
(if magit-log-trailer-labels
(format "%%(trailers:%s%s)"
(if (not (equal (cdr magit-log-trailer-labels) ""))
(concat (cdr magit-log-trailer-labels) ",")
"")
"unfold=true,separator=,key_value_separator=")
"")
(if (member "++header" args)
(if (member "--graph" (setq args (remove "++header" args)))
(concat "\n" magit-log-revision-headers-format "\n")
@@ -1243,7 +1284,7 @@ Do not add this to a hook variable."
(progn
(when-let ((order (seq-find (##string-match "^\\+\\+order=\\(.+\\)$" %)
args)))
(setq args (cons (format "--%s-order" (match-string 1 order))
(setq args (cons (format "--%s-order" (match-str 1 order))
(remove order args))))
(when (member "--decorate" args)
(setq args (cons "--decorate=full" (remove "--decorate" args))))
@@ -1271,18 +1312,20 @@ Do not add this to a hook variable."
:parent magit-commit-section-map)
(defconst magit-log-heading-re
;; Note: A form feed instead of a null byte is used as the delimiter
;; because using the latter interferes with the graph prefix when
;; ++header is used.
;; Use a form feed instead of a null byte as the delimiter because using
;; the latter interferes with the graph prefix when ++header is used.
(concat "^"
"\\(?4:[-_/|\\*o<>. ]*\\)" ; graph
"\\(?1:[0-9a-fA-F]+\\)? " ; hash
"\\(?3:[^ \n]+\\)? " ; refs
"\\(?7:[BGUXYREN]\\)? " ; gpg
"\\(?5:[^ \n]*\\) " ; author
;; Note: Date is optional because, prior to Git v2.19.0,
;; `git rebase -i --root` corrupts the root's author date.
;; Prior to Git v2.19.0, "git rebase -i --root" corrupted the
;; root's author date. Keep date optional because even though
;; we no longer support such old releases, the roots they create
;; may live on.
"\\(?6:[^ \n]*\\) " ; date
"\\(?12:[^ \n]+\\)? " ; trailers
"\\(?2:.*\\)$")) ; msg
(defconst magit-log-cherry-re
@@ -1376,129 +1419,145 @@ Do not add this to a hook variable."
('stash magit-log-stash-re)
('bisect-vis magit-log-bisect-vis-re)
('bisect-log magit-log-bisect-log-re)))
(magit-bind-match-strings
(hash msg refs graph author date gpg cherry _ refsub side) nil
(setq msg (substring-no-properties msg))
(when refs
(setq refs (substring-no-properties refs)))
(let ((align (or (eq style 'cherry)
(not (member "--stat" magit-buffer-log-args))))
(non-graph-re (if (eq style 'bisect-vis)
magit-log-bisect-vis-re
magit-log-heading-re)))
(magit-delete-line)
;; If the reflog entries have been pruned, the output of `git
;; reflog show' includes a partial line that refers to the hash
;; of the youngest expired reflog entry.
(when (and (eq style 'reflog) (not date))
(cl-return-from magit-log-wash-rev t))
(magit-insert-section
((eval (pcase style
('stash 'stash)
('module 'module-commit)
(_ 'commit)))
hash)
(setq hash (propertize (if (eq style 'bisect-log)
(magit-rev-parse "--short" hash)
hash)
'font-lock-face
(pcase (and gpg (aref gpg 0))
(?G 'magit-signature-good)
(?B 'magit-signature-bad)
(?U 'magit-signature-untrusted)
(?X 'magit-signature-expired)
(?Y 'magit-signature-expired-key)
(?R 'magit-signature-revoked)
(?E 'magit-signature-error)
(?N 'magit-hash)
(_ 'magit-hash))))
(when cherry
(when (and (derived-mode-p 'magit-refs-mode)
magit-refs-show-commit-count)
(insert (make-string (1- magit-refs-focus-column-width) ?\s)))
(insert (propertize cherry 'font-lock-face
(if (string= cherry "-")
'magit-cherry-equivalent
'magit-cherry-unmatched)))
(insert ?\s))
(when side
(insert (propertize side 'font-lock-face
(if (string= side "<")
'magit-cherry-equivalent
'magit-cherry-unmatched)))
(insert ?\s))
(when align
(insert hash ?\s))
(when graph
(insert graph))
(unless align
(insert hash ?\s))
(when (and refs (not magit-log-show-refname-after-summary))
(insert (magit-format-ref-labels refs) ?\s))
(when (eq style 'reflog)
(insert (format "%-2s " (1- magit-log-count)))
(when refsub
(insert (magit-reflog-format-subject
(substring refsub 0
(if (string-search ":" refsub) -2 -1))))))
(insert (magit-log--wash-summary msg))
(when (and refs magit-log-show-refname-after-summary)
(insert ?\s)
(insert (magit-format-ref-labels refs)))
(insert ?\n)
(when (memq style '(log reflog stash))
(goto-char (line-beginning-position))
(when (and refsub
(string-match "\\`\\([^ ]\\) \\+\\(..\\)\\(..\\)" date))
(setq date (+ (string-to-number (match-string 1 date))
(* (string-to-number (match-string 2 date)) 60 60)
(* (string-to-number (match-string 3 date)) 60))))
(magit-log-format-margin hash author date))
(when (and (eq style 'cherry)
(magit-buffer-margin-p))
(apply #'magit-log-format-margin hash
(split-string (magit-rev-format "%aN%x00%ct" hash) "\0")))
(when (and graph
(not (eobp))
(not (looking-at non-graph-re)))
(when (looking-at "")
(let* ((hash (match-str 1))
(msg (match-str 2))
(refs (match-str 3))
(refs (and refs (magit-format-ref-labels refs)))
(graph (match-string 4))
(author (match-str 5))
(date (match-str 6))
(gpg (match-str 7))
(cherry (match-str 8))
(refsub (match-str 10))
(side (match-str 11))
(trailers (match-str 12))
(trailers (and trailers
(funcall (car magit-log-trailer-labels)
(mapcar (##split-string % "")
(split-string trailers "")))))
(align (or (eq style 'cherry)
(not (member "--stat" magit-buffer-log-args))))
(non-graph-re (if (eq style 'bisect-vis)
magit-log-bisect-vis-re
magit-log-heading-re)))
(magit-delete-line)
;; If the reflog entries have been pruned, the output of `git
;; reflog show' includes a partial line that refers to the hash
;; of the youngest expired reflog entry.
(when (and (eq style 'reflog) (not date))
(cl-return-from magit-log-wash-rev t))
(magit-insert-section
((eval (pcase style
('stash 'stash)
('module 'module-commit)
(_ 'commit)))
hash)
(setq hash (propertize (if (eq style 'bisect-log)
(magit-rev-parse "--short" hash)
hash)
'font-lock-face
(pcase (and gpg (aref gpg 0))
(?G 'magit-signature-good)
(?B 'magit-signature-bad)
(?U 'magit-signature-untrusted)
(?X 'magit-signature-expired)
(?Y 'magit-signature-expired-key)
(?R 'magit-signature-revoked)
(?E 'magit-signature-error)
(?N 'magit-hash)
(_ 'magit-hash))))
(when cherry
(when (and (derived-mode-p 'magit-refs-mode)
magit-refs-show-commit-count)
(insert (make-string (1- magit-refs-focus-column-width) ?\s)))
(insert (propertize cherry 'font-lock-face
(if (string= cherry "-")
'magit-cherry-equivalent
'magit-cherry-unmatched)))
(insert ?\s))
(when side
(insert (propertize side 'font-lock-face
(if (string= side "<")
'magit-cherry-equivalent
'magit-cherry-unmatched)))
(insert ?\s))
(when align
(insert hash ?\s))
(when graph
(insert graph))
(unless align
(insert hash ?\s))
(unless magit-log-show-refname-after-summary
(when refs
(insert refs ?\s))
(when trailers
(insert trailers ?\s)))
(when (eq style 'reflog)
(insert (format "%-2s " (1- magit-log-count)))
(when refsub
(insert (magit-reflog-format-subject
(substring refsub 0
(if (string-search ":" refsub) -2 -1))))))
(insert (magit-log--wash-summary msg))
(when magit-log-show-refname-after-summary
(when refs
(insert ?\s refs))
(when trailers
(insert ?\s trailers)))
(insert ?\n)
(when (memq style '(log reflog stash))
(goto-char (line-beginning-position))
(when (and refsub
(string-match "\\`\\([^ ]\\) \\+\\(..\\)\\(..\\)" date))
(setq date (+ (string-to-number (match-str 1 date))
(* (string-to-number (match-str 2 date)) 60 60)
(* (string-to-number (match-str 3 date)) 60))))
(magit-log-format-margin hash author date))
(when (and (eq style 'cherry)
(magit--right-margin-active))
(apply #'magit-log-format-margin hash
(split-string (magit-rev-format "%aN%x00%ct" hash) "\0")))
(when (and graph
(not (eobp))
(not (looking-at non-graph-re)))
(when (looking-at "")
(magit-insert-heading)
(delete-char 1)
(magit-insert-section (commit-header)
(forward-line)
(magit-insert-heading)
(delete-char 1)
(magit-insert-section (commit-header)
(forward-line)
(magit-insert-heading)
(re-search-forward "")
(delete-char -1)
(forward-char)
(insert ?\n))
(delete-char 1))
(if (looking-at "^\\(---\\|\n\s\\|\ndiff\\)")
(let ((limit (save-excursion
(and (re-search-forward non-graph-re nil t)
(match-beginning 0)))))
(unless (oref magit-insert-section--current content)
(magit-insert-heading))
(delete-char (if (looking-at "\n") 1 4))
(magit-diff-wash-diffs (list "--stat") limit))
(re-search-forward "")
(delete-char -1)
(forward-char)
(insert ?\n))
(delete-char 1))
(if (looking-at "^\\(---\\|\n\s\\|\ndiff\\)")
(let ((limit (save-excursion
(and (re-search-forward non-graph-re nil t)
(match-beginning 0)))))
(unless (oref magit-insert-section--current content)
(magit-insert-heading))
(delete-char (if (looking-at "\n") 1 4))
(magit-diff-wash-diffs (list "--stat") limit))
(when align
(setq align (make-string (1+ abbrev) ? )))
(when (and (not (eobp)) (not (looking-at non-graph-re)))
(when align
(setq align (make-string (1+ abbrev) ? )))
(when (and (not (eobp)) (not (looking-at non-graph-re)))
(while (and (not (eobp)) (not (looking-at non-graph-re)))
(when align
(setq align (make-string (1+ abbrev) ? )))
(while (and (not (eobp)) (not (looking-at non-graph-re)))
(when align
(save-excursion (insert align)))
(forward-line)
(magit-make-margin-overlay))
;; When `--format' is used and its value isn't one of the
;; predefined formats, then `git-log' does not insert a
;; separator line.
(save-excursion
(forward-line -1)
(looking-at "[-_/|\\*o<>. ]*"))
(setq graph (match-string 0))
(unless (string-match-p "[/\\.]" graph)
(insert graph ?\n))))))))
(save-excursion (insert align)))
(forward-line)
(magit-make-margin-overlay))
;; When `--format' is used and its value isn't one of the
;; predefined formats, then `git-log' does not insert a
;; separator line.
(save-excursion
(forward-line -1)
(looking-at "[-_/|\\*o<>. ]*"))
(setq graph (match-string 0))
(unless (string-match-p "[/\\.]" graph)
(insert graph ?\n)))))))
t)
(defun magit-log--wash-summary (summary)
@@ -1582,9 +1641,9 @@ See also info node `(magit)Section Movement'."
(with-selected-window (get-buffer-window buf)
(with-current-buffer buf
(save-excursion
(magit-blob-visit (list (magit-rev-parse rev)
(magit-file-relative-name
magit-buffer-file-name)))))))))))))
(magit-blob-visit (magit-rev-parse rev)
(magit-file-relative-name
magit-buffer-file-name))))))))))))
(defun magit-log-goto-commit-section (rev)
(let ((abbrev (magit-rev-format "%h" rev)))
@@ -1611,18 +1670,18 @@ The shortstat style is experimental and rather slow."
(interactive)
(setq magit-log-margin-show-shortstat
(not magit-log-margin-show-shortstat))
(magit-set-buffer-margin nil t))
(magit-set-buffer-margins nil t))
(defun magit-log-format-margin (rev author date)
(when (magit-margin-option)
(when (magit--right-margin-option)
(if magit-log-margin-show-shortstat
(magit-log-format-shortstat-margin rev)
(magit-log-format-author-margin author date))))
(defun magit-log-format-author-margin (author date)
(pcase-let ((`(,_ ,style ,width ,details ,details-width)
(or magit-buffer-margin
(symbol-value (magit-margin-option))
(or magit--right-margin-config
(symbol-value (magit--right-margin-option))
(error "No margin format specified for %s" major-mode))))
(magit-make-margin-overlay
(concat (and details
@@ -1745,15 +1804,14 @@ Type \\[magit-log-select-quit] to abort without selecting a commit."
(magit-log-select-setup-buffer
(or branch (magit-get-current-branch) "HEAD")
(append args
(car (magit-log--get-value 'magit-log-select-mode
magit-direct-use-buffer-arguments))))
(car (magit-log--get-value 'magit-log-select-mode 'direct))))
(if initial
(magit-log-goto-commit-section initial)
(while-let ((rev (magit-section-value-if 'commit))
((string-match-p "\\`\\(squash!\\|fixup!\\|amend!\\)"
(magit-rev-format "%s" rev)))
(section (magit-current-section))
(next (car (magit-section-siblings section 'next))))
(while-let* ((rev (magit-section-value-if 'commit))
(_(string-match-p "\\`\\(squash!\\|fixup!\\|amend!\\)"
(magit-rev-format "%s" rev)))
(section (magit-current-section))
(next (car (magit-section-siblings section 'next))))
(magit-section-goto next)))
(setq magit-log-select-pick-function pick)
(setq magit-log-select-quit-function quit)
@@ -1911,7 +1969,7 @@ need an unique value, so we use that string in the pushremote case."
"Insert commits that haven't been pulled from the push-remote yet."
(when-let* ((target (magit-get-push-branch))
(range (concat ".." target))
((magit--insert-pushremote-log-p)))
(_(magit--insert-pushremote-log-p)))
(magit-insert-section (unpulled range t)
(magit-insert-heading
(format (propertize "Unpulled from %s."
@@ -1991,7 +2049,7 @@ Show the last `magit-log-section-commit-count' commits."
"Insert commits that haven't been pushed to the push-remote yet."
(when-let* ((target (magit-get-push-branch))
(range (concat target ".."))
((magit--insert-pushremote-log-p)))
(_(magit--insert-pushremote-log-p)))
(magit-insert-section (unpushed range t)
(magit-insert-heading
(format (propertize "Unpushed to %s."
@@ -2050,4 +2108,15 @@ all others with \"-\"."
;;; _
(provide 'magit-log)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-log.el ends here

View File

@@ -49,17 +49,32 @@ does not carry to other options."
:link '(info-link "(magit)Log Margin")
:group 'magit-log)
(defvar-local magit-buffer-margin nil)
(put 'magit-buffer-margin 'permanent-local t)
;;; Settings
(defvar-local magit-set-buffer-margin-refresh nil)
(defvar-local magit--right-margin-delayed nil)
(defvar magit--age-spec)
(defvar-local magit--right-margin-config nil)
(put 'magit--right-margin-config 'permanent-local t)
(defun magit--right-margin-active ()
(car magit--right-margin-config))
(defun magit--right-margin-option ()
(pcase major-mode
('magit-cherry-mode 'magit-cherry-margin)
('magit-log-mode 'magit-log-margin)
('magit-log-select-mode 'magit-log-select-margin)
('magit-reflog-mode 'magit-reflog-margin)
('magit-refs-mode 'magit-refs-margin)
('magit-stashes-mode 'magit-stashes-margin)
('magit-status-mode 'magit-status-margin)
('forge-notifications-mode 'magit-status-margin)
('forge-topics-mode 'magit-status-margin)))
;;; Commands
(transient-define-prefix magit-margin-settings ()
"Change what information is displayed in the margin."
"Change what information is displayed in the right margin."
:info-manual "(magit) Log Margin"
["Margin"
(magit-toggle-margin)
@@ -68,96 +83,89 @@ does not carry to other options."
(magit-refs-set-show-commit-count)])
(transient-define-suffix magit-toggle-margin ()
"Show or hide the Magit margin."
"Show or hide the right margin."
:description "Toggle visibility"
:key "L"
:transient t
(interactive)
(unless (magit-margin-option)
(unless (magit--right-margin-option)
(user-error "Magit margin isn't supported in this buffer"))
(setcar magit-buffer-margin (not (magit-buffer-margin-p)))
(magit-set-buffer-margin))
(setcar magit--right-margin-config (not (magit--right-margin-active)))
(magit-set-buffer-margins))
(defvar magit-margin-default-time-format nil
"See https://github.com/magit/magit/pull/4605.")
(transient-define-suffix magit-cycle-margin-style ()
"Cycle style used for the Magit margin."
"Cycle style used for the right margin."
:description "Cycle style"
:key "l"
:transient t
(interactive)
(unless (magit-margin-option)
(unless (magit--right-margin-option)
(user-error "Magit margin isn't supported in this buffer"))
;; This is only suitable for commit margins (there are not others).
(setf (cadr magit-buffer-margin)
(pcase (cadr magit-buffer-margin)
(setf (cadr magit--right-margin-config)
(pcase (cadr magit--right-margin-config)
('age 'age-abbreviated)
('age-abbreviated
(let ((default (or magit-margin-default-time-format
(cadr (symbol-value (magit-margin-option))))))
(cadr (symbol-value (magit--right-margin-option))))))
(if (stringp default) default "%Y-%m-%d %H:%M ")))
(_ 'age)))
(magit-set-buffer-margin nil t))
(magit-set-buffer-margins nil t))
(transient-define-suffix magit-toggle-margin-details ()
"Show or hide details in the Magit margin."
"Show or hide details in the right margin."
:description "Toggle details"
:key "d"
:transient t
(interactive)
(unless (magit-margin-option)
(unless (magit--right-margin-option)
(user-error "Magit margin isn't supported in this buffer"))
(setf (nth 3 magit-buffer-margin)
(not (nth 3 magit-buffer-margin)))
(magit-set-buffer-margin nil t))
(setf (nth 3 magit--right-margin-config)
(not (nth 3 magit--right-margin-config)))
(magit-set-buffer-margins nil t))
;;; Core
(defun magit-buffer-margin-p ()
(car magit-buffer-margin))
(defun magit-set-buffer-margins (&optional reset-right refresh-right)
(let ((lmargin nil)
(rmargin nil)
(roption (magit--right-margin-option)))
(when (or lmargin roption)
(when roption
(let* ((default (symbol-value roption))
(default-width (nth 2 default)))
(when (or reset-right (not magit--right-margin-config))
(setq magit--right-margin-config (copy-sequence default)))
(pcase-let ((`(,enable ,style ,_width ,details ,details-width)
magit--right-margin-config))
(setq rmargin enable)
(when (functionp default-width)
(setf (nth 2 magit--right-margin-config)
(funcall default-width style details details-width))))))
(dolist (window (get-buffer-window-list nil nil 0))
(with-selected-window window
(magit-set-window-margins window)
(if (or lmargin rmargin)
(add-hook 'window-configuration-change-hook
#'magit-set-window-margins nil t)
(remove-hook 'window-configuration-change-hook
#'magit-set-window-margins t))))
(when (and rmargin (or refresh-right magit--right-margin-delayed))
(magit-refresh-buffer)))))
(defun magit-margin-option ()
(pcase major-mode
('magit-cherry-mode 'magit-cherry-margin)
('magit-log-mode 'magit-log-margin)
('magit-log-select-mode 'magit-log-select-margin)
('magit-reflog-mode 'magit-reflog-margin)
('magit-refs-mode 'magit-refs-margin)
('magit-stashes-mode 'magit-stashes-margin)
('magit-status-mode 'magit-status-margin)
('forge-notifications-mode 'magit-status-margin)
('forge-topics-mode 'magit-status-margin)))
(defun magit-set-buffer-margin (&optional reset refresh)
(when-let ((option (magit-margin-option)))
(let* ((default (symbol-value option))
(default-width (nth 2 default)))
(when (or reset (not magit-buffer-margin))
(setq magit-buffer-margin (copy-sequence default)))
(pcase-let ((`(,enable ,style ,_width ,details ,details-width)
magit-buffer-margin))
(when (functionp default-width)
(setf (nth 2 magit-buffer-margin)
(funcall default-width style details details-width)))
(dolist (window (get-buffer-window-list nil nil 0))
(with-selected-window window
(magit-set-window-margin window)
(if enable
(add-hook 'window-configuration-change-hook
#'magit-set-window-margin nil t)
(remove-hook 'window-configuration-change-hook
#'magit-set-window-margin t))))
(when (and enable (or refresh magit-set-buffer-margin-refresh))
(magit-refresh-buffer))))))
(defun magit-set-window-margin (&optional window)
(defun magit-set-window-margins (&optional window)
(when (or window (setq window (get-buffer-window)))
(with-selected-window window
(set-window-margins
nil (car (window-margins))
(and (magit-buffer-margin-p)
(nth 2 magit-buffer-margin))))))
nil
(if (characterp (car (magit-section-visibility-indicator)))
1
(car (window-margins)))
(and (magit--right-margin-active)
(nth 2 magit--right-margin-config))))))
(cl-defun magit-make-margin-overlay (&optional string (previous-line nil sline))
"Display STRING in the margin of the previous (or current) line.
@@ -180,7 +188,7 @@ line is affected."
[remote branchbuf]
[shelved branchbuf]
[tags branchbuf]
topics issues pullreqs))
topics discussions issues pullreqs))
(defun magit-maybe-make-margin-overlay ()
(when (magit-section-match magit-margin-overlay-conditions
@@ -195,7 +203,7 @@ line is affected."
(dolist (buffer (buffer-list))
(with-current-buffer buffer
(when (eq major-mode mode)
(magit-set-buffer-margin t)
(magit-set-buffer-margins t)
(magit-refresh))))
(message "Updating margins in %s buffers...done" mode))
@@ -233,21 +241,31 @@ as an option, because most other parts of Magit are always in
English.")
(defun magit--age (date &optional abbreviate)
(cl-labels ((fn (age spec)
(pcase-let ((`(,char ,unit ,units ,weight) (car spec)))
(let ((cnt (round (/ age weight 1.0))))
(if (or (not (cdr spec))
(>= (/ age weight) 1))
(list cnt (cond (abbreviate char)
((= cnt 1) unit)
(t units)))
(fn age (cdr spec)))))))
(fn (abs (- (float-time)
(if (stringp date)
(string-to-number date)
date)))
magit--age-spec)))
(named-let calc ((age (abs (- (float-time)
(if (stringp date)
(string-to-number date)
date))))
(spec magit--age-spec))
(pcase-let* ((`((,char ,unit ,units ,weight) . ,spec) spec)
(cnt (round (/ age weight 1.0))))
(if (or (not spec)
(>= (/ age weight) 1))
(list cnt (cond (abbreviate char)
((= cnt 1) unit)
(units)))
(calc age spec)))))
;;; _
(provide 'magit-margin)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-margin.el ends here

View File

@@ -33,7 +33,7 @@
;;; Commands
;;;###autoload (autoload 'magit-merge "magit" nil t)
;;;###autoload(autoload 'magit-merge "magit" nil t)
(transient-define-prefix magit-merge ()
"Merge branches."
:man-page "git-merge"
@@ -172,21 +172,21 @@ then also remove the respective remote branch."
(format "Do you really want to merge `%s' into another branch? "
branch))
(user-error "Abort")))
(if-let ((target (magit-get-push-branch branch t)))
(progn
(magit-git-push branch target (list "--force-with-lease"))
(set-process-sentinel
magit-this-process
(lambda (process event)
(when (memq (process-status process) '(exit signal))
(if (not (zerop (process-exit-status process)))
(magit-process-sentinel process event)
(process-put process 'inhibit-refresh t)
(magit-process-sentinel process event)
(magit--merge-absorb-1 branch args))
(when message
(message message))))))
(magit--merge-absorb-1 branch args)))
(cond-let
([target (magit-get-push-branch branch t)]
(magit-git-push branch target (list "--force-with-lease"))
(set-process-sentinel
magit-this-process
(lambda (process event)
(when (memq (process-status process) '(exit signal))
(if (not (zerop (process-exit-status process)))
(magit-process-sentinel process event)
(process-put process 'inhibit-refresh t)
(magit-process-sentinel process event)
(magit--merge-absorb-1 branch args))
(when message
(message message))))))
((magit--merge-absorb-1 branch args))))
(defun magit--merge-absorb-1 (branch args)
(if-let ((pr (magit-get "branch" branch "pullRequest")))
@@ -241,15 +241,14 @@ then also remove the respective remote branch."
"During a conflict checkout and stage side, or restore conflict."
(interactive
(let ((file (magit-completing-read "Checkout file"
(magit-tracked-files) nil nil nil
(magit-tracked-files) nil 'any nil
'magit-read-file-hist
(magit-current-file))))
(cond ((member file (magit-unmerged-files))
(list file (magit-checkout-read-stage file)))
((yes-or-no-p (format "Restore conflicts in %s? " file))
(list file "--merge"))
(t
(user-error "Quit")))))
((user-error "Quit")))))
(pcase (cons arg (cddr (car (magit-file-status file))))
((or `("--ours" ?D ,_)
'("--ours" ?U ?A)
@@ -312,4 +311,15 @@ If no merge is in progress, do nothing."
;;; _
(provide 'magit-merge)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-merge.el ends here

View File

@@ -47,24 +47,22 @@
(declare-function elp-restore-all "elp" ())
(defvar magit--wip-inhibit-autosave)
(defvar magit-wip-after-save-local-mode)
(defvar magit-wip-mode)
(declare-function magit-wip-get-ref "magit-wip" ())
(declare-function magit-wip-commit-worktree "magit-wip" (ref files msg))
;;; Options
(defcustom magit-mode-hook
(list #'magit-load-config-extensions)
(defcustom magit-mode-hook nil
"Hook run when entering a mode derived from Magit mode."
:package-version '(magit . "3.0.0")
:package-version '(magit . "4.4.2")
:group 'magit-modes
:type 'hook
:options (list #'magit-load-config-extensions
#'bug-reference-mode))
:options (list #'bug-reference-mode))
(defcustom magit-setup-buffer-hook
(list #'magit-maybe-save-repository-buffers
'magit-set-buffer-margin) ; from magit-margin.el
'magit-set-buffer-margins) ; from magit-margin.el
"Hook run by `magit-setup-buffer'.
This is run right after displaying the buffer and right before
@@ -76,7 +74,7 @@ should be used instead of this one."
:group 'magit-modes
:type 'hook
:options (list #'magit-maybe-save-repository-buffers
'magit-set-buffer-margin))
'magit-set-buffer-margins))
(defcustom magit-pre-refresh-hook
(list #'magit-maybe-save-repository-buffers)
@@ -95,6 +93,7 @@ inside your function."
(defcustom magit-post-refresh-hook
;; Do not function-quote to avoid circular dependencies.
;; Functions added here have to be autoloaded.
'(magit-auto-revert-buffers
magit-run-post-commit-hook
magit-run-post-stage-hook
@@ -425,6 +424,7 @@ recommended value."
"C-c C-w" 'magit-copy-thing
"C-w" 'magit-copy-section-value
"M-w" 'magit-copy-buffer-revision
"<remap> <mouse-set-point>" 'magit-mouse-set-point
"<remap> <back-to-indentation>" 'magit-back-to-indentation
"<remap> <previous-line>" 'magit-previous-line
"<remap> <next-line>" 'magit-next-line
@@ -435,52 +435,52 @@ recommended value."
"This is a placeholder command, which signals an error if called.
Where applicable, other keymaps remap this command to another,
which actually deletes the thing at point."
(declare (completion ignore))
(interactive)
(user-error "There is no thing at point that could be deleted"))
;; Starting with Emacs 28.1 we could use (declare (completion ignore)).
(put 'magit-delete-thing 'completion-predicate #'ignore)
(defun magit-visit-thing ()
"This is a placeholder command, which may signal an error if called.
Where applicable, other keymaps remap this command to another,
which actually visits the thing at point."
(declare (completion ignore))
(interactive)
(if (eq transient-current-command 'magit-dispatch)
(call-interactively (key-binding (this-command-keys)))
(if-let ((url (thing-at-point 'url t)))
(browse-url url)
(user-error "There is no thing at point that could be visited"))))
(put 'magit-visit-thing 'completion-predicate #'ignore)
(cond-let
((eq transient-current-command 'magit-dispatch)
(call-interactively (key-binding (this-command-keys))))
([url (thing-at-point 'url t)]
(browse-url url))
((user-error "There is no thing at point that could be visited"))))
(defun magit-edit-thing ()
"This is a placeholder command, which may signal an error if called.
Where applicable, other keymaps remap this command to another,
which actually lets you edit the thing at point, likely in another
buffer."
(declare (completion ignore))
(interactive)
(if (eq transient-current-command 'magit-dispatch)
(call-interactively (key-binding (this-command-keys)))
(user-error "There is no thing at point that could be edited")))
(put 'magit-edit-thing 'completion-predicate #'ignore)
(defun magit-browse-thing ()
"This is a placeholder command, which may signal an error if called.
Where applicable, other keymaps remap this command to another,
which actually visits thing at point using `browse-url'."
(declare (completion ignore))
(interactive)
(if-let ((url (thing-at-point 'url t)))
(browse-url url)
(user-error "There is no thing at point that could be browsed")))
(put 'magit-browse-thing 'completion-predicate #'ignore)
(defun magit-copy-thing ()
"This is a placeholder command, which signals an error if called.
Where applicable, other keymaps remap this command to another,
which actually copies some representation of the thing at point
to the kill ring."
(declare (completion ignore))
(interactive)
(user-error "There is no thing at point that we know how to copy"))
(put 'magit-copy-thing 'completion-predicate #'ignore)
;;;###autoload
(defun magit-info ()
@@ -554,13 +554,6 @@ to the kill ring."
;;; Mode
(defun magit-load-config-extensions ()
"Load Magit extensions that are defined at the Git config layer."
(dolist (ext (magit-get-all "magit.extension"))
(let ((sym (intern (format "magit-%s-mode" ext))))
(when (fboundp sym)
(funcall sym 1)))))
(define-derived-mode magit-mode magit-section-mode "Magit"
"Parent major mode from which Magit major modes inherit.
@@ -615,6 +608,21 @@ Magit is documented in info node `(magit)'."
;; function does not reinstate this.
(put 'magit-buffer-diff-files-suspended 'permanent-local t)
(defun magit-buffer-file-name ()
"Return `magit-buffer-file-name' or if that is nil `buffer-file-name'.
In an indirect buffer get the value for its base buffer."
(or magit-buffer-file-name
(buffer-file-name (buffer-base-buffer))))
(defun magit-buffer-revision ()
"Return `magit-buffer-revision' or if that is nil \"{worktree}\".
If not visiting a blob or file, or the file isn't being tracked,
return nil."
(or magit-buffer-revision
(and buffer-file-name
(magit-file-tracked-p buffer-file-name)
"{worktree}")))
(cl-defgeneric magit-buffer-value ()
"Return the value of the current buffer.
The \"value\" identifies what is being displayed in the buffer.
@@ -626,24 +634,35 @@ The buffer's major-mode should derive from `magit-section-mode'."
;;; Setup Buffer
(defmacro magit-setup-buffer (mode &optional locked &rest bindings)
(declare (indent 2))
`(magit-setup-buffer-internal
,mode ,locked
,(cons 'list (mapcar (pcase-lambda (`(,var ,form))
`(list ',var ,form))
bindings))))
(defmacro magit-setup-buffer (mode &optional locked &rest args)
"\n\n(fn MODE &optional LOCKED &key BUFFER DIRECTORY \
INITIAL-SECTION SELECT-SECTION &rest BINDINGS)"
(declare (indent 2)
(debug (form [&optional locked]
[&rest keywordp form]
[&rest (symbolp form)])))
(let (kwargs)
(while (keywordp (car args))
(push (pop args) kwargs)
(push (pop args) kwargs))
`(magit-setup-buffer-internal
,mode ,locked
,(cons 'list (mapcar (pcase-lambda (`(,var ,form))
`(list ',var ,form))
args))
,@(nreverse kwargs))))
(defun magit-setup-buffer-internal ( mode locked bindings
&optional buffer-or-name directory)
(cl-defun magit-setup-buffer-internal
( mode locked bindings
&key buffer directory initial-section select-section)
(let* ((value (and locked
(with-temp-buffer
(pcase-dolist (`(,var ,val) bindings)
(set (make-local-variable var) val))
(let ((major-mode mode))
(magit-buffer-value)))))
(buffer (if buffer-or-name
(get-buffer-create buffer-or-name)
(buffer (if buffer
(get-buffer-create buffer)
(magit-get-mode-buffer mode value)))
(section (and buffer (magit-current-section)))
(created (not buffer)))
@@ -662,7 +681,9 @@ The buffer's major-mode should derive from `magit-section-mode'."
(magit-display-buffer buffer)
(with-current-buffer buffer
(run-hooks 'magit-setup-buffer-hook)
(magit-refresh-buffer created)
(magit-refresh-buffer created
:initial-section initial-section
:select-section select-section)
(when created
(run-hooks 'magit-post-create-buffer-hook)))
buffer))
@@ -689,8 +710,8 @@ and `magit-post-display-buffer-hook'."
(let ((window (funcall (or display-function magit-display-buffer-function)
buffer)))
(unless magit-display-buffer-noselect
(let* ((old-frame (selected-frame))
(new-frame (window-frame window)))
(let ((old-frame (selected-frame))
(new-frame (window-frame window)))
(select-window window)
(unless (eq old-frame new-frame)
(select-frame-set-input-focus new-frame)))))
@@ -777,8 +798,7 @@ split is made vertically or horizontally is determined by
((with-current-buffer buffer
(derived-mode-p 'magit-diff-mode 'magit-process-mode))
'(magit--display-buffer-topleft))
(t
'(display-buffer-same-window)))))
('(display-buffer-same-window)))))
(defun magit--display-buffer-fullcolumn (buffer alist)
(when-let ((window (or (display-buffer-reuse-window buffer alist)
@@ -809,8 +829,7 @@ the mode of the current buffer derives from `magit-log-mode' or
((with-current-buffer buffer
(derived-mode-p 'magit-process-mode))
nil)
(t
'(magit--display-buffer-fullcolumn)))))
('(magit--display-buffer-fullcolumn)))))
(defun magit-maybe-set-dedicated ()
"Mark the selected window as dedicated if appropriate.
@@ -944,32 +963,33 @@ and another unlocked buffer already exists for that mode and
repository, then the former buffer is instead deleted and the
latter is displayed in its place."
(interactive)
(if magit-buffer-locked-p
(if-let ((unlocked (magit-get-mode-buffer major-mode)))
(let ((locked (current-buffer)))
(switch-to-buffer unlocked nil t)
(kill-buffer locked))
(setq magit-buffer-locked-p nil)
(let ((name (funcall magit-generate-buffer-name-function major-mode))
(buffer (current-buffer))
(mode major-mode))
(rename-buffer (generate-new-buffer-name name))
(with-temp-buffer
(magit--maybe-uniquify-buffer-names buffer name mode))))
(if-let ((value (magit-buffer-value)))
(if-let ((locked (magit-get-mode-buffer major-mode value)))
(let ((unlocked (current-buffer)))
(switch-to-buffer locked nil t)
(kill-buffer unlocked))
(setq magit-buffer-locked-p t)
(let ((name (funcall magit-generate-buffer-name-function
major-mode value))
(buffer (current-buffer))
(mode major-mode))
(rename-buffer (generate-new-buffer-name name))
(with-temp-buffer
(magit--maybe-uniquify-buffer-names buffer name mode))))
(user-error "Buffer has no value it could be locked to"))))
(cond-let
(magit-buffer-locked-p
(if-let ((unlocked (magit-get-mode-buffer major-mode)))
(let ((locked (current-buffer)))
(switch-to-buffer unlocked nil t)
(kill-buffer locked))
(setq magit-buffer-locked-p nil)
(let ((name (funcall magit-generate-buffer-name-function major-mode))
(buffer (current-buffer))
(mode major-mode))
(rename-buffer (generate-new-buffer-name name))
(with-temp-buffer
(magit--maybe-uniquify-buffer-names buffer name mode)))))
([value (magit-buffer-value)]
(if-let ((locked (magit-get-mode-buffer major-mode value)))
(let ((unlocked (current-buffer)))
(switch-to-buffer locked nil t)
(kill-buffer unlocked))
(setq magit-buffer-locked-p t)
(let ((name (funcall magit-generate-buffer-name-function
major-mode value))
(buffer (current-buffer))
(mode major-mode))
(rename-buffer (generate-new-buffer-name name))
(with-temp-buffer
(magit--maybe-uniquify-buffer-names buffer name mode)))))
((user-error "Buffer has no value it could be locked to"))))
;;; Bury Buffer
@@ -1065,10 +1085,10 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
(defvar-local magit--refresh-start-time nil)
(defvar magit--initial-section-hook nil)
(defun magit-refresh-buffer (&optional created)
"Refresh the current Magit buffer."
(cl-defun magit-refresh-buffer ( &optional created
&key initial-section select-section)
"Refresh the current Magit buffer.
The arguments are for internal use."
(interactive)
(when-let ((refresh (magit--refresh-buffer-function)))
(let ((magit--refreshing-buffer-p t)
@@ -1080,8 +1100,8 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
(cond
(created
(funcall refresh)
(run-hooks 'magit--initial-section-hook)
(setq-local magit--initial-section-hook nil))
(cond (initial-section (funcall initial-section))
(select-section (funcall select-section))))
(t
(deactivate-mark)
(setq magit-section-pre-command-section nil)
@@ -1091,7 +1111,8 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
(setq magit-section-focused-sections nil)
(let ((positions (magit--refresh-buffer-get-positions)))
(funcall refresh)
(magit--refresh-buffer-set-positions positions))))
(cond (select-section (funcall select-section))
((magit--refresh-buffer-set-positions positions))))))
(let ((magit-section-cache-visibility nil))
(magit-section-show magit-root-section))
(run-hooks 'magit-refresh-buffer-hook)
@@ -1117,17 +1138,20 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
(lambda (window)
(with-selected-window window
(with-current-buffer buffer
(and-let* ((section (magit-section-at)))
(and-let ((section (magit-section-at)))
`((,window
,section
,@(magit-section-get-relative-position section)
,@(and-let* ((ws (magit-section-at (window-start))))
,@(and-let ((ws (magit-section-at (window-start))))
(list ws
(car (magit-section-get-relative-position ws))
(window-start)))))))))
(get-buffer-window-list buffer nil t)))
(and-let* ((section (magit-section-at)))
`((nil ,section ,@(magit-section-get-relative-position section))))))
;; For hunks we run `magit-section-movement-hook' (once for
;; each window displaying the buffer). The selected window
;; comes first in this list, but we want to process it last.
(nreverse (get-buffer-window-list buffer nil t))))
(and$ (magit-section-at)
`((nil ,$ ,@(magit-section-get-relative-position $))))))
(defun magit--refresh-buffer-set-positions (positions)
(pcase-dolist
@@ -1136,18 +1160,26 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
(if window
(with-selected-window window
(magit-section-goto-successor section line char)
(cond
((or (not window-start)
(> window-start (point))))
((magit-section-equal ws-section (magit-section-at window-start))
(set-window-start window window-start t))
((not (derived-mode-p 'magit-log-mode))
(when-let ((pos (save-excursion
(and (magit-section-goto-successor--same
ws-section ws-line 0)
(point)))))
(set-window-start window pos t)))))
(magit-section-goto-successor section line char))))
(cond-let
((derived-mode-p 'magit-log-mode))
((or (not window-start)
(> window-start (point))))
((magit-section-equal ws-section (magit-section-at window-start))
(set-window-start window window-start t))
([pos (save-excursion
(and (magit-section-goto-successor--same
ws-section ws-line 0)
(point)))]
(set-window-start window pos t))))
;; We must make sure this does not call `set-window-start',
;; which the HUNK METHOD does by calling `magit-section-goto'
;; because that runs the `magit-section-goto-successor-hook'
;; and thus `magit-hunk-set-window-start'. The window does
;; not display this buffer, so the window start would be set
;; for the wrong buffer. Originally reported in #4196 and
;; fixed with 482c25a3204468a4f6c2fe12ff061666b61f5f4d.
(let ((magit-section-movement-hook nil))
(magit-section-goto-successor section line char)))))
(defun magit-revert-buffer (_ignore-auto _noconfirm)
"Wrapper around `magit-refresh-buffer' suitable as `revert-buffer-function'."
@@ -1214,8 +1246,8 @@ Note that refreshing a Magit buffer is done by re-creating its
contents from scratch, which can be slow in large repositories.
If you are not satisfied with Magit's performance, then you
should obviously not add this function to that hook."
(when-let (((and (not magit-inhibit-refresh)
(magit-inside-worktree-p t)))
(when-let ((_(not magit-inhibit-refresh))
(_(magit-inside-worktree-p t))
(buf (ignore-errors (magit-get-mode-buffer 'magit-status-mode))))
(cl-pushnew buf magit-after-save-refresh-buffers)
(add-hook 'post-command-hook #'magit-after-save-refresh-buffers)))
@@ -1238,16 +1270,51 @@ if you so desire."
(defvar-local magit-inhibit-refresh-save nil)
(defvar magit-save-repository-buffers-predicate
(lambda (topdir)
(let ((remote (file-remote-p default-directory))
(topdirs nil)
;; If the current file is modified and resides inside
;; a repository, and a let-binding is in effect, which
;; places us in another repository, then this binding
;; is needed to prevent that file from being saved.
(default-directory default-directory))
(and buffer-file-name
(setq default-directory (file-name-directory buffer-file-name))
;; Check whether the repository still exists.
(file-exists-p default-directory)
;; Check whether refreshing is disabled.
(not magit-inhibit-refresh-save)
;; Check whether the visited file is either on the
;; same remote as the repository, or both are on
;; the local system.
(equal (file-remote-p buffer-file-name) remote)
;; Delayed checks that are more expensive for remote
;; repositories, due to the required network access.
;;
;; Check whether the file is inside the repository.
(equal (or (cdr (assoc default-directory topdirs))
(let ((top (magit-rev-parse-safe "--show-toplevel")))
(push (cons default-directory top) topdirs)
top))
topdir)
;; Check whether the file is actually writable.
(file-writable-p buffer-file-name))))
"Predicate for `magit-save-repository-buffers'.
This function is called for each buffer that might need saving with
one argument, the working tree of the respective repository. If it
returns non-nil, the current buffer is saved.")
(defun magit-save-repository-buffers (&optional arg)
"Save file-visiting buffers belonging to the current repository.
After any buffer where `buffer-save-without-query' is non-nil
is saved without asking, the user is asked about each modified
buffer which visits a file in the current repository. Optional
buffer, which visits a file in the current repository. Optional
argument (the prefix) non-nil means save all with no questions."
(interactive "P")
(when-let ((topdir (magit-rev-parse-safe "--show-toplevel")))
(let ((remote (file-remote-p default-directory))
(save-some-buffers-action-alist
(let ((save-some-buffers-action-alist
`((?Y ,(##with-current-buffer %
(setq buffer-save-without-query t)
(save-buffer))
@@ -1256,53 +1323,26 @@ argument (the prefix) non-nil means save all with no questions."
(setq magit-inhibit-refresh-save t))
"to skip the current buffer and remember choice")
,@save-some-buffers-action-alist))
(topdirs nil)
(unwiped nil)
(magit--wip-inhibit-autosave t))
;; Create a single wip commit for all saved files.
(magit--wip-inhibit-autosave t)
(saved nil))
(unwind-protect
(save-some-buffers
arg
(lambda ()
;; If the current file is modified and resides inside
;; a repository, and a let-binding is in effect, which
;; places us in another repository, then this binding
;; is needed to prevent that file from being saved.
(and-let* ((default-directory
(and buffer-file-name
(file-name-directory buffer-file-name))))
(and
;; Check whether the repository still exists.
(file-exists-p default-directory)
;; Check whether refreshing is disabled.
(not magit-inhibit-refresh-save)
;; Check whether the visited file is either on the
;; same remote as the repository, or both are on
;; the local system.
(equal (file-remote-p buffer-file-name) remote)
;; Delayed checks that are more expensive for remote
;; repositories, due to the required network access.
;;
;; Check whether the file is inside the repository.
(equal (or (cdr (assoc default-directory topdirs))
(let ((top (magit-rev-parse-safe "--show-toplevel")))
(push (cons default-directory top) topdirs)
top))
topdir)
;; Check whether the file is actually writable.
(file-writable-p buffer-file-name)
(prog1 t
;; Schedule for wip commit, if appropriate.
(when magit-wip-after-save-local-mode
(push (expand-file-name buffer-file-name) unwiped)))))))
(when unwiped
(and (funcall magit-save-repository-buffers-predicate topdir)
(prog1 t
(when magit-wip-mode
(push (expand-file-name buffer-file-name) saved))))))
(when saved
(let ((default-directory topdir))
(magit-wip-commit-worktree
(magit-wip-get-ref)
unwiped
(if (cdr unwiped)
(format "autosave %s files after save" (length unwiped))
saved
(if (cdr saved)
(format "autosave %s files after save" (length saved))
(format "autosave %s after save"
(file-relative-name (car unwiped)))))))))))
(file-relative-name (car saved)))))))))))
;;; Restore Window Configuration
@@ -1316,12 +1356,12 @@ argument (the prefix) non-nil means save all with no questions."
Later, when the buffer is buried, it may be restored by
`magit-restore-window-configuration'."
(if magit-inhibit-save-previous-winconf
(when (eq magit-inhibit-save-previous-winconf 'unset)
(setq magit-previous-window-configuration nil))
(unless (get-buffer-window (current-buffer) (selected-frame))
(setq magit-previous-window-configuration
(current-window-configuration)))))
(cond (magit-inhibit-save-previous-winconf
(when (eq magit-inhibit-save-previous-winconf 'unset)
(setq magit-previous-window-configuration nil)))
((not (get-buffer-window (current-buffer) (selected-frame)))
(setq magit-previous-window-configuration
(current-window-configuration)))))
(defun magit-restore-window-configuration (&optional kill-buffer)
"Bury or kill the current buffer and restore previous window configuration."
@@ -1443,9 +1483,9 @@ Return a (KEY . VALUE) cons cell.
The KEY is matched using `equal'.
Unless specified, REPOSITORY is the current buffer's repository."
(and-let* ((cache (assoc (or repository
(magit-repository-local-repository))
magit-repository-local-cache)))
(and-let ((cache (assoc (or repository
(magit-repository-local-repository))
magit-repository-local-cache)))
(assoc key (cdr cache))))
(defun magit-repository-local-get (key &optional default repository)
@@ -1466,13 +1506,13 @@ Unless specified, REPOSITORY is the current buffer's repository."
Unless specified, REPOSITORY is the current buffer's repository.
If REPOSITORY is `all', then delete the value for KEY for all
repositories."
(if (eq repository 'all)
(dolist (cache magit-repository-local-cache)
(setf cache (compat-call assoc-delete-all key cache)))
(when-let ((cache (assoc (or repository
(magit-repository-local-repository))
magit-repository-local-cache)))
(setf cache (compat-call assoc-delete-all key cache)))))
(cond-let
((eq repository 'all)
(dolist (cache magit-repository-local-cache)
(setf cache (compat-call assoc-delete-all key cache))))
([cache (assoc (or repository (magit-repository-local-repository))
magit-repository-local-cache)]
(setf cache (compat-call assoc-delete-all key cache)))))
(defmacro magit--with-repository-local-cache (key &rest body)
(declare (indent 1) (debug (form body)))
@@ -1556,7 +1596,7 @@ The additional output can be found in the *Messages* buffer."
The returned value has the form (BEGINNING-LINE END-LINE). If
the region end at the beginning of a line, do not include that
line. Avoid including the line after the end of the file."
(and (or magit-buffer-file-name buffer-file-name)
(and (magit-buffer-file-name)
(region-active-p)
(not (= (region-beginning) (region-end) (1+ (buffer-size))))
(let ((beg (region-beginning))
@@ -1569,4 +1609,15 @@ line. Avoid including the line after the end of the file."
;;; _
(provide 'magit-mode)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-mode.el ends here

View File

@@ -30,7 +30,7 @@
;;; Commands
;;;###autoload (autoload 'magit-notes "magit" nil t)
;;;###autoload(autoload 'magit-notes "magit" nil t)
(transient-define-prefix magit-notes ()
"Edit notes attached to commits."
:man-page "git-notes"
@@ -163,14 +163,14 @@ Also see `magit-notes-merge'."
;;; Readers
(defun magit-notes-read-ref (prompt _initial-input history)
(and-let* ((ref (magit-completing-read
prompt (magit-list-notes-refnames) nil nil
(and-let* ((def (magit-get "core.notesRef")))
(if (string-prefix-p "refs/notes/" def)
(substring def 11)
def))
history)))
(defun magit-notes-read-ref (prompt &optional _initial-input history)
(and-let ((ref (magit-completing-read
prompt (magit-list-notes-refnames) nil t
(and-let ((def (magit-get "core.notesRef")))
(if (string-prefix-p "refs/notes/" def)
(substring def 11)
def))
history)))
(if (string-prefix-p "refs/" ref)
ref
(concat "refs/notes/" ref))))
@@ -192,10 +192,21 @@ Also see `magit-notes-merge'."
(defun magit-notes-read-args (prompt)
(list (magit-read-branch-or-commit prompt (magit-stash-at-point))
(and-let* ((str (seq-find (##string-match "^--ref=\\(.+\\)" %)
(transient-args 'magit-notes))))
(match-string 1 str))))
(and-let ((str (seq-find (##string-match "^--ref=\\(.+\\)" %)
(transient-args 'magit-notes))))
(match-str 1 str))))
;;; _
(provide 'magit-notes)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-notes.el ends here

View File

@@ -28,6 +28,8 @@
(require 'magit)
(declare-function message-goto-body "message" (&optional interactive))
;;; Options
(defcustom magit-patch-save-arguments '(exclude "--stat")
@@ -50,7 +52,7 @@ the prefix argument."
;;; Commands
;;;###autoload (autoload 'magit-patch "magit-patch" nil t)
;;;###autoload(autoload 'magit-patch "magit-patch" nil t)
(transient-define-prefix magit-patch ()
"Create or apply patches."
["Actions"
@@ -60,7 +62,7 @@ the prefix argument."
("s" "Save diff as patch" magit-patch-save)]
[("r" "Request pull" magit-request-pull)]])
;;;###autoload (autoload 'magit-patch-create "magit-patch" nil t)
;;;###autoload(autoload 'magit-patch-create "magit-patch" nil t)
(transient-define-prefix magit-patch-create (range args files)
"Create patches for the commits in RANGE.
When a single commit is given for RANGE, create a patch for the
@@ -116,8 +118,8 @@ which creates patches for all commits that are reachable from
(save-match-data
(find-file
(expand-file-name
(concat (and-let* ((v (transient-arg-value "--reroll-count=" args)))
(format "v%s-" v))
(concat (and$ (transient-arg-value "--reroll-count=" args)
(format "v%s-" $))
"0000-cover-letter.patch")
(let ((topdir (magit-toplevel)))
(if-let ((dir (transient-arg-value "--output-directory=" args)))
@@ -150,9 +152,8 @@ which creates patches for all commits that are reachable from
:reader #'magit-format-patch-select-base)
(defun magit-format-patch-select-base (prompt initial-input history)
(or (magit-completing-read prompt (cons "auto" (magit-list-refnames))
nil nil initial-input history "auto")
(user-error "Nothing selected")))
(magit-completing-read prompt (cons "auto" (magit-list-refnames))
nil 'any initial-input history "auto"))
(transient-define-argument magit-format-patch:--reroll-count ()
:description "Reroll count"
@@ -235,7 +236,7 @@ which creates patches for all commits that are reachable from
:argument "--output-directory="
:reader #'transient-read-existing-directory)
;;;###autoload (autoload 'magit-patch-apply "magit-patch" nil t)
;;;###autoload(autoload 'magit-patch-apply "magit-patch" nil t)
(transient-define-prefix magit-patch-apply (file &rest args)
"Apply the patch file FILE."
:man-page "git-apply"
@@ -251,8 +252,8 @@ which creates patches for all commits that are reachable from
(list (expand-file-name
(read-file-name "Apply patch: "
default-directory nil nil
(and-let* ((file (magit-file-at-point)))
(file-relative-name file))))
(and$ (magit-file-at-point)
(file-relative-name $))))
(transient-args 'magit-patch-apply))))
(if (not file)
(transient-setup 'magit-patch-apply)
@@ -315,6 +316,7 @@ is asked to pull. START has to be reachable from that commit."
(list (magit-get "remote" (magit-read-remote "Remote") "url")
(magit-read-branch-or-commit "Start" (magit-get-upstream-branch))
(magit-read-branch-or-commit "End")))
(require 'message)
(let ((dir default-directory))
;; mu4e changes default-directory
(compose-mail)
@@ -325,4 +327,15 @@ is asked to pull. START has to be reachable from that commit."
;;; _
(provide 'magit-patch)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-patch.el ends here

View File

@@ -1,16 +1,17 @@
;; -*- no-byte-compile: t; lexical-binding: nil -*-
(define-package "magit" "20250711.1903"
(define-package "magit" "20251125.101"
"A Git porcelain inside Emacs."
'((emacs "27.1")
'((emacs "28.1")
(compat "30.1")
(llama "1.0.0")
(magit-section "4.3.8")
(cond-let "0.1")
(llama "1.0")
(magit-section "4.4")
(seq "2.24")
(transient "0.9.3")
(with-editor "3.4.4"))
(transient "0.10")
(with-editor "3.4"))
:url "https://github.com/magit/magit"
:commit "d8b4690900a00bc32e9f4dd0fb71b96614a96b51"
:revdesc "d8b4690900a0"
:commit "ced3d5afc33d06305f04dd1557bf2fe849914511"
:revdesc "ced3d5afc33d"
:keywords '("git" "tools" "vc")
:authors '(("Marius Vollmer" . "marius.vollmer@gmail.com")
("Jonas Bernoulli" . "emacs.magit@jonas.bernoulli.dev"))

View File

@@ -784,7 +784,8 @@ Magit status buffer."
default-directory))))
(concat (file-relative-name pwd default-directory) " "))
(magit-process--format-arguments program args))))
(magit-insert-heading (if face (propertize cmd 'face face) cmd)))
(magit-insert-heading
(if face (magit--propertize-face cmd face) cmd)))
(when errlog
(if (bufferp errlog)
(insert (with-current-buffer errlog
@@ -810,8 +811,7 @@ Magit status buffer."
((and args (equal program shell-file-name))
(propertize (cadr args)
'font-lock-face 'magit-section-heading))
(t
(concat (propertize (file-name-nondirectory program)
((concat (propertize (file-name-nondirectory program)
'font-lock-face 'magit-section-heading)
" "
(propertize (mapconcat #'shell-quote-argument args " ")
@@ -832,8 +832,7 @@ Magit status buffer."
(delete-region (oref section start)
(1+ (oref section end)))
(cl-decf count))
(t
(push section head))))
((push section head))))
(pop tail))
(oset magit-root-section children
(nconc (reverse head) tail)))))
@@ -861,7 +860,7 @@ Magit status buffer."
(when (memq (process-status process) '(exit signal))
(magit-process-sentinel process event)
(when-let* ((process-buf (process-buffer process))
((buffer-live-p process-buf))
(_(buffer-live-p process-buf))
(status-buf (with-current-buffer process-buf
(magit-get-mode-buffer 'magit-status-mode))))
(with-current-buffer status-buf
@@ -947,8 +946,8 @@ PARENT is used as the parent of the returned keymap."
(y-or-n-p-map
(magit-process-make-keymap process y-or-n-p-map)))
(yes-or-no-p (substring string 0 beg))))
(concat (downcase (match-string 1 string)) "\n")
(concat (downcase (match-string 2 string)) "\n")))))
(concat (downcase (match-str 1 string)) "\n")
(concat (downcase (match-str 2 string)) "\n")))))
(defun magit-process-password-auth-source (key)
"Use `auth-source-search' to get a password.
@@ -990,8 +989,8 @@ be translated on the fly by doing this once
(require 'auth-source)
(and (fboundp 'auth-source-search)
(string-match "\\`\\(.+\\)@\\([^@]+\\)\\'" key)
(let* ((user (match-string 1 key))
(host (match-string 2 key))
(let* ((user (match-str 1 key))
(host (match-str 2 key))
(secret
(plist-get
(car (or (auth-source-search :max 1 :host host :user user)
@@ -1026,9 +1025,9 @@ from the user."
magit-process-password-prompt-regexps string)))
(process-send-string
process
(concat (or (and-let* ((key (match-string 99 string)))
(run-hook-with-args-until-success
'magit-process-find-password-functions key))
(concat (or (and$ (match-str 99 string)
(run-hook-with-args-until-success
'magit-process-find-password-functions $))
(let ((read-passwd-map
(magit-process-make-keymap process read-passwd-map)))
(read-passwd prompt)))
@@ -1048,7 +1047,7 @@ from the user."
"Match STRING against PROMPTS and set match data.
Return the matched string, appending \": \" if needed."
(when (seq-some (##string-match % string) prompts)
(let ((prompt (match-string 0 string)))
(let ((prompt (match-str 0 string)))
(cond ((string-suffix-p ": " prompt) prompt)
((string-suffix-p ":" prompt) (concat prompt " "))
(t (concat prompt ": "))))))
@@ -1209,7 +1208,7 @@ If STR is supplied, it replaces the `mode-line-process' text."
(lambda (re)
(save-excursion
(and (re-search-backward re (oref section start) t)
(match-string-no-properties 1))))))))))
(match-str 1))))))))))
(defun magit-process-error-tooltip (process-buf section)
"Returns the text from SECTION of the PROCESS-BUF buffer.
@@ -1292,16 +1291,16 @@ Limited by `magit-process-error-tooltip-max-lines'."
(when (eq magit-process-apply-ansi-colors t)
(ansi-color-apply-on-region (oref section content)
(oref section end)))
(if (= (oref section end)
(+ (line-end-position) 2))
(save-excursion
(goto-char (1+ (line-end-position)))
(delete-char -1)
(oset section content nil))
(when (and (= exit-code 0)
(not (seq-some (##eq (window-buffer %) buffer)
(window-list))))
(magit-section-hide section)))))
(cond ((= (oref section end)
(+ (line-end-position) 2))
(save-excursion
(goto-char (1+ (line-end-position)))
(delete-char -1)
(oset section content nil)))
((and (= exit-code 0)
(not (seq-some (##eq (window-buffer %) buffer)
(window-list))))
(magit-section-hide section)))))
(defun magit-process-display-buffer (process)
(when (process-live-p process)
@@ -1314,20 +1313,20 @@ Limited by `magit-process-error-tooltip-max-lines'."
((> magit-process-popup-time 0)
(run-with-timer magit-process-popup-time nil
(lambda (p)
(when (eq (process-status p) 'run)
(let ((buf (process-buffer p)))
(when (buffer-live-p buf)
(if (minibufferp)
(switch-to-buffer-other-window buf)
(pop-to-buffer buf))))))
(when-let* ((_(eq (process-status p) 'run))
(buf (process-buffer p))
(_(buffer-live-p buf)))
(if (minibufferp)
(switch-to-buffer-other-window buf)
(pop-to-buffer buf))))
process))))))
(defun magit--log-action (summary line list)
(let (heading lines)
(if (cdr list)
(progn (setq heading (funcall summary list))
(setq lines (mapcar line list)))
(setq heading (funcall line (car list))))
(cond ((cdr list)
(setq lines (mapcar line list))
(setq heading (funcall summary list)))
((setq heading (funcall line (car list)))))
(with-current-buffer (magit-process-buffer t)
(goto-char (1- (point-max)))
(let ((inhibit-read-only t))
@@ -1344,4 +1343,15 @@ Limited by `magit-process-error-tooltip-max-lines'."
;;; _
(provide 'magit-process)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-process.el ends here

View File

@@ -38,7 +38,7 @@
;;; Commands
;;;###autoload (autoload 'magit-pull "magit-pull" nil t)
;;;###autoload(autoload 'magit-pull "magit-pull" nil t)
(transient-define-prefix magit-pull ()
"Pull from another repository."
:man-page "git-pull"
@@ -78,7 +78,7 @@
(defun magit-pull-arguments ()
(transient-args 'magit-pull))
;;;###autoload (autoload 'magit-pull-from-pushremote "magit-pull" nil t)
;;;###autoload(autoload 'magit-pull-from-pushremote "magit-pull" nil t)
(transient-define-suffix magit-pull-from-pushremote (args)
"Pull from the push-remote of the current branch.
@@ -99,16 +99,14 @@ push-remote."
(target (magit-get-push-branch branch t))
(remote (magit-get-push-remote branch))
(v (magit--push-remote-variable branch t)))
(cond
(target)
((member remote (magit-list-remotes))
(format "%s, replacing non-existent" v))
(remote
(format "%s, replacing invalid" v))
(t
(format "%s, setting that" v)))))
(cond (target)
((member remote (magit-list-remotes))
(format "%s, replacing non-existent" v))
(remote
(format "%s, replacing invalid" v))
((format "%s, setting that" v)))))
;;;###autoload (autoload 'magit-pull-from-upstream "magit-pull" nil t)
;;;###autoload(autoload 'magit-pull-from-upstream "magit-pull" nil t)
(transient-define-suffix magit-pull-from-upstream (args)
"Pull from the upstream of the current branch.
@@ -134,7 +132,7 @@ the upstream."
(magit-run-git-with-editor "pull" args remote merge)))
(defun magit-pull--upstream-description ()
(and-let* ((branch (magit-get-current-branch)))
(and-let ((branch (magit-get-current-branch)))
(or (magit-get-upstream-branch branch)
(let ((remote (magit-get "branch" branch "remote"))
(merge (magit-get "branch" branch "merge"))
@@ -148,8 +146,7 @@ the upstream."
(concat u ", replacing non-existent"))
((or remote merge)
(concat u ", replacing invalid"))
(t
(concat u ", setting that")))))))
((concat u ", setting that")))))))
;;;###autoload
(defun magit-pull-branch (source args)
@@ -163,4 +160,15 @@ the upstream."
;;; _
(provide 'magit-pull)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-pull.el ends here

View File

@@ -30,7 +30,7 @@
;;; Commands
;;;###autoload (autoload 'magit-push "magit-push" nil t)
;;;###autoload(autoload 'magit-push "magit-push" nil t)
(transient-define-prefix magit-push ()
"Push to another repository."
:man-page "git-push"
@@ -73,7 +73,7 @@
(magit-run-git-async "push" "-v" args remote
(format "%s:%s%s" branch namespace target))))
;;;###autoload (autoload 'magit-push-current-to-pushremote "magit-push" nil t)
;;;###autoload(autoload 'magit-push-current-to-pushremote "magit-push" nil t)
(transient-define-suffix magit-push-current-to-pushremote (args)
"Push the current branch to its push-remote.
@@ -107,10 +107,9 @@ argument the push-remote can be changed before pushed to it."
'magit-branch-remote)))
(remote
(format "%s, replacing invalid" v))
(t
(format "%s, setting that" v)))))
((format "%s, setting that" v)))))
;;;###autoload (autoload 'magit-push-current-to-upstream "magit-push" nil t)
;;;###autoload(autoload 'magit-push-current-to-upstream "magit-push" nil t)
(transient-define-suffix magit-push-current-to-upstream (args)
"Push the current branch to its upstream branch.
@@ -134,7 +133,7 @@ the upstream."
:test #'equal))
(upstream (magit-completing-read
(format "Set upstream of %s and push there" branch)
branches nil nil nil 'magit-revision-history
branches nil 'any nil 'magit-revision-history
(or (car (member (magit-remote-branch-at-point) branches))
(car (member "origin/master" branches)))))
(upstream* (or (magit-get-tracked upstream)
@@ -155,7 +154,7 @@ the upstream."
(magit-run-git-async "push" "-v" args remote (concat branch ":" merge))))
(defun magit-push--upstream-description ()
(and-let* ((branch (magit-get-current-branch)))
(and-let ((branch (magit-get-current-branch)))
(or (magit-get-upstream-branch branch)
(let ((remote (magit-get "branch" branch "remote"))
(merge (magit-get "branch" branch "merge"))
@@ -171,8 +170,7 @@ the upstream."
(magit--propertize-face merge 'magit-branch-remote)))
((or remote merge)
(concat u ", creating it and replacing invalid"))
(t
(concat u ", creating it")))))))
((concat u ", creating it")))))))
;;;###autoload
(defun magit-push-current (target args)
@@ -194,10 +192,10 @@ Both the source and the target are read in the minibuffer."
(list source
(magit-read-remote-branch
(format "Push %s to" source) nil
(if (magit-local-branch-p source)
(or (magit-get-push-branch source)
(magit-get-upstream-branch source))
(and (magit-rev-ancestor-p source "HEAD")
(cond ((magit-local-branch-p source)
(or (magit-get-push-branch source)
(magit-get-upstream-branch source)))
((magit-rev-ancestor-p source "HEAD")
(or (magit-get-push-branch)
(magit-get-upstream-branch))))
source 'confirm)
@@ -218,7 +216,7 @@ is used."
(magit-completing-read-multiple
"Push refspec,s: "
(cons "HEAD" (magit-list-local-branch-names))
nil nil nil 'magit-push-refspecs-history)
nil 'any nil 'magit-push-refspecs-history)
(magit-push-arguments)))
(run-hooks 'magit-credential-hook)
(magit-run-git-async "push" "-v" args remote refspecs))
@@ -258,14 +256,14 @@ branch as default."
(defun magit-push-notes-ref (ref remote &optional args)
"Push a notes ref to another repository."
(interactive
(let ((note (magit-notes-read-ref "Push notes" nil nil)))
(let ((note (magit-notes-read-ref "Push notes")))
(list note
(magit-read-remote (format "Push %s to remote" note) nil t)
(magit-push-arguments))))
(run-hooks 'magit-credential-hook)
(magit-run-git-async "push" remote ref args))
;;;###autoload (autoload 'magit-push-implicitly "magit-push" nil t)
;;;###autoload(autoload 'magit-push-implicitly "magit-push" nil t)
(transient-define-suffix magit-push-implicitly (args)
"Push somewhere without using an explicit refspec.
@@ -302,12 +300,12 @@ what this command will do. To add it use something like:
;; Note: Avoid `magit-get-remote' because it
;; filters out the local repo case (".").
(magit-get "branch" branch "remote")
(let ((remotes (magit-list-remotes)))
(cond
((and (magit-git-version>= "2.27")
(length= remotes 1))
(car remotes))
((member "origin" remotes) "origin"))))))
(cond-let
[[remotes (magit-list-remotes)]]
((and (magit-git-version>= "2.27")
(length= remotes 1))
(car remotes))
((car (member "origin" remotes)))))))
(if (null remote)
"nothing (no remote)"
(let ((refspec (magit-get "remote" remote "push")))
@@ -343,7 +341,7 @@ what this command will do. To add it use something like:
("matching" (format "all matching to %s"
(magit--propertize-face remote 'bold)))))))))
;;;###autoload (autoload 'magit-push-to-remote "magit-push" nil t)
;;;###autoload(autoload 'magit-push-to-remote "magit-push" nil t)
(transient-define-suffix magit-push-to-remote (remote args)
"Push to REMOTE without using an explicit refspec.
The REMOTE is read in the minibuffer.
@@ -370,4 +368,15 @@ You can add this command as a suffix using something like:
;;; _
(provide 'magit-push)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-push.el ends here

View File

@@ -189,9 +189,9 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
(defun magit-reflog-format-subject (subject)
(let* ((match (string-match magit-reflog-subject-re subject))
(command (and match (match-string 1 subject)))
(option (and match (match-string 2 subject)))
(type (and match (match-string 3 subject)))
(command (and match (match-str 1 subject)))
(option (and match (match-str 2 subject)))
(type (and match (match-str 3 subject)))
(label (if (string= command "commit")
(or type command)
command))
@@ -205,4 +205,15 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
;;; _
(provide 'magit-reflog)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-reflog.el ends here

View File

@@ -314,7 +314,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
(magit-buffer-arguments args)))
(defun magit-refs-refresh-buffer ()
(setq magit-set-buffer-margin-refresh (not (magit-buffer-margin-p)))
(setq magit--right-margin-delayed (not (magit--right-margin-active)))
(unless (magit-rev-verify magit-buffer-upstream)
(setq magit-refs-show-commit-count nil))
(magit-set-header-line-format
@@ -329,7 +329,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
;;; Commands
;;;###autoload (autoload 'magit-show-refs "magit-refs" nil t)
;;;###autoload(autoload 'magit-show-refs "magit-refs" nil t)
(transient-define-prefix magit-show-refs (&optional transient)
"List and compare references in a dedicated buffer."
:man-page "git-branch"
@@ -356,22 +356,16 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
(defun magit-show-refs-arguments (&optional use-buffer-args)
(unless use-buffer-args
(setq use-buffer-args magit-direct-use-buffer-arguments))
(let (args)
(cond
((eq transient-current-command 'magit-show-refs)
(setq args (transient-args 'magit-show-refs)))
((eq major-mode 'magit-refs-mode)
(setq args magit-buffer-arguments))
((and (memq use-buffer-args '(always selected))
(and-let* ((buffer (magit-get-mode-buffer
'magit-refs-mode nil
(eq use-buffer-args 'selected))))
(progn
(setq args (buffer-local-value 'magit-buffer-arguments buffer))
t))))
(t
(setq args (alist-get 'magit-show-refs transient-values))))
args))
(cond-let*
((eq transient-current-command 'magit-show-refs)
(transient-args 'magit-show-refs))
((eq major-mode 'magit-refs-mode)
magit-buffer-arguments)
([_(memq use-buffer-args '(always selected))]
[buffer (magit-get-mode-buffer 'magit-refs-mode nil
(eq use-buffer-args 'selected))]
(buffer-local-value 'magit-buffer-arguments buffer))
((alist-get 'magit-show-refs transient-values))))
(transient-define-argument magit-for-each-ref:--contains ()
:description "Contains"
@@ -441,47 +435,48 @@ different, but only if you have customized the option
`magit-visit-ref-behavior' (which see). When invoked from a
menu this command always behaves like `magit-show-commit'."
(interactive)
(if (and (derived-mode-p 'magit-refs-mode)
(magit-section-match '(branch tag))
(not (magit-menu-position)))
(let ((ref (oref (magit-current-section) value)))
(cond (current-prefix-arg
(cond ((memq 'focus-on-ref magit-visit-ref-behavior)
(magit-refs-setup-buffer ref (magit-show-refs-arguments)))
(magit-visit-ref-behavior
;; Don't prompt for commit to visit.
(let ((current-prefix-arg nil))
(call-interactively #'magit-show-commit)))))
((and (memq 'create-branch magit-visit-ref-behavior)
(magit-section-match [branch remote]))
(let ((branch (cdr (magit-split-branch-name ref))))
(if (magit-branch-p branch)
(if (magit-rev-eq branch ref)
(magit-call-git "checkout" branch)
(setq branch (propertize branch 'face 'magit-branch-local))
(setq ref (propertize ref 'face 'magit-branch-remote))
(pcase (prog1 (read-char-choice (format (propertize "\
(cond-let
((not (and (derived-mode-p 'magit-refs-mode)
(magit-section-match '(branch tag))
(not (magit-menu-position))))
(call-interactively #'magit-show-commit))
[[ref (oref (magit-current-section) value)]]
((and current-prefix-arg
(memq 'focus-on-ref magit-visit-ref-behavior))
(magit-refs-setup-buffer ref (magit-show-refs-arguments)))
((and current-prefix-arg
magit-visit-ref-behavior
;; Don't prompt for commit to visit.
(let ((current-prefix-arg nil))
(call-interactively #'magit-show-commit))))
((and (memq 'create-branch magit-visit-ref-behavior)
(magit-section-match [branch remote]))
(let ((branch (cdr (magit-split-branch-name ref))))
(if (magit-branch-p branch)
(if (magit-rev-eq branch ref)
(magit-call-git "checkout" branch)
(setq branch (propertize branch 'face 'magit-branch-local))
(setq ref (propertize ref 'face 'magit-branch-remote))
(pcase (prog1 (read-char-choice (format (propertize "\
Branch %s already exists.
[c]heckout %s as-is
[r]reset %s to %s and checkout %s
[a]bort " 'face 'minibuffer-prompt) branch branch branch ref branch)
'(?c ?r ?a))
(message "")) ; otherwise prompt sticks
(?c (magit-call-git "checkout" branch))
(?r (magit-call-git "checkout" "-B" branch ref))
(?a (user-error "Abort"))))
(magit-call-git "checkout" "-b" branch ref))
(setq magit-buffer-upstream branch)
(magit-refresh)))
((or (memq 'checkout-any magit-visit-ref-behavior)
(and (memq 'checkout-branch magit-visit-ref-behavior)
(magit-section-match [branch local])))
(magit-call-git "checkout" ref)
(setq magit-buffer-upstream ref)
(magit-refresh))
(t
(call-interactively #'magit-show-commit))))
(call-interactively #'magit-show-commit)))
'(?c ?r ?a))
(message "")) ; otherwise prompt sticks
(?c (magit-call-git "checkout" branch))
(?r (magit-call-git "checkout" "-B" branch ref))
(?a (user-error "Abort"))))
(magit-call-git "checkout" "-b" branch ref))
(setq magit-buffer-upstream branch)
(magit-refresh)))
((or (memq 'checkout-any magit-visit-ref-behavior)
(and (memq 'checkout-branch magit-visit-ref-behavior)
(magit-section-match [branch local])))
(magit-call-git "checkout" ref)
(setq magit-buffer-upstream ref)
(magit-refresh))
((call-interactively #'magit-show-commit))))
;;; Sections
@@ -501,6 +496,10 @@ Branch %s already exists.
"<2>" (magit-menu-item "Delete %m" #'magit-branch-delete)
"<1>" (magit-menu-item "Visit commit" #'magit-visit-ref))
(defvar-keymap magit-shelved-branch-section-map
:doc "Keymap for `shelved-branch' sections."
"<remap> <magit-delete-thing>" #'magit-delete-shelved-branch)
(defvar-keymap magit-tag-section-map
:doc "Keymap for `tag' sections."
"<remap> <magit-delete-thing>" #'magit-tag-delete
@@ -509,8 +508,8 @@ Branch %s already exists.
"<1>" (magit-menu-item "Visit %s" #'magit-visit-ref))
(defun magit--painted-branch-as-menu-section (section)
(and-let* ((branch (and (magit-section-match 'commit)
(magit--painted-branch-at-point))))
(and-let ((_(magit-section-match 'commit))
(branch (magit--painted-branch-at-point)))
(let ((dummy (magit-section :type 'branch :value branch)))
(oset dummy keymap magit-branch-section-map)
(dolist (slot '(start content hidden parent children))
@@ -547,8 +546,8 @@ line is inserted at all."
(magit-insert-heading (length tags) "Tags")
(dolist (tag tags)
(string-match "^\\([^ \t]+\\)[ \t]+\\([^ \t\n].*\\)?" tag)
(let ((tag (match-string 1 tag))
(msg (match-string 2 tag)))
(let ((tag (match-str 1 tag))
(msg (match-str 2 tag)))
(when (magit-refs--insert-refname-p tag)
(magit-insert-section (tag tag t)
(magit-insert-heading
@@ -561,8 +560,8 @@ line is inserted at all."
(length tag)))
?\s)
(and msg (magit-log--wash-summary msg)))
(when (and magit-refs-margin-for-tags (magit-buffer-margin-p))
(magit-refs--format-margin tag))
(when magit-refs-margin-for-tags
(magit-refs--maybe-format-margin tag))
(magit-refs--insert-cherry-commits tag)))))
(insert ?\n)
(magit-make-margin-overlay)))))
@@ -616,8 +615,7 @@ line is inserted at all."
(length abbrev)))
?\s)
(and msg (magit-log--wash-summary msg))))
(when (magit-buffer-margin-p)
(magit-refs--format-margin branch))
(magit-refs--maybe-format-margin branch)
(magit-refs--insert-cherry-commits branch))))))))
(insert ?\n)
(magit-make-margin-overlay))))
@@ -633,8 +631,7 @@ line is inserted at all."
(or branch (magit-rev-parse "HEAD"))
t)
(apply #'magit-insert-heading strings)
(when (magit-buffer-margin-p)
(magit-refs--format-margin branch))
(magit-refs--maybe-format-margin branch)
(magit-refs--insert-cherry-commits branch))))
(insert ?\n)
(magit-make-margin-overlay)))
@@ -642,14 +639,13 @@ line is inserted at all."
(defun magit-insert-shelved-branches ()
"Insert sections showing all shelved branches."
(when-let ((refs (magit-list-refs "refs/shelved/")))
(magit-insert-section (shelved nil)
(magit-insert-section (shelved nil t)
(magit-insert-heading t "Shelved branches")
(dolist (ref (nreverse refs))
(magit-insert-section (shelved-branch ref t)
(magit-insert-heading
" " (magit--propertize-face (substring ref 13) 'magit-refname))
(when (magit-buffer-margin-p)
(magit-refs--format-margin ref))
(magit-refs--maybe-format-margin ref)
(magit-refs--insert-cherry-commits ref)))
(insert ?\n)
(magit-make-margin-overlay))))
@@ -709,20 +705,20 @@ line is inserted at all."
(string-match "ahead \\([0-9]+\\)" u:track)
(magit--propertize-face
(concat (and magit-refs-pad-commit-counts " ")
(match-string 1 u:track)
(match-str 1 u:track)
">")
'magit-dimmed)))
(u:behind (and u:track
(string-match "behind \\([0-9]+\\)" u:track)
(magit--propertize-face
(concat "<"
(match-string 1 u:track)
(match-str 1 u:track)
(and magit-refs-pad-commit-counts " "))
'magit-dimmed)))
(p:ahead (and pushp p:track
(string-match "ahead \\([0-9]+\\)" p:track)
(magit--propertize-face
(concat (match-string 1 p:track)
(concat (match-str 1 p:track)
">"
(and magit-refs-pad-commit-counts " "))
'magit-branch-remote)))
@@ -730,7 +726,7 @@ line is inserted at all."
(string-match "behind \\([0-9]+\\)" p:track)
(magit--propertize-face
(concat "<"
(match-string 1 p:track)
(match-str 1 p:track)
(and magit-refs-pad-commit-counts " "))
'magit-dimmed))))
(list (1+ (length (concat branch-pretty u:ahead p:ahead u:behind)))
@@ -748,7 +744,7 @@ line is inserted at all."
(magit--propertize-face
push 'magit-branch-remote)
" "))
(if-let ((magit-refs-show-branch-descriptions)
(if-let ((_ magit-refs-show-branch-descriptions)
(desc (magit-get "branch" branch "description")))
(magit--propertize-face desc 'bold)
(and msg (magit-log--wash-summary msg))))))))
@@ -774,9 +770,9 @@ line is inserted at all."
(magit--propertize-face
(cond ((> ahead 0) (concat "<" (number-to-string ahead)))
((> behind 0) (concat (number-to-string behind) ">"))
(t "="))
("="))
'magit-dimmed)))
(t "")))))
("")))))
(defun magit-refs--propertize-branch (branch ref &optional head-face)
(let ((face (cdr (cl-find-if (pcase-lambda (`(,re . ,_))
@@ -804,11 +800,23 @@ line is inserted at all."
(message "No cherries for %s" ref)
(magit-make-margin-overlay)))))
(defun magit-refs--format-margin (rev)
(if-let ((line (magit-rev-format "%cN%x00%ct" rev)))
(apply #'magit-log-format-margin rev (split-string line "\0"))
(magit-make-margin-overlay)))
(defun magit-refs--maybe-format-margin (rev)
(when (magit--right-margin-active)
(if-let ((line (magit-rev-format "%cN%x00%ct" rev)))
(apply #'magit-log-format-margin rev (split-string line "\0"))
(magit-make-margin-overlay))))
;;; _
(provide 'magit-refs)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-refs.el ends here

View File

@@ -62,7 +62,7 @@ has to be used to view and change remote related variables."
;;; Commands
;;;###autoload (autoload 'magit-remote "magit-remote" nil t)
;;;###autoload(autoload 'magit-remote "magit-remote" nil t)
(transient-define-prefix magit-remote (remote)
"Add, configure or remove a remote."
:man-page "git-remote"
@@ -175,8 +175,8 @@ the now stale refspecs. Other stale branches are not removed."
stale)
(dolist (refspec refspecs)
(when (string-match magit--refspec-re refspec)
(let ((theirs (match-string 2 refspec))
(ours (match-string 3 refspec)))
(let ((theirs (match-str 2 refspec))
(ours (match-str 3 refspec)))
(unless (if (string-match "\\*" theirs)
(let ((re (replace-match ".*" t t theirs)))
(seq-some (##string-match-p re %) remote-refs))
@@ -253,7 +253,7 @@ Delete the symbolic-ref \"refs/remotes/<remote>/HEAD\"."
(interactive (list (magit-read-remote "Unset HEAD for remote")))
(magit-run-git "remote" "set-head" remote "--delete"))
;;;###autoload (autoload 'magit-update-default-branch "magit-remote" nil t)
;;;###autoload(autoload 'magit-update-default-branch "magit-remote" nil t)
(transient-define-suffix magit-update-default-branch ()
"Update name of the default branch after upstream changed it."
:description "Update default branch"
@@ -305,7 +305,7 @@ refspec."
;;; Configure
;;;###autoload (autoload 'magit-remote-configure "magit-remote" nil t)
;;;###autoload(autoload 'magit-remote-configure "magit-remote" nil t)
(transient-define-prefix magit-remote-configure (remote)
"Configure a remote."
:man-page "git-remote"
@@ -393,4 +393,15 @@ refspec."
;;; _
(provide 'magit-remote)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-remote.el ends here

View File

@@ -31,6 +31,7 @@
(require 'magit-core)
(declare-function magit-status-setup-buffer "magit-status" (&optional directory))
(declare-function magit-dired-jump "magit-dired" (&optional other-window))
(defvar x-stretch-cursor)
@@ -262,7 +263,8 @@ If it contains \"%s\" then the directory is substituted for that."
"m" #'magit-repolist-mark
"u" #'magit-repolist-unmark
"f" #'magit-repolist-fetch
"5" #'magit-repolist-find-file-other-frame)
"5" #'magit-repolist-find-file-other-frame
"<remap> <dired-jump>" #'magit-dired-jump)
(define-derived-mode magit-repolist-mode tabulated-list-mode "Repos"
"Major mode for browsing a list of Git repositories."
@@ -308,7 +310,7 @@ If it contains \"%s\" then the directory is substituted for that."
sort-fn #'identity idx))
(sort-fn sort-fn)
(sort-set nil)
(t t)))
(t)))
(flatten-tree props))))
magit-repolist-columns))))
@@ -372,10 +374,10 @@ Usually this is just its basename."
(defun magit-repolist-column-version (_)
"Insert a description of the repository's `HEAD' revision."
(and-let* ((v (or (magit-git-string "describe" "--tags" "--dirty")
;; If there are no tags, use the date in MELPA format.
(magit-rev-format "%cd-g%h" nil
"--date=format:%Y%m%d.%H%M"))))
(and-let ((v (or (magit-git-string "describe" "--tags" "--dirty")
;; If there are no tags, use the date in MELPA format.
(magit-rev-format "%cd-g%h" nil
"--date=format:%Y%m%d.%H%M"))))
(save-match-data
(when (string-match magit-repolist-column-version-regexp v)
(magit--put-face (match-beginning 0) (match-end 0) 'shadow v)
@@ -384,24 +386,25 @@ Usually this is just its basename."
(when (match-end 4)
(magit--put-face (or (match-beginning 3) (match-beginning 4))
(match-end 4) 'error v))
(when (and (equal (match-string 2 v) "1")
(when (and (equal (match-str 2 v) "1")
(string-match-p magit-repolist-column-version-resume-regexp
(magit-rev-format "%s")))
(setq v (replace-match (propertize "+" 'face 'shadow) t t v 1))))
(if (and v (string-match "\\`[0-9]" v))
(concat " " v)
(when (and v (string-match "\\`[^0-9]+" v))
(magit--put-face 0 (match-end 0) 'shadow v))
v))))
(cond ((not v) nil)
((string-match "\\`[0-9]" v)
(concat " " v))
((string-match "\\`[^0-9]+" v)
(magit--put-face 0 (match-end 0) 'shadow v)
v)))))
(defun magit-repolist-version< (a b)
(save-match-data
(let ((re "[0-9]+\\(\\.[0-9]*\\)*"))
(setq a (and (string-match re a) (match-string 0 a)))
(setq b (and (string-match re b) (match-string 0 b)))
(setq a (and (string-match re a) (match-str 0 a)))
(setq b (and (string-match re b) (match-str 0 b)))
(cond ((and a b) (version< a b))
(b nil)
(t t)))))
(t)))))
(defun magit-repolist-column-branch (_)
"Insert the current branch."
@@ -437,23 +440,27 @@ which only lists the first one found."
(defun magit-repolist-column-unpulled-from-upstream (spec)
"Insert number of upstream commits not in the current branch."
(and-let* ((br (magit-get-upstream-branch)))
(magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" br)) spec)))
(and$ (magit-get-upstream-branch)
(magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" $))
spec)))
(defun magit-repolist-column-unpulled-from-pushremote (spec)
"Insert number of commits in the push branch but not the current branch."
(and-let* ((br (magit-get-push-branch nil t)))
(magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" br)) spec)))
(and$ (magit-get-push-branch nil t)
(magit-repolist-insert-count (cadr (magit-rev-diff-count "HEAD" $))
spec)))
(defun magit-repolist-column-unpushed-to-upstream (spec)
"Insert number of commits in the current branch but not its upstream."
(and-let* ((br (magit-get-upstream-branch)))
(magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" br)) spec)))
(and$ (magit-get-upstream-branch)
(magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" $))
spec)))
(defun magit-repolist-column-unpushed-to-pushremote (spec)
"Insert number of commits in the current branch but not its push branch."
(and-let* ((br (magit-get-push-branch nil t)))
(magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" br)) spec)))
(and$ (magit-get-push-branch nil t)
(magit-repolist-insert-count (car (magit-rev-diff-count "HEAD" $))
spec)))
(defun magit-repolist-column-branches (spec)
"Insert number of branches."
@@ -490,7 +497,7 @@ instead."
(if-let ((repos (and (not read-directory-name)
magit-repository-directories
(magit-repos-alist))))
(let ((reply (magit-completing-read "Git repository" repos)))
(let ((reply (magit-completing-read "Git repository" repos nil 'any)))
(file-name-as-directory
(or (cdr (assoc reply repos))
(if (file-directory-p reply)
@@ -544,4 +551,15 @@ instead."
;;; _
(provide 'magit-repos)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-repos.el ends here

View File

@@ -30,7 +30,7 @@
;;; Commands
;;;###autoload (autoload 'magit-reset "magit" nil t)
;;;###autoload(autoload 'magit-reset "magit" nil t)
(transient-define-prefix magit-reset ()
"Reset the `HEAD', index and/or worktree to a previous state."
:man-page "git-reset"
@@ -89,10 +89,10 @@ head this effectively unstages all changes.
"Reset the worktree to COMMIT.
Keep the `HEAD' and index as-is."
(interactive (list (magit-read-branch-or-commit "Reset worktree to")))
(magit-wip-commit-before-change nil " before reset")
(magit-run-before-change-functions nil "reset")
(magit-with-temp-index commit nil
(magit-call-git "checkout-index" "--all" "--force"))
(magit-wip-commit-after-apply nil " after reset")
(magit-run-after-apply-functions nil "reset")
(magit-refresh))
;;;###autoload
@@ -127,11 +127,22 @@ or \"detached head\" will be substituted for %s."
(git-commit-setup-font-lock)
(git-commit-save-message)))
(let ((cmd (if (and (equal commit "HEAD") (not arg)) "unstage" "reset")))
(magit-wip-commit-before-change nil (concat " before " cmd))
(magit-run-before-change-functions nil cmd)
(magit-run-git "reset" arg commit "--" path)
(when (equal cmd "unstage")
(magit-wip-commit-after-apply nil " after unstage"))))
(magit-run-after-apply-functions nil "unstage"))))
;;; _
(provide 'magit-reset)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-reset.el ends here

View File

@@ -32,7 +32,7 @@
;; For `magit-rebase--todo'.
(declare-function git-rebase-current-line "git-rebase" (&optional batch))
(eval-when-compile
(eval-and-compile
(cl-pushnew 'action-type eieio--known-slot-names)
(cl-pushnew 'action eieio--known-slot-names)
(cl-pushnew 'action-options eieio--known-slot-names)
@@ -131,7 +131,7 @@ This discards all changes made since the sequence started."
(defvar magit-perl-executable "perl"
"The Perl executable.")
;;;###autoload (autoload 'magit-cherry-pick "magit-sequence" nil t)
;;;###autoload(autoload 'magit-cherry-pick "magit-sequence" nil t)
(transient-define-prefix magit-cherry-pick ()
"Apply or transplant commits."
:man-page "git-cherry-pick"
@@ -349,8 +349,7 @@ the process manually."
command))
((seq-find (##string-prefix-p "--mainline=" %) args)
args)
(t
(cons (format "--mainline=%s"
((cons (format "--mainline=%s"
(read-number "Replay merges relative to parent: "))
args))))
commits)))
@@ -361,13 +360,12 @@ the process manually."
(or (file-exists-p (expand-file-name "CHERRY_PICK_HEAD" dir))
;; And CHERRY_PICK_HEAD does not exist when a conflict happens
;; while picking a series of commits with --no-commit.
(and-let* ((line (magit-file-line
(expand-file-name "sequencer/todo" dir))))
(string-prefix-p "pick" line)))))
(and$ (magit-file-line (expand-file-name "sequencer/todo" dir))
(string-prefix-p "pick" $)))))
;;; Revert
;;;###autoload (autoload 'magit-revert "magit-sequence" nil t)
;;;###autoload(autoload 'magit-revert "magit-sequence" nil t)
(transient-define-prefix magit-revert ()
"Revert existing commits, with or without creating new commits."
:man-page "git-revert"
@@ -419,13 +417,12 @@ without prompting."
(or (file-exists-p (expand-file-name "REVERT_HEAD" dir))
;; And REVERT_HEAD does not exist when a conflict happens
;; while reverting a series of commits with --no-commit.
(and-let* ((line (magit-file-line
(expand-file-name "sequencer/todo" dir))))
(string-prefix-p "revert" line)))))
(and$ (magit-file-line (expand-file-name "sequencer/todo" dir))
(string-prefix-p "revert" $)))))
;;; Patch
;;;###autoload (autoload 'magit-am "magit-sequence" nil t)
;;;###autoload(autoload 'magit-am "magit-sequence" nil t)
(transient-define-prefix magit-am ()
"Apply patches received by email."
:man-page "git-am"
@@ -519,7 +516,7 @@ This discards all changes made since the sequence started."
;;; Rebase
;;;###autoload (autoload 'magit-rebase "magit-sequence" nil t)
;;;###autoload(autoload 'magit-rebase "magit-sequence" nil t)
(transient-define-prefix magit-rebase ()
"Transplant commits and/or modify existing commits."
:man-page "git-rebase"
@@ -587,7 +584,7 @@ This discards all changes made since the sequence started."
(defun magit-git-rebase (target args)
(magit-run-git-sequencer "rebase" args target))
;;;###autoload (autoload 'magit-rebase-onto-pushremote "magit-sequence" nil t)
;;;###autoload(autoload 'magit-rebase-onto-pushremote "magit-sequence" nil t)
(transient-define-suffix magit-rebase-onto-pushremote (args)
"Rebase the current branch onto its push-remote branch.
@@ -601,7 +598,7 @@ push-remote."
(magit--select-push-remote "rebase onto that")))
(magit-git-rebase (concat remote "/" branch) args)))
;;;###autoload (autoload 'magit-rebase-onto-upstream "magit-sequence" nil t)
;;;###autoload(autoload 'magit-rebase-onto-upstream "magit-sequence" nil t)
(transient-define-suffix magit-rebase-onto-upstream (args)
"Rebase the current branch onto its upstream branch.
@@ -622,7 +619,7 @@ the upstream."
(magit-git-rebase upstream args)))
(defun magit-rebase--upstream-description ()
(and-let* ((branch (magit-get-current-branch)))
(and-let ((branch (magit-get-current-branch)))
(or (magit-get-upstream-branch branch)
(let ((remote (magit-get "branch" branch "remote"))
(merge (magit-get "branch" branch "merge"))
@@ -634,8 +631,7 @@ the upstream."
(concat u ", replacing non-existent"))
((or remote merge)
(concat u ", replacing invalid"))
(t
(concat u ", setting that")))))))
((concat u ", setting that")))))))
;;;###autoload
(defun magit-rebase-branch (target args)
@@ -658,29 +654,27 @@ START has to be selected from a list of recent commits."
(magit-get-upstream-branch))
nil
(magit-rebase-arguments)))
(if start
(progn (message "Rebasing...")
(magit-run-git-sequencer "rebase" "--onto" newbase start args)
(message "Rebasing...done"))
(magit-log-select
`(lambda (commit)
(magit-rebase-subset ,newbase (concat commit "^") (list ,@args)))
(concat "Type %p on a commit to rebase it "
"and commits above it onto " newbase ","))))
(defvar magit-rebase-interactive-include-selected t)
(cond (start
(message "Rebasing...")
(magit-run-git-sequencer "rebase" "--onto" newbase start args)
(message "Rebasing...done"))
((magit-log-select
`(lambda (commit)
(magit-rebase-subset ,newbase (concat commit "^") (list ,@args)))
(concat "Type %p on a commit to rebase it "
"and commits above it onto " newbase ",")))))
(defun magit-rebase-interactive-1
(commit args message &optional editor delay-edit-confirm noassert confirm)
( commit args message
&optional editor delay-edit-confirm noassert confirm exact)
(declare (indent 2))
(when commit
(unless (magit-rev-ancestor-p commit "HEAD")
(user-error "%s isn't an ancestor of HEAD" commit))
(if (magit-commit-parents commit)
(when (or (not (eq this-command 'magit-rebase-interactive))
magit-rebase-interactive-include-selected)
(setq commit (concat commit "^")))
(setq args (cons "--root" args))))
(cond ((not commit))
((not (magit-rev-ancestor-p commit "HEAD"))
(user-error "%s isn't an ancestor of HEAD" commit))
((not (magit-commit-parents commit))
(setq args (cons "--root" args)))
((not exact)
(setq commit (concat commit "^"))))
(when (and commit (not noassert))
(setq commit (magit-rebase-interactive-assert
commit delay-edit-confirm
@@ -746,6 +740,8 @@ START has to be selected from a list of recent commits."
;; The "--root" argument is being used.
since))
(defvar magit-rebase-interactive-include-selected t)
;;;###autoload
(defun magit-rebase-interactive (commit args)
"Start an interactive rebase sequence."
@@ -753,7 +749,8 @@ START has to be selected from a list of recent commits."
(magit-rebase-arguments)))
(magit-rebase-interactive-1 commit args
"Type %p on a commit to rebase it and all commits above it,"
nil t))
nil t nil nil
(not magit-rebase-interactive-include-selected)))
;;;###autoload
(defun magit-rebase-autosquash (select args)
@@ -764,12 +761,12 @@ argument, prompt for the first commit to potentially squash into."
(interactive (list current-prefix-arg
(magit-rebase-arguments)))
(magit-rebase-interactive-1
(and-let* (((not select))
(upstream (magit-get-upstream-branch)))
(and-let ((_(not select))
(upstream (magit-get-upstream-branch)))
(magit-git-string "merge-base" upstream "HEAD"))
(nconc (list "--autosquash" "--keep-empty") args)
"Type %p on a commit to squash into it and then rebase as necessary,"
"true" nil t))
"true" nil t nil t))
;;;###autoload
(defun magit-rebase-edit-commit (commit args)
@@ -822,25 +819,26 @@ argument, prompt for the first commit to potentially squash into."
In some cases this pops up a commit message buffer for you do
edit. With a prefix argument the old message is reused as-is."
(interactive "P")
(if (magit-rebase-in-progress-p)
(if (magit-anything-unstaged-p t)
(user-error "Cannot continue rebase with unstaged changes")
(let ((dir (magit-gitdir)))
(when (and (magit-anything-staged-p)
(file-exists-p (expand-file-name "rebase-merge" dir))
(not (member (magit-toplevel)
magit--rebase-public-edit-confirmed)))
(magit-commit-amend-assert
(magit-file-line
(expand-file-name "rebase-merge/orig-head" dir)))))
(if noedit
(with-environment-variables (("GIT_EDITOR" "true"))
(magit-run-git-async (magit--rebase-resume-command) "--continue")
(set-process-sentinel magit-this-process
#'magit-sequencer-process-sentinel)
magit-this-process)
(magit-run-git-sequencer (magit--rebase-resume-command) "--continue")))
(user-error "No rebase in progress")))
(cond
((not (magit-rebase-in-progress-p))
(user-error "No rebase in progress"))
((magit-anything-unstaged-p t)
(user-error "Cannot continue rebase with unstaged changes"))
(t
(let ((dir (magit-gitdir)))
(when (and (magit-anything-staged-p)
(file-exists-p (expand-file-name "rebase-merge" dir))
(not (member (magit-toplevel)
magit--rebase-public-edit-confirmed)))
(magit-commit-amend-assert
(magit-file-line (expand-file-name "rebase-merge/orig-head" dir)))))
(if noedit
(with-environment-variables (("GIT_EDITOR" "true"))
(magit-run-git-async (magit--rebase-resume-command) "--continue")
(set-process-sentinel magit-this-process
#'magit-sequencer-process-sentinel)
magit-this-process)
(magit-run-git-sequencer (magit--rebase-resume-command) "--continue")))))
;;;###autoload
(defun magit-rebase-skip ()
@@ -942,8 +940,7 @@ If no such sequence is in progress, do nothing."
(commit
(magit-sequence-insert-commit
"pick" commit 'magit-sequence-pick))
(t
(magit-sequence-insert-am-patch
((magit-sequence-insert-am-patch
"pick" patch 'magit-sequence-pick)))
(cl-decf i)))
(magit-sequence-insert-sequence nil "ORIG_HEAD")
@@ -1010,7 +1007,7 @@ status buffer (i.e., the reverse of how they will be applied)."
(if (eq (oref obj action-type) 'merge)
(let ((options (oref obj action-options)))
(and (string-match "-[cC] \\([^ ]+\\)" options)
(match-string 1 options)))
(match-str 1 options)))
(oref obj target)))
commits)))))
(cl-assert (equal (length commits) (length abbrevs)))
@@ -1031,9 +1028,8 @@ status buffer (i.e., the reverse of how they will be applied)."
(magit-sequence-insert-sequence
(magit-file-line (expand-file-name "rebase-merge/stopped-sha" dir))
onto
(and-let* ((lines (magit-file-lines
(expand-file-name "rebase-merge/done" dir))))
(cadr (split-string (car (last lines))))))))
(and$ (magit-file-lines (expand-file-name "rebase-merge/done" dir))
(cadr (split-string (car (last $))))))))
(defun magit-rebase-insert-apply-sequence (onto)
(let* ((dir (magit-gitdir))
@@ -1090,15 +1086,14 @@ status buffer (i.e., the reverse of how they will be applied)."
(equal (magit-patch-id unstaged) id))
"same")
;; ...and some changes are gone and/or others were added.
(t "work")))
("work")))
stop 'magit-sequence-part))
;; The commit is definitely gone...
((assoc (##magit-rev-equal % stop) done)
;; ...but all of its changes are still in effect.
(magit-sequence-insert-commit "poof" stop 'magit-sequence-drop))
(t
;; ...and some changes are gone and/or other changes were added.
(magit-sequence-insert-commit "gone" stop 'magit-sequence-drop)))
;; ...and some changes are gone and/or other changes were added.
((magit-sequence-insert-commit "gone" stop 'magit-sequence-drop)))
(setq stop nil))))
(pcase-dolist (`(,rev ,abbrev ,msg) done)
(apply #'magit-sequence-insert-commit
@@ -1116,8 +1111,7 @@ status buffer (i.e., the reverse of how they will be applied)."
abbrev msg))
((equal rev head)
(list "done" rev 'magit-sequence-head abbrev msg))
(t
(list "done" rev 'magit-sequence-done abbrev msg)))))
((list "done" rev 'magit-sequence-done abbrev msg)))))
(magit-sequence-insert-commit "onto" onto
(if (equal onto head)
'magit-sequence-head
@@ -1126,9 +1120,9 @@ status buffer (i.e., the reverse of how they will be applied)."
(defun magit-sequence-insert-commit (type hash face &optional abbrev msg)
(magit-insert-section (commit hash)
(magit-insert-heading
(propertize type 'font-lock-face face) " "
(magit--propertize-face type face) " "
(if abbrev
(concat (propertize abbrev 'face 'magit-hash) " " msg "\n")
(concat (magit--propertize-face abbrev 'magit-hash) " " msg "\n")
(concat (magit-format-rev-summary hash) "\n")))))
(defun magit-sequence-insert-step (type target)
@@ -1141,4 +1135,15 @@ status buffer (i.e., the reverse of how they will be applied)."
;;; _
(provide 'magit-sequence)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-sequence.el ends here

View File

@@ -23,15 +23,7 @@
;;; 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.
;; command (operating in cone mode).
;;; Code:
@@ -62,7 +54,7 @@ See the `git sparse-checkout' manpage for details about
;;; Commands
;;;###autoload (autoload 'magit-sparse-checkout "magit-sparse-checkout" nil t)
;;;###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"
@@ -155,4 +147,15 @@ This header is not inserted by default. To enable it, add it to
;;; _
(provide 'magit-sparse-checkout)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-sparse-checkout.el ends here

View File

@@ -87,7 +87,7 @@ AUTHOR-WIDTH has to be an integer. When the name of the author
;;; Commands
;;;###autoload (autoload 'magit-stash "magit-stash" nil t)
;;;###autoload(autoload 'magit-stash "magit-stash" nil t)
(transient-define-prefix magit-stash ()
"Stash uncommitted changes."
:man-page "git-stash"
@@ -234,7 +234,7 @@ while two prefix arguments are equivalent to `--all'."
(magit-stash-save (concat "WIP on " (magit-stash-summary))
index worktree untracked refresh t))
;;;###autoload (autoload 'magit-stash-push "magit-stash" nil t)
;;;###autoload(autoload 'magit-stash-push "magit-stash" nil t)
(transient-define-prefix magit-stash-push (&optional transient args)
"Create stash using \"git stash push\".
@@ -448,7 +448,7 @@ Then apply STASH, dropping it if it applies cleanly."
(unless noerror
(user-error "No %s changes to save" (cond ((not index) "unstaged")
((not worktree) "staged")
(t "local"))))))
("local"))))))
(defun magit-stash-store (message ref rev)
(magit-update-ref ref message rev))
@@ -681,4 +681,15 @@ that make up the stash."
;;; _
(provide 'magit-stash)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-stash.el ends here

View File

@@ -147,7 +147,7 @@ The functions which respect this option are
- If nil, do not list any untracked files.
- If t, list untracked files, but if a directory does not contain any
untracked files, then only list that directory, not the contained
tracked files, then only list that directory, not the contained
untracked files.
- If all, then list each individual untracked files. This is can be
very slow and is discouraged.
@@ -346,8 +346,12 @@ also contains other useful hints.")
;;;###autoload
(defun magit-status-here ()
"Like `magit-status' but with non-nil `magit-status-goto-file-position'."
"Like `magit-status' but with non-nil `magit-status-goto-file-position'.
Before doing so, save all file-visiting buffers belonging to the current
repository without prompting."
(interactive)
(let ((magit-inhibit-refresh t))
(magit-save-repository-buffers t))
(let ((magit-status-goto-file-position t))
(call-interactively #'magit-status)))
@@ -433,9 +437,6 @@ Type \\[magit-commit] to create a commit.
:interactive nil
:group 'magit-status
(magit-hack-dir-local-variables)
(when magit-status-initial-section
(add-hook 'magit--initial-section-hook
#'magit-status-goto-initial-section nil t))
(setq magit--imenu-group-types '(not branch commit)))
(put 'magit-status-mode 'magit-diff-default-arguments
@@ -445,42 +446,47 @@ Type \\[magit-commit] to create a commit.
;;;###autoload
(defun magit-status-setup-buffer (&optional directory)
(unless directory
(setq directory default-directory))
(when (file-remote-p directory)
(magit-git-version-assert))
(let* ((default-directory directory)
(d (magit-diff--get-value 'magit-status-mode
magit-status-use-buffer-arguments))
(l (magit-log--get-value 'magit-status-mode
magit-status-use-buffer-arguments))
(file (and magit-status-goto-file-position
(magit-file-relative-name)))
(line (and file (save-restriction (widen) (line-number-at-pos))))
(col (and file (save-restriction (widen) (current-column))))
(buf (magit-setup-buffer #'magit-status-mode nil
(magit-buffer-diff-args (nth 0 d))
(magit-buffer-diff-files (nth 1 d))
(magit-buffer-log-args (nth 0 l))
(magit-buffer-log-files (nth 1 l)))))
(when file
(with-current-buffer buf
(let ((staged (magit-get-section '((staged) (status)))))
(if (and staged
(cadr (magit-diff--locate-hunk file line staged)))
(magit-diff--goto-position file line col staged)
(let ((unstaged (magit-get-section '((unstaged) (status)))))
(unless (and unstaged
(magit-diff--goto-position file line col unstaged))
(when staged
(magit-diff--goto-position file line col staged))))))))
buf))
(let ((default-directory (or directory default-directory)))
(when (file-remote-p default-directory)
(magit-git-version-assert))
(pcase-let
((`(,dargs ,dfiles) (magit-diff--get-value 'magit-status-mode 'status))
(`(,largs ,lfiles) (magit-log--get-value 'magit-status-mode 'status)))
(magit-setup-buffer #'magit-status-mode nil
:initial-section #'magit-status-goto-initial-section
:select-section (and$ (magit-status--get-file-position)
(lambda () (apply #'magit-status--goto-file-position $)))
(magit-buffer-diff-args dargs)
(magit-buffer-diff-files dfiles)
(magit-buffer-log-args largs)
(magit-buffer-log-files lfiles)))))
(defun magit-status-refresh-buffer ()
(magit-git-exit-code "update-index" "--refresh")
(magit-insert-section (status)
(magit-run-section-hook 'magit-status-sections-hook)))
(defun magit-status--get-file-position ()
(and-let* ((_ magit-status-goto-file-position)
(file (magit-file-relative-name)))
(save-excursion
(widen)
(list file (line-number-at-pos) (current-column)))))
(defun magit-status--goto-file-position (file line column)
(pcase-let ((`(,upos ,uloc)
(magit-diff--locate-file-position file line column 'unstaged))
(`(,spos ,sloc)
(magit-diff--locate-file-position file line column 'staged)))
(cond ((eq uloc 'line) (goto-char upos))
((eq sloc 'line) (goto-char spos))
((eq uloc 'hunk) (goto-char upos))
((eq sloc 'hunk) (goto-char spos))
(upos (goto-char upos))
(spos (goto-char spos)))
(when (or upos spos)
(magit-section-reveal (magit-current-section)))))
(defun magit-status-goto-initial-section ()
"Jump to the section specified by `magit-status-initial-section'."
(when-let ((section
@@ -547,7 +553,7 @@ the status buffer causes this section to disappear again."
(insert (propertize (format "%-10s" "GitError! ")
'font-lock-face 'magit-section-heading))
(insert (propertize magit-this-error 'font-lock-face 'error))
(when-let ((magit-show-process-buffer-hint)
(when-let ((_ magit-show-process-buffer-hint)
(key (car (where-is-internal 'magit-process-buffer))))
(insert (format " [Type `%s' for details]" (key-description key))))
(insert ?\n))
@@ -613,35 +619,34 @@ arguments are for internal use only."
(_ (setq rebase (magit-get-boolean "pull.rebase"))))
(insert (format "%-10s" (or keyword (if rebase "Rebase: " "Merge: "))))
(insert
(if upstream
(concat (and magit-status-show-hashes-in-headers
(concat (propertize (magit-rev-format "%h" upstream)
'font-lock-face 'magit-hash)
" "))
upstream " "
(magit-log--wash-summary
(or (magit-rev-format "%s" upstream)
"(no commit message)")))
(cond
((magit--unnamed-upstream-p remote merge)
(concat (propertize merge 'font-lock-face 'magit-branch-remote)
" from "
(propertize remote 'font-lock-face 'bold)))
((magit--valid-upstream-p remote merge)
(if (equal remote ".")
(concat
(propertize merge 'font-lock-face 'magit-branch-local) " "
(propertize "does not exist"
'font-lock-face 'magit-branch-warning))
(format
"%s %s %s"
(propertize merge 'font-lock-face 'magit-branch-remote)
(propertize "does not exist on"
'font-lock-face 'magit-branch-warning)
(propertize remote 'font-lock-face 'magit-branch-remote))))
(t
(propertize "invalid upstream configuration"
'font-lock-face 'magit-branch-warning)))))
(cond
(upstream
(concat (and magit-status-show-hashes-in-headers
(concat (propertize (magit-rev-format "%h" upstream)
'font-lock-face 'magit-hash)
" "))
upstream " "
(magit-log--wash-summary
(or (magit-rev-format "%s" upstream)
"(no commit message)"))))
((magit--unnamed-upstream-p remote merge)
(concat (propertize merge 'font-lock-face 'magit-branch-remote)
" from "
(propertize remote 'font-lock-face 'bold)))
((magit--valid-upstream-p remote merge)
(if (equal remote ".")
(concat
(propertize merge 'font-lock-face 'magit-branch-local) " "
(propertize "does not exist"
'font-lock-face 'magit-branch-warning))
(format
"%s %s %s"
(propertize merge 'font-lock-face 'magit-branch-remote)
(propertize "does not exist on"
'font-lock-face 'magit-branch-warning)
(propertize remote 'font-lock-face 'magit-branch-remote))))
((propertize "invalid upstream configuration"
'font-lock-face 'magit-branch-warning))))
(insert ?\n))))))
(defun magit-insert-push-branch-header ()
@@ -651,22 +656,24 @@ arguments are for internal use only."
(magit-insert-section (branch target)
(insert (format "%-10s" "Push: "))
(insert
(if (magit-rev-verify target)
(concat (and magit-status-show-hashes-in-headers
(concat (propertize (magit-rev-format "%h" target)
'font-lock-face 'magit-hash)
" "))
target " "
(magit-log--wash-summary (or (magit-rev-format "%s" target)
"(no commit message)")))
(let ((remote (magit-get-push-remote branch)))
(if (magit-remote-p remote)
(concat target " "
(propertize "does not exist"
'font-lock-face 'magit-branch-warning))
(concat remote " "
(propertize "remote does not exist"
'font-lock-face 'magit-branch-warning))))))
(cond-let
((magit-rev-verify target)
(concat (and magit-status-show-hashes-in-headers
(concat (propertize (magit-rev-format "%h" target)
'font-lock-face 'magit-hash)
" "))
target " "
(magit-log--wash-summary
(or (magit-rev-format "%s" target)
"(no commit message)"))))
[[remote (magit-get-push-remote branch)]]
((magit-remote-p remote)
(concat target " "
(propertize "does not exist"
'font-lock-face 'magit-branch-warning)))
((concat remote " "
(propertize "remote does not exist"
'font-lock-face 'magit-branch-warning)))))
(insert ?\n))))
(defun magit-insert-tags-header ()
@@ -811,4 +818,15 @@ Honor the buffer's file filter, which can be set using \"D - -\"."
;;; _
(provide 'magit-status)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-status.el ends here

View File

@@ -158,7 +158,7 @@ and also setting this variable to t will lead to tears."
;;; Popup
;;;###autoload (autoload 'magit-submodule "magit-submodule" nil t)
;;;###autoload(autoload 'magit-submodule "magit-submodule" nil t)
(transient-define-prefix magit-submodule ()
"Act on a submodule."
:man-page "git-submodule"
@@ -205,7 +205,7 @@ and also setting this variable to t will lead to tears."
(propertize "|" 'face 'transient-inactive-argument))))
(cl-call-next-method obj))))
;;;###autoload (autoload 'magit-submodule-add "magit-submodule" nil t)
;;;###autoload(autoload 'magit-submodule-add "magit-submodule" nil t)
(transient-define-suffix magit-submodule-add (url &optional path name args)
"Add the repository at URL as a module.
@@ -230,7 +230,7 @@ it is nil, then PATH also becomes the name."
(file-relative-name
(read-directory-name prompt nil nil nil
(and (string-match "\\([^./]+\\)\\(\\.git\\)?$" url)
(match-string 1 url))))))
(match-str 1 url))))))
(defun magit-submodule-add-1 (url &optional path name args)
(magit-with-toplevel
@@ -262,7 +262,7 @@ it is nil, then PATH also becomes the name."
(magit-git-lines "config" "--list" "-f" ".gitmodules"))
(if prefer-short name path)))))
;;;###autoload (autoload 'magit-submodule-register "magit-submodule" nil t)
;;;###autoload(autoload 'magit-submodule-register "magit-submodule" nil t)
(transient-define-suffix magit-submodule-register (modules)
"Register MODULES.
@@ -281,7 +281,7 @@ single module from the user."
(magit-with-toplevel
(magit-run-git-async "submodule" "init" "--" modules)))
;;;###autoload (autoload 'magit-submodule-populate "magit-submodule" nil t)
;;;###autoload(autoload 'magit-submodule-populate "magit-submodule" nil t)
(transient-define-suffix magit-submodule-populate (modules args)
"Create MODULES working directories, checking out the recorded commits.
@@ -300,7 +300,7 @@ single module from the user."
(magit-with-toplevel
(magit-run-git-async "submodule" "update" "--init" args "--" modules)))
;;;###autoload (autoload 'magit-submodule-update "magit-submodule" nil t)
;;;###autoload(autoload 'magit-submodule-update "magit-submodule" nil t)
(transient-define-suffix magit-submodule-update (modules args)
"Update MODULES by checking out the recorded commits.
@@ -323,7 +323,7 @@ single module from the user."
(magit-with-toplevel
(magit-run-git-async "submodule" "update" args "--" modules)))
;;;###autoload (autoload 'magit-submodule-synchronize "magit-submodule" nil t)
;;;###autoload(autoload 'magit-submodule-synchronize "magit-submodule" nil t)
(transient-define-suffix magit-submodule-synchronize (modules args)
"Synchronize url configuration of MODULES.
@@ -339,7 +339,7 @@ single module from the user."
(magit-with-toplevel
(magit-run-git-async "submodule" "sync" args "--" modules)))
;;;###autoload (autoload 'magit-submodule-unpopulate "magit-submodule" nil t)
;;;###autoload(autoload 'magit-submodule-unpopulate "magit-submodule" nil t)
(transient-define-suffix magit-submodule-unpopulate (modules args)
"Remove working directories of MODULES.
@@ -498,13 +498,14 @@ or, failing that, the abbreviated HEAD commit hash."
(if-let ((branch (magit-get-current-branch)))
(propertize branch 'font-lock-face 'magit-branch-local)
(propertize "(detached)" 'font-lock-face 'warning))))
(if-let ((desc (magit-git-string "describe" "--tags")))
(progn (when (and magit-modules-overview-align-numbers
(string-match-p "\\`[0-9]" desc))
(insert ?\s))
(insert (propertize desc 'font-lock-face 'magit-tag)))
(when-let ((abbrev (magit-rev-format "%h")))
(insert (propertize abbrev 'font-lock-face 'magit-hash)))))
(cond-let
([desc (magit-git-string "describe" "--tags")]
(when (and magit-modules-overview-align-numbers
(string-match-p "\\`[0-9]" desc))
(insert ?\s))
(insert (propertize desc 'font-lock-face 'magit-tag)))
([abbrev (magit-rev-format "%h")]
(insert (propertize abbrev 'font-lock-face 'magit-hash)))))
(insert ?\n))))))
(insert ?\n))
@@ -587,24 +588,24 @@ These sections can be expanded to show the respective commits."
(defun magit--insert-modules-logs (heading type range)
"For internal use, don't add to a hook."
(when-let (((not (magit-ignore-submodules-p)))
(when-let ((_(not (magit-ignore-submodules-p)))
(modules (magit-list-module-paths)))
(magit-insert-section ((eval type) nil t)
(string-match "\\`\\(.+\\) \\([^ ]+\\)\\'" heading)
(magit-insert-heading
(propertize (match-string 1 heading)
(propertize (match-str 1 heading)
'font-lock-face 'magit-section-heading)
" "
(propertize (match-string 2 heading)
(propertize (match-str 2 heading)
'font-lock-face 'magit-branch-remote)
":")
(dolist (module modules)
(when-let* ((default-directory (expand-file-name module))
((file-exists-p (expand-file-name ".git")))
(_(file-exists-p (expand-file-name ".git")))
(lines (magit-git-lines "-c" "push.default=current"
"log" "--oneline" range))
(count (length lines))
((> count 0)))
(_(> count 0)))
(magit-insert-section
( module module t
:range range)
@@ -612,8 +613,8 @@ These sections can be expanded to show the respective commits."
(propertize module 'font-lock-face 'magit-diff-file-heading))
(dolist (line lines)
(string-match magit-log-module-re line)
(let ((rev (match-string 1 line))
(msg (match-string 2 line)))
(let ((rev (match-str 1 line))
(msg (match-str 2 line)))
(magit-insert-section (module-commit rev t)
(insert (propertize rev 'font-lock-face 'magit-hash) " "
(magit-log--wash-summary msg) "\n")))))))
@@ -713,4 +714,15 @@ These sections can be expanded to show the respective commits."
;;; _
(provide 'magit-submodule)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-submodule.el ends here

View File

@@ -33,7 +33,7 @@
;;; Commands
;;;###autoload (autoload 'magit-subtree "magit-subtree" nil t)
;;;###autoload(autoload 'magit-subtree "magit-subtree" nil t)
(transient-define-prefix magit-subtree ()
"Import or export subtrees."
:man-page "git-subtree"
@@ -41,7 +41,7 @@
("i" "Import" magit-subtree-import)
("e" "Export" magit-subtree-export)])
;;;###autoload (autoload 'magit-subtree-import "magit-subtree" nil t)
;;;###autoload(autoload 'magit-subtree-import "magit-subtree" nil t)
(transient-define-prefix magit-subtree-import ()
"Import subtrees."
:man-page "git-subtree"
@@ -55,7 +55,7 @@
[("m" "Merge" magit-subtree-merge)
("f" "Pull" magit-subtree-pull)]])
;;;###autoload (autoload 'magit-subtree-export "magit-subtree" nil t)
;;;###autoload(autoload 'magit-subtree-export "magit-subtree" nil t)
(transient-define-prefix magit-subtree-export ()
"Export subtrees."
:man-page "git-subtree"
@@ -184,4 +184,15 @@
;;; _
(provide 'magit-subtree)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-subtree.el ends here

View File

@@ -33,7 +33,7 @@
;;; Commands
;;;###autoload (autoload 'magit-tag "magit" nil t)
;;;###autoload(autoload 'magit-tag "magit" nil t)
(transient-define-prefix magit-tag ()
"Create or delete a tag."
:man-page "git-tag"
@@ -66,7 +66,7 @@
"Create a new tag with the given NAME at COMMIT.
With a prefix argument annotate the tag.
\n(git tag [--annotate] NAME REV)"
(interactive (list (magit-read-tag "Tag name")
(interactive (list (magit-completing-read "Create tag" (magit-list-tags))
(magit-read-branch-or-commit "Place tag on")
(let ((args (magit-tag-arguments)))
(when current-prefix-arg
@@ -84,7 +84,7 @@ defaulting to the tag at point.
(interactive (list (if-let ((tags (magit-region-values 'tag)))
(magit-confirm t nil "Delete %d tags" nil tags)
(let ((helm-comp-read-use-marked t))
(magit-read-tag "Delete tag" t)))))
(magit-read-tag "Delete tag")))))
(magit-run-git "tag" "-d" tags))
;;;###autoload
@@ -128,7 +128,7 @@ defaulting to the tag at point.
See also `magit-release-tag-regexp'.")
(defvar magit-release-tag-regexp "\\`\
\\(?1:\\(?:v\\(?:ersion\\)?\\|r\\(?:elease\\)?\\)[-_]?\\)?\
\\(?1:\\(?:v\\(?:ersion\\)?\\|r\\(?:elease\\)?\\)[-_/]?\\)?\
\\(?2:[0-9]+\\(?:\\.[0-9]+\\)*\
\\(?:-[a-zA-Z0-9-]+\\(?:\\.[a-zA-Z0-9-]+\\)*\\)?\\)\\'"
"Regexp used by `magit-tag-release' to parse release tags.
@@ -167,7 +167,7 @@ that is not the case, propose a message using a reasonable format."
(`(,pver ,ptag ,pmsg) (car (magit--list-releases)))
(msg (magit-rev-format "%s"))
(ver (and (string-match magit-release-commit-regexp msg)
(match-string 1 msg)))
(match-str 1 msg)))
(_ (and (not ver)
(require (quote sisyphus) nil t)
(string-match magit-release-commit-regexp
@@ -185,14 +185,13 @@ that is not the case, propose a message using a reasonable format."
ver)))
(ver
(concat (and (string-match magit-release-tag-regexp ptag)
(match-string 1 ptag))
(match-str 1 ptag))
ver))
(t
(read-string
(format "Create release tag (previous was %s): " ptag)
ptag))))
((read-string (format "Create release tag (previous was %s): "
ptag)
ptag))))
(ver (and (string-match magit-release-tag-regexp tag)
(match-string 2 tag))))
(match-str 2 tag))))
(list tag
(and (seq-some (apply-partially
#'string-match-p
@@ -226,17 +225,16 @@ a tag qualifies as a release tag."
(mapcar
#'cdr
(nreverse
(cl-sort (mapcan
(cl-sort (seq-keep
(lambda (line)
(and (string-match " +" line)
(let ((tag (substring line 0 (match-beginning 0)))
(msg (substring line (match-end 0))))
(and (string-match magit-release-tag-regexp tag)
(let ((ver (match-string 2 tag))
(version-regexp-alist
magit-tag-version-regexp-alist))
(list (list (version-to-list ver)
ver tag msg)))))))
(and-let*
((_(string-match " +" line))
(tag (substring line 0 (match-beginning 0)))
(msg (substring line (match-end 0)))
(_(string-match magit-release-tag-regexp tag))
(ver (match-str 2 tag))
(version-regexp-alist magit-tag-version-regexp-alist))
(list (version-to-list ver) ver tag msg)))
;; Cannot rely on "--sort=-version:refname" because
;; that gets confused if the version prefix has changed.
(magit-git-lines "tag" "-n"))
@@ -245,4 +243,15 @@ a tag qualifies as a release tag."
;;; _
(provide 'magit-tag)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-tag.el ends here

View File

@@ -68,8 +68,7 @@
(oset obj value
(cond ((oref obj multi-value)
(magit-get-all arg variable))
(t
(magit-get arg variable))))))
((magit-get arg variable))))))
(cl-defmethod transient-init-value ((obj magit--git-variable:boolean))
(let ((variable (format (oref obj variable)
@@ -93,18 +92,19 @@
(let ((choices (oref obj choices)))
(when (functionp choices)
(setq choices (funcall choices)))
(if current-prefix-arg
(pcase-let*
((`(,fallback . ,choices)
(magit--git-variable-list-choices obj))
(choice (magit-completing-read
(format "Set `%s' to" (oref obj variable))
(if fallback (nconc choices (list fallback)) choices)
nil t)))
(if (equal choice fallback) nil choice))
(if-let ((value (oref obj value)))
(cadr (member value choices))
(car choices)))))
(cond-let
(current-prefix-arg
(pcase-let*
((`(,fallback . ,choices)
(magit--git-variable-list-choices obj))
(choice (magit-completing-read
(format "Set `%s' to" (oref obj variable))
(if fallback (nconc choices (list fallback)) choices)
nil t)))
(if (equal choice fallback) nil choice)))
([value (oref obj value)]
(cadr (member value choices)))
((car choices)))))
;;;; Readers
@@ -118,11 +118,10 @@
nil nil initial-input history))
(defun magit-transient-read-revision (prompt initial-input history)
(or (magit-completing-read prompt (cons "HEAD" (magit-list-refnames))
nil nil initial-input history
(or (magit-branch-or-commit-at-point)
(magit-get-current-branch)))
(user-error "Nothing selected")))
(magit-completing-read prompt (cons "HEAD" (magit-list-refnames))
nil 'any initial-input history
(or (magit-branch-or-commit-at-point)
(magit-get-current-branch))))
;;;; Set
@@ -156,20 +155,21 @@
(oref obj variable)))
(cl-defmethod transient-format-value ((obj magit--git-variable))
(if-let ((value (oref obj value)))
(if (oref obj multi-value)
(if (cdr value)
(mapconcat (##concat "\n "
(propertize % 'face 'transient-value))
value "")
(propertize (car value) 'face 'transient-value))
(propertize (car (split-string value "\n"))
'face 'transient-value))
(if-let* ((default (oref obj default))
(default (if (functionp default) (funcall default) default)))
(concat (propertize "default:" 'face 'transient-inactive-value)
(propertize default 'face 'transient-value))
(propertize "unset" 'face 'transient-inactive-value))))
(cond-let*
([value (oref obj value)]
(if (oref obj multi-value)
(if (cdr value)
(mapconcat (##concat "\n "
(propertize % 'face 'transient-value))
value "")
(propertize (car value) 'face 'transient-value))
(propertize (car (split-string value "\n"))
'face 'transient-value)))
([default (oref obj default)]
[default (if (functionp default) (funcall default) default)]
(concat (propertize "default:" 'face 'transient-inactive-value)
(propertize default 'face 'transient-value)))
((propertize "unset" 'face 'transient-inactive-value))))
(cl-defmethod transient-format-value ((obj magit--git-variable:choices))
(pcase-let ((`(,fallback . ,choices) (magit--git-variable-list-choices obj)))
@@ -191,8 +191,8 @@
(default (if (functionp defaultp) (funcall defaultp obj) defaultp))
(fallback (oref obj fallback))
(fallback (and fallback
(and-let* ((val (magit-get fallback)))
(concat fallback ":" val)))))
(and$ (magit-get fallback)
(concat fallback ":" $)))))
(if (not globalp)
(setq value (magit-git-string "config" "--local" variable))
(setq value global)
@@ -205,8 +205,7 @@
'transient-inactive-value)
((member global choices)
'transient-value)
(t
'font-lock-warning-face))))
('font-lock-warning-face))))
(fallback
(propertize fallback
'face (if value
@@ -229,15 +228,17 @@
(cons value choices)
choices)))))
;;; Utilities
(defun magit--transient-args-and-files ()
"Return (args files) for use by log and diff functions.
The value derives from that returned by `transient-get-value'."
(let ((args (transient-get-value)))
(list (seq-filter #'atom args)
(cdr (assoc "--" args)))))
;;; _
(provide 'magit-transient)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-transient.el ends here

View File

@@ -1,6 +1,6 @@
;;; magit-version.el --- The Magit version you are using -*- lexical-binding:t -*-
(setq magit-version "4.3.8")
(setq magit-version "4.4.2")
(provide 'magit-version)

View File

@@ -22,7 +22,7 @@
;;; Commentary:
;; This library defines tree global modes which automatically commit
;; This library defines global modes which automatically commit
;; snapshots to branch-specific work-in-progress refs before and after
;; making changes, and two commands which can be used to do so on
;; demand.
@@ -57,10 +57,17 @@ never garbage collected.
If nil and the current branch has new commits, then the wip ref
is reset to the tip of the branch before creating a new wip
commit. With this setting wip commits are eventually garbage
collected. This is currently the default."
collected. This is currently the default.
If `immediately', then use `git-commit-post-finish-hook' to
create the merge commit. This is discouraged because it can
lead to a race condition, e.g., during rebases."
:package-version '(magit . "2.90.0")
:group 'magit-wip
:type 'boolean)
:type '(choice
(const :tag "Yes (safely, just in time)" t)
(const :tag "Yes (immediately, with race condition)" immediately)
(const :tag "No" nil)))
(defcustom magit-wip-namespace "refs/wip/"
"Namespace used for work-in-progress refs.
@@ -72,173 +79,57 @@ is used as `branch-ref'."
:group 'magit-wip
:type 'string)
;;; Modes
;;; Mode
(defvar magit--wip-activation-cache nil)
(defvar magit--wip-inhibit-autosave nil)
;;;###autoload
(define-minor-mode magit-wip-mode
"Save uncommitted changes to work-in-progress refs.
Whenever appropriate (i.e., when dataloss would be a possibility
otherwise) this mode causes uncommitted changes to be committed
to dedicated work-in-progress refs.
For historic reasons this mode is implemented on top of four
other `magit-wip-*' modes, which can also be used individually,
if you want finer control over when the wip refs are updated;
but that is discouraged."
"Automatically save uncommitted changes to work-in-progress refs."
:package-version '(magit . "2.90.0")
:lighter magit-wip-mode-lighter
:global t
(let ((arg (if magit-wip-mode 1 -1)))
(let ((magit--wip-activation-cache (list t)))
(magit-wip-after-save-mode arg))
(magit-wip-after-apply-mode arg)
(magit-wip-before-change-mode arg)
(magit-wip-initial-backup-mode arg)))
(define-minor-mode magit-wip-after-save-local-mode
"After saving, also commit to a worktree work-in-progress ref.
After saving the current file-visiting buffer this mode also
commits the changes to the worktree work-in-progress ref for
the current branch.
This mode should be enabled globally by turning on the globalized
variant `magit-wip-after-save-mode'."
:package-version '(magit . "2.1.0")
(if magit-wip-after-save-local-mode
(if (and buffer-file-name (magit-inside-worktree-p t))
(add-hook 'after-save-hook #'magit-wip-commit-buffer-file t t)
(setq magit-wip-after-save-local-mode nil)
(user-error "Need a worktree and a file"))
(remove-hook 'after-save-hook #'magit-wip-commit-buffer-file t)))
(defun magit-wip-after-save-local-mode-turn-on ()
(when (and buffer-file-name
(if magit--wip-activation-cache
(if-let ((elt (assoc default-directory
magit--wip-activation-cache)))
(and-let* ((top (cadr elt)))
(member (file-relative-name buffer-file-name top)
(cddr elt)))
(if-let ((top (magit-toplevel)))
(let (files)
(if-let ((elt (assoc top magit--wip-activation-cache)))
(setq files (cddr elt))
(setq files (let ((default-directory top))
(magit-tracked-files)))
(push `(,top ,top ,@files)
magit--wip-activation-cache)
(unless (eq default-directory top)
(push `(,default-directory ,top ,@files)
magit--wip-activation-cache)))
(member (file-relative-name buffer-file-name) files))
(push (list default-directory nil)
magit--wip-activation-cache)
nil))
(and (magit-inside-worktree-p t)
(magit-file-tracked-p buffer-file-name))))
(magit-wip-after-save-local-mode)))
;;;###autoload
(define-globalized-minor-mode magit-wip-after-save-mode
magit-wip-after-save-local-mode magit-wip-after-save-local-mode-turn-on
:package-version '(magit . "2.1.0")
:group 'magit-wip)
(cond
(magit-wip-mode
(add-hook 'after-save-hook #'magit-wip-commit-buffer-file)
(add-hook 'magit-after-apply-functions #'magit-wip-commit)
(add-hook 'magit-before-change-functions #'magit-wip-commit)
(add-hook 'before-save-hook #'magit-wip-commit-initial-backup)
(add-hook 'git-commit-post-finish-hook #'magit-wip-commit-post-editmsg))
(t
(remove-hook 'after-save-hook #'magit-wip-commit-buffer-file)
(remove-hook 'magit-after-apply-functions #'magit-wip-commit)
(remove-hook 'magit-before-change-functions #'magit-wip-commit)
(remove-hook 'before-save-hook #'magit-wip-commit-initial-backup)
(remove-hook 'git-commit-post-finish-hook #'magit-wip-commit-post-editmsg))))
(defun magit-wip-commit-buffer-file (&optional msg)
"Commit visited file to a worktree work-in-progress ref.
"Commit visited file to a worktree work-in-progress ref."
(interactive (list "save %s snapshot"))
(when (and (not magit--wip-inhibit-autosave)
buffer-file-name
(magit-inside-worktree-p t)
(magit-file-tracked-p buffer-file-name))
(magit-wip-commit-worktree
(magit-wip-get-ref)
(list buffer-file-name)
(format (or msg "autosave %s after save")
(magit-file-relative-name buffer-file-name)))))
Also see `magit-wip-after-save-mode' which calls this function
automatically whenever a buffer visiting a tracked file is saved."
(interactive (list "wip-save %s after save"))
(when-let (((not magit--wip-inhibit-autosave))
(ref (magit-wip-get-ref)))
(magit-with-toplevel
(let ((file (file-relative-name buffer-file-name)))
(magit-wip-commit-worktree
ref (list file)
(format (or msg "autosave %s after save") file))))))
(defun magit-run-after-apply-functions (files task)
(run-hook-with-args 'magit-after-apply-functions
(ensure-list files)
(format " after %s" task)))
;;;###autoload
(define-minor-mode magit-wip-after-apply-mode
"Commit to work-in-progress refs.
After applying a change using any \"apply variant\"
command (apply, stage, unstage, discard, and reverse) commit the
affected files to the current wip refs. For each branch there
may be two wip refs; one contains snapshots of the files as found
in the worktree and the other contains snapshots of the entries
in the index."
:package-version '(magit . "2.1.0")
:group 'magit-wip
:global t)
(defun magit-wip-commit-after-apply (&optional files msg)
(when magit-wip-after-apply-mode
(magit-wip-commit files msg)))
;;;###autoload
(define-minor-mode magit-wip-before-change-mode
"Commit to work-in-progress refs before certain destructive changes.
Before invoking a revert command or an \"apply variant\"
command (apply, stage, unstage, discard, and reverse) commit the
affected tracked files to the current wip refs. For each branch
there may be two wip refs; one contains snapshots of the files
as found in the worktree and the other contains snapshots of the
entries in the index.
Only changes to files which could potentially be affected by the
command which is about to be called are committed."
:package-version '(magit . "2.1.0")
:group 'magit-wip
:global t)
(defun magit-wip-commit-before-change (&optional files msg)
(when magit-wip-before-change-mode
(magit-with-toplevel
(magit-wip-commit files msg))))
(define-minor-mode magit-wip-initial-backup-mode
"Before saving a buffer for the first time, commit to a wip ref."
:package-version '(magit . "2.90.0")
:group 'magit-wip
:global t
(if magit-wip-initial-backup-mode
(add-hook 'before-save-hook #'magit-wip-commit-initial-backup)
(remove-hook 'before-save-hook #'magit-wip-commit-initial-backup)))
(defun magit--any-wip-mode-enabled-p ()
"Return non-nil if any global wip mode is enabled."
(or magit-wip-mode
magit-wip-after-save-mode
magit-wip-after-apply-mode
magit-wip-before-change-mode
magit-wip-initial-backup-mode))
(defun magit-run-before-change-functions (files task)
(run-hook-with-args 'magit-before-change-functions
(ensure-list files)
(format " before %s" task)))
(defvar-local magit-wip-buffer-backed-up nil)
(put 'magit-wip-buffer-backed-up 'permanent-local t)
;;;###autoload
(defun magit-wip-commit-initial-backup ()
"Before saving, commit current file to a worktree wip ref.
The user has to add this function to `before-save-hook'.
Commit the current state of the visited file before saving the
current buffer to that file. This backs up the same version of
the file as `backup-buffer' would, but stores the backup in the
worktree wip ref, which is also used by the various Magit Wip
modes, instead of in a backup file as `backup-buffer' would.
This function ignores the variables that affect `backup-buffer'
and can be used along-side that function, which is recommended
because this function only backs up files that are tracked in
a Git repository."
(when (and (not magit-wip-buffer-backed-up)
buffer-file-name
(magit-inside-worktree-p t)
@@ -247,6 +138,10 @@ a Git repository."
(magit-wip-commit-buffer-file "autosave %s before save"))
(setq magit-wip-buffer-backed-up t)))
(defun magit-wip-commit-post-editmsg ()
(when (eq magit-wip-merge-branch 'immediately)
(magit-wip-commit)))
;;; Core
(defun magit-wip-commit (&optional files msg)
@@ -352,24 +247,11 @@ commit message."
(defun magit--wip-ref (namespace &optional ref)
(concat magit-wip-namespace namespace
(or (and ref (string-prefix-p "refs/" ref) ref)
(and-let* ((branch (and (not (equal ref "HEAD"))
(or ref (magit-get-current-branch)))))
(and-let ((_(not (equal ref "HEAD")))
(branch (or ref (magit-get-current-branch))))
(concat "refs/heads/" branch))
"HEAD")))
(defun magit-wip-maybe-add-commit-hook ()
(when (and magit-wip-merge-branch
(magit-wip-any-enabled-p))
(add-hook 'git-commit-post-finish-hook #'magit-wip-commit nil t)))
(defun magit-wip-any-enabled-p ()
(or magit-wip-mode
magit-wip-after-save-local-mode
magit-wip-after-save-mode
magit-wip-after-apply-mode
magit-wip-before-change-mode
magit-wip-initial-backup-mode))
;;; Log
(defun magit-wip-log-index (args files)
@@ -420,7 +302,7 @@ many \"branches\" of each wip ref are shown."
args files))
(defun magit-wip-log-get-tips (wipref count)
(and-let* ((reflog (magit-git-lines "reflog" wipref)))
(and-let ((reflog (magit-git-lines "reflog" wipref)))
(let (tips)
(while (and reflog (> count 1))
;; "start autosaving ..." is the current message, but it used
@@ -430,7 +312,7 @@ many \"branches\" of each wip ref are shown."
reflog :test #'string-match-p))
(when (and (cadr reflog)
(string-match "^[^ ]+ \\([^:]+\\)" (cadr reflog)))
(push (match-string 1 (cadr reflog)) tips))
(push (match-str 1 (cadr reflog)) tips))
(setq reflog (cddr reflog))
(cl-decf count))
(cons wipref (nreverse tips)))))
@@ -438,24 +320,35 @@ many \"branches\" of each wip ref are shown."
(defun magit-wip-purge ()
"Ask to delete all wip-refs that no longer have a corresponding ref."
(interactive)
(if-let ((wiprefs (thread-last
(cl-set-difference (magit-list-refs "refs/wip/")
(magit-list-refs)
:test (##equal (substring %1 15) %2))
(delete "refs/wip/index/HEAD")
(delete "refs/wip/wtree/HEAD"))))
(progn
(magit-confirm 'purge-dangling-wiprefs
"Delete wip-ref %s without corresponding ref"
"Delete %d wip-refs without corresponding ref"
nil wiprefs)
(message "Deleting wip-refs...")
(dolist (wipref wiprefs)
(magit-call-git "update-ref" "-d" wipref))
(message "Deleting wip-refs...done")
(magit-refresh))
(message "All wip-refs have a corresponding ref")))
(cond-let
([wiprefs (thread-last
(cl-set-difference (magit-list-refs "refs/wip/")
(magit-list-refs)
:test (##equal (substring %1 15) %2))
(delete "refs/wip/index/HEAD")
(delete "refs/wip/wtree/HEAD"))]
(magit-confirm 'purge-dangling-wiprefs
"Delete wip-ref %s without corresponding ref"
"Delete %d wip-refs without corresponding ref"
nil wiprefs)
(message "Deleting wip-refs...")
(dolist (wipref wiprefs)
(magit-call-git "update-ref" "-d" wipref))
(message "Deleting wip-refs...done")
(magit-refresh))
((message "All wip-refs have a corresponding ref"))))
;;; _
(provide 'magit-wip)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-wip.el ends here

View File

@@ -30,18 +30,102 @@
;;; Options
(defcustom magit-worktree-read-directory-name-function #'read-directory-name
"Function used to read a directory for worktree commands.
This is called with one argument, the prompt, and can be used
to, e.g., use a base directory other than `default-directory'.
Used by `magit-worktree-checkout' and `magit-worktree-branch'."
:package-version '(magit . "3.0.0")
(defcustom magit-read-worktree-directory-function
#'magit-read-worktree-directory-sibling
"Function used to read the directory to be used as a new worktree.
This is called with two arguments, the prompt and the branch to be
checked out. When not checking out a branch then use nil for the
second argument."
:package-version '(magit . "4.4.0")
:group 'magit-commands
:type 'function)
:type `(radio (function-item ,#'magit-read-worktree-directory)
(function-item ,#'magit-read-worktree-directory-nested)
(function-item ,#'magit-read-worktree-directory-sibling)
(function-item ,#'magit-read-worktree-directory-offsite)
function))
(defcustom magit-read-worktree-offsite-directory
(expand-file-name "wtrees/" (or (getenv "XDG_DATA_HOME") "~/.local/share"))
"Base directory used by `magit-read-worktree-directory-offsite'.
That function is suitable as `magit-read-worktree-directory-function',
but is not used by default."
:package-version '(magit . "4.4.0")
:group 'magit-commands
:type 'directory)
(defvar magit-worktree-read-directory-name-function nil
"Like `magit-read-worktree-directory-function' but takes only one argument.")
(make-obsolete-variable 'magit-worktree-read-directory-name-function
'magit-read-worktree-directory-function
"Magit 4.4.0")
;;; Functions
(defun magit-read-worktree-directory (prompt _branch)
"Call `read-directory-name' with PROMPT, but ignoring _BRANCH."
(read-directory-name prompt))
(defun magit-read-worktree-directory-nested (prompt branch)
"Call `read-directory-name' in current worktree.
For `read-directory-name's INITIAL argument use a string based on
BRANCH, replacing slashes with dashes. If BRANCH is nil, use nil
as INITIAL. Always forward PROMPT as-is."
(read-directory-name prompt nil nil nil
(and branch (string-replace "/" "-" branch))))
(defun magit-read-worktree-directory-sibling (prompt branch)
"Call `read-directory-name' in parent directory of current worktree.
For `read-directory-name's INITIAL argument use a string based on the
name of the current worktree and BRANCH. Use \"PREFIX_BRANCH\" where
PREFIX is the name of the current worktree, up to the first underscore,
and slashes in BRANCH are replaced with dashes. If BRANCH is nil use
just \"PREFIX_\". Always forward PROMPT as-is."
(let* ((path (directory-file-name default-directory))
(name (file-name-nondirectory path)))
(read-directory-name
prompt (file-name-directory path) nil nil
(concat (if (string-match "_" name)
(substring name 0 (match-beginning 0))
name)
"_"
(and branch (string-replace "/" "-" branch))))))
(defun magit-read-worktree-directory-offsite (prompt branch)
"Call `read-directory-name' in a directory shared by all repositories.
Option `magit-read-worktree-offsite-directory' specifies that shared
base directory.
For `read-directory-name's INITIAL argument use a string based on the
name of the current worktree and BRANCH. Use \"PREFIX_BRANCH\" where
PREFIX is the name of the current worktree, up to the first underscore,
and slashes in BRANCH are replaced with dashes. If BRANCH is nil use
just \"PREFIX_\". Always forward PROMPT as-is."
(mkdir magit-read-worktree-offsite-directory t)
(read-directory-name
prompt magit-read-worktree-offsite-directory nil nil
(let* ((name (file-name-nondirectory (directory-file-name default-directory)))
(name (if (string-match "_" name)
(substring name 0 (match-beginning 0))
name))
(name (concat name "_")))
(if branch
(concat name (string-replace "/" "-" branch))
(file-name-nondirectory
(make-temp-name
(expand-file-name name magit-read-worktree-offsite-directory)))))))
(defun magit--read-worktree-directory (rev branchp)
(let ((default-directory (magit-toplevel))
(prompt (format "Checkout %s in new worktree: " rev)))
(if magit-worktree-read-directory-name-function
(funcall magit-worktree-read-directory-name-function prompt)
(funcall magit-read-worktree-directory-function
prompt (and branchp rev)))))
;;; Commands
;;;###autoload (autoload 'magit-worktree "magit-worktree" nil t)
;;;###autoload(autoload 'magit-worktree "magit-worktree" nil t)
(transient-define-prefix magit-worktree ()
"Act on a worktree."
:man-page "git-worktree"
@@ -54,51 +138,56 @@ Used by `magit-worktree-checkout' and `magit-worktree-branch'."
("g" "Visit worktree" magit-worktree-status)]])
;;;###autoload
(defun magit-worktree-checkout (path branch)
"Checkout BRANCH in a new worktree at PATH."
(defun magit-worktree-checkout (directory commit)
"Checkout COMMIT in a new worktree in DIRECTORY.
COMMIT may, but does not have to be, a local branch.
Interactively, use `magit-read-worktree-directory-function'."
(interactive
(let ((branch (magit-read-branch-or-commit "Checkout")))
(list (funcall magit-worktree-read-directory-name-function
(format "Checkout %s in new worktree: " branch))
branch)))
(let ((commit (magit-read-branch-or-commit
"In new worktree; checkout" nil
(mapcar #'caddr (magit-list-worktrees)))))
(list (magit--read-worktree-directory commit (magit-local-branch-p commit))
commit)))
(when (zerop (magit-run-git "worktree" "add"
(magit--expand-worktree path) branch))
(magit-diff-visit-directory path)))
(magit--expand-worktree directory) commit))
(magit-diff-visit-directory directory)))
;;;###autoload
(defun magit-worktree-branch (path branch start-point)
"Create a new BRANCH and check it out in a new worktree at PATH."
(defun magit-worktree-branch (directory branch start-point)
"Create a new BRANCH and check it out in a new worktree at DIRECTORY.
Interactively, use `magit-read-worktree-directory-function'."
(interactive
`(,(funcall magit-worktree-read-directory-name-function
"Create worktree: ")
,@(magit-branch-read-args "Create and checkout branch")))
(pcase-let
((`(,branch ,start-point)
(magit-branch-read-args "In new worktree; checkout new branch")))
(list (magit--read-worktree-directory branch t)
branch start-point)))
(when (zerop (magit-run-git "worktree" "add" "-b" branch
(magit--expand-worktree path) start-point))
(magit-diff-visit-directory path)))
(magit--expand-worktree directory) start-point))
(magit-diff-visit-directory directory)))
;;;###autoload
(defun magit-worktree-move (worktree path)
"Move WORKTREE to PATH."
(defun magit-worktree-move (worktree directory)
"Move existing WORKTREE directory to DIRECTORY."
(interactive
(list (magit-completing-read "Move worktree"
(cdr (magit-list-worktrees))
nil t nil nil
(magit-section-value-if 'worktree))
(funcall magit-worktree-read-directory-name-function
"Move worktree to: ")))
(read-directory-name "Move worktree to: ")))
(if (file-directory-p (expand-file-name ".git" worktree))
(user-error "You may not move the main working tree")
(let ((preexisting-directory (file-directory-p path)))
(let ((preexisting-directory (file-directory-p directory)))
(when (and (zerop (magit-call-git "worktree" "move" worktree
(magit--expand-worktree path)))
(magit--expand-worktree directory)))
(not (file-exists-p default-directory))
(derived-mode-p 'magit-status-mode))
(kill-buffer)
(magit-diff-visit-directory
(if preexisting-directory
(concat (file-name-as-directory path)
(concat (file-name-as-directory directory)
(file-name-nondirectory worktree))
path)))
directory)))
(magit-refresh))))
(defun magit-worktree-delete (worktree)
@@ -106,7 +195,7 @@ Used by `magit-worktree-checkout' and `magit-worktree-branch'."
The primary worktree cannot be deleted."
(interactive
(list (magit-completing-read "Delete worktree"
(cdr (magit-list-worktrees))
(mapcar #'car (cdr (magit-list-worktrees)))
nil t nil nil
(magit-section-value-if 'worktree))))
(if (file-directory-p (expand-file-name ".git" worktree))
@@ -137,11 +226,12 @@ then show it in Dired instead."
"Show status for worktree"
(cl-delete (directory-file-name (magit-toplevel))
(magit-list-worktrees)
:test #'equal :key #'car)))))
:test #'equal :key #'car)
nil t))))
(magit-diff-visit-directory worktree))
(defun magit--expand-worktree (path)
(magit-convert-filename-for-git (expand-file-name path)))
(defun magit--expand-worktree (directory)
(magit-convert-filename-for-git (expand-file-name directory)))
;;; Sections
@@ -204,4 +294,15 @@ with padding for alignment."
;;; _
(provide 'magit-worktree)
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit-worktree.el ends here

View File

@@ -17,16 +17,17 @@
;; Homepage: https://github.com/magit/magit
;; Keywords: git tools vc
;; Package-Version: 20250711.1903
;; Package-Revision: d8b4690900a0
;; Package-Version: 20251125.101
;; Package-Revision: ced3d5afc33d
;; Package-Requires: (
;; (emacs "27.1")
;; (compat "30.1")
;; (llama "1.0.0")
;; (magit-section "4.3.8")
;; (seq "2.24")
;; (transient "0.9.3")
;; (with-editor "3.4.4"))
;; (emacs "28.1")
;; (compat "30.1")
;; (cond-let "0.1")
;; (llama "1.0")
;; (magit-section "4.4")
;; (seq "2.24")
;; (transient "0.10")
;; (with-editor "3.4"))
;; SPDX-License-Identifier: GPL-3.0-or-later
@@ -69,15 +70,10 @@
(require 'magit-repos)
(require 'git-commit)
(require 'epa) ;used in magit-read-gpg-{secret,signing}-key
(require 'format-spec)
(require 'package nil t) ; used in `magit-version'
(require 'with-editor)
;; For `magit:--gpg-sign'
(declare-function epg-list-keys "epg" (context &optional name mode))
(declare-function epg-decode-dn "epg" (alist))
(defvar epa-protocol)
;;; Options
(defcustom magit-openpgp-default-signing-key nil
@@ -329,7 +325,7 @@ already been run."
;;; Dispatch Popup
;;;###autoload (autoload 'magit-dispatch "magit" nil t)
;;;###autoload(autoload 'magit-dispatch "magit" nil t)
(transient-define-prefix magit-dispatch ()
"Invoke a Magit command from a list of available commands."
:info-manual "(magit)Top"
@@ -420,7 +416,7 @@ This affects `magit-git-command', `magit-git-command-topdir',
(defvar magit-git-command-history nil)
;;;###autoload (autoload 'magit-run "magit" nil t)
;;;###autoload(autoload 'magit-run "magit" nil t)
(transient-define-prefix magit-run ()
"Run git or another command, or launch a graphical utility."
[["Run git subcommand"
@@ -524,7 +520,7 @@ is run in the top-level directory of the current working tree."
(defun magit-read-gpg-secret-key
(prompt &optional initial-input history predicate default)
(require 'epa)
(let* ((keys (mapcan
(let* ((keys (seq-keep
(lambda (cert)
(and (or (not predicate)
(funcall predicate cert))
@@ -532,17 +528,16 @@ is run in the top-level directory of the current working tree."
(fpr (epg-sub-key-fingerprint key))
(id (epg-sub-key-id key))
(author
(and-let* ((id-obj
(car (epg-key-user-id-list cert))))
(and-let ((id-obj
(car (epg-key-user-id-list cert))))
(let ((id-str (epg-user-id-string id-obj)))
(if (stringp id-str)
id-str
(epg-decode-dn id-obj))))))
(list
(propertize fpr 'display
(concat (substring fpr 0 (- (length id)))
(propertize id 'face 'highlight)
" " author))))))
(propertize fpr 'display
(concat (substring fpr 0 (- (length id)))
(propertize id 'face 'highlight)
" " author)))))
(epg-list-keys (epg-make-context epa-protocol) nil t)))
(choice (or (and (not current-prefix-arg)
(or (and (length= keys 1) (car keys))
@@ -638,7 +633,9 @@ the output in the kill ring.
(push t debug)
(load-file static)
magit-version))
(when (featurep 'package)
(when (and (featurep 'package)
(boundp 'package-alist)
(fboundp 'package-version-join))
(push 'elpa debug)
(ignore-errors
(when-let ((version (cadr (assq 'magit package-alist))))
@@ -652,7 +649,7 @@ the output in the kill ring.
(let ((dirname (file-name-nondirectory
(directory-file-name topdir))))
(when (string-match "\\`magit-\\([0-9].*\\)" dirname)
(setq magit-version (match-string 1 dirname)))))
(setq magit-version (match-str 1 dirname)))))
;; If all else fails, just report the commit hash. It's
;; better than nothing and we cannot do better in the case
;; of e.g., a shallow clone.
@@ -667,44 +664,44 @@ the output in the kill ring.
(magit-git-string "rev-parse" "HEAD"))))))))
(if (stringp magit-version)
(when print-dest
(let ((str (format
"Magit %s%s, Transient %s,%s Git %s, Emacs %s, %s"
(or magit-version "(unknown)")
(or (and (ignore-errors
(let* ((alt (or (and (ignore-errors
(magit--version>= magit-version "2008"))
(ignore-errors
(require 'lisp-mnt)
(and (fboundp 'lm-header)
(format
" [>= %s]"
(with-temp-buffer
(insert-file-contents
(locate-library "magit.el" t))
(lm-header "Package-Version"))))))
"")
(or (ignore-errors
(require 'lisp-mnt)
(and (fboundp 'lm-header)
(with-temp-buffer
(insert-file-contents
(locate-library "transient.el" t))
(lm-header "Package-Version"))))
"(unknown)")
(let ((lib (locate-library "forge.el" t)))
(or (and lib
(format
" Forge %s,"
(or (ignore-errors
(require 'lisp-mnt)
(with-temp-buffer
(insert-file-contents lib)
(and (fboundp 'lm-header)
(lm-header "Package-Version"))))
"(unknown)")))
""))
(magit--safe-git-version)
emacs-version
system-type)))
(with-temp-buffer
(insert-file-contents
(locate-library "magit.el" t))
(lm-header "Package-Version")))))))
(str (format
"Magit %s%s, Transient %s,%s Git %s, Emacs %s, %s"
(or magit-version "(unknown)")
(if (and alt (not (equal alt magit-version)))
(format " [>= %s]" alt)
"")
(or (ignore-errors
(require 'lisp-mnt)
(and (fboundp 'lm-header)
(with-temp-buffer
(insert-file-contents
(locate-library "transient.el" t))
(lm-header "Package-Version"))))
"(unknown)")
(let ((lib (locate-library "forge.el" t)))
(or (and lib
(format
" Forge %s,"
(or (ignore-errors
(require 'lisp-mnt)
(with-temp-buffer
(insert-file-contents lib)
(and (fboundp 'lm-header)
(lm-header "Package-Version"))))
"(unknown)")))
""))
(magit--safe-git-version)
emacs-version
system-type)))
(when interactive
(kill-new str))
(princ str print-dest)))
@@ -776,7 +773,11 @@ For X11 something like ~/.xinitrc should work.\n"
(require 'magit-stash)
(require 'magit-blame)
(require 'magit-submodule)
(unless (load "magit-autoloads" t t)
;; The `provide' form may be missing so we have to
;; try harder to ensure this is loaded exactly once.
(unless (or (featurep 'magit-autoloads)
(autoloadp (symbol-function 'magit-patch))
(load "magit-autoloads" t))
(require 'magit-patch)
(require 'magit-subtree)
(require 'magit-ediff)
@@ -797,4 +798,15 @@ For X11 something like ~/.xinitrc should work.\n"
(add-hook 'after-init-hook #'magit-startup-asserts t)
(add-hook 'after-init-hook #'magit-version t)))
;; Local Variables:
;; read-symbol-shorthands: (
;; ("and$" . "cond-let--and$")
;; ("and>" . "cond-let--and>")
;; ("and-let" . "cond-let--and-let")
;; ("if-let" . "cond-let--if-let")
;; ("when-let" . "cond-let--when-let")
;; ("while-let" . "cond-let--while-let")
;; ("match-string" . "match-string")
;; ("match-str" . "match-string-no-properties"))
;; End:
;;; magit.el ends here

File diff suppressed because it is too large Load Diff