Klimi's new dotfiles with stow.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

267 rader
9.5 KiB

4 år sedan
  1. ;;; magit-patch.el --- creating and applying patches -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2008-2019 The Magit Project Contributors
  3. ;;
  4. ;; You should have received a copy of the AUTHORS.md file which
  5. ;; lists all contributors. If not, see http://magit.vc/authors.
  6. ;; Author: Jonas Bernoulli <jonas@bernoul.li>
  7. ;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
  8. ;; Magit is free software; you can redistribute it and/or modify it
  9. ;; under the terms of the GNU General Public License as published by
  10. ;; the Free Software Foundation; either version 3, or (at your option)
  11. ;; any later version.
  12. ;;
  13. ;; Magit is distributed in the hope that it will be useful, but WITHOUT
  14. ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  15. ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  16. ;; License for more details.
  17. ;;
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with Magit. If not, see http://www.gnu.org/licenses.
  20. ;;; Commentary:
  21. ;; This library implements patch commands.
  22. ;;; Code:
  23. (eval-when-compile
  24. (require 'subr-x))
  25. (require 'magit)
  26. ;;; Options
  27. (defcustom magit-patch-save-arguments '(exclude "--stat")
  28. "Control arguments used by the command `magit-patch-save'.
  29. `magit-patch-save' (which see) saves a diff for the changes
  30. shown in the current buffer in a patch file. It may use the
  31. same arguments as used in the buffer or a subset thereof, or
  32. a constant list of arguments, depending on this option and
  33. the prefix argument."
  34. :package-version '(magit . "2.12.0")
  35. :group 'magit-diff
  36. :type '(choice (const :tag "use buffer arguments" buffer)
  37. (cons :tag "use buffer arguments except"
  38. (const :format "" exclude)
  39. (repeat :format "%v%i\n"
  40. (string :tag "Argument")))
  41. (repeat :tag "use constant arguments"
  42. (string :tag "Argument"))))
  43. ;;; Commands
  44. ;;;###autoload (autoload 'magit-patch "magit-patch" nil t)
  45. (define-transient-command magit-patch ()
  46. "Create or apply patches."
  47. ["Actions"
  48. ("c" "Create patches" magit-patch-create)
  49. ("a" "Apply patch" magit-patch-apply)
  50. ("s" "Save diff as patch" magit-patch-save)
  51. ("r" "Request pull" magit-request-pull)])
  52. ;;;###autoload (autoload 'magit-patch-create "magit-patch" nil t)
  53. (define-transient-command magit-patch-create (range args files)
  54. "Create patches for the commits in RANGE.
  55. When a single commit is given for RANGE, create a patch for the
  56. changes introduced by that commit (unlike 'git format-patch'
  57. which creates patches for all commits that are reachable from
  58. `HEAD' but not from the specified commit)."
  59. :man-page "git-format-patch"
  60. ["Mail arguments"
  61. (magit-format-patch:--in-reply-to)
  62. (magit-format-patch:--thread)
  63. (magit-format-patch:--reroll-count)
  64. (magit-format-patch:--subject-prefix)
  65. ("C-m l " "Add cover letter" "--cover-letter")
  66. (magit-format-patch:--from)
  67. (magit-format-patch:--to)
  68. (magit-format-patch:--cc)
  69. (magit-format-patch:--output-directory)]
  70. ["Diff arguments"
  71. (magit-diff:-U)
  72. (magit-diff:-M)
  73. (magit-diff:-C)
  74. (magit-diff:--diff-algorithm)
  75. (magit:--)
  76. (7 "-b" "Ignore whitespace changes" ("-b" "--ignore-space-change"))
  77. (7 "-w" "Ignore all whitespace" ("-w" "--ignore-all-space"))]
  78. ["Actions"
  79. ("c" "Create patches" magit-patch-create)]
  80. (interactive
  81. (if (not (eq current-transient-command 'magit-patch-create))
  82. (list nil nil nil)
  83. (cons (if-let ((revs (magit-region-values 'commit t)))
  84. (concat (car (last revs)) "^.." (car revs))
  85. (let ((range (magit-read-range-or-commit
  86. "Format range or commit")))
  87. (if (string-match-p "\\.\\." range)
  88. range
  89. (format "%s~..%s" range range))))
  90. (let ((args (transient-args 'magit-patch-create)))
  91. (list (-filter #'stringp args)
  92. (cdr (assoc "--" args)))))))
  93. (if (not range)
  94. (transient-setup 'magit-patch-create)
  95. (magit-run-git "format-patch" range args "--" files)
  96. (when (member "--cover-letter" args)
  97. (save-match-data
  98. (find-file
  99. (expand-file-name
  100. (concat (--some (and (string-match "\\`--reroll-count=\\(.+\\)" it)
  101. (format "v%s-" (match-string 1 it)))
  102. args)
  103. "0000-cover-letter.patch")
  104. (let ((topdir (magit-toplevel)))
  105. (or (--some (and (string-match "\\`--output-directory=\\(.+\\)" it)
  106. (expand-file-name (match-string 1 it) topdir))
  107. args)
  108. topdir))))))))
  109. (define-infix-argument magit-format-patch:--in-reply-to ()
  110. :description "In reply to"
  111. :class 'transient-option
  112. :key "C-m r "
  113. :argument "--in-reply-to=")
  114. (define-infix-argument magit-format-patch:--thread ()
  115. :description "Thread style"
  116. :class 'transient-option
  117. :key "C-m s "
  118. :argument "--thread=")
  119. (define-infix-argument magit-format-patch:--reroll-count ()
  120. :description "Reroll count"
  121. :class 'transient-option
  122. :key "C-m v "
  123. :shortarg "-v"
  124. :argument "--reroll-count="
  125. :reader 'transient-read-number-N+)
  126. (define-infix-argument magit-format-patch:--subject-prefix ()
  127. :description "Subject Prefix"
  128. :class 'transient-option
  129. :key "C-m p "
  130. :argument "--subject-prefix=")
  131. (define-infix-argument magit-format-patch:--from ()
  132. :description "From"
  133. :class 'transient-option
  134. :key "C-m C-f"
  135. :argument "--from="
  136. :reader 'magit-transient-read-person)
  137. (define-infix-argument magit-format-patch:--to ()
  138. :description "To"
  139. :class 'transient-option
  140. :key "C-m C-t"
  141. :argument "--to="
  142. :reader 'magit-transient-read-person)
  143. (define-infix-argument magit-format-patch:--cc ()
  144. :description "CC"
  145. :class 'transient-option
  146. :key "C-m C-c"
  147. :argument "--cc="
  148. :reader 'magit-transient-read-person)
  149. (define-infix-argument magit-format-patch:--output-directory ()
  150. :description "Output directory"
  151. :class 'transient-option
  152. :key "C-m o "
  153. :shortarg "-o"
  154. :argument "--output-directory="
  155. :reader 'transient-read-existing-directory)
  156. ;;;###autoload (autoload 'magit-patch-apply "magit-patch" nil t)
  157. (define-transient-command magit-patch-apply (file &rest args)
  158. "Apply the patch file FILE."
  159. :man-page "git-apply"
  160. ["Arguments"
  161. ("-i" "Also apply to index" "--index")
  162. ("-c" "Only apply to index" "--cached")
  163. ("-3" "Fall back on 3way merge" ("-3" "--3way"))]
  164. ["Actions"
  165. ("a" "Apply patch" magit-patch-apply)]
  166. (interactive
  167. (if (not (eq current-transient-command 'magit-patch-apply))
  168. (list nil)
  169. (list (expand-file-name
  170. (read-file-name "Apply patch: "
  171. default-directory nil nil
  172. (when-let ((file (magit-file-at-point)))
  173. (file-relative-name file))))
  174. (transient-args 'magit-patch-apply))))
  175. (if (not file)
  176. (transient-setup 'magit-patch-apply)
  177. (magit-run-git "apply" args "--" (magit-convert-filename-for-git file))))
  178. ;;;###autoload
  179. (defun magit-patch-save (file &optional arg)
  180. "Write current diff into patch FILE.
  181. What arguments are used to create the patch depends on the value
  182. of `magit-patch-save-arguments' and whether a prefix argument is
  183. used.
  184. If the value is the symbol `buffer', then use the same arguments
  185. as the buffer. With a prefix argument use no arguments.
  186. If the value is a list beginning with the symbol `exclude', then
  187. use the same arguments as the buffer except for those matched by
  188. entries in the cdr of the list. The comparison is done using
  189. `string-prefix-p'. With a prefix argument use the same arguments
  190. as the buffer.
  191. If the value is a list of strings (including the empty list),
  192. then use those arguments. With a prefix argument use the same
  193. arguments as the buffer.
  194. Of course the arguments that are required to actually show the
  195. same differences as those shown in the buffer are always used."
  196. (interactive (list (read-file-name "Write patch file: " default-directory)
  197. current-prefix-arg))
  198. (unless (derived-mode-p 'magit-diff-mode)
  199. (user-error "Only diff buffers can be saved as patches"))
  200. (let ((rev magit-buffer-range)
  201. (typearg magit-buffer-typearg)
  202. (args magit-buffer-diff-args)
  203. (files magit-buffer-diff-files))
  204. (cond ((eq magit-patch-save-arguments 'buffer)
  205. (when arg
  206. (setq args nil)))
  207. ((eq (car-safe magit-patch-save-arguments) 'exclude)
  208. (unless arg
  209. (setq args (-difference args (cdr magit-patch-save-arguments)))))
  210. ((not arg)
  211. (setq args magit-patch-save-arguments)))
  212. (with-temp-file file
  213. (magit-git-insert "diff" rev "-p" typearg args "--" files)))
  214. (magit-refresh))
  215. ;;;###autoload
  216. (defun magit-request-pull (url start end)
  217. "Request upstream to pull from you public repository.
  218. URL is the url of your publically accessible repository.
  219. START is a commit that already is in the upstream repository.
  220. END is the last commit, usually a branch name, which upstream
  221. is asked to pull. START has to be reachable from that commit."
  222. (interactive
  223. (list (magit-get "remote" (magit-read-remote "Remote") "url")
  224. (magit-read-branch-or-commit "Start" (magit-get-upstream-branch))
  225. (magit-read-branch-or-commit "End")))
  226. (let ((dir default-directory))
  227. ;; mu4e changes default-directory
  228. (compose-mail)
  229. (setq default-directory dir))
  230. (message-goto-body)
  231. (magit-git-insert "request-pull" start url end)
  232. (set-buffer-modified-p nil))
  233. ;;; _
  234. (provide 'magit-patch)
  235. ;;; magit-patch.el ends here