emacs-31 74ec15e7684: ; Fix 'package--save-selected-packages' edge case (Bug#81091)

Philip Kaludercic <[email protected]> Sun, 2 Aug 2026 07:45:01 -0400 (EDT)
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: emacs-31
commit 74ec15e76847f4269d98aa83e1d43437bf307ca8
Author: Philip Kaludercic <[email protected]>
Commit: Philip Kaludercic <[email protected]>

    ; Fix 'package--save-selected-packages' edge case (Bug#81091)
    
    * lisp/emacs-lisp/package.el (package--save-selected-packages-1):
    Add new function to just save the current value of
    'package-selected-packages'.
    (package--save-selected-packages): Do not add the function
    itself to 'after-init-hook' during init-time, to avoid
    distinguishing between between function calls wheren the
    function is invoked without any argument by the hook or with a
    single nil argument.
---
 lisp/emacs-lisp/package.el | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 3d04d52644b..0eac0c56464 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -1850,16 +1850,27 @@ Used to populate `package-selected-packages'."
              unless (memq name dep-list)
              collect name)))
 
+(defun package--save-selected-packages-1 ()
+  "Save the current value of `package-selected-packages'."
+  (customize-save-variable
+   'package-selected-packages
+   (sort package-selected-packages #'string<)))
+
 (defun package--save-selected-packages (&optional value)
-  "Set and save `package-selected-packages' to VALUE."
+  "Set `package-selected-packages' to VALUE.
+During initialization, we record VALUE but to not persist it using
+Customize, to avoid overwriting configurations that haven't yet been
+loaded.  After initisation we update the user option directly."
   (when (or value after-init-time)
     ;; It is valid to set it to nil, for example when the last package
-    ;; is uninstalled.  But it shouldn't be done at init time, to
-    ;; avoid overwriting configurations that haven't yet been loaded.
-    (setq package-selected-packages (sort value #'string<)))
+    ;; is uninstalled.  But it shouldn't be done at init time, to avoid
+    ;; overwriting configurations that haven't yet been loaded.  We fall
+    ;; back to the default value of `package-selected-packages' when
+    ;; this function is invoked by `after-init-hook'.
+    (setq package-selected-packages value))
   (if after-init-time
-      (customize-save-variable 'package-selected-packages package-selected-packages)
-    (add-hook 'after-init-hook #'package--save-selected-packages)))
+      (package--save-selected-packages-1)
+    (add-hook 'after-init-hook #'package--save-selected-packages-1)))
 
 (defun package--user-selected-p (pkg)
   "Return non-nil if PKG is a package was installed by the user.