]> git.eshelyaron.com Git - emacs.git/commitdiff
vc-git-checkin: Offer to unstage conflicting changes
authorSean Whitton <spwhitton@spwhitton.name>
Fri, 16 Dec 2022 18:28:20 +0000 (11:28 -0700)
committerSean Whitton <spwhitton@spwhitton.name>
Tue, 20 Dec 2022 23:09:12 +0000 (16:09 -0700)
* lisp/vc/vc-git.el (vc-git-checkin): When committing a patch, if
conflicting changes are already staged, offer to clear them, instead
of just immediately failing with "Index not empty" (bug#60126).

lisp/vc/vc-git.el

index 9f27f759d352799427e9102f1570d94f7ef0f827..8f995021dcc1bbefbfd720b0124caf0568559ef4 100644 (file)
@@ -1030,23 +1030,31 @@ It is based on `log-edit-mode', and has Git-specific extensions."
         (with-temp-buffer
           (vc-git-command (current-buffer) t nil "diff" "--cached")
           (goto-char (point-min))
-          (let ((pos (point)) file-diff file-beg)
+          (let ((pos (point)) file-name file-diff file-beg)
             (while (not (eobp))
+              (when (and (looking-at "^diff --git a/\\(.+\\) b/\\(.+\\)")
+                         (string= (match-string 1) (match-string 2)))
+                (setq file-name (match-string 1)))
               (forward-line 1) ; skip current "diff --git" line
               (search-forward "diff --git" nil 'move)
               (move-beginning-of-line 1)
               (setq file-diff (buffer-substring pos (point)))
-              (if (and (setq file-beg (string-search
-                                       file-diff vc-git-patch-string))
-                       ;; Check that file diff ends with an empty string
-                       ;; or the beginning of the next file diff.
-                       (string-match-p "\\`\\'\\|\\`diff --git"
-                                       (substring
-                                        vc-git-patch-string
-                                        (+ file-beg (length file-diff)))))
-                  (setq vc-git-patch-string
-                        (string-replace file-diff "" vc-git-patch-string))
-                (user-error "Index not empty"))
+              (cond ((and (setq file-beg (string-search
+                                          file-diff vc-git-patch-string))
+                          ;; Check that file diff ends with an empty string
+                          ;; or the beginning of the next file diff.
+                          (string-match-p "\\`\\'\\|\\`diff --git"
+                                          (substring
+                                           vc-git-patch-string
+                                           (+ file-beg (length file-diff)))))
+                     (setq vc-git-patch-string
+                           (string-replace file-diff "" vc-git-patch-string)))
+                    ((and file-name
+                          (yes-or-no-p
+                           (format "Unstage already-staged changes to %s?"
+                                   file-name)))
+                     (vc-git-command nil 0 file-name "reset" "-q" "--"))
+                    (t (user-error "Index not empty")))
               (setq pos (point))))))
       (let ((patch-file (make-nearby-temp-file "git-patch")))
         (with-temp-file patch-file