unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Juri Linkov <juri@linkov.net>
To: Dmitry Gutov <dgutov@yandex.ru>
Cc: 52349@debbugs.gnu.org
Subject: bug#52349: 29.0.50; vc-git and diff-mode: stage hunks
Date: Tue, 08 Feb 2022 21:57:58 +0200	[thread overview]
Message-ID: <8635ktjfll.fsf@mail.linkov.net> (raw)
In-Reply-To: <95d2d999-49ad-13c4-9f25-0935650a1e42@yandex.ru> (Dmitry Gutov's message of "Fri, 10 Dec 2021 02:17:18 +0300")

[-- Attachment #1: Type: text/plain, Size: 576 bytes --]

Hi Dmitry,

>> So if using ‘git apply --cached’ is the preferred solution,
>> then I could finish the patch with it.
>
> I don't have a particularly strong opinion, but the approach with 'git
> apply --cached' followed by 'git commit' seems easier to implement and
> avoids changing the file contents on disk, or risking any of the
> stashes. So I'd try implementing it first and then see if the remaining
> problems are worth the trouble of doing it in a more difficult way.

This is implemented now, and I'm already using it without problems.
Please review this patch:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: vc-git-checkin-from-diff.patch --]
[-- Type: text/x-diff, Size: 5743 bytes --]

diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 0bf7899246..84128d40b8 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2860,6 +2860,17 @@ diff-syntax-fontify-props
     (nreverse props)))
 
 
