update packages
This commit is contained in:
15
lisp/magit/.dir-locals.el
Normal file
15
lisp/magit/.dir-locals.el
Normal file
@@ -0,0 +1,15 @@
|
||||
((nil
|
||||
(indent-tabs-mode . nil))
|
||||
(makefile-mode
|
||||
(indent-tabs-mode . t)
|
||||
(outline-regexp . "#\\(#+\\)")
|
||||
(mode . outline-minor))
|
||||
(emacs-lisp-mode
|
||||
(checkdoc-allow-quoting-nil-and-t . t))
|
||||
(git-commit-mode
|
||||
(git-commit-major-mode . git-commit-elisp-text-mode))
|
||||
(".github/PULL_REQUEST_TEMPLATE"
|
||||
(nil (truncate-lines . nil)))
|
||||
("CHANGELOG"
|
||||
(nil (fill-column . 70)
|
||||
(mode . display-fill-column-indicator))))
|
||||
@@ -331,6 +331,7 @@ All Contributors
|
||||
- Rémi Vanicat
|
||||
- René Stadler
|
||||
- Richard Kim
|
||||
- Richard Sent
|
||||
- Robert Boone
|
||||
- Robert Irelan
|
||||
- Robin Green
|
||||
@@ -408,6 +409,7 @@ All Contributors
|
||||
- Win Treese
|
||||
- Wojciech Siewierski
|
||||
- Wouter Bolsterlee
|
||||
- X4lldux
|
||||
- Xavier Noria
|
||||
- Xu Chunyang
|
||||
- Yann Herklotz
|
||||
|
||||
1224
lisp/magit/git-commit.el
Normal file
1224
lisp/magit/git-commit.el
Normal file
File diff suppressed because it is too large
Load Diff
@@ -44,8 +44,8 @@
|
||||
;; M-p Move the commit at point up.
|
||||
;; M-n Move the commit at point down.
|
||||
;;
|
||||
;; k Drop the commit at point.
|
||||
;; c Don't drop the commit at point.
|
||||
;; d Drop the commit at point.
|
||||
;; c Keep the commit at point.
|
||||
;; r Change the message of the commit at point.
|
||||
;; e Edit the commit at point.
|
||||
;; s Squash the commit at point, into the one above.
|
||||
@@ -53,6 +53,7 @@
|
||||
;; b Break for editing at this point in the sequence.
|
||||
;; x Add a script to be run with the commit at point
|
||||
;; being checked out.
|
||||
;; k Un-/comment current line.
|
||||
;; z Add noop action at point.
|
||||
;;
|
||||
;; SPC Show the commit at point in another buffer.
|
||||
@@ -152,6 +153,7 @@
|
||||
"M-p" #'git-rebase-move-line-up
|
||||
"M-n" #'git-rebase-move-line-down
|
||||
"c" #'git-rebase-pick
|
||||
"d" #'git-rebase-drop
|
||||
"k" #'git-rebase-kill-line
|
||||
"C-k" #'git-rebase-kill-line
|
||||
"b" #'git-rebase-break
|
||||
@@ -160,11 +162,14 @@
|
||||
"M M" #'git-rebase-merge
|
||||
"M t" #'git-rebase-merge-toggle-editmsg
|
||||
"m" #'git-rebase-edit
|
||||
"s" #'git-rebase-squash
|
||||
"S" #'git-rebase-squish
|
||||
"f" #'git-rebase-fixup
|
||||
"F" #'git-rebase-alter
|
||||
"A" #'git-rebase-alter
|
||||
"q" #'undefined
|
||||
"r" #'git-rebase-reword
|
||||
"w" #'git-rebase-reword
|
||||
"s" #'git-rebase-squash
|
||||
"t" #'git-rebase-reset
|
||||
"u" #'git-rebase-update-ref
|
||||
"x" #'git-rebase-exec
|
||||
@@ -176,6 +181,7 @@
|
||||
"M-<up>" #'git-rebase-move-line-up
|
||||
"M-<down>" #'git-rebase-move-line-down
|
||||
"<remap> <undo>" #'git-rebase-undo)
|
||||
(put 'git-rebase-alter :advertised-binding (kbd "F"))
|
||||
(put 'git-rebase-reword :advertised-binding (kbd "r"))
|
||||
(put 'git-rebase-move-line-up :advertised-binding (kbd "M-p"))
|
||||
(put 'git-rebase-kill-line :advertised-binding (kbd "k"))
|
||||
@@ -184,6 +190,7 @@
|
||||
"Git-Rebase mode menu."
|
||||
'("Rebase"
|
||||
["Pick" git-rebase-pick t]
|
||||
["Drop" git-rebase-drop t]
|
||||
["Reword" git-rebase-reword t]
|
||||
["Edit" git-rebase-edit t]
|
||||
["Squash" git-rebase-squash t]
|
||||
@@ -208,10 +215,22 @@
|
||||
(git-rebase-show-commit
|
||||
. "show the commit at point in another buffer and select its window")
|
||||
(undo . "undo last change")
|
||||
(git-rebase-kill-line . "drop the commit at point")
|
||||
(git-rebase-drop . "drop the commit at point")
|
||||
(git-rebase-kill-line . "un-/comment current line")
|
||||
(git-rebase-insert . "insert a line for an arbitrary commit")
|
||||
(git-rebase-noop . "add noop action at point")))
|
||||
|
||||
(defvar git-rebase-fixup-descriptions
|
||||
'((git-rebase-squish
|
||||
. "fixup -c <commit> = use commit, but meld into previous commit,\n#\
|
||||
dropping previous commit's message, and open the editor")
|
||||
(git-rebase-fixup
|
||||
. "fixup <commit> = use commit, but meld into previous commit,\n#\
|
||||
dropping <commit>'s message")
|
||||
(git-rebase-alter
|
||||
. "fixup -C <commit> = use commit, but meld into previous commit,\n#\
|
||||
dropping previous commit's message")))
|
||||
|
||||
;;; Commands
|
||||
|
||||
(defun git-rebase-pick ()
|
||||
@@ -220,6 +239,12 @@ If the region is active, act on all lines touched by the region."
|
||||
(interactive)
|
||||
(git-rebase-set-action "pick"))
|
||||
|
||||
(defun git-rebase-drop ()
|
||||
"Drop commit on current line.
|
||||
If the region is active, act on all lines touched by the region."
|
||||
(interactive)
|
||||
(git-rebase-set-action "drop"))
|
||||
|
||||
(defun git-rebase-reword ()
|
||||
"Edit message of commit on current line.
|
||||
If the region is active, act on all lines touched by the region."
|
||||
@@ -233,21 +258,38 @@ If the region is active, act on all lines touched by the region."
|
||||
(git-rebase-set-action "edit"))
|
||||
|
||||
(defun git-rebase-squash ()
|
||||
"Meld commit on current line into previous commit, edit message.
|
||||
"Fold commit on current line into previous commit, edit combined message.
|
||||
If the region is active, act on all lines touched by the region."
|
||||
(interactive)
|
||||
(git-rebase-set-action "squash"))
|
||||
|
||||
(defun git-rebase-squish ()
|
||||
"Fold current into previous commit, discard previous message and edit current.
|
||||
This is like `git-rebase-squash', except that the other message is kept.
|
||||
The action indicatore shown in the list commits is \"fixup -c\". If the
|
||||
region is active, act on all lines touched by the region."
|
||||
(interactive)
|
||||
(git-rebase-set-action "fixup -c"))
|
||||
|
||||
(defun git-rebase-fixup ()
|
||||
"Meld commit on current line into previous commit, discard its message.
|
||||
"Fold commit on current line into previous commit, discard current message.
|
||||
If the region is active, act on all lines touched by the region."
|
||||
(interactive)
|
||||
(git-rebase-set-action "fixup"))
|
||||
|
||||
(defun git-rebase-alter ()
|
||||
"Meld current into previous commit, discard previous message and use current.
|
||||
This is like `git-rebase-fixup', except that the other message is kept.
|
||||
The action indicatore shown in the list commits is \"fixup -C\". If the
|
||||
region is active, act on all lines touched by the region."
|
||||
(interactive)
|
||||
(git-rebase-set-action "fixup -C"))
|
||||
|
||||
(defvar-local git-rebase-comment-re nil)
|
||||
|
||||
(defvar git-rebase-short-options
|
||||
'((?b . "break")
|
||||
(?d . "drop")
|
||||
(?e . "edit")
|
||||
(?f . "fixup")
|
||||
(?l . "label")
|
||||
@@ -275,15 +317,19 @@ If the region is active, act on all lines touched by the region."
|
||||
(action-options :initarg :action-options :initform nil)
|
||||
(target :initarg :target :initform nil)
|
||||
(trailer :initarg :trailer :initform nil)
|
||||
(comment-p :initarg :comment-p :initform nil)))
|
||||
(comment-p :initarg :comment-p :initform nil)
|
||||
(abbrev)))
|
||||
|
||||
(defvar git-rebase-line-regexps
|
||||
`((commit . ,(concat
|
||||
(regexp-opt '("e" "edit"
|
||||
"f" "fixup"
|
||||
"p" "pick"
|
||||
"r" "reword"
|
||||
"s" "squash")
|
||||
(regexp-opt '("d" "drop"
|
||||
"e" "edit"
|
||||
"f" "fixup"
|
||||
"f -C" "fixup -C"
|
||||
"f -c" "fixup -c"
|
||||
"p" "pick"
|
||||
"r" "reword"
|
||||
"s" "squash")
|
||||
"\\(?1:")
|
||||
" \\(?3:[^ \n]+\\) ?\\(?4:.*\\)"))
|
||||
(exec . "\\(?1:x\\|exec\\) \\(?3:.*\\)")
|
||||
@@ -300,18 +346,21 @@ If the region is active, act on all lines touched by the region."
|
||||
" ?\\(?4:.*\\)"))))
|
||||
|
||||
;;;###autoload
|
||||
(defun git-rebase-current-line ()
|
||||
(defun git-rebase-current-line (&optional batch)
|
||||
"Parse current line into a `git-rebase-action' instance.
|
||||
If the current line isn't recognized as a rebase line, an
|
||||
instance with all nil values is returned."
|
||||
instance with all nil values is returned, unless optional
|
||||
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 (concat "^\\(?5:" (regexp-quote comment-start)
|
||||
"\\)? *"))
|
||||
(type (seq-some (lambda (arg)
|
||||
(if-let ((re-start (if batch
|
||||
"^"
|
||||
(format "^\\(?5:%s\\)? *"
|
||||
(regexp-quote comment-start))))
|
||||
(type (seq-some (pcase-lambda (`(,type . ,re))
|
||||
(let ((case-fold-search nil))
|
||||
(and (looking-at (concat re-start (cdr arg)))
|
||||
(car arg))))
|
||||
(and (looking-at (concat re-start re)) type)))
|
||||
git-rebase-line-regexps)))
|
||||
(git-rebase-action
|
||||
:action-type type
|
||||
@@ -322,15 +371,16 @@ instance with all nil values is returned."
|
||||
:target (match-string-no-properties 3)
|
||||
:trailer (match-string-no-properties 4)
|
||||
:comment-p (and (match-string 5) t))
|
||||
;; Use default empty class rather than nil to ease handling.
|
||||
(git-rebase-action))))
|
||||
(and (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.
|
||||
If the region is active, operate on all lines that it touches.
|
||||
Otherwise, operate on the current line. As a special case, an
|
||||
ACTION of nil comments the rebase line, regardless of its action
|
||||
type."
|
||||
ACTION of nil comments or uncomments the rebase line, regardless
|
||||
of its action type."
|
||||
(pcase (git-rebase-region-bounds t)
|
||||
(`(,beg ,end)
|
||||
(let ((end-marker (copy-marker end))
|
||||
@@ -345,9 +395,11 @@ type."
|
||||
(let ((inhibit-read-only t))
|
||||
(magit-delete-line)
|
||||
(insert (concat action " " target " " trailer "\n"))))
|
||||
((and action-type (not (or action comment-p)))
|
||||
((and (not action) action-type)
|
||||
(let ((inhibit-read-only t))
|
||||
(insert comment-start " "))
|
||||
(if comment-p
|
||||
(delete-region beg (+ beg 2))
|
||||
(insert comment-start " ")))
|
||||
(forward-line))
|
||||
(t
|
||||
;; In the case of --rebase-merges, commit lines may have
|
||||
@@ -441,8 +493,8 @@ current line."
|
||||
(bounds (git-rebase-region-bounds)))
|
||||
(mapc #'delete-overlay magit-section-highlight-overlays)
|
||||
(when bounds
|
||||
(magit-section-make-overlay (car bounds) (cadr bounds)
|
||||
'magit-section-heading-selection))
|
||||
(magit-section-highlight-range (car bounds) (cadr bounds)
|
||||
'magit-section-heading-selection))
|
||||
(if (and bounds (not magit-section-keep-region-overlay))
|
||||
(funcall (default-value 'redisplay-unhighlight-region-function) rol)
|
||||
(funcall (default-value 'redisplay-highlight-region-function)
|
||||
@@ -453,7 +505,8 @@ current line."
|
||||
(funcall (default-value 'redisplay-unhighlight-region-function) rol))
|
||||
|
||||
(defun git-rebase-kill-line ()
|
||||
"Kill the current action line.
|
||||
"Comment the current action line.
|
||||
If the action line is already commented, then uncomment it.
|
||||
If the region is active, act on all lines touched by the region."
|
||||
(interactive)
|
||||
(git-rebase-set-action nil))
|
||||
@@ -588,8 +641,7 @@ commit. For an upper-case -C, the message will be used as is."
|
||||
(insert
|
||||
(format "merge %s %s %s\n"
|
||||
(replace-regexp-in-string
|
||||
"-[cC]" (lambda (c)
|
||||
(if (equal c "-c") "-C" "-c"))
|
||||
"-[cC]" (##if (equal % "-c") "-C" "-c")
|
||||
action-options t t)
|
||||
target
|
||||
trailer)))
|
||||
@@ -770,6 +822,8 @@ running \"man git-rebase\" at the command line) for details."
|
||||
("^\\(m\\(?:erge\\)?\\) \\([^ \n]+\\)"
|
||||
(1 'git-rebase-action)
|
||||
(2 'git-rebase-label))
|
||||
("^drop \\(.+\\)"
|
||||
1 'git-rebase-killed-action t)
|
||||
(,(concat git-rebase-comment-re " *"
|
||||
(cdr (assq 'commit git-rebase-line-regexps)))
|
||||
0 'git-rebase-killed-action t)
|
||||
@@ -799,24 +853,23 @@ except for the \"pick\" command."
|
||||
(concat git-rebase-comment-re "\\s-+p, pick")
|
||||
nil t))
|
||||
(goto-char (line-beginning-position))
|
||||
(pcase-dolist (`(,cmd . ,desc) git-rebase-command-descriptions)
|
||||
(insert (format (propertize "%s %s %s\n"
|
||||
'font-lock-face 'font-lock-comment-face)
|
||||
comment-start
|
||||
(string-pad
|
||||
(substitute-command-keys (format "\\[%s]" cmd)) 8)
|
||||
desc)))
|
||||
(while (re-search-forward
|
||||
(concat git-rebase-comment-re "\\(?:"
|
||||
"\\( \\.? *\\)\\|"
|
||||
"\\( +\\)\\([^\n,],\\) \\([^\n ]+\\) \\)")
|
||||
nil t)
|
||||
(if (match-string 1)
|
||||
(replace-match (make-string 10 ?\s) t t nil 1)
|
||||
(let ((cmd (intern (concat "git-rebase-" (match-string 4)))))
|
||||
(if (not (fboundp cmd))
|
||||
(delete-region (line-beginning-position)
|
||||
(1+ (line-end-position)))
|
||||
(git-rebase--insert-descriptions git-rebase-command-descriptions)
|
||||
(let ((cmd nil)
|
||||
(line (concat git-rebase-comment-re "\\(?:\\( \\.? *\\)\\|"
|
||||
"\\( +\\)\\([^\n,],\\) \\([^\n ]+\\) \\)")))
|
||||
(while (re-search-forward line nil t)
|
||||
(if (match-string 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))))
|
||||
(cond
|
||||
((not (fboundp cmd))
|
||||
(delete-line))
|
||||
((eq cmd 'git-rebase-fixup)
|
||||
(delete-line)
|
||||
(git-rebase--insert-descriptions git-rebase-fixup-descriptions))
|
||||
(t
|
||||
(add-text-properties (line-beginning-position)
|
||||
(1+ (line-end-position))
|
||||
'(font-lock-face font-lock-comment-face))
|
||||
@@ -826,7 +879,16 @@ except for the \"pick\" command."
|
||||
(save-match-data
|
||||
(substitute-command-keys (format "\\[%s]" cmd)))
|
||||
8)
|
||||
t t nil 3)))))))))
|
||||
t t nil 3))))))))))
|
||||
|
||||
(defun git-rebase--insert-descriptions (alist)
|
||||
(pcase-dolist (`(,cmd . ,desc) alist)
|
||||
(insert (format (propertize "%s %s %s\n"
|
||||
'font-lock-face 'font-lock-comment-face)
|
||||
comment-start
|
||||
(string-pad
|
||||
(substitute-command-keys (format "\\[%s]" cmd)) 8)
|
||||
(replace-regexp-in-string "#" comment-start desc)))))
|
||||
|
||||
(add-hook 'git-rebase-mode-hook #'git-rebase-mode-show-keybindings t)
|
||||
|
||||
|
||||
@@ -137,11 +137,9 @@ so causes the change to be applied to the index as well."
|
||||
(defun magit-apply-diffs (sections &rest args)
|
||||
(setq sections (magit-apply--get-diffs sections))
|
||||
(magit-apply-patch sections args
|
||||
(mapconcat
|
||||
(lambda (s)
|
||||
(concat (magit-diff-file-header s)
|
||||
(magit-apply--section-content s)))
|
||||
sections "")))
|
||||
(mapconcat (##concat (magit-diff-file-header %)
|
||||
(magit-apply--section-content %))
|
||||
sections "")))
|
||||
|
||||
(defun magit-apply-diff (section &rest args)
|
||||
(setq section (car (magit-apply--get-diffs (list section))))
|
||||
@@ -222,6 +220,7 @@ adjusted as \"@@ -10,6 +10,7 @@\" and \"@@ -18,6 +19,7 @@\"."
|
||||
(command (if (and command (string-match "^magit-\\([^-]+\\)" command))
|
||||
(match-string 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"))
|
||||
@@ -229,10 +228,11 @@ adjusted as \"@@ -10,6 +10,7 @@\" and \"@@ -18,6 +19,7 @@\"."
|
||||
(magit-wip-commit-before-change files (concat " before " command)))
|
||||
(with-temp-buffer
|
||||
(insert patch)
|
||||
(magit-run-git-with-input
|
||||
"apply" args "-p0"
|
||||
(and ignore-context "-C0")
|
||||
"--ignore-space-change" "-"))
|
||||
(let ((magit-inhibit-refresh t))
|
||||
(magit-run-git-with-input
|
||||
"apply" args "-p0"
|
||||
(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)))
|
||||
@@ -243,9 +243,10 @@ adjusted as \"@@ -10,6 +10,7 @@\" and \"@@ -18,6 +19,7 @@\"."
|
||||
(let ((section (magit-current-section)))
|
||||
(pcase (oref section type)
|
||||
((or 'hunk 'file 'module) section)
|
||||
((or 'staged 'unstaged 'untracked
|
||||
((or 'staged 'unstaged
|
||||
'stashed-index 'stashed-worktree 'stashed-untracked)
|
||||
(oref section children))
|
||||
('untracked t)
|
||||
(_ (user-error "Cannot apply this, it's not a change"))))))
|
||||
|
||||
(defun magit-apply--get-diffs (sections)
|
||||
@@ -273,8 +274,7 @@ return nil, possibly causing whitespace changes to be applied."
|
||||
"--ignore-all-space"
|
||||
"--ignore-blank-lines")))
|
||||
magit-buffer-diff-args)
|
||||
(not (cl-find-if (lambda (section)
|
||||
(oref section binary))
|
||||
(not (cl-find-if (##oref % binary)
|
||||
(ensure-list selection)))))
|
||||
|
||||
;;;; Stage
|
||||
@@ -303,23 +303,10 @@ at point, stage the file but not its content."
|
||||
(`(staged ,_ ,_) (user-error "Already staged"))
|
||||
(`(committed ,_ ,_) (user-error "Cannot stage committed changes"))
|
||||
(`(undefined ,_ ,_) (user-error "Cannot stage this change")))
|
||||
(call-interactively #'magit-stage-file)))
|
||||
(call-interactively #'magit-stage-files)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-stage-buffer-file ()
|
||||
"Stage all changes to the file being visited in the current buffer."
|
||||
(interactive)
|
||||
(unless buffer-file-name
|
||||
(user-error "Not visiting a file"))
|
||||
(magit-with-toplevel
|
||||
(magit-stage-1 (and (magit-file-ignored-p buffer-file-name)
|
||||
(if (y-or-n-p "Visited file is ignored; stage anyway?")
|
||||
"--force"
|
||||
(user-error "Abort")))
|
||||
(list (magit-file-relative-name)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-stage-file (files &optional force)
|
||||
(defun magit-stage-files (files &optional force)
|
||||
"Read one or more files and stage all changes in those files.
|
||||
With prefix argument FORCE, offer ignored files for completion."
|
||||
(interactive
|
||||
@@ -335,10 +322,7 @@ With prefix argument FORCE, offer ignored files for completion."
|
||||
choices nil t nil nil default)
|
||||
current-prefix-arg)))
|
||||
(magit-with-toplevel
|
||||
;; For backward compatibility, and because of
|
||||
;; the function's name, don't require a list.
|
||||
(magit-stage-1 (and force "--force")
|
||||
(ensure-list files))))
|
||||
(magit-stage-1 (and force "--force") files)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-stage-modified (&optional all)
|
||||
@@ -408,9 +392,9 @@ ignored) files."
|
||||
|
||||
(defvar magit-post-stage-hook-commands
|
||||
(list #'magit-stage
|
||||
#'magit-stage-buffer-file
|
||||
#'magit-stage-file
|
||||
#'magit-stage-modified))
|
||||
#'magit-stage-files
|
||||
#'magit-stage-modified
|
||||
'magit-file-stage))
|
||||
|
||||
(defun magit-run-post-stage-hook ()
|
||||
(when (memq this-command magit-post-stage-hook-commands)
|
||||
@@ -445,16 +429,7 @@ ignored) files."
|
||||
(`(undefined ,_ ,_) (user-error "Cannot unstage this change")))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-unstage-buffer-file ()
|
||||
"Unstage all changes to the file being visited in the current buffer."
|
||||
(interactive)
|
||||
(unless buffer-file-name
|
||||
(user-error "Not visiting a file"))
|
||||
(magit-with-toplevel
|
||||
(magit-unstage-1 (list (magit-file-relative-name)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-unstage-file (files)
|
||||
(defun magit-unstage-files (files)
|
||||
"Read one or more files and unstage all changes to those files."
|
||||
(interactive
|
||||
(let* ((choices (magit-staged-files))
|
||||
@@ -464,9 +439,7 @@ ignored) files."
|
||||
(list (magit-completing-read-multiple "Unstage file,s: " choices
|
||||
nil t nil nil default))))
|
||||
(magit-with-toplevel
|
||||
;; For backward compatibility, and because of
|
||||
;; the function's name, don't require a list.
|
||||
(magit-unstage-1 (ensure-list files))))
|
||||
(magit-unstage-1 files)))
|
||||
|
||||
(defun magit-unstage-1 (files)
|
||||
(magit-wip-commit-before-change files " before unstage")
|
||||
@@ -496,9 +469,9 @@ ignored) files."
|
||||
|
||||
(defvar magit-post-unstage-hook-commands
|
||||
(list #'magit-unstage
|
||||
#'magit-unstage-buffer-file
|
||||
#'magit-unstage-file
|
||||
#'magit-unstage-all))
|
||||
#'magit-unstage-files
|
||||
#'magit-unstage-all
|
||||
'magit-file-unstage))
|
||||
|
||||
(defun magit-run-post-unstage-hook ()
|
||||
(when (memq this-command magit-post-unstage-hook-commands)
|
||||
@@ -515,14 +488,18 @@ of a side, then keep that side without prompting."
|
||||
(interactive)
|
||||
(when-let ((s (magit-apply--get-selection)))
|
||||
(pcase (list (magit-diff-type) (magit-diff-scope))
|
||||
(`(committed ,_) (user-error "Cannot discard committed changes"))
|
||||
(`(undefined ,_) (user-error "Cannot discard this change"))
|
||||
(`(,_ region) (magit-discard-region s))
|
||||
(`(,_ hunk) (magit-discard-hunk s))
|
||||
(`(,_ hunks) (magit-discard-hunks s))
|
||||
(`(,_ file) (magit-discard-file s))
|
||||
(`(,_ files) (magit-discard-files s))
|
||||
(`(,_ list) (magit-discard-files s)))))
|
||||
(`(committed ,_) (user-error "Cannot discard committed changes"))
|
||||
(`(undefined ,_) (user-error "Cannot discard this change"))
|
||||
(`(untracked list) (magit-discard-files--delete
|
||||
(magit-with-toplevel
|
||||
(magit-untracked-files nil nil "--directory"))
|
||||
nil))
|
||||
(`(,_ region) (magit-discard-region s))
|
||||
(`(,_ hunk) (magit-discard-hunk s))
|
||||
(`(,_ hunks) (magit-discard-hunks s))
|
||||
(`(,_ file) (magit-discard-file s))
|
||||
(`(,_ files) (magit-discard-files s))
|
||||
(`(,_ list) (magit-discard-files s)))))
|
||||
|
||||
(defun magit-discard-region (section)
|
||||
(magit-confirm 'discard "Discard region")
|
||||
@@ -623,9 +600,7 @@ of a side, then keep that side without prompting."
|
||||
(magit-read-char-case
|
||||
(format "For these %d files\n%s\ncheckout:\n"
|
||||
(length files)
|
||||
(mapconcat (lambda (file)
|
||||
(concat " " file))
|
||||
files "\n"))
|
||||
(mapconcat (##concat " " %) files "\n"))
|
||||
t
|
||||
(?o "[o]ur stage" "--ours")
|
||||
(?t "[t]heir stage" "--theirs")
|
||||
|
||||
@@ -69,21 +69,17 @@
|
||||
(defcustom magit-completing-read-function #'magit-builtin-completing-read
|
||||
"Function to be called when requesting input from the user.
|
||||
|
||||
If you have enabled `ivy-mode' or `helm-mode', then you don't
|
||||
have to customize this option; `magit-builtin-completing-read'
|
||||
will work just fine. However, if you use Ido completion, then
|
||||
you do have to use `magit-ido-completing-read', because Ido is
|
||||
less well behaved than the former, more modern alternatives.
|
||||
The default, `magit-builtin-completing-read', support third-party
|
||||
completion frameworks, including `vertico-mode', `ivy-mode' and
|
||||
`helm-mode'.
|
||||
|
||||
If you would like to use Ivy or Helm completion with Magit but
|
||||
not enable the respective modes globally, then customize this
|
||||
option to use `ivy-completing-read' or
|
||||
`helm--completing-read-default'. If you choose to use
|
||||
`ivy-completing-read', note that the items may always be shown in
|
||||
alphabetical order, depending on your version of Ivy."
|
||||
However, if you would like to use Ivy or Helm completion with Magit but
|
||||
not enable the respective modes globally, then customize this option to
|
||||
use `ivy-completing-read' or `helm--completing-read-default'.
|
||||
|
||||
If you still use `ido-mode', you'll likely need the `magit-ido' package."
|
||||
:group 'magit-essentials
|
||||
:type `(radio (function-item ,#'magit-builtin-completing-read)
|
||||
(function-item ,#'magit-ido-completing-read)
|
||||
(function-item ivy-completing-read)
|
||||
(function-item helm--completing-read-default)
|
||||
(function :tag "Other function")))
|
||||
@@ -486,7 +482,9 @@ and delay of your graphical environment or operating system."
|
||||
((keymap :initform 'magit-file-section-map)
|
||||
(source :initform nil :initarg :source)
|
||||
(header :initform nil :initarg :header)
|
||||
(binary :initform nil :initarg :binary)))
|
||||
(binary :initform nil :initarg :binary)
|
||||
(heading-highlight-face :initform 'magit-diff-file-heading-highlight)
|
||||
(heading-selection-face :initform 'magit-diff-file-heading-selection)))
|
||||
|
||||
(defclass magit-module-section (magit-file-section)
|
||||
((keymap :initform 'magit-module-section-map)
|
||||
@@ -494,12 +492,15 @@ 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)
|
||||
(refined :initform nil)
|
||||
(combined :initform nil :initarg :combined)
|
||||
(from-range :initform nil :initarg :from-range)
|
||||
(from-ranges :initform nil)
|
||||
(to-range :initform nil :initarg :to-range)
|
||||
(about :initform nil :initarg :about)))
|
||||
(about :initform nil :initarg :about)
|
||||
(heading-highlight-face :initform 'magit-diff-hunk-heading-highlight)
|
||||
(heading-selection-face :initform 'magit-diff-hunk-heading-selection)))
|
||||
|
||||
(setf (alist-get 'file magit--section-type-alist) 'magit-file-section)
|
||||
(setf (alist-get 'module magit--section-type-alist) 'magit-module-section)
|
||||
@@ -604,21 +605,21 @@ acts similarly to `completing-read', except for the following:
|
||||
def)
|
||||
(unless def
|
||||
(setq def fallback))
|
||||
(when (and def
|
||||
(not (functionp collection))
|
||||
(not (member def collection)))
|
||||
(setq collection (cons def collection)))
|
||||
(let ((command this-command)
|
||||
(reply (funcall
|
||||
magit-completing-read-function
|
||||
(magit--format-prompt prompt def)
|
||||
(if (and (not (functionp collection))
|
||||
def
|
||||
(not (member def collection)))
|
||||
(cons def collection)
|
||||
collection)
|
||||
predicate
|
||||
require-match initial-input hist def)))
|
||||
(reply (funcall magit-completing-read-function
|
||||
(magit--format-prompt prompt def)
|
||||
collection predicate
|
||||
require-match initial-input hist def)))
|
||||
(setq this-command command)
|
||||
;; Note: Avoid `string=' to support `helm-comp-read-use-marked'.
|
||||
(if (equal reply "")
|
||||
(if require-match
|
||||
(if (and require-match
|
||||
(not (and (listp collection)
|
||||
(member "" collection))))
|
||||
(user-error "Nothing selected")
|
||||
nil)
|
||||
reply))))
|
||||
@@ -642,9 +643,13 @@ acts similarly to `completing-read', except for the following:
|
||||
(unless (or (bound-and-true-p helm-mode)
|
||||
(bound-and-true-p ivy-mode))
|
||||
(setq choices (magit--completion-table choices)))
|
||||
(let ((ivy-sort-functions-alist nil)
|
||||
(vertico-sort-function nil))
|
||||
(completing-read prompt choices
|
||||
(let ((ivy-sort-functions-alist nil))
|
||||
(completing-read prompt
|
||||
(lambda (str pred action)
|
||||
(if (eq action 'metadata)
|
||||
'(metadata (display-sort-function . identity)
|
||||
(cycle-sort-function . identity))
|
||||
(complete-with-action action choices str pred)))
|
||||
predicate require-match
|
||||
initial-input hist def)))
|
||||
|
||||
@@ -695,27 +700,6 @@ third-party completion frameworks."
|
||||
hist def inherit-input-method)))
|
||||
(if no-split input values)))
|
||||
|
||||
(defun magit-ido-completing-read
|
||||
(prompt choices &optional predicate require-match initial-input hist def)
|
||||
"Ido-based `completing-read' almost-replacement.
|
||||
|
||||
Unfortunately `ido-completing-read' is not suitable as a
|
||||
drop-in replacement for `completing-read', instead we use
|
||||
`ido-completing-read+' from the third-party package by the
|
||||
same name."
|
||||
(if (and (require 'ido-completing-read+ nil t)
|
||||
(fboundp 'ido-completing-read+))
|
||||
(ido-completing-read+ prompt choices predicate require-match
|
||||
initial-input hist
|
||||
(or def (and require-match (car choices))))
|
||||
(display-warning 'magit "ido-completing-read+ is not installed
|
||||
|
||||
To use Ido completion with Magit you need to install the
|
||||
third-party `ido-completing-read+' packages. Falling
|
||||
back to built-in `completing-read' for now." :error)
|
||||
(magit-builtin-completing-read prompt choices predicate require-match
|
||||
initial-input hist def)))
|
||||
|
||||
(defvar-keymap magit-minibuffer-local-ns-map
|
||||
:parent minibuffer-local-map
|
||||
"SPC" #'magit-whitespace-disallowed
|
||||
@@ -804,12 +788,12 @@ ACTION is a member of option `magit-slow-confirm'."
|
||||
(when (and prompt (listp prompt))
|
||||
(setq prompt
|
||||
(apply #'format (car prompt)
|
||||
(mapcar (lambda (a) (if (stringp a) (string-replace "%" "%%" a) a))
|
||||
(mapcar (##if (stringp %) (string-replace "%" "%%" %) %)
|
||||
(cdr prompt)))))
|
||||
(when (and prompt-n (listp prompt-n))
|
||||
(setq prompt-n
|
||||
(apply #'format (car prompt-n)
|
||||
(mapcar (lambda (a) (if (stringp a) (string-replace "%" "%%" a) a))
|
||||
(mapcar (##if (stringp %) (string-replace "%" "%%" %) %)
|
||||
(cdr prompt-n)))))
|
||||
(setq prompt-n (format (concat (or prompt-n prompt) "? ") (length items)))
|
||||
(setq prompt (format (concat (or prompt (magit-confirm-make-prompt action))
|
||||
@@ -874,7 +858,7 @@ See info node `(magit)Debugging Tools' for more information."
|
||||
`(,(concat invocation-directory invocation-name)
|
||||
"-Q" "--eval" "(setq debug-on-error t)"
|
||||
,@(mapcan
|
||||
(lambda (dir) (list "-L" dir))
|
||||
(##list "-L" %)
|
||||
(delete-dups
|
||||
(mapcan
|
||||
(lambda (lib)
|
||||
@@ -1043,7 +1027,7 @@ This function should be named `version>=' and be part of Emacs."
|
||||
;;; Kludges for Emacs Bugs
|
||||
|
||||
(defun magit-which-function ()
|
||||
"Return current function name based on point.
|
||||
"Return current function name based on point, without caching.
|
||||
|
||||
This is a simple wrapper around `which-function', that resets
|
||||
Imenu's potentially outdated and therefore unreliable cache by
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
["Arguments"
|
||||
("-n" "Don't checkout commits" "--no-checkout")
|
||||
("-p" "Follow only first parent of a merge" "--first-parent"
|
||||
:if (lambda () (magit-git-version>= "2.29")))
|
||||
:if (##magit-git-version>= "2.29"))
|
||||
(magit-bisect:--term-old :level 6)
|
||||
(magit-bisect:--term-new :level 6)]
|
||||
["Actions"
|
||||
|
||||
@@ -94,12 +94,17 @@ The following %-specs can be used in `heading-format' and
|
||||
`margin-format':
|
||||
|
||||
%H hash using face `magit-blame-hash'
|
||||
%h truncated hash using face `magit-blame-hash'
|
||||
%s summary using face `magit-blame-summary'
|
||||
%a author using face `magit-blame-name'
|
||||
%A author time using face `magit-blame-date'
|
||||
%c committer using face `magit-blame-name'
|
||||
%C committer time using face `magit-blame-date'
|
||||
|
||||
Note that for performance reasons %h results in truncated
|
||||
hashes, as opposed to properly abbreviated hashes that are
|
||||
guaranteed to uniquely identify a commit.
|
||||
|
||||
Additionally if `margin-format' ends with %f, then the string
|
||||
that is displayed in the margin is made at least `margin-width'
|
||||
characters wide, which may be desirable if the used face sets
|
||||
@@ -343,8 +348,7 @@ in `magit-blame-read-only-mode-map' instead."
|
||||
(unless magit-blame--style
|
||||
(setq magit-blame--style (car magit-blame-styles)))
|
||||
(setq magit-blame--make-margin-overlays
|
||||
(and (cl-find-if (lambda (style)
|
||||
(assq 'margin-format (cdr style)))
|
||||
(and (cl-find-if (##assq 'margin-format (cdr %))
|
||||
magit-blame-styles)))
|
||||
(magit-blame--update-margin 'enable))
|
||||
(t
|
||||
@@ -702,6 +706,7 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
(cdr (assoc k2 revinfo)))
|
||||
f)))
|
||||
`((?H . ,(p0 rev 'magit-blame-hash))
|
||||
(?h . ,(p0 (magit-blame--abbrev-hash rev) 'magit-blame-hash))
|
||||
(?s . ,(p1 "summary" 'magit-blame-summary))
|
||||
(?a . ,(p1 "author" 'magit-blame-name))
|
||||
(?c . ,(p1 "committer" 'magit-blame-name))
|
||||
@@ -732,6 +737,13 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
(seconds-to-time (string-to-number time))
|
||||
tz-in-second)))
|
||||
|
||||
(defvar-local magit-blame--abbrev-length nil)
|
||||
|
||||
(defun magit-blame--abbrev-hash (rev)
|
||||
(substring rev 0 (or magit-blame--abbrev-length
|
||||
(setq magit-blame--abbrev-length
|
||||
(magit-abbrev-length)))))
|
||||
|
||||
(defun magit-blame--remove-overlays (&optional beg end)
|
||||
(save-restriction
|
||||
(widen)
|
||||
@@ -758,10 +770,9 @@ modes is toggled, then this mode also gets toggled automatically.
|
||||
Show the information about the chunk at point in the echo area
|
||||
when moving between chunks. Unlike other blaming commands, do
|
||||
not turn on `read-only-mode'."
|
||||
:if (lambda ()
|
||||
(and buffer-file-name
|
||||
:if (##and buffer-file-name
|
||||
(or (not magit-blame-mode)
|
||||
buffer-read-only)))
|
||||
buffer-read-only))
|
||||
(interactive (list (magit-blame-arguments)))
|
||||
(when magit-buffer-file-name
|
||||
(user-error "Blob buffers aren't supported"))
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
(cl-defmethod magit-bookmark-get-filename (&context (major-mode magit-mode))
|
||||
(magit-toplevel))
|
||||
|
||||
(cl-defmethod magit-bookmark-get-value
|
||||
(bookmark &context (major-mode magit-mode))
|
||||
(dolist (var (get major-mode 'magit-bookmark-variables))
|
||||
(bookmark-prop-set bookmark var (symbol-value var))))
|
||||
|
||||
(cl-defmethod magit-bookmark-get-buffer-create
|
||||
(bookmark (mode (derived-mode magit-mode)))
|
||||
(let ((default-directory (bookmark-get-filename bookmark))
|
||||
|
||||
@@ -208,11 +208,10 @@ has to be used to view and change branch related variables."
|
||||
(transient-define-prefix magit-branch (branch)
|
||||
"Add, configure or remove a branch."
|
||||
:man-page "git-branch"
|
||||
[:if (lambda () (and magit-branch-direct-configure (transient-scope)))
|
||||
:description
|
||||
(lambda ()
|
||||
(concat (propertize "Configure " 'face 'transient-heading)
|
||||
(propertize (transient-scope) 'face 'magit-branch-local)))
|
||||
[:if (##and magit-branch-direct-configure (transient-scope))
|
||||
:description (##concat
|
||||
(propertize "Configure " 'face 'transient-heading)
|
||||
(propertize (transient-scope) 'face 'magit-branch-local))
|
||||
("d" magit-branch.<branch>.description)
|
||||
("u" magit-branch.<branch>.merge/remote)
|
||||
("r" magit-branch.<branch>.rebase)
|
||||
@@ -813,11 +812,13 @@ the remote."
|
||||
;;;###autoload
|
||||
(defun magit-branch-shelve (branch)
|
||||
"Shelve a BRANCH.
|
||||
Rename \"refs/heads/BRANCH\" to \"refs/shelved/BRANCH\",
|
||||
Rename \"refs/heads/BRANCH\" to \"refs/shelved/YYYY-MM-DD-BRANCH\",
|
||||
and also rename the respective reflog file."
|
||||
(interactive (list (magit-read-other-local-branch "Shelve branch")))
|
||||
(let ((old (concat "refs/heads/" branch))
|
||||
(new (concat "refs/shelved/" branch)))
|
||||
(let ((old (concat "refs/heads/" branch))
|
||||
(new (format "refs/shelved/%s-%s"
|
||||
(magit-rev-format "%cs" branch)
|
||||
branch)))
|
||||
(magit-git "update-ref" new old "")
|
||||
(magit--rename-reflog-file old new)
|
||||
(magit-branch-unset-pushRemote branch)
|
||||
@@ -826,16 +827,21 @@ and also rename the respective reflog file."
|
||||
;;;###autoload
|
||||
(defun magit-branch-unshelve (branch)
|
||||
"Unshelve a BRANCH.
|
||||
Rename \"refs/shelved/BRANCH\" to \"refs/heads/BRANCH\",
|
||||
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)
|
||||
(magit-list-refnames "refs/shelved"))
|
||||
(nreverse (magit-list-refnames "refs/shelved")))
|
||||
nil t)))
|
||||
(let ((old (concat "refs/shelved/" branch))
|
||||
(new (concat "refs/heads/" branch)))
|
||||
(new (concat "refs/heads/"
|
||||
(if (string-match-p
|
||||
"\\`[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}-" branch)
|
||||
(substring branch 11)
|
||||
branch))))
|
||||
(magit-git "update-ref" new old "")
|
||||
(magit--rename-reflog-file old new)
|
||||
(magit-run-git "update-ref" "-d" old)))
|
||||
@@ -854,10 +860,9 @@ and also rename the respective reflog file."
|
||||
(transient-define-prefix magit-branch-configure (branch)
|
||||
"Configure a branch."
|
||||
:man-page "git-branch"
|
||||
[:description
|
||||
(lambda ()
|
||||
(concat (propertize "Configure " 'face 'transient-heading)
|
||||
(propertize (transient-scope) 'face 'magit-branch-local)))
|
||||
[:description (##concat
|
||||
(propertize "Configure " 'face 'transient-heading)
|
||||
(propertize (transient-scope) 'face 'magit-branch-local))
|
||||
("d" magit-branch.<branch>.description)
|
||||
("u" magit-branch.<branch>.merge/remote)
|
||||
("r" magit-branch.<branch>.rebase)
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
(declare-function magit-blame-mode "magit-blame" (&optional arg))
|
||||
(defvar magit-blame-mode)
|
||||
;; For `magit-diff-show-or-scroll'
|
||||
(declare-function git-rebase-current-line "git-rebase" ())
|
||||
(declare-function git-rebase-current-line "git-rebase" (&optional batch))
|
||||
;; For `magit-diff-unmerged'
|
||||
(declare-function magit-merge-in-progress-p "magit-merge" ())
|
||||
(declare-function magit--merge-range "magit-merge" (&optional head))
|
||||
@@ -73,7 +73,7 @@
|
||||
(declare-function magit-commit-add-log "magit-commit" ())
|
||||
(declare-function magit-diff-trace-definition "magit-log" ())
|
||||
(declare-function magit-patch-save "magit-patch" (files &optional arg))
|
||||
(declare-function magit-do-async-shell-command "magit-extras" (file))
|
||||
(declare-function magit-do-async-shell-command "magit-dired" (file))
|
||||
(declare-function magit-add-change-log-entry "magit-extras"
|
||||
(&optional whoami file-name other-window))
|
||||
(declare-function magit-add-change-log-entry-other-window "magit-extras"
|
||||
@@ -141,9 +141,7 @@ to have any effect."
|
||||
:type 'float)
|
||||
|
||||
(defcustom magit-diff-highlight-hunk-body t
|
||||
"Whether to highlight bodies of selected hunk sections.
|
||||
This only has an effect if `magit-diff-highlight' is a
|
||||
member of `magit-section-highlight-hook', which see."
|
||||
"Whether to highlight bodies of selected hunk sections."
|
||||
:package-version '(magit . "2.1.0")
|
||||
:group 'magit-diff
|
||||
:type 'boolean)
|
||||
@@ -194,13 +192,16 @@ keep their distinct foreground colors."
|
||||
"Whether to show word-granularity differences within diff hunks.
|
||||
|
||||
`nil' Never show fine differences.
|
||||
`t' Show fine differences for the current diff hunk only.
|
||||
`all' Show fine differences for all displayed diff hunks."
|
||||
`all' Show fine differences for all displayed diff hunks.
|
||||
`t' Refine each hunk once it becomes the current section.
|
||||
Keep the refinement when another section is selected.
|
||||
Refreshing the buffer removes all refinement. This
|
||||
variant is only provided for performance reasons."
|
||||
:group 'magit-diff
|
||||
:safe (lambda (val) (memq val '(nil t all)))
|
||||
:type '(choice (const :tag "Never" nil)
|
||||
(const :tag "Current" t)
|
||||
(const :tag "All" all)))
|
||||
:safe (##memq % '(nil t all))
|
||||
:type '(choice (const :tag "No refinement" nil)
|
||||
(const :tag "Immediately refine all hunks" all)
|
||||
(const :tag "Refine each hunk when moving to it" t)))
|
||||
|
||||
(defcustom magit-diff-refine-ignore-whitespace smerge-refine-ignore-whitespace
|
||||
"Whether to ignore whitespace changes in word-granularity differences."
|
||||
@@ -258,7 +259,7 @@ The options `magit-diff-highlight-trailing' and
|
||||
`magit-diff-highlight-indentation' control what kind of
|
||||
whitespace errors are highlighted."
|
||||
:group 'magit-diff
|
||||
:safe (lambda (val) (memq val '(t nil uncommitted status)))
|
||||
:safe (##memq % '(t nil uncommitted status))
|
||||
:type '(choice (const :tag "In all diffs" t)
|
||||
(const :tag "Only in uncommitted changes" uncommitted)
|
||||
(const :tag "Never" nil)))
|
||||
@@ -271,7 +272,7 @@ whitespace errors are highlighted."
|
||||
`all' Highlight in added, removed and context lines."
|
||||
:package-version '(magit . "3.0.0")
|
||||
:group 'magit-diff
|
||||
:safe (lambda (val) (memq val '(t both all)))
|
||||
:safe (##memq % '(t both all))
|
||||
:type '(choice (const :tag "In added lines" t)
|
||||
(const :tag "In added and removed lines" both)
|
||||
(const :tag "In added, removed and context lines" all)))
|
||||
@@ -332,10 +333,10 @@ it receives either three or five arguments; the signature has to be
|
||||
`module', `stat' and `list'."
|
||||
:package-version '(magit . "4.3.1")
|
||||
:group 'magit-diff
|
||||
:type `(choice (function-item ,#'magit-format-file-default)
|
||||
(function-item ,#'magit-format-file-all-the-icons)
|
||||
(function-item ,#'magit-format-file-nerd-icons)
|
||||
function))
|
||||
:type `(radio (function-item ,#'magit-format-file-default)
|
||||
(function-item ,#'magit-format-file-all-the-icons)
|
||||
(function-item ,#'magit-format-file-nerd-icons)
|
||||
function))
|
||||
|
||||
;;;; File Diff
|
||||
|
||||
@@ -897,37 +898,35 @@ and `:slant'."
|
||||
;;; Commands
|
||||
;;;; Prefix Commands
|
||||
|
||||
(eval-and-compile
|
||||
(defvar magit-diff-infix-arguments
|
||||
[:class transient-subgroups
|
||||
["Limit arguments"
|
||||
(magit:--)
|
||||
(magit-diff:--ignore-submodules)
|
||||
("-b" "Ignore whitespace changes" ("-b" "--ignore-space-change"))
|
||||
("-w" "Ignore all whitespace" ("-w" "--ignore-all-space"))
|
||||
("-D" "Omit preimage for deletes" ("-D" "--irreversible-delete")
|
||||
:level 5)]
|
||||
["Context arguments"
|
||||
(magit-diff:-U)
|
||||
("-W" "Show surrounding functions" ("-W" "--function-context"))]
|
||||
["Tune arguments"
|
||||
(magit-diff:--diff-algorithm)
|
||||
(magit-diff:--diff-merges)
|
||||
(magit-diff:-M)
|
||||
(magit-diff:-C)
|
||||
(magit-diff:-R :level 5)
|
||||
(magit-diff:--color-moved :level 5)
|
||||
(magit-diff:--color-moved-ws :level 5)
|
||||
(magit-diff:--no-ext-diff)
|
||||
(magit-diff:--stat)
|
||||
(magit-diff:--show-signature)]]))
|
||||
(transient-define-group magit-diff-infix-arguments
|
||||
["Limit arguments"
|
||||
(magit:--)
|
||||
(magit-diff:--ignore-submodules)
|
||||
("-b" "Ignore whitespace changes" ("-b" "--ignore-space-change"))
|
||||
("-w" "Ignore all whitespace" ("-w" "--ignore-all-space"))
|
||||
("-D" "Omit preimage for deletes" ("-D" "--irreversible-delete")
|
||||
:level 5)]
|
||||
["Context arguments"
|
||||
(magit-diff:-U)
|
||||
("-W" "Show surrounding functions" ("-W" "--function-context"))]
|
||||
["Tune arguments"
|
||||
(magit-diff:--diff-algorithm)
|
||||
(magit-diff:--diff-merges)
|
||||
(magit-diff:-M)
|
||||
(magit-diff:-C)
|
||||
(magit-diff:-R :level 5)
|
||||
(magit-diff:--color-moved :level 5)
|
||||
(magit-diff:--color-moved-ws :level 5)
|
||||
(magit-diff:--no-ext-diff)
|
||||
(magit-diff:--stat)
|
||||
(magit-diff:--show-signature)])
|
||||
|
||||
;;;###autoload (autoload 'magit-diff "magit-diff" nil t)
|
||||
(transient-define-prefix magit-diff ()
|
||||
"Show changes between different versions."
|
||||
:man-page "git-diff"
|
||||
:class 'magit-diff-prefix
|
||||
[magit-diff-infix-arguments]
|
||||
'magit-diff-infix-arguments
|
||||
["Actions"
|
||||
[("d" "Dwim" magit-diff-dwim)
|
||||
("r" "Diff range" magit-diff-range)
|
||||
@@ -943,7 +942,7 @@ and `:slant'."
|
||||
"Change the arguments used for the diff(s) in the current buffer."
|
||||
:man-page "git-diff"
|
||||
:class 'magit-diff-refresh-prefix
|
||||
[magit-diff-infix-arguments]
|
||||
'magit-diff-infix-arguments
|
||||
[["Refresh"
|
||||
("g" "buffer" magit-diff-refresh)
|
||||
("s" "buffer and set defaults" transient-set-and-exit)
|
||||
@@ -1406,7 +1405,7 @@ for a revision."
|
||||
(magit-section-parent-value (magit-current-section))))))
|
||||
(require 'magit)
|
||||
(let* ((file (magit-file-relative-name))
|
||||
(ln (and file (line-number-at-pos))))
|
||||
(line (and file (line-number-at-pos))))
|
||||
(magit-with-toplevel
|
||||
(when module
|
||||
(setq default-directory
|
||||
@@ -1417,15 +1416,14 @@ for a revision."
|
||||
(save-buffer))
|
||||
(let ((buf (magit-revision-setup-buffer rev args files)))
|
||||
(when file
|
||||
(let ((line (magit-diff-visit--offset file (list "-R" rev) ln))
|
||||
(let ((line (magit-diff-visit--offset file (list "-R" rev) line))
|
||||
(col (current-column)))
|
||||
(with-current-buffer buf
|
||||
(magit-diff--goto-position file line col))))))))
|
||||
|
||||
(defun magit-diff--locate-hunk (file line &optional parent)
|
||||
(and-let* ((diff (cl-find-if (lambda (section)
|
||||
(and (cl-typep section 'magit-file-section)
|
||||
(equal (oref section value) file)))
|
||||
(and-let* ((diff (cl-find-if (##and (cl-typep % 'magit-file-section)
|
||||
(equal (oref % value) file))
|
||||
(oref (or parent magit-root-section) children))))
|
||||
(let ((hunks (oref diff children)))
|
||||
(cl-block nil
|
||||
@@ -1458,7 +1456,6 @@ for a revision."
|
||||
(when (oref section hidden)
|
||||
(magit-section-show section))
|
||||
(setq section (oref section parent))))
|
||||
(magit-section-update-highlight)
|
||||
t))
|
||||
|
||||
;;;; Setting Commands
|
||||
@@ -1522,12 +1519,12 @@ instead."
|
||||
(defun magit-diff-less-context (&optional count)
|
||||
"Decrease the context for diff hunks by COUNT lines."
|
||||
(interactive "p")
|
||||
(magit-diff-set-context (lambda (cur) (max 0 (- (or cur 0) count)))))
|
||||
(magit-diff-set-context (##max 0 (- (or % 0) count))))
|
||||
|
||||
(defun magit-diff-more-context (&optional count)
|
||||
"Increase the context for diff hunks by COUNT lines."
|
||||
(interactive "p")
|
||||
(magit-diff-set-context (lambda (cur) (+ (or cur 0) count))))
|
||||
(magit-diff-set-context (##+ (or % 0) count)))
|
||||
|
||||
(defun magit-diff-default-context ()
|
||||
"Reset context for diff hunks to the default height."
|
||||
@@ -1552,6 +1549,14 @@ instead."
|
||||
(setq magit-buffer-diff-args val))
|
||||
(magit-refresh))
|
||||
|
||||
(defun magit-diff-get-context ()
|
||||
(string-to-number
|
||||
(or (seq-some (##and (string-match "\\`-U\\([0-9]+\\)?\\'" %)
|
||||
(match-string 1 %))
|
||||
magit-buffer-diff-args)
|
||||
(magit-get "diff.context")
|
||||
"3")))
|
||||
|
||||
(defun magit-diff-context-p ()
|
||||
(if-let ((arg (seq-find (##string-match "^-U\\([0-9]+\\)$" %)
|
||||
magit-buffer-diff-args)))
|
||||
@@ -1597,9 +1602,9 @@ Display the buffer in the selected window. With a prefix
|
||||
argument OTHER-WINDOW display the buffer in another window
|
||||
instead.
|
||||
|
||||
Visit the worktree version of the appropriate file. The location
|
||||
of point inside the diff determines which file is being visited.
|
||||
The visited version depends on what changes the diff is about.
|
||||
The location of point inside the diff determines which file is
|
||||
being visited. The visited version depends on what changes the
|
||||
diff is about.
|
||||
|
||||
1. If the diff shows uncommitted changes (i.e., stage or unstaged
|
||||
changes), then visit the file in the working tree (i.e., the
|
||||
@@ -2125,8 +2130,8 @@ keymap is the parent of their keymaps."
|
||||
"<remap> <magit-visit-thing>" #'magit-diff-visit-file
|
||||
"<remap> <magit-revert-no-commit>" #'magit-reverse
|
||||
"<remap> <magit-delete-thing>" #'magit-discard
|
||||
"<remap> <magit-unstage-file>" #'magit-unstage
|
||||
"<remap> <magit-stage-file>" #'magit-stage
|
||||
"<remap> <magit-unstage-files>" #'magit-unstage
|
||||
"<remap> <magit-stage-files>" #'magit-stage
|
||||
"<remap> <magit-cherry-apply>" #'magit-apply
|
||||
"<8>" (magit-menu-item "Rename file" #'magit-file-rename
|
||||
'(:enable (eq (magit-diff-scope) 'file)))
|
||||
@@ -2232,7 +2237,7 @@ keymap is the parent of their keymaps."
|
||||
(unless (equal cmd "merge-tree")
|
||||
(push "--ita-visible-in-index" args))
|
||||
(setq args (magit-diff--maybe-add-stat-arguments args))
|
||||
(when (cl-member-if (lambda (arg) (string-prefix-p "--color-moved" arg)) args)
|
||||
(when (cl-member-if (##string-prefix-p "--color-moved" %) args)
|
||||
(push "--color=always" args)
|
||||
(setq magit-git-global-arguments
|
||||
(append magit-diff--reset-non-color-moved
|
||||
@@ -2240,7 +2245,7 @@ keymap is the parent of their keymaps."
|
||||
(magit--git-wash #'magit-diff-wash-diffs
|
||||
(if (member "--no-index" args)
|
||||
'wash-anyway
|
||||
(or keep-error magit--git-wash-keep-error))
|
||||
(or keep-error t))
|
||||
cmd args)))
|
||||
|
||||
(defun magit-diff--maybe-add-stat-arguments (args)
|
||||
@@ -2339,7 +2344,7 @@ keymap is the parent of their keymaps."
|
||||
(if (looking-at "^$") (forward-line) (insert "\n"))))))
|
||||
|
||||
(defun magit-diff-wash-diff (args)
|
||||
(when (cl-member-if (lambda (arg) (string-prefix-p "--color-moved" arg)) args)
|
||||
(when (cl-member-if (##string-prefix-p "--color-moved" %) args)
|
||||
(require 'ansi-color)
|
||||
(ansi-color-apply-on-region (point-min) (point-max)))
|
||||
(cond
|
||||
@@ -2454,7 +2459,7 @@ keymap is the parent of their keymaps."
|
||||
(setq header (nreverse header))
|
||||
;; KLUDGE `git-log' ignores `--no-prefix' when `-L' is used.
|
||||
(when (and (derived-mode-p 'magit-log-mode)
|
||||
(seq-some (lambda (arg) (string-prefix-p "-L" arg))
|
||||
(seq-some (##string-prefix-p "-L" %)
|
||||
magit-buffer-log-args))
|
||||
(when orig
|
||||
(setq orig (substring orig 2)))
|
||||
@@ -2498,11 +2503,15 @@ keymap is the parent of their keymaps."
|
||||
(funcall magit-format-file-function kind file face status orig))
|
||||
|
||||
(defun magit-format-file-default (_kind file face &optional status orig)
|
||||
"Show only the Git status and the filename."
|
||||
(propertize (concat (and status (format "%-11s" status))
|
||||
(if orig (format "%s -> %s" orig file) file))
|
||||
'font-lock-face face))
|
||||
|
||||
(defun magit-format-file-all-the-icons (kind file face &optional status orig)
|
||||
"Show the status, filename and icon (using the `all-the-icons' package).
|
||||
You have to explicitly install the `all-the-icons' package, else this
|
||||
function errors."
|
||||
(cl-flet ((icon (if (or (eq kind 'module) (string-suffix-p "/" file))
|
||||
'all-the-icons-icon-for-dir
|
||||
'all-the-icons-icon-for-file)))
|
||||
@@ -2519,6 +2528,9 @@ keymap is the parent of their keymaps."
|
||||
'font-lock-face face))))
|
||||
|
||||
(defun magit-format-file-nerd-icons (kind file face &optional status orig)
|
||||
"Show the status, filename and icon (using the `nerd-icons' package).
|
||||
You have to explicitly install the `nerd-icons' package, else this
|
||||
function errors."
|
||||
(cl-flet ((icon (if (or (eq kind 'module) (string-suffix-p "/" file))
|
||||
'nerd-icons-icon-for-dir
|
||||
'nerd-icons-icon-for-file)))
|
||||
@@ -2616,7 +2628,6 @@ keymap is the parent of their keymaps."
|
||||
(magit-delete-line)
|
||||
(magit-insert-section
|
||||
( hunk value nil
|
||||
:washer #'magit-diff-paint-hunk
|
||||
:combined combined
|
||||
:from-range (if combined (butlast ranges) (car ranges))
|
||||
:to-range (car (last ranges))
|
||||
@@ -2631,7 +2642,7 @@ keymap is the parent of their keymaps."
|
||||
(defun magit-diff-expansion-threshold (section)
|
||||
"Keep new diff sections collapsed if washing takes too long."
|
||||
(and (magit-file-section-p section)
|
||||
(> (float-time (time-since magit-refresh-start-time))
|
||||
(> (float-time (time-since magit--refresh-start-time))
|
||||
magit-diff-expansion-threshold)
|
||||
'hide))
|
||||
|
||||
@@ -2877,10 +2888,10 @@ or a ref which is not a branch, then it inserts nothing."
|
||||
(defun magit-insert-revision-headers ()
|
||||
"Insert headers about the commit into a revision buffer."
|
||||
(magit-insert-section (headers)
|
||||
(magit-insert-heading
|
||||
(magit-insert-heading nil
|
||||
(and-let* ((string (magit-rev-format "%D" magit-buffer-revision
|
||||
"--decorate=full")))
|
||||
(magit-format-ref-labels string) ?\s)
|
||||
(concat (magit-format-ref-labels string) " "))
|
||||
(propertize
|
||||
(magit-rev-parse (magit--rev-dereference magit-buffer-revision))
|
||||
'font-lock-face 'magit-hash))
|
||||
@@ -2936,18 +2947,18 @@ Refer to user option `magit-revision-insert-related-refs-display-alist'."
|
||||
|
||||
(defun magit--insert-related-refs (rev arg title remote)
|
||||
(when-let ((refs (magit-list-related-branches arg rev (and remote "-a"))))
|
||||
(insert title ":" (make-string (- 10 (length title)) ?\s))
|
||||
(dolist (branch refs)
|
||||
(if (<= (+ (current-column) 1 (length branch))
|
||||
(window-width))
|
||||
(insert ?\s)
|
||||
(insert ?\n (make-string 12 ?\s)))
|
||||
(magit-insert-section (branch branch)
|
||||
(magit-insert-section (related-refs)
|
||||
(insert title ":" (make-string (- 10 (length title)) ?\s))
|
||||
(dolist (branch refs)
|
||||
(if (<= (+ (current-column) 1 (length branch))
|
||||
(window-width))
|
||||
(insert ?\s)
|
||||
(insert ?\n (make-string 12 ?\s)))
|
||||
(insert (propertize branch 'font-lock-face
|
||||
(if (string-prefix-p "remotes/" branch)
|
||||
'magit-branch-remote
|
||||
'magit-branch-local)))))
|
||||
(insert ?\n)))
|
||||
'magit-branch-local))))
|
||||
(insert ?\n))))
|
||||
|
||||
(defun magit-insert-revision-gravatars (rev beg)
|
||||
(when (and magit-revision-show-gravatars
|
||||
@@ -3100,7 +3111,7 @@ It the SECTION has a different type, then do nothing."
|
||||
(defvar-keymap magit-unstaged-section-map
|
||||
:doc "Keymap for the `unstaged' section."
|
||||
"<remap> <magit-visit-thing>" #'magit-diff-unstaged
|
||||
"<remap> <magit-stage-file>" #'magit-stage
|
||||
"<remap> <magit-stage-files>" #'magit-stage
|
||||
"<remap> <magit-delete-thing>" #'magit-discard
|
||||
"<3>" (magit-menu-item "Discard all" #'magit-discard)
|
||||
"<2>" (magit-menu-item "Stage all" #'magit-stage)
|
||||
@@ -3121,7 +3132,7 @@ It the SECTION has a different type, then do nothing."
|
||||
:doc "Keymap for the `staged' section."
|
||||
"<remap> <magit-revert-no-commit>" #'magit-reverse
|
||||
"<remap> <magit-delete-thing>" #'magit-discard
|
||||
"<remap> <magit-unstage-file>" #'magit-unstage
|
||||
"<remap> <magit-unstage-files>" #'magit-unstage
|
||||
"<remap> <magit-visit-thing>" #'magit-diff-staged
|
||||
"<4>" (magit-menu-item "Reverse all" #'magit-reverse)
|
||||
"<3>" (magit-menu-item "Discard all" #'magit-discard)
|
||||
@@ -3243,12 +3254,12 @@ actually a `diff' but a `diffstat' section."
|
||||
(and siblings t)
|
||||
(magit-diff-use-hunk-region-p)
|
||||
ssection)
|
||||
(`(hunk nil t ,_)
|
||||
(`(hunk nil t ,_)
|
||||
(if (magit-section-internal-region-p section) 'region 'hunk))
|
||||
('(hunk t t nil) 'hunks)
|
||||
(`(hunk ,_ ,_ ,_) 'hunk)
|
||||
('(file t t nil) 'files)
|
||||
(`(file ,_ ,_ ,_) 'file)
|
||||
('(hunk t t nil) 'hunks)
|
||||
(`(hunk ,_ ,_ ,_) 'hunk)
|
||||
('(file t t nil) 'files)
|
||||
(`(file ,_ ,_ ,_) 'file)
|
||||
('(module t t nil) 'files)
|
||||
(`(module ,_ ,_ ,_) 'file)
|
||||
(`(,(or 'staged 'unstaged 'untracked) nil ,_ ,_) 'list)))))
|
||||
@@ -3265,159 +3276,53 @@ actually a `diff' but a `diffstat' section."
|
||||
(byte-code-function-p last-command))
|
||||
(eq (region-end) (region-beginning))))))
|
||||
|
||||
;;; Diff Highlight
|
||||
|
||||
(add-hook 'magit-section-unhighlight-hook #'magit-diff-unhighlight)
|
||||
(add-hook 'magit-section-highlight-hook #'magit-diff-highlight)
|
||||
|
||||
(defun magit-diff-unhighlight (section selection)
|
||||
"Remove the highlighting of the diff-related SECTION."
|
||||
(when (magit-hunk-section-p section)
|
||||
(magit-diff-paint-hunk section selection nil)
|
||||
t))
|
||||
|
||||
(defun magit-diff-highlight (section selection)
|
||||
"Highlight the diff-related SECTION.
|
||||
If SECTION is not a diff-related section, then do nothing and
|
||||
return nil. If SELECTION is non-nil, then it is a list of sections
|
||||
selected by the region, including SECTION. All of these sections
|
||||
are highlighted."
|
||||
(if (and (magit-section-match 'commit section)
|
||||
(oref section children))
|
||||
(progn (if selection
|
||||
(dolist (section selection)
|
||||
(magit-diff-highlight-list section selection))
|
||||
(magit-diff-highlight-list section))
|
||||
t)
|
||||
(when-let ((scope (magit-diff-scope section t)))
|
||||
(cond ((eq scope 'region)
|
||||
(magit-diff-paint-hunk section selection t))
|
||||
(selection
|
||||
(dolist (section selection)
|
||||
(magit-diff-highlight-recursive section selection)))
|
||||
(t
|
||||
(magit-diff-highlight-recursive section)))
|
||||
t)))
|
||||
|
||||
(defun magit-diff-highlight-recursive (section &optional selection)
|
||||
(pcase (magit-diff-scope section)
|
||||
('list (magit-diff-highlight-list section selection))
|
||||
('file (magit-diff-highlight-file section selection))
|
||||
('hunk (magit-diff-highlight-heading section selection)
|
||||
(magit-diff-paint-hunk section selection t))
|
||||
(_ (magit-section-highlight section nil))))
|
||||
|
||||
(defun magit-diff-highlight-list (section &optional selection)
|
||||
(if (oref section children)
|
||||
(let ((beg (oref section start))
|
||||
(cnt (oref section content))
|
||||
(end (oref section end)))
|
||||
(when (or (eq this-command #'mouse-drag-region)
|
||||
(not selection))
|
||||
(unless (and (region-active-p)
|
||||
(<= (region-beginning) beg))
|
||||
(magit-section-make-overlay beg cnt 'magit-section-highlight))
|
||||
(if (oref section hidden)
|
||||
(oset section washer #'ignore)
|
||||
(dolist (child (oref section children))
|
||||
(when (or (eq this-command #'mouse-drag-region)
|
||||
(not (and (region-active-p)
|
||||
(<= (region-beginning)
|
||||
(oref child start)))))
|
||||
(magit-diff-highlight-recursive child selection)))))
|
||||
(when magit-diff-highlight-hunk-body
|
||||
(magit-section-make-overlay (1- end) end 'magit-section-highlight)))
|
||||
(magit-section-highlight section nil)))
|
||||
|
||||
(defun magit-diff-highlight-file (section &optional selection)
|
||||
(magit-diff-highlight-heading section selection)
|
||||
(when (or (not (oref section hidden))
|
||||
(cl-typep section 'magit-module-section))
|
||||
(dolist (child (oref section children))
|
||||
(magit-diff-highlight-recursive child selection))))
|
||||
|
||||
(defun magit-diff-highlight-heading (section &optional selection)
|
||||
(magit-section-make-overlay
|
||||
(oref section start)
|
||||
(or (oref section content)
|
||||
(oref section end))
|
||||
(pcase (list (oref section type)
|
||||
(and (member section selection)
|
||||
(not (eq this-command #'mouse-drag-region))))
|
||||
('(file t) 'magit-diff-file-heading-selection)
|
||||
('(file nil) 'magit-diff-file-heading-highlight)
|
||||
('(module t) 'magit-diff-file-heading-selection)
|
||||
('(module nil) 'magit-diff-file-heading-highlight)
|
||||
('(hunk t) 'magit-diff-hunk-heading-selection)
|
||||
('(hunk nil) 'magit-diff-hunk-heading-highlight))))
|
||||
|
||||
;;; Hunk Paint
|
||||
|
||||
(cl-defun magit-diff-paint-hunk
|
||||
(section &optional selection
|
||||
(highlight (magit-section-selected-p section selection)))
|
||||
(let (paint)
|
||||
(unless magit-diff-highlight-hunk-body
|
||||
(setq highlight nil))
|
||||
(cond (highlight
|
||||
(unless (oref section hidden)
|
||||
(cl-pushnew section magit-section-highlighted-sections)
|
||||
(cond ((memq section magit-section-unhighlight-sections)
|
||||
(setq magit-section-unhighlight-sections
|
||||
(delq section magit-section-unhighlight-sections)))
|
||||
(magit-diff-highlight-hunk-body
|
||||
(setq paint t)))))
|
||||
(t
|
||||
(cond ((and (oref section hidden)
|
||||
(memq section magit-section-unhighlight-sections))
|
||||
(cl-pushnew section magit-section-highlighted-sections)
|
||||
(setq magit-section-unhighlight-sections
|
||||
(delq section magit-section-unhighlight-sections)))
|
||||
(t
|
||||
(setq paint t)))))
|
||||
(when paint
|
||||
(save-excursion
|
||||
(goto-char (oref section start))
|
||||
(let ((end (oref section end))
|
||||
(merging (looking-at "@@@"))
|
||||
(diff-type (magit-diff-type))
|
||||
(stage nil)
|
||||
(tab-width (magit-diff-tab-width
|
||||
(magit-section-parent-value section))))
|
||||
(forward-line)
|
||||
(while (< (point) end)
|
||||
(when (and magit-diff-hide-trailing-cr-characters
|
||||
(char-equal ?\r (char-before (line-end-position))))
|
||||
(put-text-property (1- (line-end-position)) (line-end-position)
|
||||
'invisible t))
|
||||
(put-text-property
|
||||
(point) (1+ (line-end-position)) 'font-lock-face
|
||||
(cond
|
||||
((looking-at "^\\+\\+?\\([<=|>]\\)\\{7\\}")
|
||||
(setq stage (pcase (list (match-string 1) highlight)
|
||||
('("<" nil) 'magit-diff-our)
|
||||
('("<" t) 'magit-diff-our-highlight)
|
||||
('("|" nil) 'magit-diff-base)
|
||||
('("|" t) 'magit-diff-base-highlight)
|
||||
('("=" nil) 'magit-diff-their)
|
||||
('("=" t) 'magit-diff-their-highlight)
|
||||
('(">" nil) nil)))
|
||||
'magit-diff-conflict-heading)
|
||||
((looking-at (if merging "^\\(\\+\\| \\+\\)" "^\\+"))
|
||||
(magit-diff-paint-tab merging tab-width)
|
||||
(magit-diff-paint-whitespace merging 'added diff-type)
|
||||
(or stage
|
||||
(if highlight 'magit-diff-added-highlight 'magit-diff-added)))
|
||||
((looking-at (if merging "^\\(-\\| -\\)" "^-"))
|
||||
(magit-diff-paint-tab merging tab-width)
|
||||
(magit-diff-paint-whitespace merging 'removed diff-type)
|
||||
(if highlight 'magit-diff-removed-highlight 'magit-diff-removed))
|
||||
(t
|
||||
(magit-diff-paint-tab merging tab-width)
|
||||
(magit-diff-paint-whitespace merging 'context diff-type)
|
||||
(if highlight 'magit-diff-context-highlight 'magit-diff-context))))
|
||||
(forward-line))))))
|
||||
(magit-diff-update-hunk-refinement section))
|
||||
(cl-defmethod magit-section-paint ((section magit-hunk-section) highlight)
|
||||
(unless magit-diff-highlight-hunk-body
|
||||
(setq highlight nil))
|
||||
(let ((end (oref section end))
|
||||
(merging (looking-at "@@@"))
|
||||
(diff-type (magit-diff-type))
|
||||
(stage nil)
|
||||
(tab-width (magit-diff-tab-width
|
||||
(magit-section-parent-value section))))
|
||||
(forward-line)
|
||||
(while (< (point) end)
|
||||
(when (and magit-diff-hide-trailing-cr-characters
|
||||
(char-equal ?\r (char-before (line-end-position))))
|
||||
(put-text-property (1- (line-end-position)) (line-end-position)
|
||||
'invisible t))
|
||||
(put-text-property
|
||||
(point) (1+ (line-end-position)) 'font-lock-face
|
||||
(cond
|
||||
((looking-at "^\\+\\+?\\([<=|>]\\)\\{7\\}")
|
||||
(setq stage (pcase (list (match-string 1) highlight)
|
||||
('("<" nil) 'magit-diff-our)
|
||||
('("<" t) 'magit-diff-our-highlight)
|
||||
('("|" nil) 'magit-diff-base)
|
||||
('("|" t) 'magit-diff-base-highlight)
|
||||
('("=" nil) 'magit-diff-their)
|
||||
('("=" t) 'magit-diff-their-highlight)
|
||||
('(">" nil) nil)))
|
||||
'magit-diff-conflict-heading)
|
||||
((looking-at (if merging "^\\(\\+\\| \\+\\)" "^\\+"))
|
||||
(magit-diff-paint-tab merging tab-width)
|
||||
(magit-diff-paint-whitespace merging 'added diff-type)
|
||||
(or stage
|
||||
(if highlight 'magit-diff-added-highlight 'magit-diff-added)))
|
||||
((looking-at (if merging "^\\(-\\| -\\)" "^-"))
|
||||
(magit-diff-paint-tab merging tab-width)
|
||||
(magit-diff-paint-whitespace merging 'removed diff-type)
|
||||
(if highlight 'magit-diff-removed-highlight 'magit-diff-removed))
|
||||
(t
|
||||
(magit-diff-paint-tab merging tab-width)
|
||||
(magit-diff-paint-whitespace merging 'context diff-type)
|
||||
(if highlight 'magit-diff-context-highlight 'magit-diff-context))))
|
||||
(forward-line)))
|
||||
(when (eq magit-diff-refine-hunk 'all)
|
||||
(magit-diff-update-hunk-refinement section))
|
||||
(oset section painted (if highlight 'highlight 'plain)))
|
||||
|
||||
(defvar magit-diff--tab-width-cache nil)
|
||||
|
||||
@@ -3490,7 +3395,11 @@ are highlighted."
|
||||
(overlay-put ov 'font-lock-face 'magit-diff-whitespace-warning)
|
||||
(overlay-put ov 'priority 2)
|
||||
(overlay-put ov 'evaporate t))))))
|
||||
|
||||
|
||||
(cl-defmethod magit-section--refine ((section magit-hunk-section))
|
||||
(when (eq magit-diff-refine-hunk t)
|
||||
(magit-diff-update-hunk-refinement section)))
|
||||
|
||||
(defun magit-diff-update-hunk-refinement (&optional section allow-remove)
|
||||
(if section
|
||||
(unless (oref section hidden)
|
||||
@@ -3504,22 +3413,22 @@ are highlighted."
|
||||
;; `diff-refine-hunk' does not handle combined diffs.
|
||||
(unless (looking-at "@@@")
|
||||
(let ((smerge-refine-ignore-whitespace
|
||||
magit-diff-refine-ignore-whitespace)
|
||||
magit-diff-refine-ignore-whitespace)
|
||||
;; Avoid fsyncing many small temp files.
|
||||
(write-region-inhibit-fsync t))
|
||||
(diff-refine-hunk)))))
|
||||
(diff-refine-hunk)))))
|
||||
((and (guard allow-remove)
|
||||
(or `(nil t ,_) '(t t nil)))
|
||||
(oset section refined nil)
|
||||
(remove-overlays (oref section start)
|
||||
(oref section end)
|
||||
'diff-mode 'fine))))
|
||||
(cl-labels ((recurse (section)
|
||||
(if (magit-section-match 'hunk section)
|
||||
(if (magit-section-match 'hunk section)
|
||||
(magit-diff-update-hunk-refinement section t)
|
||||
(dolist (child (oref section children))
|
||||
(recurse child)))))
|
||||
(recurse magit-root-section))))
|
||||
|
||||
|
||||
;;; Hunk Region
|
||||
|
||||
|
||||
109
lisp/magit/magit-dired.el
Normal file
109
lisp/magit/magit-dired.el
Normal file
@@ -0,0 +1,109 @@
|
||||
;;; magit-dired.el --- Dired support for Magit -*- lexical-binding:t -*-
|
||||
|
||||
;; Copyright (C) 2008-2025 The Magit Project Contributors
|
||||
|
||||
;; Author: Jonas Bernoulli <emacs.magit@jonas.bernoulli.dev>
|
||||
;; Maintainer: Jonas Bernoulli <emacs.magit@jonas.bernoulli.dev>
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
;; Magit is free software: you can redistribute it and/or modify it
|
||||
;; under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
;;
|
||||
;; Magit is distributed in the hope that it will be useful, but WITHOUT
|
||||
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
;; License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with Magit. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Dired support for Magit.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'magit)
|
||||
|
||||
;; For `magit-do-async-shell-command'.
|
||||
(declare-function dired-read-shell-command "dired-aux" (prompt arg files))
|
||||
|
||||
;;; Open Dired from Magit
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-dired-jump (&optional other-window)
|
||||
"Visit file at point using Dired.
|
||||
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)))
|
||||
(expand-file-name (if (file-directory-p file)
|
||||
(file-name-as-directory file)
|
||||
file)))))
|
||||
|
||||
;;; Commands for Dired Buffers
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-dired-stage ()
|
||||
"In Dired, staged all marked files or the file at point."
|
||||
(interactive)
|
||||
(magit-stage-files (dired-get-marked-files)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-dired-unstage ()
|
||||
"In Dired, unstaged all marked files or the file at point."
|
||||
(interactive)
|
||||
(magit-unstage-files (dired-get-marked-files)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-dired-log (&optional follow)
|
||||
"In Dired, show log for all marked files or the directory if none are marked."
|
||||
(interactive "P")
|
||||
(if-let ((topdir (magit-toplevel default-directory)))
|
||||
(let ((args (car (magit-log-arguments)))
|
||||
(files (or (dired-get-marked-files nil 'marked)
|
||||
(list default-directory))))
|
||||
(when (and follow
|
||||
(not (member "--follow" args))
|
||||
(not (cdr files)))
|
||||
(push "--follow" args))
|
||||
(magit-log-setup-buffer
|
||||
(list (or (magit-get-current-branch) "HEAD"))
|
||||
args
|
||||
(let ((default-directory topdir))
|
||||
(mapcar #'file-relative-name files))
|
||||
magit-log-buffer-file-locked))
|
||||
(magit--not-inside-repository-error)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-dired-am-apply-patches (repo &optional arg)
|
||||
"In Dired, apply the marked (or next ARG) files as patches.
|
||||
If inside a repository, then apply in that. Otherwise prompt
|
||||
for a repository."
|
||||
(interactive (list (or (magit-toplevel)
|
||||
(magit-read-repository t))
|
||||
current-prefix-arg))
|
||||
(let ((files (dired-get-marked-files nil arg nil nil t)))
|
||||
(magit-status-setup-buffer repo)
|
||||
(magit-am-apply-patches files)))
|
||||
|
||||
;;; Miscellaneous Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-do-async-shell-command (file)
|
||||
"Open FILE with `dired-do-async-shell-command'.
|
||||
Interactively, open the file at point."
|
||||
(interactive (list (or (magit-file-at-point)
|
||||
(magit-read-file "Act on file"))))
|
||||
(require 'dired-aux)
|
||||
(dired-do-async-shell-command
|
||||
(dired-read-shell-command "& on %s: " current-prefix-arg (list file))
|
||||
nil (list file)))
|
||||
|
||||
;;; _
|
||||
(provide 'magit-dired)
|
||||
;;; magit-dired.el ends here
|
||||
@@ -224,8 +224,7 @@ and alternative commands."
|
||||
(let* ((dir (magit-gitdir))
|
||||
(revA (or (magit-name-branch "HEAD")
|
||||
(magit-commit-p "HEAD")))
|
||||
(revB (cl-find-if (lambda (head)
|
||||
(file-exists-p (expand-file-name head dir)))
|
||||
(revB (cl-find-if (##file-exists-p (expand-file-name % dir))
|
||||
'("MERGE_HEAD" "CHERRY_PICK_HEAD" "REVERT_HEAD")))
|
||||
(revB (or (magit-name-branch revB)
|
||||
(magit-commit-p revB)))
|
||||
@@ -266,7 +265,7 @@ and alternative commands."
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(unless (re-search-forward "^<<<<<<< " nil t)
|
||||
(magit-stage-file file))))))))
|
||||
(magit-stage-files (list file)))))))))
|
||||
(if fileC
|
||||
(magit-ediff-buffers
|
||||
((magit-get-revision-buffer revA fileA)
|
||||
|
||||
@@ -28,14 +28,10 @@
|
||||
|
||||
(require 'magit)
|
||||
|
||||
;; For `magit-do-async-shell-command'.
|
||||
(declare-function dired-read-shell-command "dired-aux" (prompt arg files))
|
||||
;; For `magit-project-status'.
|
||||
(declare-function vc-git-command "vc-git"
|
||||
(buffer okstatus file-or-list &rest flags))
|
||||
|
||||
(defvar ido-exit)
|
||||
(defvar ido-fallback)
|
||||
(defvar project-prefix-map)
|
||||
(defvar project-switch-commands)
|
||||
|
||||
@@ -193,19 +189,6 @@ blame to center around the line point is on."
|
||||
|
||||
;;; Emacs Tools
|
||||
|
||||
;;;###autoload
|
||||
(defun ido-enter-magit-status ()
|
||||
"Drop into `magit-status' from file switching.
|
||||
|
||||
To make this command available use something like:
|
||||
|
||||
(keymap-set ido-common-completion-map
|
||||
\"C-x g\" \\='ido-enter-magit-status)"
|
||||
(interactive)
|
||||
(setq ido-exit 'fallback)
|
||||
(setq ido-fallback #'magit-status)
|
||||
(exit-minibuffer))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-project-status ()
|
||||
"Run `magit-status' in the current project's root."
|
||||
@@ -232,62 +215,6 @@ to nil before loading Magit to prevent \"m\" from being bound.")
|
||||
(keymap-set project-prefix-map "m" #'magit-project-status)
|
||||
(add-to-list 'project-switch-commands '(magit-project-status "Magit") t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-dired-jump (&optional other-window)
|
||||
"Visit file at point using Dired.
|
||||
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)))
|
||||
(expand-file-name (if (file-directory-p file)
|
||||
(file-name-as-directory file)
|
||||
file)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-dired-log (&optional follow)
|
||||
"Show log for all marked files, or the current file."
|
||||
(interactive "P")
|
||||
(if-let ((topdir (magit-toplevel default-directory)))
|
||||
(let ((args (car (magit-log-arguments)))
|
||||
(files (dired-get-marked-files nil nil #'magit-file-tracked-p)))
|
||||
(unless files
|
||||
(user-error "No marked file is being tracked by Git"))
|
||||
(when (and follow
|
||||
(not (member "--follow" args))
|
||||
(not (cdr files)))
|
||||
(push "--follow" args))
|
||||
(magit-log-setup-buffer
|
||||
(list (or (magit-get-current-branch) "HEAD"))
|
||||
args
|
||||
(let ((default-directory topdir))
|
||||
(mapcar #'file-relative-name files))
|
||||
magit-log-buffer-file-locked))
|
||||
(magit--not-inside-repository-error)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-dired-am-apply-patches (repo &optional arg)
|
||||
"In Dired, apply the marked (or next ARG) files as patches.
|
||||
If inside a repository, then apply in that. Otherwise prompt
|
||||
for a repository."
|
||||
(interactive (list (or (magit-toplevel)
|
||||
(magit-read-repository t))
|
||||
current-prefix-arg))
|
||||
(let ((files (dired-get-marked-files nil arg nil nil t)))
|
||||
(magit-status-setup-buffer repo)
|
||||
(magit-am-apply-patches files)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-do-async-shell-command (file)
|
||||
"Open FILE with `dired-do-async-shell-command'.
|
||||
Interactively, open the file at point."
|
||||
(interactive (list (or (magit-file-at-point)
|
||||
(magit-read-file "Act on file"))))
|
||||
(require 'dired-aux)
|
||||
(dired-do-async-shell-command
|
||||
(dired-read-shell-command "& on %s: " current-prefix-arg (list file))
|
||||
nil (list file)))
|
||||
|
||||
;;; Shift Selection
|
||||
|
||||
(defun magit--turn-on-shift-select-mode-p ()
|
||||
|
||||
@@ -99,8 +99,8 @@ Otherwise if a remote named \"origin\" exists, then use that.
|
||||
If no remote can be determined, then this command is not available
|
||||
from the `magit-fetch' transient prefix and invoking it directly
|
||||
results in an error."
|
||||
:if (lambda () (magit-get-current-remote t))
|
||||
:description (lambda () (magit-get-current-remote t))
|
||||
:if (##magit-get-current-remote t)
|
||||
:description (##magit-get-current-remote t)
|
||||
(interactive (list (magit-get-current-remote t)
|
||||
(magit-fetch-arguments)))
|
||||
(unless remote
|
||||
|
||||
@@ -300,8 +300,10 @@ to `magit-dispatch'."
|
||||
:info-manual "(magit) Minor Mode for Buffers Visiting Files"
|
||||
[:if magit-file-relative-name
|
||||
["File actions"
|
||||
(" s" "Stage" magit-stage-buffer-file)
|
||||
(" u" "Unstage" magit-unstage-buffer-file)
|
||||
(" s" "Stage" magit-file-stage :if-not-derived dired-mode)
|
||||
(" s" "Stage" magit-dired-stage :if-derived dired-mode)
|
||||
(" u" "Unstage" magit-file-unstage :if-not-derived dired-mode)
|
||||
(" u" "Unstage" magit-dired-unstage :if-derived dired-mode)
|
||||
(", x" "Untrack" magit-file-untrack)
|
||||
(", r" "Rename" magit-file-rename)
|
||||
(", k" "Delete" magit-file-delete)
|
||||
@@ -311,9 +313,10 @@ to `magit-dispatch'."
|
||||
("d" "Diff" magit-diff-buffer-file)]
|
||||
[""
|
||||
("L" "Log..." magit-log)
|
||||
("l" "Log" magit-log-buffer-file)
|
||||
("l" "Log" magit-log-buffer-file :if-not-derived dired-mode)
|
||||
("l" "Log" magit-dired-log :if-derived dired-mode)
|
||||
("t" "Trace" magit-log-trace-definition)
|
||||
(7 "M" "Merged" magit-log-merged)]
|
||||
("M" "Merged" magit-log-merged :level 7)]
|
||||
[""
|
||||
("B" "Blame..." magit-blame)
|
||||
("b" "Blame" magit-blame-addition)
|
||||
@@ -333,8 +336,8 @@ to `magit-dispatch'."
|
||||
("e" "Edit line" magit-edit-line-commit)]]
|
||||
[:if-not magit-file-relative-name
|
||||
["File actions"
|
||||
("s" "Stage" magit-stage-file)
|
||||
("u" "Unstage" magit-unstage-file)
|
||||
("s" "Stage" magit-stage-files)
|
||||
("u" "Unstage" magit-unstage-files)
|
||||
("x" "Untrack" magit-file-untrack)
|
||||
("r" "Rename" magit-file-rename)
|
||||
("k" "Delete" magit-file-delete)
|
||||
@@ -419,6 +422,44 @@ the same location in the respective file in the working tree."
|
||||
|
||||
;;; File Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-file-stage ()
|
||||
"Stage all changes to the file being visited in the current buffer."
|
||||
(interactive)
|
||||
(unless buffer-file-name
|
||||
(user-error "Not visiting a file"))
|
||||
(magit-with-toplevel
|
||||
(magit-stage-1 (and (magit-file-ignored-p buffer-file-name)
|
||||
(if (y-or-n-p "Visited file is ignored; stage anyway?")
|
||||
"--force"
|
||||
(user-error "Abort")))
|
||||
(list (magit-file-relative-name)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-file-unstage ()
|
||||
"Unstage all changes to the file being visited in the current buffer."
|
||||
(interactive)
|
||||
(unless buffer-file-name
|
||||
(user-error "Not visiting a file"))
|
||||
(magit-with-toplevel
|
||||
(magit-unstage-1 (list (magit-file-relative-name)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-file-untrack (files &optional force)
|
||||
"Untrack the selected FILES or one file read in the minibuffer.
|
||||
|
||||
With a prefix argument FORCE do so even when the files have
|
||||
staged as well as unstaged changes."
|
||||
(interactive (list (or (if-let ((files (magit-region-values 'file t)))
|
||||
(if (magit-file-tracked-p (car files))
|
||||
(magit-confirm-files 'untrack files "Untrack")
|
||||
(user-error "Already untracked"))
|
||||
(list (magit-read-tracked-file "Untrack file"))))
|
||||
current-prefix-arg))
|
||||
(magit-with-toplevel
|
||||
(magit-run-git "rm" "--cached" (and force "--force") "--" files)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-file-rename (file newname)
|
||||
"Rename or move FILE to NEWNAME.
|
||||
NEWNAME may be a file or directory name. If FILE isn't tracked in
|
||||
@@ -455,20 +496,7 @@ Git, fallback to using `rename-file'."
|
||||
(vc-find-file-hook))))))
|
||||
(magit-refresh))
|
||||
|
||||
(defun magit-file-untrack (files &optional force)
|
||||
"Untrack the selected FILES or one file read in the minibuffer.
|
||||
|
||||
With a prefix argument FORCE do so even when the files have
|
||||
staged as well as unstaged changes."
|
||||
(interactive (list (or (if-let ((files (magit-region-values 'file t)))
|
||||
(if (magit-file-tracked-p (car files))
|
||||
(magit-confirm-files 'untrack files "Untrack")
|
||||
(user-error "Already untracked"))
|
||||
(list (magit-read-tracked-file "Untrack file"))))
|
||||
current-prefix-arg))
|
||||
(magit-with-toplevel
|
||||
(magit-run-git "rm" "--cached" (and force "--force") "--" files)))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-file-delete (files &optional force)
|
||||
"Delete the selected FILES or one file read in the minibuffer.
|
||||
|
||||
@@ -556,5 +584,12 @@ If DEFAULT is non-nil, use this as the default value instead of
|
||||
(concat "No file changed in " rev-or-range)))
|
||||
|
||||
;;; _
|
||||
|
||||
(define-obsolete-function-alias 'magit-stage-buffer-file
|
||||
'magit-file-stage "Magit 4.3.2")
|
||||
|
||||
(define-obsolete-function-alias 'magit-unstage-buffer-file
|
||||
'magit-file-unstage "Magit 4.3.2")
|
||||
|
||||
(provide 'magit-files)
|
||||
;;; magit-files.el ends here
|
||||
|
||||
@@ -150,6 +150,7 @@ option."
|
||||
"-c" "log.showSignature=false"
|
||||
"-c" "color.ui=false"
|
||||
"-c" "color.diff=false"
|
||||
"-c" "diff.noPrefix=false"
|
||||
,@(and (eq system-type 'windows-nt)
|
||||
(list "-c" "i18n.logOutputEncoding=UTF-8")))
|
||||
"Global Git arguments.
|
||||
@@ -165,7 +166,7 @@ anything that is part of the default value, unless you really
|
||||
know what you are doing. And think very hard before adding
|
||||
something; it will be used every time Magit runs Git for any
|
||||
purpose."
|
||||
:package-version '(magit . "2.9.0")
|
||||
:package-version '(magit . "4.3.2")
|
||||
:group 'magit-commands
|
||||
:group 'magit-process
|
||||
:type '(repeat string))
|
||||
@@ -225,7 +226,16 @@ framework ultimately determines how the collection is displayed."
|
||||
|
||||
;;; Git
|
||||
|
||||
(defvar magit-git-debug nil)
|
||||
(defvar magit-git-debug nil
|
||||
"Whether and how to enable additional debugging of git errors.
|
||||
|
||||
Use `magit-toggle-git-debug' (which see) to toggle the boolean value of
|
||||
this variable. This can also manually be set to `include-success', in
|
||||
which case successful git invocations are also logged.
|
||||
|
||||
This can also be a function, which takes one argument, the error output
|
||||
as a string. This is intended for internal use and is established using
|
||||
let-bindings around critical code (i.e., in `magit--assert-usable-git').")
|
||||
|
||||
(defun magit-toggle-git-debug ()
|
||||
"Toggle whether additional git errors are reported.
|
||||
@@ -234,7 +244,8 @@ Magit basically calls git for one of these two reasons: for
|
||||
side-effects or to do something with its standard output.
|
||||
|
||||
When git is run for side-effects then its output, including error
|
||||
messages, go into the process buffer which is shown when using ~$~.
|
||||
messages, go into the process buffer which is shown when using \
|
||||
\\<magit-mode-map>\\[magit-process-buffer].
|
||||
|
||||
When git's output is consumed in some way, then it would be too
|
||||
expensive to also insert it into this buffer, but with this command
|
||||
@@ -452,7 +463,7 @@ a boolean, then raise an error."
|
||||
|
||||
(defun magit-git-insert (&rest args)
|
||||
"Execute Git with ARGS, insert stdout at point and return exit code.
|
||||
If `magit-git-debug' in non-nil and the exit code is non-zero, then
|
||||
If `magit-git-debug' is non-nil and the exit code is non-zero, then
|
||||
insert the run command and stderr into the process buffer."
|
||||
(apply #'magit--git-insert nil args))
|
||||
|
||||
@@ -465,7 +476,7 @@ insert the run command and stderr into the process buffer."
|
||||
(setq log (make-temp-file "magit-stderr"))
|
||||
(delete-file log)
|
||||
(setq exit (magit-process-git (list t log) args))
|
||||
(when (or (> exit 0) (eq magit-git-debug 'all))
|
||||
(when (or (> exit 0) (eq magit-git-debug 'include-success))
|
||||
(when (file-exists-p log)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents log)
|
||||
@@ -473,7 +484,8 @@ insert the run command and stderr into the process buffer."
|
||||
(setq errmsg
|
||||
(cond
|
||||
((eq return-error 'full)
|
||||
(buffer-string))
|
||||
(let ((str (buffer-string)))
|
||||
(and (not (equal str "")) str)))
|
||||
((functionp magit-git-debug)
|
||||
(funcall magit-git-debug (buffer-string)))
|
||||
((magit--locate-error-message)))))
|
||||
@@ -497,7 +509,7 @@ insert the run command and stderr into the process buffer."
|
||||
(defun magit--locate-error-message ()
|
||||
(goto-char (point-max))
|
||||
(and (run-hook-wrapped 'magit-process-error-message-regexps
|
||||
(lambda (re) (re-search-backward re nil t)))
|
||||
(##re-search-backward % nil t))
|
||||
(match-string-no-properties 1)))
|
||||
|
||||
(defun magit-git-string (&rest args)
|
||||
@@ -516,8 +528,8 @@ newline, return an empty string."
|
||||
"Execute Git with ARGS, returning its output as a list of lines.
|
||||
Empty lines anywhere in the output are omitted.
|
||||
|
||||
If Git exits with a non-zero exit status, then report show a
|
||||
message and add a section in the respective process buffer."
|
||||
If Git exits with a non-zero exit status, show a message and add
|
||||
a section in the respective process buffer."
|
||||
(magit--with-temp-process-buffer
|
||||
(apply #'magit-git-insert args)
|
||||
(split-string (buffer-string) "\n" t)))
|
||||
@@ -526,24 +538,32 @@ message and add a section in the respective process buffer."
|
||||
"Execute Git with ARGS, returning its null-separated output as a list.
|
||||
Empty items anywhere in the output are omitted.
|
||||
|
||||
If Git exits with a non-zero exit status, then report show a
|
||||
message and add a section in the respective process buffer."
|
||||
If Git exits with a non-zero exit status, show a message and add
|
||||
a section in the respective process buffer."
|
||||
(magit--with-temp-process-buffer
|
||||
(apply #'magit-git-insert args)
|
||||
(split-string (buffer-string) "\0" t)))
|
||||
|
||||
(defvar magit--git-wash-keep-error t)
|
||||
|
||||
(defun magit-git-wash (washer &rest args)
|
||||
"Execute Git with ARGS, inserting washed output at point.
|
||||
Actually first insert the raw output at point. If there is no
|
||||
output, call `magit-cancel-section'. Otherwise temporarily narrow
|
||||
the buffer to the inserted text, move to its beginning, and then
|
||||
call function WASHER with ARGS as its sole argument."
|
||||
"Execute git with ARGS, inserting washed output at point.
|
||||
|
||||
First insert the raw output at point. If there is no output, call
|
||||
`magit-cancel-section'. Otherwise temporarily narrow the buffer to
|
||||
the inserted text, move to its beginning, and finally call function
|
||||
WASHER with ARGS as its sole argument.
|
||||
|
||||
If git exits with a non-zero exit status, apply the `error' face to
|
||||
the error message, instead of calling WASHER. To instead cancel the
|
||||
section use `magit--git-wash'."
|
||||
(declare (indent 1))
|
||||
(apply #'magit--git-wash washer magit--git-wash-keep-error args))
|
||||
(apply #'magit--git-wash washer t args))
|
||||
|
||||
(defun magit--git-wash (washer keep-error &rest args)
|
||||
"Execute git with ARGS, inserting washed output at point.
|
||||
|
||||
Like `magit-git-wash' but if KEEP-ERROR is nil and an error occurs, also
|
||||
insert standard error. If KEEP-ERROR is `wash-anyway', insert and wash
|
||||
standard output even in case of an error."
|
||||
(declare (indent 2))
|
||||
(setq args (flatten-tree args))
|
||||
(let ((beg (point))
|
||||
@@ -678,7 +698,7 @@ values of `magit-remote-git-executable' and `exec-path'.\n"))
|
||||
Also include information about `magit-remote-git-executable'.
|
||||
See info node `(magit)Debugging Tools' for more information."
|
||||
(interactive)
|
||||
(with-current-buffer (get-buffer-create "*magit-git-debug*")
|
||||
(with-current-buffer (get-buffer-create "*magit-git-executable*")
|
||||
(pop-to-buffer (current-buffer))
|
||||
(erase-buffer)
|
||||
(insert (format "magit-remote-git-executable: %S\n"
|
||||
@@ -794,7 +814,7 @@ Also see `magit-git-config-p'."
|
||||
|
||||
(defun magit-git-dir (&optional path)
|
||||
"Like (expand-file-name PATH (magit-gitdir)) or just (magit-gitdir)."
|
||||
(declare (obsolete 'magit-gitdir "Magit 4.0.0"))
|
||||
(declare (obsolete magit-gitdir "Magit 4.0.0"))
|
||||
(and-let* ((dir (magit-gitdir)))
|
||||
(if path
|
||||
(expand-file-name (convert-standard-filename path) dir)
|
||||
@@ -1181,7 +1201,7 @@ Sorted from longest to shortest CYGWIN name."
|
||||
(setq filename (expand-file-name filename)))
|
||||
(if-let ((cyg:win (and (not (file-remote-p default-directory)) ; see #4976
|
||||
(cl-assoc filename magit-cygwin-mount-points
|
||||
:test (lambda (f cyg) (string-prefix-p cyg f))))))
|
||||
:test (##string-prefix-p %2 %1)))))
|
||||
(concat (cdr cyg:win)
|
||||
(substring filename (length (car cyg:win))))
|
||||
filename))
|
||||
@@ -1195,7 +1215,7 @@ Sorted from longest to shortest CYGWIN name."
|
||||
3. Deal with an `windows-nt' Emacs vs. Cygwin Git incompatibility."
|
||||
(if (file-name-absolute-p filename)
|
||||
(if-let ((cyg:win (cl-rassoc filename magit-cygwin-mount-points
|
||||
:test (lambda (f win) (string-prefix-p win f)))))
|
||||
:test (##string-prefix-p %2 %1))))
|
||||
(concat (car cyg:win)
|
||||
(substring filename (length (cdr cyg:win))))
|
||||
(let ((expanded (expand-file-name filename)))
|
||||
@@ -1285,8 +1305,7 @@ are considered."
|
||||
(not (magit-module-worktree-p module)))
|
||||
|
||||
(defun magit-ignore-submodules-p (&optional return-argument)
|
||||
(or (cl-find-if (lambda (arg)
|
||||
(string-prefix-p "--ignore-submodules" arg))
|
||||
(or (cl-find-if (##string-prefix-p "--ignore-submodules" %)
|
||||
magit-buffer-diff-args)
|
||||
(and-let* ((value (magit-get "diff.ignoreSubmodules")))
|
||||
(if return-argument
|
||||
@@ -1508,6 +1527,7 @@ to, or to some other symbolic-ref that points to the same ref."
|
||||
(pullreq (and (fboundp 'forge--pullreq-branch)
|
||||
(magit-branch-p
|
||||
(forge--pullreq-branch (oref it value)))))
|
||||
(related-refs (magit--painted-branch-at-point))
|
||||
((unpulled unpushed)
|
||||
(magit-ref-abbrev
|
||||
(replace-regexp-in-string "\\.\\.\\.?" "" (oref it value))))))
|
||||
@@ -1629,7 +1649,7 @@ The amount of time spent searching is limited by
|
||||
(defun magit--set-default-branch (newname oldname)
|
||||
(let ((remote (or (magit-primary-remote)
|
||||
(user-error "Cannot determine primary remote")))
|
||||
(branches (mapcar (lambda (line) (split-string line "\t"))
|
||||
(branches (mapcar (##split-string % "\t")
|
||||
(magit-git-lines
|
||||
"for-each-ref" "refs/heads"
|
||||
"--format=%(refname:short)\t%(upstream:short)"))))
|
||||
@@ -1697,6 +1717,11 @@ according to the branch type."
|
||||
'magit-branch-local
|
||||
'magit-branch-remote)))))
|
||||
|
||||
(defun magit-get-local-upstream-branch (&optional branch)
|
||||
(and-let* ((upstream (magit-get-upstream-branch branch))
|
||||
(upstream (cdr (magit-split-branch-name upstream))))
|
||||
(and (magit-branch-p upstream) upstream)))
|
||||
|
||||
(defun magit-get-indirect-upstream-branch (branch &optional force)
|
||||
(let ((remote (magit-get "branch" branch "remote")))
|
||||
(and remote (not (equal remote "."))
|
||||
@@ -1807,8 +1832,7 @@ exists, then remotes in `magit-primary-remote-names' are tried in
|
||||
order and the first remote from that list that actually exists in
|
||||
the current repository is considered its primary remote."
|
||||
(let ((remotes (magit-list-remotes)))
|
||||
(seq-find (lambda (name)
|
||||
(member name remotes))
|
||||
(seq-find (##member % remotes)
|
||||
(delete-dups
|
||||
(delq nil
|
||||
(cons (magit-get "magit.primaryRemote")
|
||||
@@ -1982,8 +2006,7 @@ SORTBY is a key or list of keys to pass to the `--sort' flag of
|
||||
|
||||
(defun magit-list-special-refnames ()
|
||||
(let ((gitdir (magit-gitdir)))
|
||||
(cl-remove-if-not (lambda (name)
|
||||
(file-exists-p (expand-file-name name gitdir)))
|
||||
(cl-remove-if-not (##file-exists-p (expand-file-name % gitdir))
|
||||
magit-special-refnames)))
|
||||
|
||||
(defun magit-list-branch-names ()
|
||||
@@ -2043,9 +2066,8 @@ SORTBY is a key or list of keys to pass to the `--sort' flag of
|
||||
|
||||
(defun magit-remote-head (remote)
|
||||
(and-let* ((line (cl-find-if
|
||||
(lambda (line)
|
||||
(string-match
|
||||
"\\`ref: refs/heads/\\([^\s\t]+\\)[\s\t]HEAD\\'" line))
|
||||
(##string-match
|
||||
"\\`ref: refs/heads/\\([^\s\t]+\\)[\s\t]HEAD\\'" %)
|
||||
(magit-git-lines "ls-remote" "--symref" remote "HEAD"))))
|
||||
(match-string 1 line)))
|
||||
|
||||
@@ -2182,8 +2204,7 @@ exists, then the branch names in `magit-main-branch-names' are
|
||||
tried in order. The first branch from that list that actually
|
||||
exists in the current repository is considered its main branch."
|
||||
(let ((branches (magit-list-local-branch-names)))
|
||||
(seq-find (lambda (name)
|
||||
(member name branches))
|
||||
(seq-find (##member % branches)
|
||||
(delete-dups
|
||||
(delq nil
|
||||
(cons (magit-get "init.defaultBranch")
|
||||
|
||||
@@ -42,10 +42,9 @@
|
||||
("p" "privately (.git/info/exclude)"
|
||||
magit-gitignore-in-gitdir)
|
||||
("g" magit-gitignore-on-system
|
||||
:if (lambda () (magit-get "core.excludesfile"))
|
||||
:description (lambda ()
|
||||
(format "privately for all repositories (%s)"
|
||||
(magit-get "core.excludesfile"))))]
|
||||
:if (##magit-get "core.excludesfile")
|
||||
:description (##format "privately for all repositories (%s)"
|
||||
(magit-get "core.excludesfile")))]
|
||||
["Skip worktree"
|
||||
(7 "w" "do skip worktree" magit-skip-worktree)
|
||||
(7 "W" "do not skip worktree" magit-no-skip-worktree)]
|
||||
|
||||
@@ -31,6 +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-cherry-apply "magit-sequence" (commit &optional args))
|
||||
(declare-function magit-insert-head-branch-header "magit-status"
|
||||
@@ -77,7 +78,7 @@
|
||||
:group 'magit-log
|
||||
:type 'hook)
|
||||
|
||||
(defcustom magit-log-remove-graph-args '("--follow" "--grep" "-G" "-S" "-L")
|
||||
(defcustom magit-log-remove-graph-args '("--follow" "-G" "-S" "-L")
|
||||
"The log arguments that cause the `--graph' argument to be dropped.
|
||||
|
||||
The default value lists the arguments that are incompatible with
|
||||
@@ -86,10 +87,10 @@ can add additional arguments that are available in `magit-log',
|
||||
but I recommend that you don't do that. Nowadays I would define
|
||||
this as a constant, but I am preserving it as an option, in case
|
||||
someone actually customized it."
|
||||
:package-version '(magit . "2.3.0")
|
||||
:package-version '(magit . "4.3.7")
|
||||
:group 'magit-log
|
||||
:type '(repeat (string :tag "Argument"))
|
||||
:options '("--follow" "--grep" "-G" "-S" "-L"))
|
||||
:options '("--follow" "-G" "-S" "-L"))
|
||||
|
||||
(defcustom magit-log-revision-headers-format "\
|
||||
%+b%+N
|
||||
@@ -173,9 +174,9 @@ want to use the same functions for both hooks."
|
||||
"Function used to generate text shown in header line of log buffers."
|
||||
:package-version '(magit . "2.12.0")
|
||||
:group 'magit-log
|
||||
:type `(choice (function-item ,#'magit-log-header-line-arguments)
|
||||
(function-item ,#'magit-log-header-line-sentence)
|
||||
function))
|
||||
:type `(radio (function-item ,#'magit-log-header-line-arguments)
|
||||
(function-item ,#'magit-log-header-line-sentence)
|
||||
function))
|
||||
|
||||
(defcustom magit-log-trace-definition-function #'magit-which-function
|
||||
"Function used to determine the function at point.
|
||||
@@ -184,10 +185,10 @@ You should prefer `magit-which-function' over `which-function'
|
||||
because the latter may make use of Imenu's outdated cache."
|
||||
:package-version '(magit . "3.0.0")
|
||||
:group 'magit-log
|
||||
:type `(choice (function-item ,#'magit-which-function)
|
||||
(function-item ,#'which-function)
|
||||
(function-item ,#'add-log-current-defun)
|
||||
function))
|
||||
:type `(radio (function-item ,#'magit-which-function)
|
||||
(function-item ,#'which-function)
|
||||
(function-item ,#'add-log-current-defun)
|
||||
function))
|
||||
|
||||
(defcustom magit-log-color-graph-limit 256
|
||||
"Number of commits over which log graphs are not colored.
|
||||
@@ -442,89 +443,92 @@ commits before and half after."
|
||||
;;; Commands
|
||||
;;;; Prefix Commands
|
||||
|
||||
(eval-and-compile
|
||||
(defvar magit-log-infix-arguments
|
||||
;; The grouping in git-log(1) appears to be guided by implementation
|
||||
;; details, so our logical grouping only follows it to an extend.
|
||||
;; Arguments that are "misplaced" here:
|
||||
;; 1. From "Commit Formatting".
|
||||
;; 2. From "Common Diff Options".
|
||||
;; 3. From unnamed first group.
|
||||
;; 4. Implemented by Magit.
|
||||
[:class transient-subgroups
|
||||
["Commit limiting"
|
||||
(magit-log:-n)
|
||||
(magit:--author)
|
||||
(7 magit-log:--since)
|
||||
(7 magit-log:--until)
|
||||
(magit-log:--grep)
|
||||
(7 "-i" "Search case-insensitive" ("-i" "--regexp-ignore-case"))
|
||||
(7 "-I" "Invert search pattern" "--invert-grep")
|
||||
(magit-log:-G) ;2
|
||||
(magit-log:-S) ;2
|
||||
(magit-log:-L) ;2
|
||||
(7 "=m" "Omit merges" "--no-merges")
|
||||
(7 "=p" "First parent" "--first-parent")]
|
||||
["History simplification"
|
||||
( "-D" "Simplify by decoration" "--simplify-by-decoration")
|
||||
(magit:--)
|
||||
( "-f" "Follow renames when showing single-file log" "--follow") ;3
|
||||
(6 "/s" "Only commits changing given paths" "--sparse")
|
||||
(7 "/d" "Only selected commits plus meaningful history" "--dense")
|
||||
(7 "/a" "Only commits existing directly on ancestry path" "--ancestry-path")
|
||||
(6 "/f" "Do not prune history" "--full-history")
|
||||
(7 "/m" "Prune some history" "--simplify-merges")]
|
||||
["Commit ordering"
|
||||
(magit-log:--*-order)
|
||||
("-r" "Reverse order" "--reverse")]
|
||||
["Formatting"
|
||||
("-g" "Show graph" "--graph") ;1
|
||||
("-c" "Show graph in color" "--color") ;2
|
||||
("-d" "Show refnames" "--decorate") ;3
|
||||
("=S" "Show signatures" "--show-signature") ;1
|
||||
("-h" "Show header" "++header") ;4
|
||||
("-p" "Show diffs" ("-p" "--patch")) ;2
|
||||
("-s" "Show diffstats" "--stat")] ;2
|
||||
]))
|
||||
(transient-define-group magit-log-infix-arguments
|
||||
;; The grouping in git-log(1) appears to be guided by implementation
|
||||
;; details, so our logical grouping only follows it to an extend.
|
||||
;; Arguments that are "misplaced" here:
|
||||
;; 1. From "Commit Formatting".
|
||||
;; 2. From "Common Diff Options".
|
||||
;; 3. From unnamed first group.
|
||||
;; 4. Implemented by Magit.
|
||||
["Commit limiting"
|
||||
:if magit-log-infix-arguments--show-p
|
||||
(magit-log:-n)
|
||||
(magit:--author)
|
||||
(7 magit-log:--since)
|
||||
(7 magit-log:--until)
|
||||
(magit-log:--grep)
|
||||
(7 "-i" "Search case-insensitive" ("-i" "--regexp-ignore-case"))
|
||||
(7 "-I" "Invert search pattern" "--invert-grep")
|
||||
(magit-log:-G) ;2
|
||||
(magit-log:-S) ;2
|
||||
(magit-log:-L) ;2
|
||||
(7 "=m" "Omit merges" "--no-merges")
|
||||
(7 "=p" "First parent" "--first-parent")]
|
||||
["History simplification"
|
||||
:if magit-log-infix-arguments--show-p
|
||||
( "-D" "Simplify by decoration" "--simplify-by-decoration")
|
||||
(magit:--)
|
||||
( "-f" "Follow renames when showing single-file log" "--follow") ;3
|
||||
(6 "/s" "Only commits changing given paths" "--sparse")
|
||||
(7 "/d" "Only selected commits plus meaningful history" "--dense")
|
||||
(7 "/a" "Only commits existing directly on ancestry path" "--ancestry-path")
|
||||
(6 "/f" "Do not prune history" "--full-history")
|
||||
(7 "/m" "Prune some history" "--simplify-merges")]
|
||||
["Commit ordering"
|
||||
:if magit-log-infix-arguments--show-p
|
||||
(magit-log:--*-order)
|
||||
("-r" "Reverse order" "--reverse")]
|
||||
["Formatting"
|
||||
:if magit-log-infix-arguments--show-p
|
||||
("-g" "Show graph" "--graph") ;1
|
||||
("-c" "Show graph in color" "--color") ;2
|
||||
("-d" "Show refnames" "--decorate") ;3
|
||||
("=S" "Show signatures" "--show-signature") ;1
|
||||
("-h" "Show header" "++header") ;4
|
||||
("-p" "Show diffs" ("-p" "--patch")) ;2
|
||||
("-s" "Show diffstats" "--stat")]) ;2
|
||||
|
||||
(defun magit-log-infix-arguments--show-p ()
|
||||
(if (eq (oref (transient-prefix-object) command) 'magit-log-refresh)
|
||||
(eq major-mode 'magit-log-mode)
|
||||
t))
|
||||
|
||||
;;;###autoload (autoload 'magit-log "magit-log" nil t)
|
||||
(transient-define-prefix magit-log ()
|
||||
"Show a commit or reference log."
|
||||
:man-page "git-log"
|
||||
:class 'magit-log-prefix
|
||||
[magit-log-infix-arguments]
|
||||
'magit-log-infix-arguments
|
||||
[["Log"
|
||||
("l" "current" magit-log-current)
|
||||
("h" "HEAD" magit-log-head)
|
||||
("u" "related" magit-log-related)
|
||||
("o" "other" magit-log-other)]
|
||||
("l" magit-log-current)
|
||||
("o" "other" magit-log-other)
|
||||
("h" "HEAD" magit-log-head :level 0)
|
||||
("u" "related" magit-log-related)]
|
||||
[""
|
||||
("L" "local branches" magit-log-branches)
|
||||
("b" "all branches" magit-log-all-branches)
|
||||
("a" "all references" magit-log-all)
|
||||
(7 "B" "matching branches" magit-log-matching-branches)
|
||||
(7 "T" "matching tags" magit-log-matching-tags)
|
||||
(7 "m" "merged" magit-log-merged)]
|
||||
("L" "local branches" magit-log-branches)
|
||||
("b" "all branches" magit-log-all-branches)
|
||||
("a" "all references" magit-log-all)
|
||||
("B" "matching branches" magit-log-matching-branches :level 7)
|
||||
("T" "matching tags" magit-log-matching-tags :level 7)
|
||||
("m" "merged" magit-log-merged :level 7)]
|
||||
["Reflog"
|
||||
("r" "current" magit-reflog-current)
|
||||
("H" "HEAD" magit-reflog-head)
|
||||
("O" "other" magit-reflog-other)]
|
||||
[:if (lambda ()
|
||||
(and (fboundp 'magit--any-wip-mode-enabled-p)
|
||||
(magit--any-wip-mode-enabled-p)))
|
||||
("r" "current" magit-reflog-current)
|
||||
("O" "other" magit-reflog-other)
|
||||
("H" "HEAD" magit-reflog-head)]
|
||||
[:if magit--any-wip-mode-enabled-p
|
||||
:description "Wiplog"
|
||||
("i" "index" magit-wip-log-index)
|
||||
("w" "worktree" magit-wip-log-worktree)]
|
||||
("i" "index" magit-wip-log-index)
|
||||
("w" "worktree" magit-wip-log-worktree)]
|
||||
["Other"
|
||||
(5 "s" "shortlog" magit-shortlog)]])
|
||||
("s" "shortlog" magit-shortlog)]])
|
||||
|
||||
;;;###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"
|
||||
:class 'magit-log-refresh-prefix
|
||||
[:if-mode magit-log-mode
|
||||
magit-log-infix-arguments]
|
||||
magit-log-infix-arguments
|
||||
[:if-not-mode magit-log-mode
|
||||
:description "Arguments"
|
||||
(magit-log:-n)
|
||||
@@ -652,14 +656,13 @@ 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
|
||||
(defun magit-log-current (revs &optional args files)
|
||||
"Show log for the current branch.
|
||||
When `HEAD' is detached or with a prefix argument show log for
|
||||
one or more revs read from the minibuffer."
|
||||
(interactive (cons (magit-log-read-revs t)
|
||||
(magit-log-arguments)))
|
||||
(magit-log-setup-buffer revs args files))
|
||||
;;;###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")
|
||||
(interactive (magit-log-arguments))
|
||||
(magit-log-setup-buffer (list (or (magit-get-current-branch) "HEAD"))
|
||||
args files))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-log-head (&optional args files)
|
||||
@@ -1147,8 +1150,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
(setq revs (if (< (string-to-number count) limit)
|
||||
revs
|
||||
(format "%s~%s..%s" revs limit revs))))
|
||||
(let ((delay (cl-find-if (lambda (arg)
|
||||
(member arg '("++header" "--patch" "--stat")))
|
||||
(let ((delay (cl-find-if (##member % '("++header" "--patch" "--stat"))
|
||||
args)))
|
||||
(setq magit-section-inhibit-markers (if delay 'delay t))
|
||||
(setq magit-section-insert-in-reverse (not delay)))
|
||||
@@ -1181,10 +1183,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
|
||||
(defun magit-log-header-line-arguments (revs args files)
|
||||
"Return string describing some of the used arguments."
|
||||
(mapconcat (lambda (arg)
|
||||
(if (string-search " " arg)
|
||||
(prin1 arg)
|
||||
arg))
|
||||
(mapconcat (##if (string-search " " %) (prin1 %) %)
|
||||
`("git" "log" ,@args ,@revs "--" ,@files)
|
||||
" "))
|
||||
|
||||
@@ -1454,15 +1453,11 @@ Do not add this to a hook variable."
|
||||
(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))))
|
||||
(save-excursion
|
||||
(backward-char)
|
||||
(magit-log-format-margin hash author date)))
|
||||
(magit-log-format-margin hash author date))
|
||||
(when (and (eq style 'cherry)
|
||||
(magit-buffer-margin-p))
|
||||
(save-excursion
|
||||
(backward-char)
|
||||
(apply #'magit-log-format-margin hash
|
||||
(split-string (magit-rev-format "%aN%x00%ct" hash) "\0"))))
|
||||
(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)))
|
||||
@@ -1493,8 +1488,8 @@ Do not add this to a hook variable."
|
||||
(while (and (not (eobp)) (not (looking-at non-graph-re)))
|
||||
(when align
|
||||
(save-excursion (insert align)))
|
||||
(magit-make-margin-overlay)
|
||||
(forward-line))
|
||||
(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.
|
||||
@@ -1535,7 +1530,8 @@ exists mostly for backward compatibility reasons."
|
||||
|
||||
(defun magit-log-maybe-update-revision-buffer (&optional _)
|
||||
"When moving in a log or cherry buffer, update the revision buffer.
|
||||
If there is no revision buffer in the same frame, then do nothing."
|
||||
If there is no revision buffer in the same frame, then do nothing.
|
||||
See also info node `(magit)Section Movement'."
|
||||
(when (derived-mode-p 'magit-log-mode 'magit-cherry-mode 'magit-reflog-mode)
|
||||
(magit--maybe-update-revision-buffer)))
|
||||
|
||||
@@ -1563,7 +1559,8 @@ If there is no revision buffer in the same frame, then do nothing."
|
||||
|
||||
(defun magit-log-maybe-update-blob-buffer (&optional _)
|
||||
"When moving in a log or cherry buffer, update the blob buffer.
|
||||
If there is no blob buffer in the same frame, then do nothing."
|
||||
If there is no blob buffer in the same frame, then do nothing.
|
||||
See also info node `(magit)Section Movement'."
|
||||
(when (derived-mode-p 'magit-log-mode 'magit-cherry-mode 'magit-reflog-mode)
|
||||
(magit--maybe-update-blob-buffer)))
|
||||
|
||||
@@ -1622,7 +1619,7 @@ The shortstat style is experimental and rather slow."
|
||||
(magit-log-format-shortstat-margin rev)
|
||||
(magit-log-format-author-margin author date))))
|
||||
|
||||
(defun magit-log-format-author-margin (author date &optional previous-line)
|
||||
(defun magit-log-format-author-margin (author date)
|
||||
(pcase-let ((`(,_ ,style ,width ,details ,details-width)
|
||||
(or magit-buffer-margin
|
||||
(symbol-value (magit-margin-option))
|
||||
@@ -1647,8 +1644,7 @@ The shortstat style is experimental and rather slow."
|
||||
(format (format (if abbr "%%2d%%-%dc" "%%2d %%-%ds")
|
||||
(- width (if details (1+ details-width) 0)))
|
||||
cnt unit)))
|
||||
'magit-log-date))
|
||||
previous-line)))
|
||||
'magit-log-date)))))
|
||||
|
||||
(defun magit-log-format-shortstat-margin (rev)
|
||||
(magit-make-margin-overlay
|
||||
|
||||
@@ -159,15 +159,16 @@ does not carry to other options."
|
||||
(and (magit-buffer-margin-p)
|
||||
(nth 2 magit-buffer-margin))))))
|
||||
|
||||
(defun magit-make-margin-overlay (&optional string previous-line)
|
||||
(if previous-line
|
||||
(save-excursion
|
||||
(forward-line -1)
|
||||
(magit-make-margin-overlay string))
|
||||
(cl-defun magit-make-margin-overlay (&optional string (previous-line nil sline))
|
||||
"Display STRING in the margin of the previous (or current) line.
|
||||
If point is at the beginning of a line, set the margin string for
|
||||
the previous line, otherwise for the current line. Semi-obsolete
|
||||
optional PREVIOUS-LINE can be used to explicitly specify which
|
||||
line is affected."
|
||||
(save-excursion
|
||||
(forward-line (if (if sline previous-line (bolp)) -1 0))
|
||||
;; Don't put the overlay on the complete line to work around #1880.
|
||||
(let ((o (make-overlay (1+ (line-beginning-position))
|
||||
(line-end-position)
|
||||
nil t)))
|
||||
(let ((o (make-overlay (1+ (point)) (line-end-position) nil t)))
|
||||
(overlay-put o 'evaporate t)
|
||||
(overlay-put o 'before-string
|
||||
(propertize "o" 'display
|
||||
@@ -177,13 +178,14 @@ does not carry to other options."
|
||||
(defvar magit-margin-overlay-conditions
|
||||
'( unpulled unpushed recent stashes local cherries
|
||||
[remote branchbuf]
|
||||
[shelved branchbuf]
|
||||
[tags branchbuf]
|
||||
topics issues pullreqs))
|
||||
|
||||
(defun magit-maybe-make-margin-overlay ()
|
||||
(when (magit-section-match magit-margin-overlay-conditions
|
||||
magit-insert-section--current)
|
||||
(magit-make-margin-overlay nil t)))
|
||||
(magit-make-margin-overlay)))
|
||||
|
||||
;;; Custom Support
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
[("p" "Preview merge" magit-merge-preview)
|
||||
""
|
||||
("s" "Squash merge" magit-merge-squash)
|
||||
("i" "Dissolve" magit-merge-into)]]
|
||||
("d" "Dissolve" magit-merge-dissolve)]]
|
||||
["Actions"
|
||||
:if magit-merge-in-progress-p
|
||||
("m" "Commit merge" magit-commit-create)
|
||||
@@ -129,7 +129,7 @@ inspect the merge and change the commit message.
|
||||
(magit-run-git-async "merge" "--no-commit" args rev))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-merge-into (branch &optional args)
|
||||
(defun magit-merge-dissolve (branch &optional args)
|
||||
"Merge the current branch into BRANCH and remove the former.
|
||||
|
||||
Before merging, force push the source branch to its push-remote,
|
||||
@@ -139,14 +139,11 @@ obsolete version of the commits that are being merged. Finally
|
||||
if `forge-branch-pullreq' was used to create the merged branch,
|
||||
then also remove the respective remote branch."
|
||||
(interactive
|
||||
(list (magit-read-other-local-branch
|
||||
(format "Merge `%s' into"
|
||||
(or (magit-get-current-branch)
|
||||
(magit-rev-parse "HEAD")))
|
||||
nil
|
||||
(and-let* ((upstream (magit-get-upstream-branch))
|
||||
(upstream (cdr (magit-split-branch-name upstream))))
|
||||
(and (magit-branch-p upstream) upstream)))
|
||||
(list (let ((branch (magit-get-current-branch)))
|
||||
(magit-read-other-local-branch
|
||||
(format "Merge `%s' into" (or branch (magit-rev-parse "HEAD")))
|
||||
nil
|
||||
(and branch (magit-get-local-upstream-branch branch))))
|
||||
(magit-merge-arguments)))
|
||||
(let ((current (magit-get-current-branch))
|
||||
(head (magit-rev-parse "HEAD")))
|
||||
@@ -169,7 +166,7 @@ then also remove the respective remote branch."
|
||||
(magit-merge-arguments)))
|
||||
(magit--merge-absorb branch args))
|
||||
|
||||
(defun magit--merge-absorb (branch args)
|
||||
(defun magit--merge-absorb (branch args &optional message)
|
||||
(when (equal branch (magit-main-branch))
|
||||
(unless (yes-or-no-p
|
||||
(format "Do you really want to merge `%s' into another branch? "
|
||||
@@ -186,7 +183,9 @@ then also remove the respective remote branch."
|
||||
(magit-process-sentinel process event)
|
||||
(process-put process 'inhibit-refresh t)
|
||||
(magit-process-sentinel process event)
|
||||
(magit--merge-absorb-1 branch args))))))
|
||||
(magit--merge-absorb-1 branch args))
|
||||
(when message
|
||||
(message message))))))
|
||||
(magit--merge-absorb-1 branch args)))
|
||||
|
||||
(defun magit--merge-absorb-1 (branch args)
|
||||
|
||||
@@ -398,11 +398,11 @@ recommended value."
|
||||
":" 'magit-git-command
|
||||
"r" 'magit-rebase
|
||||
"R" 'magit-file-rename
|
||||
"s" 'magit-stage-file
|
||||
"s" 'magit-stage-files
|
||||
"S" 'magit-stage-modified
|
||||
"t" 'magit-tag
|
||||
"T" 'magit-notes
|
||||
"u" 'magit-unstage-file
|
||||
"u" 'magit-unstage-files
|
||||
"U" 'magit-unstage-all
|
||||
"v" 'magit-revert-no-commit
|
||||
"V" 'magit-revert
|
||||
@@ -570,7 +570,7 @@ Magit is documented in info node `(magit)'."
|
||||
(magit-hack-dir-local-variables)
|
||||
(face-remap-add-relative 'header-line 'magit-header-line)
|
||||
(setq mode-line-process (magit-repository-local-get 'mode-line-process))
|
||||
(setq-local revert-buffer-function #'magit-refresh-buffer)
|
||||
(setq-local revert-buffer-function #'magit-revert-buffer)
|
||||
(setq-local bookmark-make-record-function #'magit--make-bookmark)
|
||||
(setq-local imenu-create-index-function #'magit--imenu-create-index)
|
||||
(setq-local imenu-default-goto-function #'magit--imenu-goto-function)
|
||||
@@ -662,7 +662,7 @@ 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)
|
||||
(magit-refresh-buffer created)
|
||||
(when created
|
||||
(run-hooks 'magit-post-create-buffer-hook)))
|
||||
buffer))
|
||||
@@ -889,17 +889,7 @@ If a frame, then only consider buffers on that frame."
|
||||
(setq magit--default-directory default-directory)
|
||||
(setq magit-buffer-locked-p (and value t))
|
||||
(magit-restore-section-visibility-cache mode))
|
||||
(when magit-uniquify-buffer-names
|
||||
(cl-pushnew mode uniquify-list-buffers-directory-modes)
|
||||
(with-current-buffer buffer
|
||||
(setq list-buffers-directory (abbreviate-file-name default-directory)))
|
||||
(let ((uniquify-buffer-name-style
|
||||
(if (memq uniquify-buffer-name-style '(nil forward))
|
||||
'post-forward-angle-brackets
|
||||
uniquify-buffer-name-style)))
|
||||
(uniquify-rationalize-file-buffer-names
|
||||
name (file-name-directory (directory-file-name default-directory))
|
||||
buffer)))
|
||||
(magit--maybe-uniquify-buffer-names buffer name mode)
|
||||
buffer))
|
||||
|
||||
(defun magit-generate-buffer-name-default-function (mode &optional value)
|
||||
@@ -922,6 +912,19 @@ account."
|
||||
(?t . ,n)
|
||||
(?x . ,(if magit-uniquify-buffer-names "" "*"))))))
|
||||
|
||||
(defun magit--maybe-uniquify-buffer-names (buffer name mode)
|
||||
(when magit-uniquify-buffer-names
|
||||
(cl-pushnew mode uniquify-list-buffers-directory-modes)
|
||||
(with-current-buffer buffer
|
||||
(setq list-buffers-directory (abbreviate-file-name default-directory)))
|
||||
(let ((uniquify-buffer-name-style
|
||||
(if (memq uniquify-buffer-name-style '(nil forward))
|
||||
'post-forward-angle-brackets
|
||||
uniquify-buffer-name-style)))
|
||||
(uniquify-rationalize-file-buffer-names
|
||||
name (file-name-directory (directory-file-name default-directory))
|
||||
buffer))))
|
||||
|
||||
;;; Buffer Lock
|
||||
|
||||
(defun magit-toggle-buffer-lock ()
|
||||
@@ -947,16 +950,25 @@ latter is displayed in its place."
|
||||
(switch-to-buffer unlocked nil t)
|
||||
(kill-buffer locked))
|
||||
(setq magit-buffer-locked-p nil)
|
||||
(rename-buffer (funcall magit-generate-buffer-name-function
|
||||
major-mode)))
|
||||
(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)
|
||||
(rename-buffer (funcall magit-generate-buffer-name-function
|
||||
major-mode value)))
|
||||
(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
|
||||
@@ -1008,7 +1020,8 @@ window."
|
||||
Refresh the current buffer if its major mode derives from
|
||||
`magit-mode', and refresh the corresponding status buffer.
|
||||
|
||||
Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
Run hooks `magit-pre-refresh-hook', `magit-post-refresh-hook'
|
||||
and `magit-unwind-refresh-hook'."
|
||||
(interactive)
|
||||
(unless magit-inhibit-refresh
|
||||
(unwind-protect
|
||||
@@ -1050,15 +1063,18 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(with-current-buffer buffer (magit-refresh-buffer)))
|
||||
(magit-run-hook-with-benchmark 'magit-post-refresh-hook))
|
||||
|
||||
(defvar-local magit-refresh-start-time nil)
|
||||
(defvar-local magit--refresh-start-time nil)
|
||||
|
||||
(defun magit-refresh-buffer (&rest _ignore)
|
||||
(defvar magit--initial-section-hook nil)
|
||||
|
||||
(defun magit-refresh-buffer (&optional created)
|
||||
"Refresh the current Magit buffer."
|
||||
(interactive)
|
||||
(setq magit-refresh-start-time (current-time))
|
||||
(let ((refresh (intern (format "%s-refresh-buffer"
|
||||
(substring (symbol-name major-mode) 0 -5))))
|
||||
(magit--refresh-cache (or magit--refresh-cache (list (cons 0 0)))))
|
||||
(let ((magit--refreshing-buffer-p t)
|
||||
(magit--refresh-start-time (current-time))
|
||||
(magit--refresh-cache (or magit--refresh-cache (list (cons 0 0))))
|
||||
(refresh (intern (format "%s-refresh-buffer"
|
||||
(substring (symbol-name major-mode) 0 -5)))))
|
||||
(when (functionp refresh)
|
||||
(when magit-refresh-verbose
|
||||
(message "Refreshing buffer `%s'..." (buffer-name)))
|
||||
@@ -1081,8 +1097,8 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(deactivate-mark)
|
||||
(setq magit-section-pre-command-section nil)
|
||||
(setq magit-section-highlight-overlays nil)
|
||||
(setq magit-section-selection-overlays nil)
|
||||
(setq magit-section-highlighted-sections nil)
|
||||
(setq magit-section-unhighlight-sections nil)
|
||||
(let ((inhibit-read-only t))
|
||||
(erase-buffer)
|
||||
(save-excursion
|
||||
@@ -1094,12 +1110,22 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(with-current-buffer buffer
|
||||
(let ((magit-section-movement-hook nil))
|
||||
(apply #'magit-section-goto-successor args)))))
|
||||
(when created
|
||||
(run-hooks 'magit--initial-section-hook)
|
||||
(setq-local magit--initial-section-hook nil))
|
||||
(let ((magit-section-cache-visibility nil))
|
||||
(magit-section-show magit-root-section))
|
||||
(run-hooks 'magit-refresh-buffer-hook)
|
||||
(magit-section-update-highlight)
|
||||
(set-buffer-modified-p nil))
|
||||
(set-buffer-modified-p nil)
|
||||
(push buffer magit-section--refreshed-buffers))
|
||||
(when magit-refresh-verbose
|
||||
(message "Refreshing buffer `%s'...done (%.3fs)" (buffer-name)
|
||||
(float-time (time-since magit-refresh-start-time)))))))
|
||||
(float-time (time-since magit--refresh-start-time)))))))
|
||||
|
||||
(defun magit-revert-buffer (_ignore-auto _noconfirm)
|
||||
"Wrapper around `magit-refresh-buffer' suitable as `revert-buffer-function'."
|
||||
(magit-refresh-buffer))
|
||||
|
||||
(defun magit-profile-refresh-buffer ()
|
||||
"Profile refreshing the current Magit buffer."
|
||||
@@ -1119,9 +1145,8 @@ Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
|
||||
(interactive)
|
||||
(require (quote elp))
|
||||
(cond ((catch 'in-progress
|
||||
(mapatoms (lambda (symbol)
|
||||
(and (get symbol elp-timer-info-property)
|
||||
(throw 'in-progress t)))))
|
||||
(mapatoms (##and (get % elp-timer-info-property)
|
||||
(throw 'in-progress t))))
|
||||
(message "Stop profiling and display results...")
|
||||
(elp-results)
|
||||
(elp-restore-all))
|
||||
@@ -1197,14 +1222,12 @@ argument (the prefix) non-nil means save all with no questions."
|
||||
(when-let ((topdir (magit-rev-parse-safe "--show-toplevel")))
|
||||
(let ((remote (file-remote-p default-directory))
|
||||
(save-some-buffers-action-alist
|
||||
`((?Y (lambda (buffer)
|
||||
(with-current-buffer buffer
|
||||
(setq buffer-save-without-query t)
|
||||
(save-buffer)))
|
||||
`((?Y ,(##with-current-buffer %
|
||||
(setq buffer-save-without-query t)
|
||||
(save-buffer))
|
||||
"to save the current buffer and remember choice")
|
||||
(?N (lambda (buffer)
|
||||
(with-current-buffer buffer
|
||||
(setq magit-inhibit-refresh-save t)))
|
||||
(?N ,(##with-current-buffer %
|
||||
(setq magit-inhibit-refresh-save t))
|
||||
"to skip the current buffer and remember choice")
|
||||
,@save-some-buffers-action-alist))
|
||||
(topdirs nil)
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
(define-package "magit" "20250305.2342" "A Git porcelain inside Emacs"
|
||||
'((emacs "27.1")
|
||||
(compat "30.0.2.0")
|
||||
(llama "0.6.1")
|
||||
(magit-section "4.3.1")
|
||||
(seq "2.24")
|
||||
(transient "0.8.5")
|
||||
(with-editor "3.4.3"))
|
||||
:commit "225ea6fd009300ba80e55a0162f3e46eb6e4f2d3" :authors
|
||||
'(("Marius Vollmer" . "marius.vollmer@gmail.com")
|
||||
("Jonas Bernoulli" . "emacs.magit@jonas.bernoulli.dev"))
|
||||
:maintainers
|
||||
'(("Jonas Bernoulli" . "emacs.magit@jonas.bernoulli.dev")
|
||||
("Kyle Meyer" . "kyle@kyleam.com"))
|
||||
:maintainer
|
||||
'("Jonas Bernoulli" . "emacs.magit@jonas.bernoulli.dev")
|
||||
:keywords
|
||||
'("git" "tools" "vc")
|
||||
:url "https://github.com/magit/magit")
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
||||
;; -*- no-byte-compile: t; lexical-binding: nil -*-
|
||||
(define-package "magit" "20250621.2237"
|
||||
"A Git porcelain inside Emacs."
|
||||
'((emacs "27.1")
|
||||
(compat "30.1")
|
||||
(llama "0.6.3")
|
||||
(magit-section "4.3.6")
|
||||
(seq "2.24")
|
||||
(transient "0.9.0")
|
||||
(with-editor "3.4.4"))
|
||||
:url "https://github.com/magit/magit"
|
||||
:commit "a4f73fb2fb55f7644a80b4442379ef43840ec5e9"
|
||||
:revdesc "a4f73fb2fb55"
|
||||
:keywords '("git" "tools" "vc")
|
||||
:authors '(("Marius Vollmer" . "marius.vollmer@gmail.com")
|
||||
("Jonas Bernoulli" . "emacs.magit@jonas.bernoulli.dev"))
|
||||
:maintainers '(("Jonas Bernoulli" . "emacs.magit@jonas.bernoulli.dev")
|
||||
("Kyle Meyer" . "kyle@kyleam.com")))
|
||||
|
||||
@@ -41,6 +41,12 @@
|
||||
(defvar messages-buffer-name)
|
||||
(defvar y-or-n-p-map)
|
||||
|
||||
(define-obsolete-variable-alias 'magit-process-finish-apply-ansi-colors
|
||||
'magit-process-apply-ansi-colors "Magit-Section 4.3.2")
|
||||
|
||||
(defclass magit-process-section (magit-section)
|
||||
((process :initform nil)))
|
||||
|
||||
;;; Options
|
||||
|
||||
(defcustom magit-process-connection-type (not (eq system-type 'cygwin))
|
||||
@@ -111,9 +117,7 @@ displays the text of `magit-process-error-summary' instead."
|
||||
(and prog
|
||||
(string-match-p
|
||||
"\\`\\(?:\\(?:/.*/\\)?git-credential-\\)?cache\\'" prog)
|
||||
(or (cl-loop for (opt val) on args
|
||||
if (string= opt "--socket")
|
||||
return val)
|
||||
(or (cadr (member "--socket" args))
|
||||
(expand-file-name "~/.git-credential-cache/socket")))))
|
||||
;; Note: `magit-process-file' is not yet defined when
|
||||
;; evaluating this form, so we use `process-lines'.
|
||||
@@ -245,11 +249,54 @@ implement such functions."
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom magit-process-display-mode-line-error t
|
||||
"Whether Magit should retain and highlight process errors in the mode line."
|
||||
"Whether Magit should retain and highlight process errors in the mode line.
|
||||
|
||||
See `magit-show-process-buffer-hint' for another way to display the
|
||||
complete output on demand."
|
||||
:package-version '(magit . "2.12.0")
|
||||
:group 'magit-process
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom magit-show-process-buffer-hint t
|
||||
"Whether to append hint about process buffer to Git error messages.
|
||||
|
||||
When Magit runs Git for side-effects, the output is always logged to
|
||||
a per-repository process buffer. If Git exits with a non-zero status,
|
||||
then a single line of its error output is shown in the repositories
|
||||
status buffer and in the echo area.
|
||||
|
||||
When a user want to learn more about the error, they can switch to that
|
||||
process buffer, to see the complete output, but initially users are not
|
||||
aware of this, so Magit appends a usage hint to the error message in
|
||||
both of these places.
|
||||
|
||||
Once you are aware of this, you probably won't need the reminder and can
|
||||
set this option to nil.
|
||||
|
||||
See `magit-process-display-mode-line-error' for another way to display
|
||||
the complete output on demand."
|
||||
:package-version '(magit . "4.3.7")
|
||||
:group 'magit-process
|
||||
:type 'boolean)
|
||||
|
||||
(defcustom magit-process-apply-ansi-colors nil
|
||||
"Whether and when to apply color escapes in the process buffer.
|
||||
|
||||
Magit instructs Git to not colorize its output, but third-party Git
|
||||
hooks may do so anyway. We recommend you figure out how to prevent
|
||||
such hooks from colorizing their output instead of customizing this
|
||||
option.
|
||||
|
||||
If `nil' (the default), do not apply color escape sequences. If `t',
|
||||
apply them once the subprocess has finished. If `filter', apply them
|
||||
as input arrives (which is more expensive and potentially fragile).
|
||||
This is a footgun; starter-kits should leave this option untouched."
|
||||
:package-version '(magit . "4.3.2")
|
||||
:group 'magit-process
|
||||
:type '(choice (const :tag "Do not apply" nil)
|
||||
(const :tag "Apply when subprocess has finished" t)
|
||||
(const :tag "Apply using process filter" filter)))
|
||||
|
||||
(defcustom magit-process-timestamp-format nil
|
||||
"Format of timestamp for each process in the process buffer.
|
||||
If non-nil, pass this to `format-time-string' when creating a
|
||||
@@ -705,9 +752,6 @@ Magit status buffer."
|
||||
|
||||
;;; Process Internals
|
||||
|
||||
(defclass magit-process-section (magit-section)
|
||||
((process :initform nil)))
|
||||
|
||||
(setf (alist-get 'process magit--section-type-alist) 'magit-process-section)
|
||||
|
||||
(defun magit-process-setup (program args)
|
||||
@@ -843,6 +887,8 @@ Magit status buffer."
|
||||
(setq string (substring string (1+ ret-pos)))
|
||||
(delete-region (line-beginning-position) (point)))
|
||||
(setq string (magit-process-remove-bogus-errors string))
|
||||
(when (eq magit-process-apply-ansi-colors 'filter)
|
||||
(setq string (ansi-color-apply string)))
|
||||
(insert (propertize string 'magit-section
|
||||
(process-get proc 'section)))
|
||||
(set-marker (process-mark proc) (point))
|
||||
@@ -1152,21 +1198,17 @@ If STR is supplied, it replaces the `mode-line-process' text."
|
||||
|
||||
(defun magit-process-error-summary (process-buf section)
|
||||
"A one-line error summary from the given SECTION."
|
||||
(or (and (buffer-live-p process-buf)
|
||||
(with-current-buffer process-buf
|
||||
(and (oref section content)
|
||||
(save-excursion
|
||||
(goto-char (oref section end))
|
||||
(run-hook-wrapped
|
||||
'magit-process-error-message-regexps
|
||||
(lambda (re)
|
||||
(save-excursion
|
||||
(and (re-search-backward
|
||||
re (oref section start) t)
|
||||
(or (match-string-no-properties 1)
|
||||
(and (not magit-process-raise-error)
|
||||
'suppressed))))))))))
|
||||
"Git failed"))
|
||||
(and (buffer-live-p process-buf)
|
||||
(with-current-buffer process-buf
|
||||
(and (oref section content)
|
||||
(save-excursion
|
||||
(goto-char (oref section end))
|
||||
(run-hook-wrapped
|
||||
'magit-process-error-message-regexps
|
||||
(lambda (re)
|
||||
(save-excursion
|
||||
(and (re-search-backward re (oref section start) t)
|
||||
(match-string-no-properties 1))))))))))
|
||||
|
||||
(defun magit-process-error-tooltip (process-buf section)
|
||||
"Returns the text from SECTION of the PROCESS-BUF buffer.
|
||||
@@ -1195,13 +1237,10 @@ Limited by `magit-process-error-tooltip-max-lines'."
|
||||
|
||||
(defvar-local magit-this-error nil)
|
||||
|
||||
(defvar magit-process-finish-apply-ansi-colors nil)
|
||||
|
||||
(defun magit-process-finish (arg &optional process-buf command-buf
|
||||
(defun magit-process-finish (arg &optional process-buf _command-buf
|
||||
default-dir section)
|
||||
(unless (integerp arg)
|
||||
(setq process-buf (process-buffer arg))
|
||||
(setq command-buf (process-get arg 'command-buf))
|
||||
(setq default-dir (process-get arg 'default-dir))
|
||||
(setq section (process-get arg 'section))
|
||||
(setq arg (process-exit-status arg)))
|
||||
@@ -1211,35 +1250,28 @@ Limited by `magit-process-error-tooltip-max-lines'."
|
||||
(with-current-buffer process-buf
|
||||
(magit-process-finish-section section arg)))
|
||||
(if (= arg 0)
|
||||
;; Unset the `mode-line-process' value upon success.
|
||||
(magit-process-unset-mode-line default-dir)
|
||||
;; Otherwise process the error.
|
||||
(let ((msg (magit-process-error-summary process-buf section)))
|
||||
;; Change `mode-line-process' to an error face upon failure.
|
||||
(if magit-process-display-mode-line-error
|
||||
(magit-process-set-mode-line-error-status
|
||||
(or (magit-process-error-tooltip process-buf section)
|
||||
msg))
|
||||
(or (magit-process-error-tooltip process-buf section) msg))
|
||||
(magit-process-unset-mode-line default-dir))
|
||||
;; Either signal the error, or else display the error summary in
|
||||
;; the status buffer and with a message in the echo area.
|
||||
(cond
|
||||
(magit-process-raise-error
|
||||
(signal 'magit-git-error (list (format "%s (in %s)" msg default-dir))))
|
||||
((not (eq msg 'suppressed))
|
||||
(when (buffer-live-p process-buf)
|
||||
(with-current-buffer process-buf
|
||||
(when-let ((status-buf (magit-get-mode-buffer 'magit-status-mode)))
|
||||
(with-current-buffer status-buf
|
||||
(setq magit-this-error msg)))))
|
||||
(message "%s ... [%s buffer %s for details]" msg
|
||||
(if-let ((key (and (buffer-live-p command-buf)
|
||||
(with-current-buffer command-buf
|
||||
(car (where-is-internal
|
||||
'magit-process-buffer))))))
|
||||
(format "Hit %s to see" (key-description key))
|
||||
"See")
|
||||
(buffer-name process-buf))))))
|
||||
(when (buffer-live-p process-buf)
|
||||
(with-current-buffer process-buf
|
||||
(when-let ((status-buf (magit-get-mode-buffer 'magit-status-mode)))
|
||||
(with-current-buffer status-buf
|
||||
(setq magit-this-error msg)))))
|
||||
(let ((usage
|
||||
(and magit-show-process-buffer-hint
|
||||
(if-let ((keys (where-is-internal 'magit-process-buffer)))
|
||||
(format "Type %s to see %S for details"
|
||||
(key-description (car keys)) process-buf)
|
||||
(format "See %S for details" process-buf)))))
|
||||
(if magit-process-raise-error
|
||||
(signal 'magit-git-error
|
||||
(list msg (or usage (list 'in default-dir))))
|
||||
(message "Git error: %s"
|
||||
(concat msg (and usage (format " [%s]" usage))))))))
|
||||
arg)
|
||||
|
||||
(defun magit-process-finish-section (section exit-code)
|
||||
@@ -1256,7 +1288,7 @@ Limited by `magit-process-error-tooltip-max-lines'."
|
||||
'magit-process-ok
|
||||
'magit-process-ng)))
|
||||
(set-marker-insertion-type marker t))
|
||||
(when magit-process-finish-apply-ansi-colors
|
||||
(when (eq magit-process-apply-ansi-colors t)
|
||||
(ansi-color-apply-on-region (oref section content)
|
||||
(oref section end)))
|
||||
(if (= (oref section end)
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
("-F" "Force" ("-f" "--force"))
|
||||
("-h" "Disable hooks" "--no-verify")
|
||||
("-n" "Dry run" ("-n" "--dry-run"))
|
||||
(5 "-u" "Set upstream" "--set-upstream")
|
||||
(7 "-t" "Follow tags" "--follow-tags")]
|
||||
("-u" "Set upstream" "--set-upstream" :level 5)
|
||||
("-T" "Include all tags" "--tags")
|
||||
("-t" "Include related annotated tags" "--follow-tags")]
|
||||
[:if magit-get-current-branch
|
||||
:description (lambda ()
|
||||
(format (propertize "Push %s to" 'face 'transient-heading)
|
||||
:description (##format (propertize "Push %s to" 'face 'transient-heading)
|
||||
(propertize (magit-get-current-branch)
|
||||
'face 'magit-branch-local)))
|
||||
'face 'magit-branch-local))
|
||||
("p" magit-push-current-to-pushremote)
|
||||
("u" magit-push-current-to-upstream)
|
||||
("e" "elsewhere" magit-push-current)]
|
||||
|
||||
@@ -63,7 +63,7 @@ To change the value in an existing buffer use the command
|
||||
`magit-refs-set-show-commit-count'."
|
||||
:package-version '(magit . "2.1.0")
|
||||
:group 'magit-refs
|
||||
:safe (lambda (val) (memq val '(all branch nil)))
|
||||
:safe (##memq % '(all branch nil))
|
||||
:type '(choice (const :tag "For branches and tags" all)
|
||||
(const :tag "For branches only" branch)
|
||||
(const :tag "Never" nil)))
|
||||
@@ -134,7 +134,7 @@ AUTHOR-WIDTH has to be an integer. When the name of the author
|
||||
:package-version '(magit . "2.9.0")
|
||||
:group 'magit-refs
|
||||
:group 'magit-margin
|
||||
:safe (lambda (val) (memq val '(all branch nil)))
|
||||
:safe (##memq % '(all branch nil))
|
||||
:type magit-log-margin--custom-type
|
||||
:initialize #'magit-custom-initialize-reset
|
||||
:set-after '(magit-log-margin)
|
||||
@@ -333,8 +333,7 @@ Type \\[magit-reset] to reset `HEAD' to the commit at point.
|
||||
(transient-define-prefix magit-show-refs (&optional transient)
|
||||
"List and compare references in a dedicated buffer."
|
||||
:man-page "git-branch"
|
||||
:value (lambda ()
|
||||
(magit-show-refs-arguments magit-prefix-use-buffer-arguments))
|
||||
:value (##magit-show-refs-arguments magit-prefix-use-buffer-arguments)
|
||||
["Arguments"
|
||||
(magit-for-each-ref:--contains)
|
||||
("-M" "Merged" "--merged=" magit-transient-read-revision)
|
||||
@@ -566,7 +565,7 @@ line is inserted at all."
|
||||
(magit-refs--format-margin tag))
|
||||
(magit-refs--insert-cherry-commits tag)))))
|
||||
(insert ?\n)
|
||||
(magit-make-margin-overlay nil t)))))
|
||||
(magit-make-margin-overlay)))))
|
||||
|
||||
(defun magit-insert-remote-branches ()
|
||||
"Insert sections showing all remote-tracking branches."
|
||||
@@ -621,7 +620,7 @@ line is inserted at all."
|
||||
(magit-refs--format-margin branch))
|
||||
(magit-refs--insert-cherry-commits branch))))))))
|
||||
(insert ?\n)
|
||||
(magit-make-margin-overlay nil t))))
|
||||
(magit-make-margin-overlay))))
|
||||
|
||||
(defun magit-insert-local-branches ()
|
||||
"Insert sections showing all local branches."
|
||||
@@ -638,7 +637,22 @@ line is inserted at all."
|
||||
(magit-refs--format-margin branch))
|
||||
(magit-refs--insert-cherry-commits branch))))
|
||||
(insert ?\n)
|
||||
(magit-make-margin-overlay nil t)))
|
||||
(magit-make-margin-overlay)))
|
||||
|
||||
(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-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--insert-cherry-commits ref)))
|
||||
(insert ?\n)
|
||||
(magit-make-margin-overlay))))
|
||||
|
||||
(defun magit-refs--format-local-branches ()
|
||||
(let ((lines (seq-keep #'magit-refs--format-local-branch
|
||||
@@ -788,15 +802,12 @@ line is inserted at all."
|
||||
"cherry" "-v" (magit-abbrev-arg) magit-buffer-upstream ref)
|
||||
(if (= (point) start)
|
||||
(message "No cherries for %s" ref)
|
||||
(magit-make-margin-overlay nil t)))))
|
||||
(magit-make-margin-overlay)))))
|
||||
|
||||
(defun magit-refs--format-margin (commit)
|
||||
(save-excursion
|
||||
(goto-char (line-beginning-position 0))
|
||||
(let ((line (magit-rev-format "%ct%cN" commit)))
|
||||
(magit-log-format-margin commit
|
||||
(substring line 10)
|
||||
(substring line 0 10)))))
|
||||
(if-let ((line (magit-rev-format "%cN%x00%ct" commit)))
|
||||
(apply #'magit-log-format-margin commit (split-string line "\0"))
|
||||
(magit-make-margin-overlay)))
|
||||
|
||||
;;; _
|
||||
(provide 'magit-refs)
|
||||
|
||||
@@ -68,7 +68,7 @@ has to be used to view and change remote related variables."
|
||||
:man-page "git-remote"
|
||||
:value '("-f")
|
||||
["Variables"
|
||||
:if (lambda () (and magit-remote-direct-configure (transient-scope)))
|
||||
:if (##and magit-remote-direct-configure (transient-scope))
|
||||
("u" magit-remote.<remote>.url)
|
||||
("U" magit-remote.<remote>.fetch)
|
||||
("s" magit-remote.<remote>.pushurl)
|
||||
@@ -210,13 +210,11 @@ the now stale refspecs. Other stale branches are not removed."
|
||||
nil refs))
|
||||
(magit-confirm 'prune-stale-refspecs nil
|
||||
(format "Prune %%d stale refspecs and %d branches"
|
||||
(length (mapcan (lambda (s) (copy-sequence (cdr s)))
|
||||
stale)))
|
||||
(length (mapcan (##copy-sequence (cdr %)) stale)))
|
||||
nil
|
||||
(mapcar (pcase-lambda (`(,refspec . ,refs))
|
||||
(concat refspec "\n"
|
||||
(mapconcat (lambda (b) (concat " " b))
|
||||
refs "\n")))
|
||||
(mapconcat (##concat " " %) refs "\n")))
|
||||
stale)))
|
||||
(pcase-dolist (`(,refspec . ,refs) stale)
|
||||
(magit-call-git "config" "--unset" variable
|
||||
@@ -311,10 +309,9 @@ refspec."
|
||||
(transient-define-prefix magit-remote-configure (remote)
|
||||
"Configure a remote."
|
||||
:man-page "git-remote"
|
||||
[:description
|
||||
(lambda ()
|
||||
(concat (propertize "Configure " 'face 'transient-heading)
|
||||
(propertize (transient-scope) 'face 'magit-branch-remote)))
|
||||
[:description (##concat
|
||||
(propertize "Configure " 'face 'transient-heading)
|
||||
(propertize (transient-scope) 'face 'magit-branch-remote))
|
||||
("u" magit-remote.<remote>.url)
|
||||
("U" magit-remote.<remote>.fetch)
|
||||
("s" magit-remote.<remote>.pushurl)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
(require 'magit)
|
||||
|
||||
;; For `magit-rebase--todo'.
|
||||
(declare-function git-rebase-current-line "git-rebase" ())
|
||||
(declare-function git-rebase-current-line "git-rebase" (&optional batch))
|
||||
(eval-when-compile
|
||||
(cl-pushnew 'action-type eieio--known-slot-names)
|
||||
(cl-pushnew 'action eieio--known-slot-names)
|
||||
@@ -528,11 +528,11 @@ This discards all changes made since the sequence started."
|
||||
:if-not magit-rebase-in-progress-p
|
||||
("-k" "Keep empty commits" "--keep-empty")
|
||||
("-p" "Preserve merges" ("-p" "--preserve-merges")
|
||||
:if (lambda () (magit-git-version< "2.33.0")))
|
||||
:if (##magit-git-version< "2.33.0"))
|
||||
("-r" "Rebase merges" ("-r" "--rebase-merges=")
|
||||
magit-rebase-merges-select-mode)
|
||||
("-u" "Update branches" "--update-refs"
|
||||
:if (lambda () (magit-git-version>= "2.38.0")))
|
||||
:if (##magit-git-version>= "2.38.0"))
|
||||
(7 magit-merge:--strategy)
|
||||
(7 magit-merge:--strategy-option)
|
||||
(7 "=X" magit-diff:--diff-algorithm :argument "-Xdiff-algorithm=")
|
||||
@@ -547,10 +547,9 @@ This discards all changes made since the sequence started."
|
||||
(magit:--gpg-sign)
|
||||
(magit:--signoff)]
|
||||
[:if-not magit-rebase-in-progress-p
|
||||
:description (lambda ()
|
||||
(format (propertize "Rebase %s onto" 'face 'transient-heading)
|
||||
:description (##format (propertize "Rebase %s onto" 'face 'transient-heading)
|
||||
(propertize (or (magit-get-current-branch) "HEAD")
|
||||
'face 'magit-branch-local)))
|
||||
'face 'magit-branch-local))
|
||||
("p" magit-rebase-onto-pushremote)
|
||||
("u" magit-rebase-onto-upstream)
|
||||
("e" "elsewhere" magit-rebase-branch)]
|
||||
@@ -675,17 +674,13 @@ START has to be selected from a list of recent commits."
|
||||
(commit args message &optional editor delay-edit-confirm noassert confirm)
|
||||
(declare (indent 2))
|
||||
(when commit
|
||||
(if (eq commit :merge-base)
|
||||
(setq commit
|
||||
(and-let* ((upstream (magit-get-upstream-branch)))
|
||||
(magit-git-string "merge-base" upstream "HEAD")))
|
||||
(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)))))
|
||||
(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))))
|
||||
(when (and commit (not noassert))
|
||||
(setq commit (magit-rebase-interactive-assert
|
||||
commit delay-edit-confirm
|
||||
@@ -761,10 +756,17 @@ START has to be selected from a list of recent commits."
|
||||
nil t))
|
||||
|
||||
;;;###autoload
|
||||
(defun magit-rebase-autosquash (args)
|
||||
"Combine squash and fixup commits with their intended targets."
|
||||
(interactive (list (magit-rebase-arguments)))
|
||||
(magit-rebase-interactive-1 :merge-base
|
||||
(defun magit-rebase-autosquash (select args)
|
||||
"Combine squash and fixup commits with their intended targets.
|
||||
By default only squash into commits that are not reachable from
|
||||
the upstream branch. If no upstream is configured or with a prefix
|
||||
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)))
|
||||
(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))
|
||||
@@ -966,9 +968,8 @@ If no such sequence is in progress, do nothing."
|
||||
If no such sequence is in progress, do nothing."
|
||||
(when (magit-rebase-in-progress-p)
|
||||
(let* ((gitdir (magit-gitdir))
|
||||
(interactive
|
||||
(file-directory-p (expand-file-name "rebase-merge" gitdir)))
|
||||
(dir (if interactive "rebase-merge/" "rebase-apply/"))
|
||||
(mergep (file-directory-p (expand-file-name "rebase-merge" gitdir)))
|
||||
(dir (if mergep "rebase-merge/" "rebase-apply/"))
|
||||
(name (thread-first (concat dir "head-name")
|
||||
(expand-file-name gitdir)
|
||||
magit-file-line))
|
||||
@@ -980,7 +981,7 @@ If no such sequence is in progress, do nothing."
|
||||
(name (or (magit-rev-name name "refs/heads/*") name)))
|
||||
(magit-insert-section (rebase-sequence)
|
||||
(magit-insert-heading (format "Rebasing %s onto %s" name onto))
|
||||
(if interactive
|
||||
(if mergep
|
||||
(magit-rebase-insert-merge-sequence onto)
|
||||
(magit-rebase-insert-apply-sequence onto))
|
||||
(insert ?\n)))))
|
||||
@@ -990,36 +991,42 @@ If no such sequence is in progress, do nothing."
|
||||
These are ordered in that the same way they'll be sorted in the
|
||||
status buffer (i.e., the reverse of how they will be applied)."
|
||||
(let ((comment-start (or (magit-get "core.commentChar") "#"))
|
||||
lines)
|
||||
(commits ())
|
||||
(actions ()))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents
|
||||
(expand-file-name "rebase-merge/git-rebase-todo" (magit-gitdir)))
|
||||
(while (not (eobp))
|
||||
(let ((ln (git-rebase-current-line)))
|
||||
(when (oref ln action-type)
|
||||
(push ln lines)))
|
||||
(when-let ((obj (git-rebase-current-line t)))
|
||||
(push obj actions)
|
||||
(when (memq (oref obj action-type) '(commit merge))
|
||||
(push obj commits)))
|
||||
(forward-line)))
|
||||
lines))
|
||||
(let ((abbrevs
|
||||
(and commits
|
||||
(magit-git-lines
|
||||
"log" "--no-walk=unsorted" "--format=%h"
|
||||
(mapcar (lambda (obj)
|
||||
(if (eq (oref obj action-type) 'merge)
|
||||
(let ((options (oref obj action-options)))
|
||||
(and (string-match "-[cC] \\([^ ]+\\)" options)
|
||||
(match-string 1 options)))
|
||||
(oref obj target)))
|
||||
commits)))))
|
||||
(cl-assert (equal (length commits) (length abbrevs)))
|
||||
(while-let ((obj (pop commits))
|
||||
(val (pop abbrevs)))
|
||||
(oset obj abbrev val)))
|
||||
actions))
|
||||
|
||||
(defun magit-rebase-insert-merge-sequence (onto)
|
||||
(dolist (line (magit-rebase--todo))
|
||||
(with-slots (action-type action action-options target) line
|
||||
(dolist (obj (magit-rebase--todo))
|
||||
(with-slots (action-type action action-options target abbrev trailer) obj
|
||||
(pcase action-type
|
||||
('commit
|
||||
(magit-sequence-insert-commit action target 'magit-sequence-pick))
|
||||
((or (or `exec `label)
|
||||
(and `merge (guard (not action-options))))
|
||||
(insert (propertize action 'font-lock-face 'magit-sequence-onto) "\s"
|
||||
(propertize target 'font-lock-face 'git-rebase-label) "\n"))
|
||||
('merge
|
||||
(if-let ((hash (and (string-match "-[cC] \\([^ ]+\\)" action-options)
|
||||
(match-string 1 action-options))))
|
||||
(magit-insert-section (commit hash)
|
||||
(magit-insert-heading
|
||||
(propertize "merge" 'font-lock-face 'magit-sequence-pick)
|
||||
"\s"
|
||||
(magit-format-rev-summary hash) "\n"))
|
||||
(error "Failed to parse merge message hash"))))))
|
||||
((or 'commit (and 'merge (guard abbrev)))
|
||||
(magit-sequence-insert-commit action target 'magit-sequence-pick
|
||||
abbrev trailer))
|
||||
((guard action) (magit-sequence-insert-step action target)))))
|
||||
(let ((dir (magit-gitdir)))
|
||||
(magit-sequence-insert-sequence
|
||||
(magit-file-line (expand-file-name "rebase-merge/stopped-sha" dir))
|
||||
@@ -1052,13 +1059,15 @@ status buffer (i.e., the reverse of how they will be applied)."
|
||||
(defun magit-sequence-insert-sequence (stop onto &optional orig)
|
||||
(let ((head (magit-rev-parse "HEAD")) done)
|
||||
(setq onto (if onto (magit-rev-parse onto) head))
|
||||
(setq done (magit-git-lines "log" "--format=%H" (concat onto "..HEAD")))
|
||||
(when (and stop (not (member (magit-rev-parse stop) done)))
|
||||
(setq done (mapcar (##split-string % "\0")
|
||||
(magit-git-lines "log" "--format=%H%x00%h%x00%s"
|
||||
(concat onto "..HEAD"))))
|
||||
(when (and stop (not (assoc (magit-rev-parse stop) done)))
|
||||
(let ((id (magit-patch-id stop)))
|
||||
(if-let ((matched (seq-find (##equal (magit-patch-id %) id) done)))
|
||||
(if-let ((matched (car (assoc (##equal (magit-patch-id %) id) done))))
|
||||
(setq stop matched)
|
||||
(cond
|
||||
((seq-find (##magit-rev-equal % stop) done)
|
||||
((assoc (##magit-rev-equal % stop) done)
|
||||
;; The commit's testament has been executed.
|
||||
(magit-sequence-insert-commit "void" stop 'magit-sequence-drop))
|
||||
;; The faith of the commit is still undecided...
|
||||
@@ -1084,14 +1093,14 @@ status buffer (i.e., the reverse of how they will be applied)."
|
||||
(t "work")))
|
||||
stop 'magit-sequence-part))
|
||||
;; The commit is definitely gone...
|
||||
((seq-find (##magit-rev-equal % stop) done)
|
||||
((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)))
|
||||
(setq stop nil))))
|
||||
(dolist (rev done)
|
||||
(pcase-dolist (`(,rev ,abbrev ,msg) done)
|
||||
(apply #'magit-sequence-insert-commit
|
||||
(cond ((equal rev stop)
|
||||
;; ...but its reincarnation lives on.
|
||||
@@ -1103,21 +1112,32 @@ status buffer (i.e., the reverse of how they will be applied)."
|
||||
"like") ; There are new commits.
|
||||
rev (if (equal rev head)
|
||||
'magit-sequence-head
|
||||
'magit-sequence-stop)))
|
||||
'magit-sequence-stop)
|
||||
abbrev msg))
|
||||
((equal rev head)
|
||||
(list "done" rev 'magit-sequence-head))
|
||||
(list "done" rev 'magit-sequence-head abbrev msg))
|
||||
(t
|
||||
(list "done" rev 'magit-sequence-done)))))
|
||||
(list "done" rev 'magit-sequence-done abbrev msg)))))
|
||||
(magit-sequence-insert-commit "onto" onto
|
||||
(if (equal onto head)
|
||||
'magit-sequence-head
|
||||
'magit-sequence-onto))))
|
||||
|
||||
(defun magit-sequence-insert-commit (type hash face)
|
||||
(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) "\s"
|
||||
(magit-format-rev-summary hash) "\n")))
|
||||
(propertize type 'font-lock-face face) " "
|
||||
(if abbrev
|
||||
(concat (propertize abbrev 'face 'magit-hash) " " msg "\n")
|
||||
(concat (magit-format-rev-summary hash) "\n")))))
|
||||
|
||||
(defun magit-sequence-insert-step (type target)
|
||||
(magit-insert-section (rebase-step (cons type target))
|
||||
(magit-insert-heading
|
||||
(propertize type 'font-lock-face 'magit-sequence-pick)
|
||||
(and target
|
||||
(concat "\s"
|
||||
(propertize target 'font-lock-face 'git-rebase-label))))))
|
||||
|
||||
;;; _
|
||||
(provide 'magit-sequence)
|
||||
|
||||
@@ -113,7 +113,7 @@ directories, call `magit-sparse-checkout-set' instead."
|
||||
(let ((re (concat
|
||||
"\\`"
|
||||
(regexp-opt (magit-sparse-checkout-directories)))))
|
||||
(lambda (d) (string-match-p re d)))
|
||||
(##string-match-p re %))
|
||||
(magit-revision-directories "HEAD")))))
|
||||
(magit-sparse-checkout--auto-enable)
|
||||
(magit-run-git-async "sparse-checkout" "add" directories))
|
||||
|
||||
@@ -173,14 +173,15 @@ while two prefix arguments are equivalent to `--all'."
|
||||
|
||||
The message that Git would have picked, is available as the
|
||||
default (used when the user enters the empty string) and as
|
||||
the next history element (which can be accessed with \
|
||||
\\<minibuffer-local-map>\\[next-history-element])."
|
||||
(read-string (format "Stash message (default: On%s:%s): "
|
||||
(magit--ellipsis) (magit--ellipsis))
|
||||
nil nil
|
||||
(format "On %s: %s"
|
||||
(or (magit-get-current-branch) "(no branch)")
|
||||
(magit-rev-format "%h %s"))))
|
||||
the first future history element. The second future history
|
||||
element is just \"On BRANCH: \". Future history elements can
|
||||
be accessed using \\<minibuffer-local-map>\\[next-history-element])."
|
||||
(let ((branch (or (magit-get-current-branch) "(no branch)"))
|
||||
(ellipsis (magit--ellipsis)))
|
||||
(read-string (format "Stash message (default: On%s:%s): " ellipsis ellipsis)
|
||||
nil nil
|
||||
(list (format "On %s: %s" branch (magit-rev-format "%h %s"))
|
||||
(format "On %s: " branch)))))
|
||||
|
||||
(defun magit-stash-read-message-traditional ()
|
||||
"Read a message from the minibuffer, to be used for a stash.
|
||||
@@ -330,7 +331,7 @@ want to fall back to using \"--3way\", without being prompted."
|
||||
(concat
|
||||
"Could not apply stash because of unstaged changes.\n\n"
|
||||
"To do a tree-way merge, these files have to be staged\n"
|
||||
(mapconcat (lambda (f) (format " %s" f)) conflicts "\n")
|
||||
(mapconcat (##format " %s" %) conflicts "\n")
|
||||
"\n")
|
||||
nil
|
||||
(?s (format
|
||||
@@ -527,16 +528,12 @@ instead of \"Stashes:\"."
|
||||
(magit-insert-section (stash autostash)
|
||||
(insert (propertize "AUTOSTASH" 'font-lock-face 'magit-hash))
|
||||
(insert " " msg "\n")
|
||||
(save-excursion
|
||||
(backward-char)
|
||||
(magit-log-format-margin autostash author date)))))
|
||||
(magit-log-format-margin autostash author date))))
|
||||
(if verified
|
||||
(magit-git-wash (apply-partially #'magit-log-wash-log 'stash)
|
||||
"reflog" "--format=%gd%x00%aN%x00%at%x00%gs" ref)
|
||||
(insert ?\n)
|
||||
(save-excursion
|
||||
(backward-char)
|
||||
(magit-make-margin-overlay)))))))
|
||||
(magit-make-margin-overlay))))))
|
||||
|
||||
;;; List Stashes
|
||||
|
||||
@@ -572,7 +569,8 @@ instead of \"Stashes:\"."
|
||||
|
||||
(defun magit-stashes-maybe-update-stash-buffer (&optional _)
|
||||
"When moving in the stashes buffer, update the stash buffer.
|
||||
If there is no stash buffer in the same frame, then do nothing."
|
||||
If there is no stash buffer in the same frame, then do nothing.
|
||||
See also info node `(magit)Section Movement'."
|
||||
(when (derived-mode-p 'magit-stashes-mode)
|
||||
(magit--maybe-update-stash-buffer)))
|
||||
|
||||
|
||||
@@ -174,8 +174,10 @@ of the work Git is responsible for. Turning that list into sections is
|
||||
also not free, so Magit only lists `magit-status-file-list-limit' files."
|
||||
:package-version '(magit . "4.3.0")
|
||||
:group 'magit-status
|
||||
:type 'boolean
|
||||
:safe 'booleanp)
|
||||
:type '(choice (const :tag "Do not list untracked files" nil)
|
||||
(const :tag "List mixture of files and directories" t)
|
||||
(const :tag "List individual files (slow)" all))
|
||||
:safe (##memq % '(nil t all)))
|
||||
|
||||
(defcustom magit-status-file-list-limit 100
|
||||
"How many files to list in file list sections in the status buffer.
|
||||
@@ -432,7 +434,7 @@ Type \\[magit-commit] to create a commit.
|
||||
:group 'magit-status
|
||||
(magit-hack-dir-local-variables)
|
||||
(when magit-status-initial-section
|
||||
(add-hook 'magit-post-create-buffer-hook
|
||||
(add-hook 'magit--initial-section-hook
|
||||
#'magit-status-goto-initial-section nil t))
|
||||
(setq magit--imenu-group-types '(not branch commit)))
|
||||
|
||||
@@ -498,19 +500,22 @@ Type \\[magit-commit] to create a commit.
|
||||
|
||||
(defun magit-status-maybe-update-revision-buffer (&optional _)
|
||||
"When moving in the status buffer, update the revision buffer.
|
||||
If there is no revision buffer in the same frame, then do nothing."
|
||||
If there is no revision buffer in the same frame, then do nothing.
|
||||
See also info node `(magit)Section Movement'."
|
||||
(when (derived-mode-p 'magit-status-mode)
|
||||
(magit--maybe-update-revision-buffer)))
|
||||
|
||||
(defun magit-status-maybe-update-stash-buffer (&optional _)
|
||||
"When moving in the status buffer, update the stash buffer.
|
||||
If there is no stash buffer in the same frame, then do nothing."
|
||||
If there is no stash buffer in the same frame, then do nothing.
|
||||
See also info node `(magit)Section Movement'."
|
||||
(when (derived-mode-p 'magit-status-mode)
|
||||
(magit--maybe-update-stash-buffer)))
|
||||
|
||||
(defun magit-status-maybe-update-blob-buffer (&optional _)
|
||||
"When moving in the status buffer, update the blob buffer.
|
||||
If there is no blob buffer in the same frame, then do nothing."
|
||||
If there is no blob buffer in the same frame, then do nothing.
|
||||
See also info node `(magit)Section Movement'."
|
||||
(when (derived-mode-p 'magit-status-mode)
|
||||
(magit--maybe-update-blob-buffer)))
|
||||
|
||||
@@ -542,7 +547,8 @@ 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 ((key (car (where-is-internal 'magit-process-buffer))))
|
||||
(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))
|
||||
(setq magit-this-error nil)))
|
||||
@@ -568,13 +574,12 @@ the status buffer causes this section to disappear again."
|
||||
"Insert a header line about the current branch.
|
||||
If `HEAD' is detached, then insert information about that commit
|
||||
instead. The optional BRANCH argument is for internal use only."
|
||||
(let ((branch (or branch (magit-get-current-branch)))
|
||||
(output (magit-rev-format "%h %s" (or branch "HEAD"))))
|
||||
(let ((output (magit-rev-format "%h %s" (or branch "HEAD"))))
|
||||
(string-match "^\\([^ ]+\\) \\(.*\\)" output)
|
||||
(magit-bind-match-strings (commit summary) output
|
||||
(when (equal summary "")
|
||||
(setq summary "(no commit message)"))
|
||||
(if branch
|
||||
(if-let ((branch (or branch (magit-get-current-branch))))
|
||||
(magit-insert-section (branch branch)
|
||||
(insert (format "%-10s" "Head: "))
|
||||
(when magit-status-show-hashes-in-headers
|
||||
@@ -726,7 +731,7 @@ remote in alphabetic order."
|
||||
(defvar-keymap magit-untracked-section-map
|
||||
:doc "Keymap for the `untracked' section."
|
||||
"<remap> <magit-delete-thing>" #'magit-discard
|
||||
"<remap> <magit-stage-file>" #'magit-stage
|
||||
"<remap> <magit-stage-files>" #'magit-stage
|
||||
"<2>" (magit-menu-item "Discard files" #'magit-discard)
|
||||
"<1>" (magit-menu-item "Stage files" #'magit-stage))
|
||||
|
||||
@@ -766,9 +771,8 @@ is always ignored."
|
||||
(magit-insert-files
|
||||
'untracked
|
||||
(lambda (files)
|
||||
(mapcan (lambda (line)
|
||||
(and (eq (aref line 0) ??)
|
||||
(list (substring line 3))))
|
||||
(mapcan (##and (eq (aref % 0) ??)
|
||||
(list (substring % 3)))
|
||||
(apply #'magit-git-items "status" "-z" "--porcelain"
|
||||
(format "--untracked-files=%s"
|
||||
(if (eq value 'all) "all" "normal"))
|
||||
@@ -782,8 +786,7 @@ Honor the buffer's file filter, which can be set using \"D - -\"."
|
||||
(defun magit-insert-ignored-files ()
|
||||
"Insert a list of ignored files.
|
||||
Honor the buffer's file filter, which can be set using \"D - -\"."
|
||||
(magit-insert-files 'ignored
|
||||
(lambda (args) (magit-ignored-files "--directory" args))))
|
||||
(magit-insert-files 'ignored (##magit-ignored-files "--directory" %)))
|
||||
|
||||
(defun magit-insert-skip-worktree-files ()
|
||||
"Insert a list of skip-worktree files.
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
|
||||
(require 'magit)
|
||||
|
||||
(defvar x-stretch-cursor)
|
||||
|
||||
;;; Options
|
||||
|
||||
(defcustom magit-module-sections-hook
|
||||
@@ -220,26 +218,20 @@ it is nil, then PATH also becomes the name."
|
||||
(interactive
|
||||
(magit-with-toplevel
|
||||
(let* ((url (magit-read-string-ns "Add submodule (remote url)"))
|
||||
(path (let ((read-file-name-function
|
||||
(if (or (eq read-file-name-function 'ido-read-file-name)
|
||||
(advice-function-member-p
|
||||
'ido-read-file-name
|
||||
read-file-name-function))
|
||||
;; The Ido variant doesn't work properly here.
|
||||
#'read-file-name-default
|
||||
read-file-name-function)))
|
||||
(directory-file-name
|
||||
(file-relative-name
|
||||
(read-directory-name
|
||||
"Add submodules at path: " nil nil nil
|
||||
(and (string-match "\\([^./]+\\)\\(\\.git\\)?$" url)
|
||||
(match-string 1 url))))))))
|
||||
(path (magit-submodule-read-path "Add submodules at path: " url)))
|
||||
(list url
|
||||
(directory-file-name path)
|
||||
(magit-submodule-read-name-for-path path)
|
||||
(magit-submodule-arguments "--force")))))
|
||||
(magit-submodule-add-1 url path name args))
|
||||
|
||||
(defun magit-submodule-read-path (prompt url)
|
||||
(directory-file-name
|
||||
(file-relative-name
|
||||
(read-directory-name prompt nil nil nil
|
||||
(and (string-match "\\([^./]+\\)\\(\\.git\\)?$" url)
|
||||
(match-string 1 url))))))
|
||||
|
||||
(defun magit-submodule-add-1 (url &optional path name args)
|
||||
(magit-with-toplevel
|
||||
(magit-submodule--maybe-reuse-gitdir name path)
|
||||
@@ -525,9 +517,9 @@ or, failing that, the abbreviated HEAD commit hash."
|
||||
:doc "Keymap for `module' sections."
|
||||
"C-j" #'magit-submodule-visit
|
||||
"C-<return>" #'magit-submodule-visit
|
||||
"<remap> <magit-unstage-file>" #'magit-unstage
|
||||
"<remap> <magit-stage-file>" #'magit-stage
|
||||
"<remap> <magit-visit-thing>" #'magit-submodule-visit
|
||||
"<remap> <magit-unstage-files>" #'magit-unstage
|
||||
"<remap> <magit-stage-files>" #'magit-stage
|
||||
"<remap> <magit-visit-thing>" #'magit-submodule-visit
|
||||
"<5>" (magit-menu-item "Module commands..." #'magit-submodule)
|
||||
"<4>" '(menu-item "--")
|
||||
"<3>" (magit-menu-item "Unstage %T" #'magit-unstage
|
||||
|
||||
@@ -82,7 +82,6 @@
|
||||
(topdir (magit-toplevel))
|
||||
(prefix (read-directory-name (concat prompt ": ") topdir default)))
|
||||
(if (file-name-absolute-p prefix)
|
||||
;; At least `ido-mode's variant is not compatible.
|
||||
(if (string-prefix-p topdir prefix)
|
||||
(file-relative-name prefix topdir)
|
||||
(user-error "%s isn't inside the repository at %s" prefix topdir))
|
||||
|
||||
@@ -93,19 +93,27 @@
|
||||
(let ((choices (oref obj choices)))
|
||||
(when (functionp choices)
|
||||
(setq choices (funcall choices)))
|
||||
(if-let ((value (oref obj value)))
|
||||
(cadr (member value choices))
|
||||
(car 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)))))
|
||||
|
||||
;;;; Readers
|
||||
|
||||
(defun magit-transient-read-person (prompt initial-input history)
|
||||
(magit-completing-read
|
||||
prompt
|
||||
(mapcar (lambda (line)
|
||||
(save-excursion
|
||||
(and (string-match "\\`[\s\t]+[0-9]+\t" line)
|
||||
(list (substring line (match-end 0))))))
|
||||
(mapcar (##save-excursion
|
||||
(and (string-match "\\`[\s\t]+[0-9]+\t" %)
|
||||
(list (substring % (match-end 0)))))
|
||||
(magit-git-lines "shortlog" "-n" "-s" "-e" "HEAD"))
|
||||
nil nil initial-input history))
|
||||
|
||||
@@ -151,9 +159,8 @@
|
||||
(if-let ((value (oref obj value)))
|
||||
(if (oref obj multi-value)
|
||||
(if (cdr value)
|
||||
(mapconcat (lambda (v)
|
||||
(concat "\n "
|
||||
(propertize v 'face 'transient-value)))
|
||||
(mapconcat (##concat "\n "
|
||||
(propertize % 'face 'transient-value))
|
||||
value "")
|
||||
(propertize (car value) 'face 'transient-value))
|
||||
(propertize (car (split-string value "\n"))
|
||||
@@ -165,6 +172,16 @@
|
||||
(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)))
|
||||
(concat
|
||||
(propertize "[" 'face 'transient-inactive-value)
|
||||
(mapconcat #'identity choices
|
||||
(propertize "|" 'face 'transient-inactive-value))
|
||||
(and fallback (propertize "|" 'face 'transient-inactive-value))
|
||||
fallback
|
||||
(propertize "]" 'face 'transient-inactive-value))))
|
||||
|
||||
(defun magit--git-variable-list-choices (obj)
|
||||
(let* ((variable (oref obj variable))
|
||||
(choices (oref obj choices))
|
||||
(globalp (oref obj global))
|
||||
@@ -182,42 +199,35 @@
|
||||
(setq global nil))
|
||||
(when (functionp choices)
|
||||
(setq choices (funcall choices)))
|
||||
(concat
|
||||
(propertize "[" 'face 'transient-inactive-value)
|
||||
(mapconcat (lambda (choice)
|
||||
(propertize choice 'face (if (equal choice value)
|
||||
(if (member choice choices)
|
||||
'transient-value
|
||||
'font-lock-warning-face)
|
||||
'transient-inactive-value)))
|
||||
(if (and value (not (member value choices)))
|
||||
(cons value choices)
|
||||
choices)
|
||||
(propertize "|" 'face 'transient-inactive-value))
|
||||
(and (or global fallback default)
|
||||
(concat
|
||||
(propertize "|" 'face 'transient-inactive-value)
|
||||
(cond (global
|
||||
(propertize (concat "global:" global)
|
||||
'face (cond (value
|
||||
'transient-inactive-value)
|
||||
((member global choices)
|
||||
'transient-value)
|
||||
(t
|
||||
'font-lock-warning-face))))
|
||||
(fallback
|
||||
(propertize fallback
|
||||
'face (if value
|
||||
'transient-inactive-value
|
||||
'transient-value)))
|
||||
(default
|
||||
(propertize (if (functionp defaultp)
|
||||
(concat "dwim:" default)
|
||||
(concat "default:" default))
|
||||
'face (if value
|
||||
'transient-inactive-value
|
||||
'transient-value))))))
|
||||
(propertize "]" 'face 'transient-inactive-value))))
|
||||
(cons (cond (global
|
||||
(propertize (concat "global:" global)
|
||||
'face (cond (value
|
||||
'transient-inactive-value)
|
||||
((member global choices)
|
||||
'transient-value)
|
||||
(t
|
||||
'font-lock-warning-face))))
|
||||
(fallback
|
||||
(propertize fallback
|
||||
'face (if value
|
||||
'transient-inactive-value
|
||||
'transient-value)))
|
||||
(default
|
||||
(propertize (if (functionp defaultp)
|
||||
(concat "dwim:" default)
|
||||
(concat "default:" default))
|
||||
'face (if value
|
||||
'transient-inactive-value
|
||||
'transient-value))))
|
||||
(mapcar (lambda (choice)
|
||||
(propertize choice 'face (if (equal choice value)
|
||||
(if (member choice choices)
|
||||
'transient-value
|
||||
'font-lock-warning-face)
|
||||
'transient-inactive-value)))
|
||||
(if (and value (not (member value choices)))
|
||||
(cons value choices)
|
||||
choices)))))
|
||||
|
||||
;;; Utilities
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
;;; magit-version.el --- the Magit version you are using
|
||||
;;; magit-version.el --- The Magit version you are using -*- lexical-binding:t -*-
|
||||
|
||||
(setq magit-version "4.3.1")
|
||||
(setq magit-version "4.3.6")
|
||||
|
||||
(provide 'migit-version)
|
||||
(provide 'magit-version)
|
||||
|
||||
;; Local Variables:
|
||||
;; version-control: never
|
||||
|
||||
@@ -435,6 +435,27 @@ many \"branches\" of each wip ref are shown."
|
||||
(cl-decf count))
|
||||
(cons wipref (nreverse tips)))))
|
||||
|
||||
(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")))
|
||||
|
||||
;;; _
|
||||
(provide 'magit-wip)
|
||||
;;; magit-wip.el ends here
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
;; Homepage: https://github.com/magit/magit
|
||||
;; Keywords: git tools vc
|
||||
|
||||
;; Package-Version: 4.3.1
|
||||
;; Package-Version: 20250621.2237
|
||||
;; Package-Revision: a4f73fb2fb55
|
||||
;; Package-Requires: (
|
||||
;; (emacs "27.1")
|
||||
;; (compat "30.0.2.0")
|
||||
;; (llama "0.6.1")
|
||||
;; (magit-section "4.3.1")
|
||||
;; (compat "30.1")
|
||||
;; (llama "0.6.3")
|
||||
;; (magit-section "4.3.6")
|
||||
;; (seq "2.24")
|
||||
;; (transient "0.8.5")
|
||||
;; (with-editor "3.4.3"))
|
||||
;; (transient "0.9.0")
|
||||
;; (with-editor "3.4.4"))
|
||||
|
||||
;; SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
@@ -782,6 +783,7 @@ For X11 something like ~/.xinitrc should work.\n"
|
||||
(require 'magit-gitignore)
|
||||
(require 'magit-sparse-checkout)
|
||||
(require 'magit-extras)
|
||||
(require 'magit-dired)
|
||||
(require 'git-rebase)
|
||||
(require 'magit-bookmark)))
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user