branch: elpa/magit
commit a08b4dd513a35c0720bb5cbdc2b248029536c9bd
Author: Jonas Bernoulli <jo...@bernoul.li>
Commit: Jonas Bernoulli <jo...@bernoul.li>

    magit-stash--apply-1: Improve presentation of fallback methods
    
    Be more verbose about the available fallback methods and also let
    the user abort.
    
    Re #5253.
---
 docs/magit.org      | 60 +++++++++++++++---------------------
 docs/magit.texi     | 60 +++++++++++++++---------------------
 lisp/magit-stash.el | 87 +++++++++++++++++++++++++++--------------------------
 3 files changed, 94 insertions(+), 113 deletions(-)

diff --git a/docs/magit.org b/docs/magit.org
index d9795c7931e..17e95df197f 100644
--- a/docs/magit.org
+++ b/docs/magit.org
@@ -6428,24 +6428,22 @@ Also see [[man:git-stash]]
 
   When using Git v2.38.0 or later, behave more intelligently:
 
-  First try ~git stash apply --index~, which tries to preserve
-  the index stored in the stash, if any.  This may fail because
-  applying the stash could result in conflicts and those have to
-  be stored in the index, making it impossible to also store the
-  stash's index there.
-
-  If the above failed, then try ~git stash apply~.  This fails
-  (with or without ~--index~) if there are any uncommitted
-  changes to files that are also modified in the stash.
-
-  If both of the above failed, then apply using ~git apply~.
-  If there are no conflicting files, use ~--3way~.  If there are
-  conflicting files, then using ~--3way~ requires that those
-  files are staged first, which may be undesirable, so prompt
-  the user whether to use ~--3way~ or ~--reject~.
-
-  Customize ~magit-no-confirm~ if you want to always use ~--3way~,
-  without being prompted.
+  First try ~git stash apply --index~, which tries to preserve the index
+  stored in the stash, if any.  This may fail because applying the
+  stash could result in conflicts and those have to be stored in the
+  index, making it impossible to also store the stash's index there.
+
+  First try ~git stash apply --index~, which tries to preserve the
+  index stored in the stash, if any.  This may fail because applying
+  the stash could result in conflicts and those have to be stored in
+  the index, making it impossible to also store the stash's index
+  there.
+
+  If ~git stash~ fails, then potentially fall back to using ~git apply~.
+  If the stash does not touch any unstaged files, then pass ~--3way~ to
+  that command.  Otherwise ask the user whether to use that argument
+  or ~--reject~.  Customize ~magit-no-confirm~ if you want to fall back
+  to using ~--3way~, without being prompted.
 
 - Key: z p (magit-stash-pop) ::
 
@@ -6458,24 +6456,16 @@ Also see [[man:git-stash]]
 
   When using Git v2.38.0 or later, behave more intelligently:
 
-  First try ~git stash pop --index~, which tries to preserve
-  the index stored in the stash, if any.  This may fail because
-  applying the stash could result in conflicts and those have to
-  be stored in the index, making it impossible to also store the
-  stash's index there.
-
-  If the above failed, then try ~git stash apply~.  This fails
-  (with or without ~--index~) if there are any uncommitted
-  changes to files that are also modified in the stash.
-
-  If both of the above failed, then apply using ~git apply~.
-  If there are no conflicting files, use ~--3way~.  If there are
-  conflicting files, then using ~--3way~ requires that those
-  files are staged first, which may be undesirable, so prompt
-  the user whether to use ~--3way~ or ~--reject~.
+  First try ~git stash pop --index~, which tries to preserve the index
+  stored in the stash, if any.  This may fail because applying the
+  stash could result in conflicts and those have to be stored in the
+  index, making it impossible to also store the stash's index there.
 
-  Customize ~magit-no-confirm~ if you want to always use ~--3way~,
-  without being prompted.
+  If ~git stash~ fails, then potentially fall back to using ~git apply~.
+  If the stash does not touch any unstaged files, then pass ~--3way~ to
+  that command.  Otherwise ask the user whether to use that argument
+  or ~--reject~.  Customize ~magit-no-confirm~ if you want to fall back
+  to using ~--3way~, without being prompted.
 
 - Key: z k (magit-stash-drop) ::
 
