New upstream version 3.1.0
Matteo F. Vescovi
2 years ago
0 | * It's Magit! A Git Porcelain inside Emacs | |
1 | ||
2 | Magit is a text-based Git user interface that puts an unmatched focus | |
3 | on streamlining workflows. Commands are invoked using short mnemonic | |
4 | key sequences that take the cursor’s position in the highly actionable | |
5 | interface into account to provide context-sensitive behavior. | |
6 | ||
7 | With Magit you can do nearly everything that you can do when using Git | |
8 | on the command-line, but at greater speed and while taking advantage | |
9 | of advanced features that previously seemed too daunting to use on a | |
10 | daily basis. Many users will find that by using Magit they can become | |
11 | more effective Git user. | |
12 | ||
13 | For more information about Magit, see https://magit.vc. | |
14 | ||
15 | * Magit v3.1.0 Release Notes | |
16 | ||
17 | Released 1st July 2021 by Jonas Bernoulli. | |
18 | ||
19 | I am pleased to announce the release of Magit version 3.1.0, | |
20 | representing 31 commits by 4 contributors over one month. | |
21 | ||
22 | Also see https://emacsair.me/2021/07/01/magit-3.1. | |
23 | ||
24 | ** Breaking changes | |
25 | ||
26 | - The function signature of ~magit-completing-read-multiple~ was not | |
27 | compatible with that of ~completing-read-multiple~, so we deprecate | |
28 | it. Use the improved ~magit-completing-read-multiple*~ instead. | |
29 | #4420 | |
30 | ||
31 | - The description of ~magit-merge-into~ in the merge menu was changed | |
32 | to "dissolve" (from "merge into"). In the future we are going to | |
33 | change the key binding from "i" to "d" as well, to keep it mnemonic. | |
34 | We don't make both changes at once in the hope that this makes the | |
35 | transition easier for existing users. 4c096921f | |
36 | ||
37 | ** Changes since v3.0.0 | |
38 | ||
39 | - Adjusted to changes to Eieio in Emacs 28. a3626277c, 54a0019f3 | |
40 | ||
41 | - Added new command ~magit-log-move-to-revision~. #4418 | |
42 | ||
43 | - ~A m~ is now also bound to ~magit-merge-squash~. Despite the name it | |
44 | fits better there. 51152fdec | |
45 | ||
46 | ** Fixes since v3.0.0 | |
47 | ||
48 | - Fixed ~magit-emacs-Q-command~ and ~make build~ for ELPA users. | |
49 | f50c3aa56 | |
50 | ||
51 | - Fixed reading choice in ~magit-process-git-credential-manager-core~. | |
52 | #4396 | |
53 | ||
54 | - ~magit-blame~ didn't account for quoted file names when parsing | |
55 | output from ~git blame~. #4400 | |
56 | ||
57 | - A regression in v3.0.0 prevented ~magit-bisect-run~ from executing | |
58 | ~git bisect run~ unless ~magit-bisect-start~ was called beforehand. | |
59 | f592e367d | |
60 | ||
61 | - ~magit-log-select-quit~ failed to call ~magit-log-select-quit-function~. | |
62 | #4423 | |
63 | ||
64 | - The entry for pull-requests in ~magit-list-refs-namespaces~ did not | |
65 | match the ref names used by Forge for that purpose. 4c3373f9a | |
66 | ||
67 | * Authors | |
68 | ||
69 | 24 Jonas Bernoulli | |
70 | 3 Kyle Meyer | |
71 | 1 Siavash Askari Nasr | |
72 | 1 TEC |
7 | 7 | #+TEXINFO_DIR_CATEGORY: Emacs |
8 | 8 | #+TEXINFO_DIR_TITLE: Magit-Section: (magit-section). |
9 | 9 | #+TEXINFO_DIR_DESC: Use Magit sections in your own packages. |
10 | #+SUBTITLE: for version 3.0.0 | |
10 | #+SUBTITLE: for version 3.1.0 | |
11 | 11 | |
12 | 12 | #+TEXINFO_DEFFN: t |
13 | 13 | #+OPTIONS: H:4 num:3 toc:2 |
25 | 25 | can use sections in your own packages. |
26 | 26 | |
27 | 27 | #+TEXINFO: @noindent |
28 | This manual is for Magit-Section version 3.0.0. | |
28 | This manual is for Magit-Section version 3.1.0. | |
29 | 29 | |
30 | 30 | #+BEGIN_QUOTE |
31 | 31 | Copyright (C) 2015-2021 Jonas Bernoulli <jonas@bernoul.li> |
30 | 30 | @finalout |
31 | 31 | @titlepage |
32 | 32 | @title Magit-Section Developer Manual |
33 | @subtitle for version 3.0.0 | |
33 | @subtitle for version 3.1.0 | |
34 | 34 | @author Jonas Bernoulli |
35 | 35 | @page |
36 | 36 | @vskip 0pt plus 1filll |
53 | 53 | can use sections in your own packages. |
54 | 54 | |
55 | 55 | @noindent |
56 | This manual is for Magit-Section version 3.0.0. | |
56 | This manual is for Magit-Section version 3.1.0. | |
57 | 57 | |
58 | 58 | @quotation |
59 | 59 | Copyright (C) 2015-2021 Jonas Bernoulli <jonas@@bernoul.li> |
7 | 7 | #+TEXINFO_DIR_CATEGORY: Emacs |
8 | 8 | #+TEXINFO_DIR_TITLE: Magit: (magit). |
9 | 9 | #+TEXINFO_DIR_DESC: Using Git from Emacs with Magit. |
10 | #+SUBTITLE: for version 3.0.0 | |
10 | #+SUBTITLE: for version 3.1.0 | |
11 | 11 | |
12 | 12 | #+TEXINFO_DEFFN: t |
13 | 13 | #+OPTIONS: H:4 num:3 toc:2 |
24 | 24 | Magit and Git itself deserve to be called porcelains. |
25 | 25 | |
26 | 26 | #+TEXINFO: @noindent |
27 | This manual is for Magit version 3.0.0. | |
27 | This manual is for Magit version 3.1.0. | |
28 | 28 | |
29 | 29 | #+BEGIN_QUOTE |
30 | 30 | Copyright (C) 2015-2021 Jonas Bernoulli <jonas@bernoul.li> |
2615 | 2615 | first parent, but a numeric prefix can be used to specify another |
2616 | 2616 | parent. |
2617 | 2617 | |
2618 | - Key: j, magit-log-move-to-revision | |
2619 | ||
2620 | Read a revision and move to it in current log buffer. | |
2621 | ||
2622 | If the chosen reference or revision isn't being displayed in | |
2623 | the current log buffer, then inform the user about that and do | |
2624 | nothing else. | |
2625 | ||
2626 | If invoked outside any log buffer, then display the log buffer | |
2627 | of the current repository first; creating it if necessary. | |
2628 | ||
2618 | 2629 | - Key: SPC, magit-diff-show-or-scroll-up |
2619 | 2630 | |
2620 | 2631 | Update the commit or diff buffer for the thing at point. |
4397 | 4408 | always require confirmation because making an error while using |
4398 | 4409 | those is harder to recover from. |
4399 | 4410 | |
4400 | - User Option magit-post-commit-hook | |
4411 | - User Option: magit-post-commit-hook | |
4401 | 4412 | |
4402 | 4413 | Hook run after creating a commit without the user editing a message. |
4403 | 4414 | |
7491 | 7502 | |
7492 | 7503 | **** Log Performance |
7493 | 7504 | :PROPERTIES: |
7494 | :NONODE: t | |
7505 | :UNNUMBERED: notoc | |
7495 | 7506 | :END: |
7496 | 7507 | |
7497 | 7508 | When showing logs, Magit limits the number of commits initially shown |
7521 | 7532 | |
7522 | 7533 | **** Diff Performance |
7523 | 7534 | :PROPERTIES: |
7524 | :NONODE: t | |
7535 | :UNNUMBERED: notoc | |
7525 | 7536 | :END: |
7526 | 7537 | |
7527 | 7538 | If diffs are slow, then consider turning off some optional diff |
7548 | 7559 | |
7549 | 7560 | **** Refs Buffer Performance |
7550 | 7561 | :PROPERTIES: |
7551 | :NONODE: t | |
7562 | :UNNUMBERED: notoc | |
7552 | 7563 | :END: |
7553 | 7564 | |
7554 | 7565 | When refreshing the "references buffer" is slow, then that's usually |
7568 | 7579 | |
7569 | 7580 | **** Committing Performance |
7570 | 7581 | :PROPERTIES: |
7571 | :NONODE: t | |
7582 | :UNNUMBERED: notoc | |
7572 | 7583 | :END: |
7573 | 7584 | |
7574 | 7585 | When you initiate a commit, then Magit by default automatically shows |
7848 | 7859 | filesystem, this function actually runs git asynchronously. But |
7849 | 7860 | then it waits for the process to return, so the function itself is |
7850 | 7861 | synchronous. |
7851 | ||
7852 | - Function: magit-run-git-with-logfile file &rest args | |
7853 | ||
7854 | Calls git synchronously with ARGS. The process's output is saved in | |
7855 | FILE. This is rarely useful and so this function might be removed | |
7856 | in the future. | |
7857 | ||
7858 | This function actually runs git asynchronously. But then it waits | |
7859 | for the process to return, so the function itself is synchronous. | |
7860 | 7862 | |
7861 | 7863 | - Function: magit-git &rest args |
7862 | 7864 | |
8715 | 8717 | always visible. If that is too drastic for your taste, then you may |
8716 | 8718 | instead use ~magit-diff-visit-file-hook~ to reveal the text, possibly |
8717 | 8719 | using ~reveal-post-command~ or for Org buffers ~org-reveal~. |
8720 | ||
8721 | *** I am unable to stage when using Tramp from MS Windows | |
8722 | ||
8723 | Magit may be unable to stage (or otherwise apply) individual hunks | |
8724 | when you are connected to remote machine using Tramp and the local | |
8725 | machine uses MS Windows. | |
8726 | ||
8727 | There appears to be a problem with ~process-send-eof~ in this scenario, | |
8728 | as mentioned at the end of ~tramp-tests.el~. I have contacted the Tramp | |
8729 | maintainer about this. For now this unfortunately means that it just | |
8730 | doesn't work and we cannot do anything about it. If you have more | |
8731 | information, then please comment on | |
8732 | https://github.com/magit/magit/issues/3624. | |
8733 | ||
8734 | *** I am no longer able to save popup defaults | |
8735 | ||
8736 | Magit used to use Magit-Popup to implement the transient popup menus. | |
8737 | Now it used Transient instead, which is Magit-Popup's successor. | |
8738 | ||
8739 | In the older Magit-Popup menus, it was possible to save user settings | |
8740 | (e.g. setting the gpg signing key for commits) by using ~C-c C-c~ in the | |
8741 | popup buffer. This would dismiss the popup, but save the settings as | |
8742 | the defaults for future popups. | |
8743 | ||
8744 | When switching to Transient menus, this functionality is now available | |
8745 | via ~C-x C-s~ instead; the ~C-x~ prefix has other options as well when | |
8746 | using Transient, which will be displayed when it is typed. See | |
8747 | https://magit.vc/manual/transient/Saving-Values.html#Saving-Values for | |
8748 | more details. | |
8718 | 8749 | |
8719 | 8750 | * Debugging Tools |
8720 | 8751 |
30 | 30 | @finalout |
31 | 31 | @titlepage |
32 | 32 | @title Magit User Manual |
33 | @subtitle for version 3.0.0 | |
33 | @subtitle for version 3.1.0 | |
34 | 34 | @author Jonas Bernoulli |
35 | 35 | @page |
36 | 36 | @vskip 0pt plus 1filll |
52 | 52 | Magit and Git itself deserve to be called porcelains. |
53 | 53 | |
54 | 54 | @noindent |
55 | This manual is for Magit version 3.0.0. | |
55 | This manual is for Magit version 3.1.0. | |
56 | 56 | |
57 | 57 | @quotation |
58 | 58 | Copyright (C) 2015-2021 Jonas Bernoulli <jonas@@bernoul.li> |
344 | 344 | * My Git hooks work on the command-line but not inside Magit:: |
345 | 345 | * @code{git-commit-mode} isn't used when committing from the command-line:: |
346 | 346 | * Point ends up inside invisible text when jumping to a file-visiting buffer:: |
347 | * I am unable to stage when using Tramp from MS Windows:: | |
348 | * I am no longer able to save popup defaults:: | |
347 | 349 | |
348 | 350 | |
349 | 351 | @end detailmenu |
3512 | 3514 | first parent, but a numeric prefix can be used to specify another |
3513 | 3515 | parent. |
3514 | 3516 | |
3517 | @kindex j | |
3518 | @cindex magit-log-move-to-revision | |
3519 | @item @kbd{j} @tie{}@tie{}@tie{}@tie{}(@code{magit-log-move-to-revision}) | |
3520 | ||
3521 | Read a revision and move to it in current log buffer. | |
3522 | ||
3523 | If the chosen reference or revision isn't being displayed in | |
3524 | the current log buffer, then inform the user about that and do | |
3525 | nothing else. | |
3526 | ||
3527 | If invoked outside any log buffer, then display the log buffer | |
3528 | of the current repository first; creating it if necessary. | |
3529 | ||
3515 | 3530 | @kindex SPC |
3516 | 3531 | @cindex magit-diff-show-or-scroll-up |
3517 | 3532 | @item @kbd{SPC} @tie{}@tie{}@tie{}@tie{}(@code{magit-diff-show-or-scroll-up}) |
6000 | 6015 | those is harder to recover from. |
6001 | 6016 | @end defopt |
6002 | 6017 | |
6003 | @itemize | |
6004 | @item | |
6005 | User Option magit-post-commit-hook | |
6018 | @defopt magit-post-commit-hook | |
6006 | 6019 | |
6007 | 6020 | Hook run after creating a commit without the user editing a message. |
6008 | 6021 | |
6012 | 6025 | the commit message in a buffer. |
6013 | 6026 | |
6014 | 6027 | Also see @code{git-commit-post-finish-hook}. |
6015 | @end itemize | |
6028 | @end defopt | |
6016 | 6029 | |
6017 | 6030 | @node Editing Commit Messages |
6018 | 6031 | @subsection Editing Commit Messages |
10175 | 10188 | * MacOS Performance:: |
10176 | 10189 | @end menu |
10177 | 10190 | |
10178 | @unnumberedsubsubsec Log Performance | |
10191 | @anchor{Log Performance} | |
10192 | @subsubheading Log Performance | |
10179 | 10193 | |
10180 | 10194 | When showing logs, Magit limits the number of commits initially shown |
10181 | 10195 | in the hope that this avoids unnecessary work. When using @code{--graph} is |
10202 | 10216 | merges. For that reason @code{--color} is not enabled by default anymore. |
10203 | 10217 | Consider leaving it at that. |
10204 | 10218 | |
10205 | @unnumberedsubsubsec Diff Performance | |
10219 | @anchor{Diff Performance} | |
10220 | @subsubheading Diff Performance | |
10206 | 10221 | |
10207 | 10222 | If diffs are slow, then consider turning off some optional diff |
10208 | 10223 | features by setting all or some of the following variables to @code{nil}: |
10225 | 10240 | setting, see @ref{Saving Values,,,transient,}. You should do this in both |
10226 | 10241 | the diff (@code{d}) and the diff refresh (@code{D}) transient popups. |
10227 | 10242 | |
10228 | @unnumberedsubsubsec Refs Buffer Performance | |
10243 | @anchor{Refs Buffer Performance} | |
10244 | @subsubheading Refs Buffer Performance | |
10229 | 10245 | |
10230 | 10246 | When refreshing the "references buffer" is slow, then that's usually |
10231 | 10247 | because several hundred refs are being displayed. The best way to |
10242 | 10258 | actually all exist. You can do so by pruning branches which no longer |
10243 | 10259 | exist using @code{f-pa}. |
10244 | 10260 | |
10245 | @unnumberedsubsubsec Committing Performance | |
10261 | @anchor{Committing Performance} | |
10262 | @subsubheading Committing Performance | |
10246 | 10263 | |
10247 | 10264 | When you initiate a commit, then Magit by default automatically shows |
10248 | 10265 | a diff of the changes you are about to commit. For large commits this |
10555 | 10572 | filesystem, this function actually runs git asynchronously. But |
10556 | 10573 | then it waits for the process to return, so the function itself is |
10557 | 10574 | synchronous. |
10558 | @end defun | |
10559 | ||
10560 | @defun magit-run-git-with-logfile file &rest args | |
10561 | ||
10562 | Calls git synchronously with ARGS@. The process's output is saved in | |
10563 | FILE@. This is rarely useful and so this function might be removed | |
10564 | in the future. | |
10565 | ||
10566 | This function actually runs git asynchronously. But then it waits | |
10567 | for the process to return, so the function itself is synchronous. | |
10568 | 10575 | @end defun |
10569 | 10576 | |
10570 | 10577 | @defun magit-git &rest args |
11335 | 11342 | * My Git hooks work on the command-line but not inside Magit:: |
11336 | 11343 | * @code{git-commit-mode} isn't used when committing from the command-line:: |
11337 | 11344 | * Point ends up inside invisible text when jumping to a file-visiting buffer:: |
11345 | * I am unable to stage when using Tramp from MS Windows:: | |
11346 | * I am no longer able to save popup defaults:: | |
11338 | 11347 | @end menu |
11339 | 11348 | |
11340 | 11349 | @node Magit is slow |
11533 | 11542 | instead use @code{magit-diff-visit-file-hook} to reveal the text, possibly |
11534 | 11543 | using @code{reveal-post-command} or for Org buffers @code{org-reveal}. |
11535 | 11544 | |
11545 | @node I am unable to stage when using Tramp from MS Windows | |
11546 | @appendixsubsec I am unable to stage when using Tramp from MS Windows | |
11547 | ||
11548 | Magit may be unable to stage (or otherwise apply) individual hunks | |
11549 | when you are connected to remote machine using Tramp and the local | |
11550 | machine uses MS Windows. | |
11551 | ||
11552 | There appears to be a problem with @code{process-send-eof} in this scenario, | |
11553 | as mentioned at the end of @code{tramp-tests.el}. I have contacted the Tramp | |
11554 | maintainer about this. For now this unfortunately means that it just | |
11555 | doesn't work and we cannot do anything about it. If you have more | |
11556 | information, then please comment on | |
11557 | @uref{https://github.com/magit/magit/issues/3624}. | |
11558 | ||
11559 | @node I am no longer able to save popup defaults | |
11560 | @appendixsubsec I am no longer able to save popup defaults | |
11561 | ||
11562 | Magit used to use Magit-Popup to implement the transient popup menus. | |
11563 | Now it used Transient instead, which is Magit-Popup's successor. | |
11564 | ||
11565 | In the older Magit-Popup menus, it was possible to save user settings | |
11566 | (e.g. setting the gpg signing key for commits) by using @code{C-c C-c} in the | |
11567 | popup buffer. This would dismiss the popup, but save the settings as | |
11568 | the defaults for future popups. | |
11569 | ||
11570 | When switching to Transient menus, this functionality is now available | |
11571 | via @code{C-x C-s} instead; the @code{C-x} prefix has other options as well when | |
11572 | using Transient, which will be displayed when it is typed. See | |
11573 | @uref{https://magit.vc/manual/transient/Saving-Values.html#Saving-Values} for | |
11574 | more details. | |
11575 | ||
11536 | 11576 | @node Debugging Tools |
11537 | 11577 | @chapter Debugging Tools |
11538 | 11578 |
222 | 222 | (with-editor ,with-editor-version)))) |
223 | 223 | (re-search-forward "^;; Package-Version: ") |
224 | 224 | (delete-region (point) (line-end-position)) |
225 | (insert git-commit-version)) | |
226 | ||
225 | (insert "$(GIT_COMMIT_VERSION)")) | |
227 | 226 | (with-temp-file "lisp/magit-libgit.el" |
228 | 227 | (insert-file-contents "lisp/magit-libgit.el") |
229 | 228 | (re-search-forward "^;; Package-Requires: ") |
234 | 233 | (libgit ,libgit-version)))) |
235 | 234 | (re-search-forward "^;; Package-Version: ") |
236 | 235 | (delete-region (point) (line-end-position)) |
237 | (insert magit-libgit-version)) | |
236 | (insert "$(MAGIT_LIBGIT_VERSION)")) | |
238 | 237 | (with-temp-file "lisp/magit-section.el" |
239 | 238 | (insert-file-contents "lisp/magit-section.el") |
240 | 239 | (re-search-forward "^;; Package-Requires: ") |
244 | 243 | (dash ,dash-version)))) |
245 | 244 | (re-search-forward "^;; Package-Version: ") |
246 | 245 | (delete-region (point) (line-end-position)) |
247 | (insert magit-section-version)) | |
246 | (insert "$(MAGIT_SECTION_VERSION)")) | |
248 | 247 | (with-temp-file "lisp/magit-pkg.el" |
249 | 248 | (insert (format |
250 | 249 | "(define-package \"magit\" \"$(VERSION)\"\ |
294 | 293 | (transient-version \"$(TRANSIENT_MELPA_SNAPSHOT)\")\ |
295 | 294 | (with-editor-version \"$(WITH_EDITOR_MELPA_SNAPSHOT)\"))\ |
296 | 295 | $$set_package_requires)" |
297 | @git commit -a -m "Reset Package-Requires for Melpa" | |
296 | @git commit -a --gpg-sign -m "Reset Package-Requires for Melpa" |
106 | 106 | git describe --tags --abbrev=0 --always | cut -c2-) |
107 | 107 | |
108 | 108 | DASH_VERSION = 2.18.1 |
109 | GIT_COMMIT_VERSION = $(VERSION) | |
109 | GIT_COMMIT_VERSION = 3.1.0 | |
110 | 110 | LIBGIT_VERSION = 0 |
111 | 111 | MAGIT_LIBGIT_VERSION = 0 |
112 | MAGIT_SECTION_VERSION = $(VERSION) | |
113 | TRANSIENT_VERSION = 0.3.3 | |
112 | MAGIT_SECTION_VERSION = 3.1.0 | |
113 | TRANSIENT_VERSION = 0.3.6 | |
114 | 114 | WITH_EDITOR_VERSION = 3.0.4 |
115 | 115 | |
116 | 116 | DASH_MELPA_SNAPSHOT = 20210330 |
117 | GIT_COMMIT_MELPA_SNAPSHOT = 20210524 | |
117 | GIT_COMMIT_MELPA_SNAPSHOT = 20210701 | |
118 | 118 | LIBGIT_MELPA_SNAPSHOT = 0 |
119 | 119 | MAGIT_LIBGIT_MELPA_SNAPSHOT = 0 |
120 | MAGIT_SECTION_MELPA_SNAPSHOT = 20210524 | |
121 | TRANSIENT_MELPA_SNAPSHOT = 20210524 | |
120 | MAGIT_SECTION_MELPA_SNAPSHOT = 20210701 | |
121 | TRANSIENT_MELPA_SNAPSHOT = 20210701 | |
122 | 122 | WITH_EDITOR_MELPA_SNAPSHOT = 20210524 |
123 | 123 | |
124 | 124 | EMACS_VERSION = 25.1 |
174 | 174 | WITH_EDITOR_DIR = $(TOP)../with-editor |
175 | 175 | endif |
176 | 176 | |
177 | MAGIT_SECTION_DIR ?= $(shell \ | |
178 | find -L $(ELPA_DIR) -maxdepth 1 -regex '.*/magit-section-[.0-9]*' 2> /dev/null | \ | |
179 | sort | tail -n 1) | |
180 | ||
177 | 181 | SYSTYPE := $(shell $(EMACSBIN) -Q --batch --eval "(princ system-type)") |
178 | 182 | ifeq ($(SYSTYPE), windows-nt) |
179 | 183 | CYGPATH := $(shell cygpath --version 2>/dev/null) |
191 | 195 | LOAD_PATH += -L $(shell cygpath --mixed $(LIBGIT_DIR)) |
192 | 196 | LOAD_PATH += -L $(shell cygpath --mixed $(TRANSIENT_DIR)) |
193 | 197 | LOAD_PATH += -L $(shell cygpath --mixed $(WITH_EDITOR_DIR)) |
198 | ifneq "$(MAGIT_SECTION_DIR)" "" | |
199 | LOAD_PATH += -L $(shell cygpath --mixed $(MAGIT_SECTION_DIR)) | |
200 | endif | |
194 | 201 | else |
195 | 202 | LOAD_PATH += -L $(DASH_DIR) |
196 | 203 | LOAD_PATH += -L $(LIBGIT_DIR) |
197 | 204 | LOAD_PATH += -L $(TRANSIENT_DIR) |
198 | 205 | LOAD_PATH += -L $(WITH_EDITOR_DIR) |
206 | ifneq "$(MAGIT_SECTION_DIR)" "" | |
207 | LOAD_PATH += -L $(MAGIT_SECTION_DIR) | |
208 | endif | |
199 | 209 | endif |
200 | 210 | |
201 | 211 | endif # ifndef LOAD_PATH |
12 | 12 | |
13 | 13 | ;; Keywords: git tools vc |
14 | 14 | ;; Homepage: https://github.com/magit/magit |
15 | ;; Package-Requires: ((emacs "25.1") (dash "2.18.1") (transient "0.3.3") (with-editor "3.0.4")) | |
16 | ;; Package-Version: 3.0.0 | |
15 | ;; Package-Requires: ((emacs "25.1") (dash "2.18.1") (transient "0.3.6") (with-editor "3.0.4")) | |
16 | ;; Package-Version: 3.1.0 | |
17 | 17 | ;; SPDX-License-Identifier: GPL-3.0-or-later |
18 | 18 | |
19 | 19 | ;; This file is free software; you can redistribute it and/or modify |
66 | 66 | ("-p" "Follow only first parent of a merge" "--first-parent" |
67 | 67 | :if (lambda () (version<= "2.29" (magit-git-version)))) |
68 | 68 | (6 magit-bisect:--term-old |
69 | :if (lambda () (version<= "2.7" (magit-git-version)))) | |
69 | :if (lambda () (version<= "2.7" (magit-git-version)))) | |
70 | 70 | (6 magit-bisect:--term-new |
71 | :if (lambda () (version<= "2.7" (magit-git-version))))] | |
71 | :if (lambda () (version<= "2.7" (magit-git-version))))] | |
72 | 72 | ["Actions" |
73 | 73 | ("B" "Start" magit-bisect-start) |
74 | 74 | ("s" "Start script" magit-bisect-run)]] |
77 | 77 | ("B" "Bad" magit-bisect-bad) |
78 | 78 | ("g" "Good" magit-bisect-good) |
79 | 79 | (6 "m" "Mark" magit-bisect-mark |
80 | :if (lambda () (version<= "2.7" (magit-git-version)))) | |
80 | :if (lambda () (version<= "2.7" (magit-git-version)))) | |
81 | 81 | ("k" "Skip" magit-bisect-skip) |
82 | 82 | ("r" "Reset" magit-bisect-reset) |
83 | 83 | ("s" "Run script" magit-bisect-run)]) |
195 | 195 | (magit-bisect-start-read-args)))) |
196 | 196 | (cons (read-shell-command "Bisect shell command: ") args))) |
197 | 197 | (when (and bad good) |
198 | (magit-bisect-start bad good args)) | |
198 | ;; Avoid `magit-git-bisect' because it's asynchronous, but the | |
199 | ;; next `git bisect run' call requires the bisect to be started. | |
200 | (magit-with-toplevel | |
201 | (apply #'magit-process-file magit-git-executable | |
202 | nil (list :file (magit-git-dir "BISECT_CMD_OUTPUT")) nil | |
203 | (magit-process-git-arguments | |
204 | (list "bisect" "start" bad good args))) | |
205 | (magit-refresh))) | |
199 | 206 | (magit-git-bisect "run" (list shell-file-name shell-command-switch cmdline))) |
200 | 207 | |
201 | 208 | (defun magit-git-bisect (subcommand &optional args no-assert) |
487 | 487 | (while (not done) |
488 | 488 | (cond ((looking-at "^filename \\(.+\\)") |
489 | 489 | (setq done t) |
490 | (setf orig-file (match-string 1))) | |
490 | (setf orig-file (magit-decode-git-path (match-string 1)))) | |
491 | 491 | ((looking-at "^previous \\(.\\{40\\}\\) \\(.+\\)") |
492 | 492 | (setf prev-rev (match-string 1)) |
493 | (setf prev-file (match-string 2))) | |
493 | (setf prev-file (magit-decode-git-path (match-string 2)))) | |
494 | 494 | ((looking-at "^\\([^ ]+\\) \\(.+\\)") |
495 | 495 | (push (cons (match-string 1) |
496 | 496 | (match-string 2)) revinfo))) |
700 | 700 | (when (magit-blame--style-get 'show-message) |
701 | 701 | (let ((message-log-max 0)) |
702 | 702 | (if-let ((msg (cdr (assoc "summary" |
703 | (gethash (oref (magit-current-blame-chunk) | |
704 | orig-rev) | |
705 | magit-blame-cache))))) | |
703 | (gethash (oref (magit-current-blame-chunk) | |
704 | orig-rev) | |
705 | magit-blame-cache))))) | |
706 | 706 | (progn (set-text-properties 0 (length msg) nil msg) |
707 | 707 | (message msg)) |
708 | 708 | (message "Commit data not available yet. Still blaming."))))) |
282 | 282 | |
283 | 283 | With a prefix argument the target COMMIT has to be confirmed. |
284 | 284 | Otherwise the commit at point may be used without confirmation |
285 | depending on the value of option `magit-commit-squash-confirm'." | |
285 | depending on the value of option `magit-commit-squash-confirm'. | |
286 | ||
287 | If you want to immediately add a message to the squash commit, | |
288 | then use `magit-commit-augment' instead of this command." | |
286 | 289 | (interactive (list (magit-commit-at-point) |
287 | 290 | (magit-commit-arguments))) |
288 | 291 | (magit-commit-squash-internal "--squash" commit args)) |
833 | 833 | ;;; Section Classes |
834 | 834 | |
835 | 835 | (defclass magit-file-section (magit-section) |
836 | ((keymap :initform magit-file-section-map) | |
836 | ((keymap :initform 'magit-file-section-map) | |
837 | 837 | (source :initform nil) |
838 | 838 | (header :initform nil))) |
839 | 839 | |
840 | 840 | (defclass magit-module-section (magit-file-section) |
841 | ((keymap :initform magit-hunk-section-map))) | |
841 | ((keymap :initform 'magit-hunk-section-map))) | |
842 | 842 | |
843 | 843 | (defclass magit-hunk-section (magit-section) |
844 | ((keymap :initform magit-hunk-section-map) | |
844 | ((keymap :initform 'magit-hunk-section-map) | |
845 | 845 | (refined :initform nil) |
846 | 846 | (combined :initform nil) |
847 | 847 | (from-range :initform nil) |
877 | 877 | ("-x" "Disallow external diff drivers" "--no-ext-diff") |
878 | 878 | ("-s" "Show stats" "--stat") |
879 | 879 | ("=g" "Show signature" "--show-signature") |
880 | (5 "-R" "Reverse sides" "-R") | |
880 | 881 | (5 magit-diff:--color-moved) |
881 | 882 | (5 magit-diff:--color-moved-ws)] |
882 | 883 | ["Actions" |
911 | 912 | ("-s" "Show stats" "--stat" |
912 | 913 | :if-derived magit-diff-mode) |
913 | 914 | ("=g" "Show signature" "--show-signature" |
915 | :if-derived magit-diff-mode) | |
916 | (5 "-R" "Reverse sides" "-R" | |
914 | 917 | :if-derived magit-diff-mode) |
915 | 918 | (5 magit-diff:--color-moved) |
916 | 919 | (5 magit-diff:--color-moved-ws)] |
1908 | 1911 | (if (equal magit-buffer-typearg "--no-index") |
1909 | 1912 | (apply #'format "Differences between %s and %s" magit-buffer-diff-files) |
1910 | 1913 | (concat (if magit-buffer-range |
1911 | (if (string-match-p "\\(\\.\\.\\|\\^-\\)" | |
1912 | magit-buffer-range) | |
1913 | (format "Changes in %s" magit-buffer-range) | |
1914 | (format "Changes from %s to working tree" magit-buffer-range)) | |
1914 | (cond | |
1915 | ((string-match-p "\\(\\.\\.\\|\\^-\\)" | |
1916 | magit-buffer-range) | |
1917 | (format "Changes in %s" magit-buffer-range)) | |
1918 | ((member "-R" magit-buffer-diff-args) | |
1919 | (format "Changes from working tree to %s" magit-buffer-range)) | |
1920 | (t | |
1921 | (format "Changes from %s to working tree" magit-buffer-range))) | |
1915 | 1922 | (if (equal magit-buffer-typearg "--cached") |
1916 | 1923 | "Staged changes" |
1917 | 1924 | "Unstaged changes")) |
2023 | 2030 | (pcase-let ((`(,cmd . ,args) |
2024 | 2031 | (-flatten args)) |
2025 | 2032 | (magit-git-global-arguments |
2026 | (remove "--literal-pathspecs" magit-git-global-arguments))) | |
2033 | (remove "--literal-pathspecs" magit-git-global-arguments))) | |
2027 | 2034 | ;; As of Git 2.19.0, we need to generate diffs with |
2028 | 2035 | ;; --ita-visible-in-index so that `magit-stage' can work with |
2029 | 2036 | ;; intent-to-add files (see #4026). Cache the result for each |
2851 | 2858 | (oref section children)) |
2852 | 2859 | (magit-section-match [* file commit] section)) |
2853 | 2860 | 'committed |
2854 | 'undefined)) | |
2861 | 'undefined)) | |
2855 | 2862 | (t 'undefined)))) |
2856 | 2863 | |
2857 | 2864 | (cl-defun magit-diff-scope (&optional (section nil ssection) strict) |
69 | 69 | (defvar magit-inhibit-libgit nil |
70 | 70 | "Whether to inhibit the use of libgit.") |
71 | 71 | |
72 | (defvar magit--libgit-available-p eieio-unbound | |
72 | (defvar magit--libgit-available-p 'unknown | |
73 | 73 | "Whether libgit is available. |
74 | 74 | Use the function by the same name instead of this variable.") |
75 | 75 | |
76 | 76 | (defun magit--libgit-available-p () |
77 | (if (eq magit--libgit-available-p eieio-unbound) | |
77 | (if (eq magit--libgit-available-p 'unknown) | |
78 | 78 | (setq magit--libgit-available-p |
79 | 79 | (and module-file-suffix |
80 | 80 | (let ((libgit (locate-library "libgit"))) |
222 | 222 | :group 'magit-commands |
223 | 223 | :type 'boolean) |
224 | 224 | |
225 | (defcustom magit-list-refs-namespaces | |
226 | '("refs/heads" | |
227 | "refs/remotes" | |
228 | "refs/tags" | |
229 | "refs/pullreqs") | |
230 | "List of ref namespaces considered when reading a ref. | |
231 | ||
232 | This controls the order of refs returned by `magit-list-refs', | |
233 | which is called by functions like `magit-list-branch-names' to | |
234 | generate the collection of refs." | |
235 | :package-version '(magit . "3.1.0") | |
236 | :group 'magit-commands | |
237 | :type '(repeat string)) | |
238 | ||
225 | 239 | (defcustom magit-list-refs-sortby nil |
226 | 240 | "How to sort the ref collection in the prompt. |
227 | 241 | |
537 | 551 | (gethash |
538 | 552 | ;; `git config --list' downcases first and last components of the key. |
539 | 553 | (--> key |
540 | (replace-regexp-in-string "\\`[^.]+" #'downcase it t t) | |
541 | (replace-regexp-in-string "[^.]+\\'" #'downcase it t t)) | |
554 | (replace-regexp-in-string "\\`[^.]+" #'downcase it t t) | |
555 | (replace-regexp-in-string "[^.]+\\'" #'downcase it t t)) | |
542 | 556 | (magit--with-refresh-cache (cons (magit-toplevel) 'config) |
543 | 557 | (let ((configs (make-hash-table :test 'equal))) |
544 | 558 | (dolist (conf (magit-git-items "config" "--list" "-z")) |
1608 | 1622 | (list it (car (magit-rev-diff-count it rev))) |
1609 | 1623 | it)))))) |
1610 | 1624 | |
1611 | (defvar magit-list-refs-namespaces | |
1612 | '("refs/heads" "refs/remotes" "refs/tags" "refs/pull")) | |
1613 | ||
1614 | 1625 | (defun magit-list-refs (&optional namespaces format sortby) |
1615 | 1626 | "Return list of references. |
1616 | 1627 | |
1670 | 1681 | |
1671 | 1682 | (defun magit-list-branches-pointing-at (commit) |
1672 | 1683 | (let ((re (format "\\`%s refs/\\(heads\\|remotes\\)/\\(.*\\)\\'" |
1673 | (magit-rev-verify commit)))) | |
1684 | (magit-rev-verify commit)))) | |
1674 | 1685 | (--keep (and (string-match re it) |
1675 | 1686 | (let ((name (match-string 2 it))) |
1676 | 1687 | (and (not (string-suffix-p "HEAD" name)) |
2182 | 2193 | (magit-get-current-branch)))) |
2183 | 2194 | |
2184 | 2195 | (defun magit-read-range (prompt &optional default) |
2185 | (magit-completing-read-multiple prompt | |
2186 | (magit-list-refnames) | |
2187 | "\\.\\.\\.?" | |
2188 | default 'magit-revision-history)) | |
2196 | (let ((crm-separator "\\.\\.\\.?")) | |
2197 | (magit-completing-read-multiple* | |
2198 | (concat prompt ": ") | |
2199 | (magit-list-refnames) | |
2200 | nil nil nil 'magit-revision-history default nil t))) | |
2189 | 2201 | |
2190 | 2202 | (defun magit-read-remote-branch |
2191 | 2203 | (prompt &optional remote default local-branch require-match) |
2224 | 2236 | (or (magit-completing-read prompt choices |
2225 | 2237 | nil nil nil 'magit-revision-history |
2226 | 2238 | (or (magit-local-branch-at-point) commit)) |
2227 | (user-error "Nothing selected")))) | |
2239 | (user-error "Nothing selected")))) | |
2228 | 2240 | |
2229 | 2241 | (defun magit-read-local-branch-or-ref (prompt &optional secondary-default) |
2230 | 2242 | (magit-completing-read prompt (nconc (magit-list-local-branch-names) |
9 | 9 | ;; Keywords: git tools vc |
10 | 10 | ;; Homepage: https://github.com/magit/magit |
11 | 11 | |
12 | ;; Package-Requires: ((emacs "26.1") (magit "3.0.0") (libgit "0")) | |
12 | ;; Package-Requires: ((emacs "26.1") (magit "3.1.0") (libgit "0")) | |
13 | 13 | ;; Package-Version: 0 |
14 | 14 | ;; SPDX-License-Identifier: GPL-3.0-or-later |
15 | 15 |
594 | 594 | |
595 | 595 | (defun magit-log-read-revs (&optional use-current) |
596 | 596 | (or (and use-current (--when-let (magit-get-current-branch) (list it))) |
597 | (let ((collection (magit-list-refnames nil t))) | |
598 | (split-string | |
599 | (magit-completing-read-multiple "Log rev,s" collection | |
600 | "\\(\\.\\.\\.?\\|[, ]\\)" | |
601 | (or (magit-branch-or-commit-at-point) | |
602 | (unless use-current | |
603 | (magit-get-previous-branch))) | |
604 | 'magit-revision-history | |
605 | magit-log-read-revs-map) | |
606 | "[, ]" t)))) | |
597 | (let ((crm-separator "\\(\\.\\.\\.?\\|[, ]\\)") | |
598 | (crm-local-completion-map magit-log-read-revs-map)) | |
599 | (split-string (magit-completing-read-multiple* | |
600 | "Log rev,s: " | |
601 | (magit-list-refnames nil t) | |
602 | nil nil nil 'magit-revision-history | |
603 | (or (magit-branch-or-commit-at-point) | |
604 | (unless use-current | |
605 | (magit-get-previous-branch))) | |
606 | nil t) | |
607 | "[, ]" t)))) | |
607 | 608 | |
608 | 609 | (defun magit-log-read-pattern (option) |
609 | 610 | "Read a string from the user to pass as parameter to OPTION." |
876 | 877 | "\\[magit-log-double-commit-limit] first")))) |
877 | 878 | (user-error "Parent %s does not exist" parent-rev)))))) |
878 | 879 | |
880 | (defun magit-log-move-to-revision (rev) | |
881 | "Read a revision and move to it in current log buffer. | |
882 | ||
883 | If the chosen reference or revision isn't being displayed in | |
884 | the current log buffer, then inform the user about that and do | |
885 | nothing else. | |
886 | ||
887 | If invoked outside any log buffer, then display the log buffer | |
888 | of the current repository first; creating it if necessary." | |
889 | (interactive (list (magit-read-branch-or-commit "In log, jump to"))) | |
890 | (with-current-buffer | |
891 | (cond ((derived-mode-p 'magit-log-mode) | |
892 | (current-buffer)) | |
893 | ((when-let ((buf (magit-get-mode-buffer 'magit-log-mode))) | |
894 | (pop-to-buffer-same-window buf))) | |
895 | (t | |
896 | (apply #'magit-log-all-branches (magit-log-arguments)))) | |
897 | (unless (magit-log-goto-commit-section (magit-rev-abbrev rev)) | |
898 | (user-error "%s isn't visible in the current log buffer" rev)))) | |
899 | ||
879 | 900 | ;;;; Shortlog Commands |
880 | 901 | |
881 | 902 | ;;;###autoload (autoload 'magit-shortlog "magit-log" nil t) |
930 | 951 | (define-key map "\C-c\C-b" 'magit-go-backward) |
931 | 952 | (define-key map "\C-c\C-f" 'magit-go-forward) |
932 | 953 | (define-key map "\C-c\C-n" 'magit-log-move-to-parent) |
954 | (define-key map "j" 'magit-log-move-to-revision) | |
933 | 955 | (define-key map "=" 'magit-log-toggle-commit-limit) |
934 | 956 | (define-key map "+" 'magit-log-double-commit-limit) |
935 | 957 | (define-key map "-" 'magit-log-half-commit-limit) |
1602 | 1624 | (funcall fun rev))) |
1603 | 1625 | |
1604 | 1626 | (defun magit-log-select-quit () |
1605 | "Abort selecting a commit, don't act on any commit." | |
1627 | "Abort selecting a commit, don't act on any commit. | |
1628 | Call `magit-log-select-quit-function' if set." | |
1606 | 1629 | (interactive) |
1607 | (magit-mode-bury-buffer 'kill) | |
1608 | (when magit-log-select-quit-function | |
1609 | (funcall magit-log-select-quit-function))) | |
1630 | (let ((fun magit-log-select-quit-function)) | |
1631 | (magit-mode-bury-buffer 'kill) | |
1632 | (when fun (funcall fun)))) | |
1610 | 1633 | |
1611 | 1634 | ;;; Cherry Mode |
1612 | 1635 |
57 | 57 | [("p" "Preview merge" magit-merge-preview) |
58 | 58 | "" |
59 | 59 | ("s" "Squash merge" magit-merge-squash) |
60 | ("i" "Merge into" magit-merge-into)]] | |
60 | ("i" "Dissolve" magit-merge-into)]] | |
61 | 61 | ["Actions" |
62 | 62 | :if magit-merge-in-progress-p |
63 | 63 | ("m" "Commit merge" magit-commit-create) |
1418 | 1418 | (dolist (buffer (magit-mode-get-buffers)) |
1419 | 1419 | (with-current-buffer buffer |
1420 | 1420 | (setq magit-section-visibility-cache nil))) |
1421 | (setq magit--libgit-available-p eieio-unbound)) | |
1421 | (setq magit--libgit-available-p 'unknown)) | |
1422 | 1422 | |
1423 | 1423 | ;;; Utilities |
1424 | 1424 |
191 | 191 | ",")))) |
192 | 192 | |
193 | 193 | (defun magit-notes-read-args (prompt) |
194 | (list (magit-read-branch-or-commit prompt (magit-stash-at-point)) | |
195 | (--when-let (--first (string-match "^--ref=\\(.+\\)" it) | |
196 | (transient-args 'magit-notes)) | |
197 | (match-string 1 it)))) | |
194 | (list (magit-read-branch-or-commit prompt (magit-stash-at-point)) | |
195 | (--when-let (--first (string-match "^--ref=\\(.+\\)" it) | |
196 | (transient-args 'magit-notes)) | |
197 | (match-string 1 it)))) | |
198 | 198 | |
199 | 199 | ;;; _ |
200 | 200 | (provide 'magit-notes) |
0 | (define-package "magit" "3.0.0" | |
0 | (define-package "magit" "3.1.0" | |
1 | 1 | "A Git porcelain inside Emacs." |
2 | 2 | '((emacs "25.1") |
3 | 3 | (dash "2.18.1") |
4 | (git-commit "3.0.0") | |
5 | (magit-section "3.0.0") | |
6 | (transient "0.3.3") | |
4 | (git-commit "3.1.0") | |
5 | (magit-section "3.1.0") | |
6 | (transient "0.3.6") | |
7 | 7 | (with-editor "3.0.4")) |
8 | 8 | :homepage "https://magit.vc" |
9 | 9 | :keywords '("git" "tools" "vc")) |
845 | 845 | (and (string-match "^option (enter for default): $" string) |
846 | 846 | (progn |
847 | 847 | (magit-process-buffer) |
848 | (process-send-string | |
849 | process | |
850 | (format "%c" (read-char-choice "Option: " '(?\r ?\j ?1 ?2))))))) | |
848 | (let ((option (format "%c\n" | |
849 | (read-char-choice "Option: " '(?\r ?\j ?1 ?2))))) | |
850 | (insert-before-markers-and-inherit option) | |
851 | (process-send-string process option))))) | |
851 | 852 | |
852 | 853 | (defun magit-process-password-prompt (process string) |
853 | 854 | "Find a password based on prompt STRING and send it to git. |
216 | 216 | is used." |
217 | 217 | (interactive |
218 | 218 | (list (magit-read-remote "Push to remote") |
219 | (split-string (magit-completing-read-multiple | |
220 | "Push refspec,s" | |
221 | (cons "HEAD" (magit-list-local-branch-names)) | |
222 | nil nil 'magit-push-refspecs-history) | |
223 | crm-default-separator t) | |
219 | (magit-completing-read-multiple* | |
220 | "Push refspec,s: " | |
221 | (cons "HEAD" (magit-list-local-branch-names)) | |
222 | nil nil nil 'magit-push-refspecs-history) | |
224 | 223 | (magit-push-arguments))) |
225 | 224 | (run-hooks 'magit-credential-hook) |
226 | 225 | (magit-run-git-async "push" "-v" args remote refspecs)) |
128 | 128 | (interactive) |
129 | 129 | (if magit-repository-directories |
130 | 130 | (with-current-buffer (get-buffer-create "*Magit Repositories*") |
131 | (message "Listing repositories...") | |
131 | 132 | (magit-repolist-mode) |
132 | 133 | (magit-repolist-refresh) |
133 | 134 | (tabulated-list-print) |
134 | (switch-to-buffer (current-buffer))) | |
135 | (switch-to-buffer (current-buffer)) | |
136 | (message "Listing repositories...done")) | |
135 | 137 | (message "You need to customize `magit-repository-directories' %s" |
136 | 138 | "before you can list repositories"))) |
137 | 139 |
10 | 10 | ;; Keywords: tools |
11 | 11 | ;; Homepage: https://github.com/magit/magit |
12 | 12 | ;; Package-Requires: ((emacs "25.1") (dash "2.18.1")) |
13 | ;; Package-Version: 3.0.0 | |
13 | ;; Package-Version: 3.1.0 | |
14 | 14 | ;; SPDX-License-Identifier: GPL-3.0-or-later |
15 | 15 | |
16 | 16 | ;; Magit-Section is free software; you can redistribute it and/or modify |
562 | 562 | `(defun ,name (&optional expand) ,(format "\ |
563 | 563 | Jump to the section \"%s\". |
564 | 564 | With a prefix argument also expand it." heading) |
565 | (interactive "P") | |
566 | (--if-let (magit-get-section | |
567 | (cons (cons ',type ,value) | |
568 | (magit-section-ident magit-root-section))) | |
569 | (progn (goto-char (oref it start)) | |
570 | (when expand | |
571 | (with-local-quit (magit-section-show it)) | |
572 | (recenter 0))) | |
573 | (message ,(format "Section \"%s\" wasn't found" heading))))) | |
565 | (interactive "P") | |
566 | (--if-let (magit-get-section | |
567 | (cons (cons ',type ,value) | |
568 | (magit-section-ident magit-root-section))) | |
569 | (progn (goto-char (oref it start)) | |
570 | (when expand | |
571 | (with-local-quit (magit-section-show it)) | |
572 | (recenter 0))) | |
573 | (message ,(format "Section \"%s\" wasn't found" heading))))) | |
574 | 574 | |
575 | 575 | ;;;; Visibility |
576 | 576 |
147 | 147 | ["Apply here" |
148 | 148 | ("A" "Pick" magit-cherry-copy) |
149 | 149 | ("a" "Apply" magit-cherry-apply) |
150 | ("h" "Harvest" magit-cherry-harvest)] | |
150 | ("h" "Harvest" magit-cherry-harvest) | |
151 | ("m" "Squash" magit-merge-squash)] | |
151 | 152 | ["Apply elsewhere" |
152 | 153 | ("d" "Donate" magit-cherry-donate) |
153 | 154 | ("n" "Spinout" magit-cherry-spinout) |
172 | 173 | |
173 | 174 | (defun magit--cherry-move-read-args (verb away fn) |
174 | 175 | (declare (indent defun)) |
175 | (let ((commits (or (nreverse (magit-region-values 'commit)) | |
176 | (list (funcall (if away | |
177 | 'magit-read-branch-or-commit | |
178 | 'magit-read-other-branch-or-commit) | |
179 | (format "%s cherry" (capitalize verb)))))) | |
180 | (current (magit-get-current-branch))) | |
181 | (unless current | |
182 | (user-error "Cannot %s cherries while HEAD is detached" verb)) | |
183 | (let ((reachable (magit-rev-ancestor-p (car commits) current)) | |
184 | (msg "Cannot %s cherries that %s reachable from HEAD")) | |
185 | (pcase (list away reachable) | |
186 | (`(nil t) (user-error msg verb "are")) | |
187 | (`(t nil) (user-error msg verb "are not")))) | |
188 | `(,commits | |
189 | ,@(funcall fn commits) | |
190 | ,(transient-args 'magit-cherry-pick)))) | |
176 | (let ((commits (or (nreverse (magit-region-values 'commit)) | |
177 | (list (funcall (if away | |
178 | 'magit-read-branch-or-commit | |
179 | 'magit-read-other-branch-or-commit) | |
180 | (format "%s cherry" (capitalize verb)))))) | |
181 | (current (magit-get-current-branch))) | |
182 | (unless current | |
183 | (user-error "Cannot %s cherries while HEAD is detached" verb)) | |
184 | (let ((reachable (magit-rev-ancestor-p (car commits) current)) | |
185 | (msg "Cannot %s cherries that %s reachable from HEAD")) | |
186 | (pcase (list away reachable) | |
187 | (`(nil t) (user-error msg verb "are")) | |
188 | (`(t nil) (user-error msg verb "are not")))) | |
189 | `(,commits | |
190 | ,@(funcall fn commits) | |
191 | ,(transient-args 'magit-cherry-pick)))) | |
191 | 192 | |
192 | 193 | (defun magit--cherry-spinoff-read-args (verb) |
193 | 194 | (magit--cherry-move-read-args verb t |
1040 | 1041 | (t |
1041 | 1042 | (list "done" rev 'magit-sequence-done))))) |
1042 | 1043 | (magit-sequence-insert-commit "onto" onto |
1043 | (if (equal onto head) | |
1044 | 'magit-sequence-head | |
1045 | 'magit-sequence-onto)))) | |
1044 | (if (equal onto head) | |
1045 | 'magit-sequence-head | |
1046 | 'magit-sequence-onto)))) | |
1046 | 1047 | |
1047 | 1048 | (defun magit-sequence-insert-commit (type hash face) |
1048 | (magit-insert-section (commit hash) | |
1049 | (magit-insert-section (commit hash) | |
1049 | 1050 | (magit-insert-heading |
1050 | 1051 | (propertize type 'font-lock-face face) "\s" |
1051 | 1052 | (magit-format-rev-summary hash) "\n"))) |
583 | 583 | (defun magit-list-submodules () |
584 | 584 | "Display a list of the current repository's submodules." |
585 | 585 | (interactive) |
586 | (message "Listing submodules...") | |
586 | 587 | (magit-display-buffer |
587 | 588 | (or (magit-get-mode-buffer 'magit-submodule-list-mode) |
588 | 589 | (magit-with-toplevel |
589 | 590 | (magit-generate-new-buffer 'magit-submodule-list-mode)))) |
590 | 591 | (magit-submodule-list-mode) |
591 | 592 | (magit-submodule-list-refresh) |
592 | (tabulated-list-print)) | |
593 | (tabulated-list-print) | |
594 | (message "Listing submodules...done")) | |
593 | 595 | |
594 | 596 | (defvar magit-submodule-list-mode-map |
595 | 597 | (let ((map (make-sparse-keymap))) |
533 | 533 | (complete-with-action action collection string pred)))) |
534 | 534 | |
535 | 535 | (defun magit-builtin-completing-read |
536 | (prompt choices &optional predicate require-match initial-input hist def) | |
536 | (prompt choices &optional predicate require-match initial-input hist def) | |
537 | 537 | "Magit wrapper for standard `completing-read' function." |
538 | 538 | (unless (or (bound-and-true-p helm-mode) |
539 | (bound-and-true-p ivy-mode) | |
540 | (bound-and-true-p vertico-mode) | |
541 | (bound-and-true-p selectrum-mode)) | |
542 | (setq prompt (magit-prompt-with-default prompt def))) | |
543 | (unless (or (bound-and-true-p helm-mode) | |
539 | 544 | (bound-and-true-p ivy-mode)) |
540 | (setq prompt (magit-prompt-with-default prompt def)) | |
541 | 545 | (setq choices (magit--completion-table choices))) |
542 | (cl-letf (((symbol-function 'completion-pcm--all-completions) | |
543 | #'magit-completion-pcm--all-completions)) | |
546 | (cl-letf (((symbol-function 'completion-pcm--all-completions))) | |
547 | (when (< emacs-major-version 26) | |
548 | (fset 'completion-pcm--all-completions | |
549 | 'magit-completion-pcm--all-completions)) | |
544 | 550 | (let ((ivy-sort-functions-alist nil)) |
545 | 551 | (completing-read prompt choices |
546 | 552 | predicate require-match |
547 | 553 | initial-input hist def)))) |
548 | 554 | |
549 | 555 | (defun magit-completing-read-multiple |
550 | (prompt choices &optional sep default hist keymap) | |
556 | (prompt choices &optional sep default hist keymap) | |
551 | 557 | "Read multiple items from CHOICES, separated by SEP. |
552 | 558 | |
553 | 559 | Set up the `crm' variables needed to read multiple values with |
560 | 566 | |
561 | 567 | Unlike `completing-read-multiple', the return value is not split |
562 | 568 | into a list." |
569 | (declare (obsolete magit-completing-read-multiple* "Magit 3.1.0")) | |
563 | 570 | (let* ((crm-separator (or sep crm-default-separator)) |
564 | 571 | (crm-completion-table (magit--completion-table choices)) |
565 | 572 | (choose-completion-string-functions |
570 | 577 | (helm-crm-default-separator nil) |
571 | 578 | (ivy-sort-matches-functions-alist nil) |
572 | 579 | (input |
573 | (cl-letf (((symbol-function 'completion-pcm--all-completions) | |
574 | #'magit-completion-pcm--all-completions)) | |
580 | (cl-letf (((symbol-function 'completion-pcm--all-completions))) | |
581 | (when (< emacs-major-version 26) | |
582 | (fset 'completion-pcm--all-completions | |
583 | 'magit-completion-pcm--all-completions)) | |
575 | 584 | (read-from-minibuffer |
576 | 585 | (concat prompt (and default (format " (%s)" default)) ": ") |
577 | 586 | nil (or keymap crm-local-completion-map) |
583 | 592 | |
584 | 593 | (defun magit-completing-read-multiple* |
585 | 594 | (prompt table &optional predicate require-match initial-input |
586 | hist def inherit-input-method) | |
595 | hist def inherit-input-method | |
596 | no-split) | |
587 | 597 | "Read multiple strings in the minibuffer, with completion. |
588 | 598 | Like `completing-read-multiple' but don't mess with order of |
589 | TABLE. Also bind `helm-completion-in-region-default-sort-fn' | |
590 | to nil." | |
591 | (unwind-protect | |
592 | (cl-letf (((symbol-function 'completion-pcm--all-completions) | |
593 | #'magit-completion-pcm--all-completions)) | |
594 | (add-hook 'choose-completion-string-functions | |
595 | 'crm--choose-completion-string) | |
596 | (let* ((minibuffer-completion-table #'crm--collection-fn) | |
597 | (minibuffer-completion-predicate predicate) | |
598 | ;; see completing_read in src/minibuf.c | |
599 | (minibuffer-completion-confirm | |
600 | (unless (eq require-match t) require-match)) | |
601 | (crm-completion-table (magit--completion-table table)) | |
602 | (map (if require-match | |
603 | crm-local-must-match-map | |
604 | crm-local-completion-map)) | |
605 | (helm-completion-in-region-default-sort-fn nil) | |
606 | (ivy-sort-matches-functions-alist nil) | |
607 | ;; If the user enters empty input, `read-from-minibuffer' | |
608 | ;; returns the empty string, not DEF. | |
609 | (input (read-from-minibuffer | |
610 | prompt initial-input map | |
611 | nil hist def inherit-input-method))) | |
612 | (and def (string-equal input "") (setq input def)) | |
613 | ;; Remove empty strings in the list of read strings. | |
614 | (split-string input crm-separator t))) | |
615 | (remove-hook 'choose-completion-string-functions | |
616 | 'crm--choose-completion-string))) | |
599 | TABLE and take an additional argument NO-SPLIT, which causes | |
600 | the user input to be returned as a single unmodified string. | |
601 | Also work around various misfeatures of various third-party | |
602 | completion frameworks." | |
603 | (cl-letf* | |
604 | (;; To implement NO-SPLIT we have to manipulate the respective | |
605 | ;; `split-string' invocation. We cannot simply advice it to | |
606 | ;; return the input string because `SELECTRUM' would choke on | |
607 | ;; it that string. Use a variable to pass along the raw user | |
608 | ;; input string. aa5f098ab | |
609 | (input nil) | |
610 | (split-string (symbol-function 'split-string)) | |
611 | ((symbol-function 'split-string) | |
612 | (lambda (string &optional separators omit-nulls trim) | |
613 | (when (and no-split | |
614 | (equal separators crm-separator) | |
615 | (equal omit-nulls t)) | |
616 | (setq input string)) | |
617 | (funcall split-string string separators omit-nulls trim))) | |
618 | ;; In Emacs 25 this function has a bug, so we use a copy of the | |
619 | ;; version from Emacs 26. bef9c7aa3 | |
620 | ((symbol-function 'completion-pcm--all-completions) | |
621 | (if (< emacs-major-version 26) | |
622 | 'magit-completion-pcm--all-completions | |
623 | (symbol-function 'completion-pcm--all-completions))) | |
624 | ;; Prevent `BUILT-IN' completion from messing up our existing | |
625 | ;; order of the completion candidates. aa5f098ab | |
626 | (table (magit--completion-table table)) | |
627 | ;; Prevent `IVY' from messing up our existing order. c7af78726 | |
628 | (ivy-sort-matches-functions-alist nil) | |
629 | ;; Prevent `HELM' from messing up our existing order. 6fcf994bd | |
630 | (helm-completion-in-region-default-sort-fn nil) | |
631 | ;; Prevent `HELM' from automatically appending the separator, | |
632 | ;; which is counterproductive when NO-SPLIT is non-nil and/or | |
633 | ;; when reading commit ranges. 798aff564 | |
634 | (helm-crm-default-separator | |
635 | (if no-split nil helm-crm-default-separator)) | |
636 | ;; And now, the moment we have all been waiting for... | |
637 | (values (completing-read-multiple | |
638 | prompt table predicate require-match initial-input | |
639 | hist def inherit-input-method))) | |
640 | (if no-split input values))) | |
617 | 641 | |
618 | 642 | (defun magit-ido-completing-read |
619 | (prompt choices &optional predicate require-match initial-input hist def) | |
643 | (prompt choices &optional predicate require-match initial-input hist def) | |
620 | 644 | "Ido-based `completing-read' almost-replacement. |
621 | 645 | |
622 | 646 | Unfortunately `ido-completing-read' is not suitable as a |
805 | 829 | "with-editor" |
806 | 830 | ;; Obviously `magit' itself is needed too. |
807 | 831 | "magit" |
808 | ;; While this is part of the Magit repository, | |
809 | ;; it is distributed as a separate package. | |
832 | ;; While these are part of the Magit repository, | |
833 | ;; they are distributed as separate packages. | |
834 | "magit-section" | |
810 | 835 | "git-commit" |
811 | ;; Even though `async' is a dependency of the | |
812 | ;; `magit' package, it is not required here. | |
813 | 836 | )))) |
814 | 837 | ;; Avoid Emacs bug#16406 by using full path. |
815 | 838 | "-l" ,(file-name-sans-extension (locate-library "magit"))) |
1024 | 1047 | (advice-add 'auto-revert-handler :around 'auto-revert-handler@bug21559) |
1025 | 1048 | ) |
1026 | 1049 | |
1027 | ;; `completion-pcm--all-completions' reverses the completion list. To | |
1028 | ;; preserve the order of our pre-sorted completions, we'll temporarily | |
1029 | ;; override it with the function below. bug#24676 | |
1030 | (defun magit-completion-pcm--all-completions (prefix pattern table pred) | |
1031 | (if (completion-pcm--pattern-trivial-p pattern) | |
1032 | (all-completions (concat prefix (car pattern)) table pred) | |
1033 | (let* ((regex (completion-pcm--pattern->regex pattern)) | |
1034 | (case-fold-search completion-ignore-case) | |
1035 | (completion-regexp-list (cons regex completion-regexp-list)) | |
1036 | (compl (all-completions | |
1037 | (concat prefix | |
1038 | (if (stringp (car pattern)) (car pattern) "")) | |
1039 | table pred))) | |
1040 | (if (not (functionp table)) | |
1041 | compl | |
1042 | (let ((poss ())) | |
1043 | (dolist (c compl) | |
1044 | (when (string-match-p regex c) (push c poss))) | |
1045 | ;; This `nreverse' call is the only code change made to the | |
1046 | ;; `completion-pcm--all-completions' that shipped with Emacs 25.1. | |
1047 | (nreverse poss)))))) | |
1050 | (when (< emacs-major-version 26) | |
1051 | ;; In Emacs 25 `completion-pcm--all-completions' reverses the | |
1052 | ;; completion list. This is the version from Emacs 26, which | |
1053 | ;; fixes that issue. bug#24676 | |
1054 | (defun magit-completion-pcm--all-completions (prefix pattern table pred) | |
1055 | (if (completion-pcm--pattern-trivial-p pattern) | |
1056 | (all-completions (concat prefix (car pattern)) table pred) | |
1057 | (let* ((regex (completion-pcm--pattern->regex pattern)) | |
1058 | (case-fold-search completion-ignore-case) | |
1059 | (completion-regexp-list (cons regex completion-regexp-list)) | |
1060 | (compl (all-completions | |
1061 | (concat prefix | |
1062 | (if (stringp (car pattern)) (car pattern) "")) | |
1063 | table pred))) | |
1064 | (if (not (functionp table)) | |
1065 | compl | |
1066 | (let ((poss ())) | |
1067 | (dolist (c compl) | |
1068 | (when (string-match-p regex c) (push c poss))) | |
1069 | (nreverse poss))))))) | |
1048 | 1070 | |
1049 | 1071 | (defun magit-which-function () |
1050 | 1072 | "Return current function name based on point. |