diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 4385b1a1722..1d654b87ed8 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -721,23 +721,44 @@ case you are concerned about moving files between file systems." :type 'directory :version "31.1") +(defconst package--review-git-diff-command + ;; Git's diff command can be used as a regular diff implementation + ;; with the --no-index flag. The advantage is that the + ;; --diff-filter=d ignores files which are not present in the + ;; newly extracted archive. This way, already compiled elc files + ;; are not shown as part of the diff for example. + '("git" "diff" "--no-index" "--no-color" "--diff-filter=d" "--minimal" + vc-git-diff-switches)) + (defcustom package-review-diff-command - (cons diff-command - (mapcar #'shell-quote-argument - '("-u" ;unified patch formatting - "-N" ;treat absent files as empty - "-x" "*.elc" ;ignore byte compiled files - "-x" "*-autoloads.el" ;ignore the autoloads file - "-x" "*-pkg.el" ;ignore the package description - "-x" "*.info" ;ignore compiled Info files - ))) + (if (executable-find "git") + package--review-git-diff-command + (list diff-command "-u" "-N")) "Configuration of how `package-review' should generate a Diff. The structure of the value must be (COMMAND . OPTIONS), where `diff-command' is rebound to be COMMAND and OPTIONS are command-line -switches and arguments passed to `diff-no-select' as the SWITCHES argument -if the user selects a diff-related option during review." - :type '(cons (string :tag "Diff command name") - (repeat :tag "Diff command-line arguments" string)) +switches and arguments passed to `diff-no-select' as the SWITCHES +argument if the user selects a diff-related option during review. +SWITCHES may additionally also include a symbol, which is replaced by +the symbol value." + :type `(choice + (const :tag "Use git diff, excluding deleted files" + ,package--review-git-diff-command) + (const :tag "Use diff, without exclusion" ("diff" "-u" "-N")) + (const :tag "Use diff, with exclusion of safe files" + ,(cons diff-command + (mapcar #'shell-quote-argument + '("-u" ;unified patch formatting + "-N" ;treat absent files as empty + "-x" "*.elc" ;ignore byte compiled files + "-x" "*-autoloads.el" ;ignore the autoloads file + "-x" "*-pkg.el" ;ignore the package description + "-x" "*.info" ;ignore compiled Info files + )))) + (cons :tag "Custom diff command" + (string :tag "Diff command name") + (repeat :tag "Diff command-line arguments" + (or symbol string)))) :version "31.1") (defun package-matches-selector-p (selector pkg-desc) @@ -781,7 +802,12 @@ review fails, the function throws a symbol `review-failed' with PKG-DESC attached." (let ((news (package-find-news-file pkg-desc)) (enable-recursive-minibuffers t) - (diff-command (car package-review-diff-command))) + (diff-command (car package-review-diff-command)) + (switches (cl-loop for switch in (cdr package-review-diff-command) + when (stringp switch) collect switch into result + when (and (symbolp switch) (boundp switch)) + append (ensure-list (symbol-value switch)) into result + finally (delq t result)))) (while (pcase-exhaustive (car (read-multiple-choice (format "Install \"%s\"?" (package-desc-name pkg-desc)) @@ -798,7 +824,7 @@ attached." (?d (display-buffer (diff-no-select - (package-desc-dir old-desc) pkg-dir (cdr package-review-diff-command) t + (package-desc-dir old-desc) pkg-dir switches t (get-buffer-create (format "*Package Review Diff: %s*" (package-desc-full-name pkg-desc))))) t) @@ -806,8 +832,7 @@ attached." (with-temp-buffer (diff-no-select (package-desc-dir old-desc) pkg-dir - (cdr package-review-diff-command) - t (current-buffer)) + switches t (current-buffer)) ;; delete sentinel message (goto-char (point-max)) (forward-line -2)