diff --git a/docs/magit.texi b/docs/magit.texi
index 04d374d7b63..65e1f5d9e1d 100644
--- a/docs/magit.texi
+++ b/docs/magit.texi
@@ -7641,24 +7641,22 @@ or with a prefix argument @code{git stash apply 
--index}.
 
 When using Git v2.38.0 or later, behave more intelligently:
 
-First try @code{git stash apply --index}, which tries to preserve
-the index stored in the stash, if any.  This may fail because
-applying the stash could result in conflicts and those have to
-be stored in the index, making it impossible to also store the
-stash's index there.
-
-If the above failed, then try @code{git stash apply}.  This fails
-(with or without @code{--index}) if there are any uncommitted
-changes to files that are also modified in the stash.
-
-If both of the above failed, then apply using @code{git apply}.
-If there are no conflicting files, use @code{--3way}.  If there are
-conflicting files, then using @code{--3way} requires that those
-files are staged first, which may be undesirable, so prompt
-the user whether to use @code{--3way} or @code{--reject}.
-
-Customize @code{magit-no-confirm} if you want to always use @code{--3way},
-without being prompted.
+First try @code{git stash apply --index}, which tries to preserve the index
+stored in the stash, if any.  This may fail because applying the
+stash could result in conflicts and those have to be stored in the
+index, making it impossible to also store the stash's index there.
+
+First try @code{git stash apply --index}, which tries to preserve the
+index stored in the stash, if any.  This may fail because applying
+the stash could result in conflicts and those have to be stored in
+the index, making it impossible to also store the stash's index
+there.
+
+If @code{git stash} fails, then potentially fall back to using @code{git 
apply}.
+If the stash does not touch any unstaged files, then pass @code{--3way} to
+that command.  Otherwise ask the user whether to use that argument
+or @code{--reject}.  Customize @code{magit-no-confirm} if you want to fall back
+to using @code{--3way}, without being prompted.
 
 @item @kbd{z p} (@code{magit-stash-pop})
 @kindex z p
@@ -7672,24 +7670,16 @@ or with a prefix argument @code{git stash pop --index}.
 
 When using Git v2.38.0 or later, behave more intelligently:
 
-First try @code{git stash pop --index}, which tries to preserve
-the index stored in the stash, if any.  This may fail because
-applying the stash could result in conflicts and those have to
-be stored in the index, making it impossible to also store the
-stash's index there.
-
-If the above failed, then try @code{git stash apply}.  This fails
-(with or without @code{--index}) if there are any uncommitted
-changes to files that are also modified in the stash.
-
-If both of the above failed, then apply using @code{git apply}.
-If there are no conflicting files, use @code{--3way}.  If there are
-conflicting files, then using @code{--3way} requires that those
-files are staged first, which may be undesirable, so prompt
-the user whether to use @code{--3way} or @code{--reject}.
+First try @code{git stash pop --index}, which tries to preserve the index
+stored in the stash, if any.  This may fail because applying the
+stash could result in conflicts and those have to be stored in the
+index, making it impossible to also store the stash's index there.
 
-Customize @code{magit-no-confirm} if you want to always use @code{--3way},
-without being prompted.
+If @code{git stash} fails, then potentially fall back to using @code{git 
apply}.
+If the stash does not touch any unstaged files, then pass @code{--3way} to
+that command.  Otherwise ask the user whether to use that argument
+or @code{--reject}.  Customize @code{magit-no-confirm} if you want to fall back
+to using @code{--3way}, without being prompted.
 
 @item @kbd{z k} (@code{magit-stash-drop})
 @kindex z k
diff --git a/lisp/magit-stash.el b/lisp/magit-stash.el
index c4fe13d8cba..3c6f5b7cf11 100644
--- a/lisp/magit-stash.el
+++ b/lisp/magit-stash.el
@@ -269,21 +269,17 @@ apply\" or with a prefix argument \"git stash apply 
--index\".
 
 When using Git v2.38.0 or later, behave more intelligently:
 