+;;;###autoload
+(defun diff-vc-deduce-fileset ()
+  (let ((backend (vc-responsible-backend default-directory))
+        files)
+    (save-excursion
+      (goto-char (point-min))
+      (while (progn (diff-file-next) (not (eobp)))
+        (push (diff-find-file-name nil t) files)))
+    (list backend (nreverse files) nil nil 'patch)))
+
+
 (defun diff--filter-substring (str)
   (when diff-font-lock-prettify
     ;; Strip the `display' properties added by diff-font-lock-prettify,
diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el
index 5c664d58f1..5400352efe 100644
--- a/lisp/vc/vc-dispatcher.el
+++ b/lisp/vc/vc-dispatcher.el
@@ -753,7 +753,8 @@ vc-finish-logentry
 (defun vc-dispatcher-browsing ()
   "Are we in a directory browser buffer?"
   (or (derived-mode-p 'vc-dir-mode)
-      (derived-mode-p 'dired-mode)))
+      (derived-mode-p 'dired-mode)
+      (derived-mode-p 'diff-mode)))
 
 ;; These are unused.
 ;; (defun vc-dispatcher-in-fileset-p (fileset)
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 208cbee0e6..ddadca2084 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -942,13 +942,23 @@ vc-git-checkin
           ;; message.  Handle also remote files.
           (if (eq system-type 'windows-nt)
               (let ((default-directory (file-name-directory file1)))
-                (make-nearby-temp-file "git-msg")))))
+                (make-nearby-temp-file "git-msg"))))
+         (patch-buffer (derived-mode-p 'diff-mode)))
+    (when patch-buffer
+      (let ((patch-string (buffer-string))
+            (patch-file (make-temp-file "git-patch")))
+        (with-temp-file patch-file
+          (insert patch-string))
+        (unwind-protect
+            (apply #'vc-git-command nil 0 patch-file
+                   (list "apply" "--cached"))
+          (delete-file patch-file))))
     (cl-flet ((boolean-arg-fn
                (argument)
                (lambda (value) (when (equal value "yes") (list argument)))))
       ;; When operating on the whole tree, better pass "-a" than ".", since "."
       ;; fails when we're committing a merge.
-      (apply #'vc-git-command nil 0 (if only files)
+      (apply #'vc-git-command nil 0 (if (and only (not patch-buffer)) files)
              (nconc (if msg-file (list "commit" "-F"
                                        (file-local-name msg-file))
                       (list "commit" "-m"))
@@ -966,7 +976,8 @@ vc-git-checkin
                           (write-region (car args) nil msg-file))
                         (setq args (cdr args)))
                       args)
-		    (if only (list "--only" "--") '("-a")))))
+		    (unless patch-buffer
+                      (if only (list "--only" "--") '("-a"))))))
     (if (and msg-file (file-exists-p msg-file)) (delete-file msg-file))))
 
 (defun vc-git-find-revision (file rev buffer)
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index a6124acadd..d55cf64b3d 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1098,6 +1098,8 @@ vc-deduce-fileset-1
                             state-model-only-files)
   (let (backend)
     (cond
+     ((derived-mode-p 'diff-mode)
+      (diff-vc-deduce-fileset))
      ((derived-mode-p 'vc-dir-mode)
       (vc-dir-deduce-fileset state-model-only-files))
      ((derived-mode-p 'dired-mode)
@@ -1114,7 +1116,8 @@ vc-deduce-fileset-1
            (or (buffer-file-name vc-parent-buffer)
 				(with-current-buffer vc-parent-buffer
 				  (or (derived-mode-p 'vc-dir-mode)
-				      (derived-mode-p 'dired-mode)))))
+				      (derived-mode-p 'dired-mode)
+				      (derived-mode-p 'diff-mode)))))
       (progn                  ;FIXME: Why not `with-current-buffer'? --Stef.
 	(set-buffer vc-parent-buffer)
 	(vc-deduce-fileset-1 not-state-changing allow-unregistered state-model-only-files)))
@@ -1230,6 +1233,7 @@ vc-next-action
       (error "Fileset files are missing, so cannot be operated on"))
      ((eq state 'ignored)
       (error "Fileset files are ignored by the version-control system"))
+     ((eq model 'patch) (vc-checkin files backend))
      ((or (null state) (eq state 'unregistered))
       (cond (verbose
              (let ((backend (vc-read-backend "Backend to register to: ")))
@@ -1800,7 +1804,11 @@ vc-diff-internal
          (orig-diff-buffer-clone
           (if revert-buffer-in-progress-p
               (clone-buffer
-               (generate-new-buffer-name " *vc-diff-clone*") nil))))
+               (generate-new-buffer-name " *vc-diff-clone*") nil)))
+         (patch-buffer (and (buffer-live-p vc-parent-buffer)
+                            (with-current-buffer vc-parent-buffer
+			      (derived-mode-p 'diff-mode))
+                            vc-parent-buffer)))
     ;; On MS-Windows and MS-DOS, Diff is likely to produce DOS-style
     ;; EOLs, which will look ugly if (car files) happens to have Unix
     ;; EOLs.
@@ -1837,8 +1845,11 @@ vc-diff-internal
                      (if async 'async 1) "diff" file
                      (append (vc-switches nil 'diff) `(,(null-device)))))))
         (setq files (nreverse filtered))))
-    (vc-call-backend (car vc-fileset) 'diff files rev1 rev2 buffer async)
+    (unless patch-buffer
+      (vc-call-backend (car vc-fileset) 'diff files rev1 rev2 buffer async))
     (set-buffer buffer)
+    (when patch-buffer
+      (insert (with-current-buffer patch-buffer (buffer-string))))
     ;; Make the *vc-diff* buffer read only, the diff-mode key
     ;; bindings are nicer for read only buffers. pcl-cvs does the
     ;; same thing.

  reply	other threads:[~2022-02-08 19:57 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-07  8:59 bug#52349: 29.0.50; vc-git and diff-mode: stage hunks Manuel Uberti via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-12-07 17:03 ` Juri Linkov
2021-12-07 17:08   ` Manuel Uberti via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-12-07 19:04     ` Juri Linkov
2021-12-07 17:10 ` Dmitry Gutov
2021-12-07 19:06   ` Juri Linkov
2021-12-08  2:29     ` Dmitry Gutov
2021-12-08 18:57       ` Juri Linkov
2021-12-09 23:17         ` Dmitry Gutov
2022-02-08 19:57           ` Juri Linkov [this message]
2022-02-12  1:43             ` Dmitry Gutov
2022-02-12 19:42               ` Juri Linkov
2022-02-13  1:32                 ` Dmitry Gutov
2022-02-13 19:48                   ` Juri Linkov
2022-02-13 22:51                     ` Dmitry Gutov
2022-02-13 19:56                   ` Juri Linkov
2022-02-13 22:41                     ` Dmitry Gutov
2022-08-21 16:07                       ` Juri Linkov
2022-02-13 22:37                   ` Dmitry Gutov
2022-08-21 18:53                     ` Juri Linkov
2022-08-24  2:06                       ` Dmitry Gutov
2022-08-24 18:20                         ` Juri Linkov
2022-08-24 20:20                           ` Dmitry Gutov
2022-08-27 20:07                             ` Juri Linkov
2022-08-28  0:40                               ` Dmitry Gutov
2022-08-28 19:45                                 ` Juri Linkov
2022-08-28 23:34                                   ` Dmitry Gutov
2022-09-08 19:29                             ` Juri Linkov
2022-09-08 22:48                               ` Sean Whitton
2022-09-10  1:36                                 ` Dmitry Gutov
2022-09-11 15:05                                   ` Juri Linkov
2022-09-11 21:57                                     ` Dmitry Gutov
2022-09-12 18:19                                       ` Juri Linkov
2022-09-19  2:09                                         ` Dmitry Gutov
2022-09-19  6:50                                           ` Juri Linkov
2022-09-19 12:57                                             ` Dmitry Gutov
2022-10-02 18:51                                               ` Juri Linkov
2022-11-04  1:32                                                 ` Dmitry Gutov
2022-08-26 17:11                       ` Filipp Gunbin
2022-08-27 19:56                         ` Juri Linkov
2021-12-07 20:07 ` Lars Ingebrigtsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8635ktjfll.fsf@mail.linkov.net \
    --to=juri@linkov.net \
    --cc=52349@debbugs.gnu.org \
    --cc=dgutov@yandex.ru \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).