-First try \"git stash apply --index\", which tries to preserve
-the index stored in the stash, if any.  This may fail because
-applying the stash could result in conflicts and those have to
-be stored in the index, making it impossible to also store the
-stash's index there.
-
-If the above failed, then try \"git stash apply\".  This fails
-\(with or without \"--index\") if there are any uncommitted
-changes to files that are also modified in the stash.
-
-If both of the above failed, then apply using \"git apply\".
-If there are no conflicting files, use \"--3way\".  If there are
-conflicting files, then using \"--3way\" requires that those
-files are staged first, which may be undesirable, so prompt
-the user whether to use \"--3way\" or \"--reject\"."
+First try \"git stash apply --index\", which tries to preserve the
+index stored in the stash, if any.  This may fail because applying
+the stash could result in conflicts and those have to be stored in
+the index, making it impossible to also store the stash's index
+there.
+
+If \"git stash\" fails, then potentially fall back to using \"git
+apply\".  If the stash does not touch any unstaged files, then pass
+\"--3way\" to that command.  Otherwise ask the user whether to use
+that argument or \"--reject\".  Customize `magit-no-confirm' if you
+want to fall back to using \"--3way\", without being prompted."
   (interactive (list (magit-read-stash "Apply stash")))
   (magit-stash--apply "apply" stash))
 
@@ -296,21 +292,17 @@ pop\" or with a prefix argument \"git stash pop --index\".
 
 When using Git v2.38.0 or later, behave more intelligently:
 
-First try \"git stash pop --index\", which tries to preserve
-the index stored in the stash, if any.  This may fail because
-applying the stash could result in conflicts and those have to
-be stored in the index, making it impossible to also store the
-stash's index there.
-
-If the above failed, then try \"git stash apply\".  This fails
-\(with or without \"--index\") if there are any uncommitted
-changes to files that are also modified in the stash.
-
-If both of the above failed, then apply using \"git apply\".
-If there are no conflicting files, use \"--3way\".  If there are
-conflicting files, then using \"--3way\" requires that those
-files are staged first, which may be undesirable, so prompt
-the user whether to use \"--3way\" or \"--reject\"."
+First try \"git stash apply --index\", which tries to preserve the
+index stored in the stash, if any.  This may fail because applying
+the stash could result in conflicts and those have to be stored in
+the index, making it impossible to also store the stash's index
+there.
+
+If \"git stash\" fails, then potentially fall back to using \"git
+apply\".  If the stash does not touch any unstaged files, then pass
+\"--3way\" to that command.  Otherwise ask the user whether to use
+that argument or \"--reject\".  Customize `magit-no-confirm' if you
+want to fall back to using \"--3way\", without being prompted."
   (interactive (list (magit-read-stash "Pop stash")))
   (magit-stash--apply "pop" stash))
 
@@ -331,19 +323,28 @@ the user whether to use \"--3way\" or \"--reject\"."
                                         (magit-untracked-files t stashed)
                                         :test #'equal)
                               #'string<))
-          (arg (cond
-                ((not conflicts) "--3way")
-                ((magit-confirm-files
-                  'stash-apply-3way conflicts
-                  "Apply stash using `--3way', which requires first staging"
-                  "(else use `--reject')"
-                  t)
-                 (magit-stage-1 nil conflicts)
-                 "--3way")
-                ("--reject"))))
-     (with-temp-buffer
-       (magit-git-insert "diff" range)
-       (magit-run-git-with-input "apply" arg "-")))))
+          (arg (if (or (not conflicts)
+                       (memq 'stash-apply-3way magit-no-confirm))
+                   "--3way"
+                 (magit-read-char-case
+                     (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")
+                      "\n")
+                     nil
+                   (?s (format
+                        "\n[s] stage file%s and apply with \"git apply 
--3way\""
+                        (if (length> conflicts 1) "s" ""))
+                       "--3way")
+                   (?r "\n[r] apply with \"git apply --reject\"" "--reject")
+                   (?c "\n[c] cancel" nil)))))
+     (when arg
+       (when (and (equal arg "--3way") conflicts)
+         (magit-stage-1 nil conflicts))
+       (with-temp-buffer
+         (magit-git-insert "diff" range)
+         (magit-run-git-with-input "apply" arg "-"))))))
 
 (defun magit--run-git-stash (&rest args)
   (magit--with-temp-process-buffer

Reply via email to