all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Óscar Fuentes" <ofv@wanadoo.es>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: Dmitry Gutov <dgutov@yandex.ru>, emacs-devel@gnu.org
Subject: Git conflict VC state detection
Date: Sun, 10 Nov 2013 21:30:08 +0100	[thread overview]
Message-ID: <87wqkgyp7z.fsf_-_@wanadoo.es> (raw)
In-Reply-To: <jwvy54w1jbl.fsf-monnier+emacs@gnu.org> (Stefan Monnier's message of "Sun, 10 Nov 2013 08:24:41 -0500")

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

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>> Is it really all it takes to detect `conflict' state?
>> Git conflict state detection worked when I implemented the feature many
>> moons ago, although it was not 100% reliable. It doesn't work anymore.
>> Maybe something was lost on one of the many merges.
>
> Could you try and make it work again and submit/install the patch for that?

I've revised the initial commit implementing conflict state detection on
my private branch and the problem with it was that it didn't detect
edited state on a staged file, i.e. a file containing staged (but
uncommitted) changes would show as up to date.

So I pursued a more precise method. The problem is that the git commands
that tells you that a file is unmerged doesn't tell that a file contains
changes if those are staged. The solution is to execute two git
commands: the first one informs about edited (but unstaged) files plus
unmerged files. If that command says that the file is up to date, a
second command is executed for detecting staged changes.

The problem with this approach is that on some platforms (i.e. Windows)
invoking git is slow. The delay is already noticeable when the modeline
is updated. Adding yet another call makes things somewhat worse.

I CC'ed Dmitry as he implemented the part that my patch touches. I'll
like to get the ok from him before installing the patch, if you (Stefan)
think that conflict detection is valuable enough to warrant an extra git
invocation.


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

diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 1d67dee..cb500eb 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -204,15 +204,26 @@ matching the resulting Git log output, and KEYWORDS is a list of
     (?M 'edited)
     (?A 'added)
     (?D 'removed)
-    (?U 'edited)     ;; FIXME
+    (?U 'conflict)
     (?T 'edited)))   ;; FIXME
 
+(defun vc-git--state-letter (file index-p)
+  (let ((diff (vc-git--run-command-string
+               file
+	       "diff-index"
+	       ;; How to conditionally add --cached without this kludge?
+	       (if index-p "--cached" "-z")
+	       "--name-status" "--raw" "-z" "HEAD" "--")))
+    (and diff
+	 (string-match "^\\([ADMUT]\\)\0" diff)
+	 (match-string 1 diff))))
+
 (defun vc-git-state (file)
   "Git-specific version of `vc-state'."
-  ;; FIXME: This can't set 'ignored or 'conflict yet
+  ;; FIXME: This can't set 'ignored yet.
   ;; The 'ignored state could be detected with `git ls-files -i -o
-  ;; --exclude-standard` It also can't set 'needs-update or
-  ;; 'needs-merge. The rough equivalent would be that upstream branch
+  ;; --exclude-standard` It also can't set 'needs-update.
+  ;; The rough equivalent would be that upstream branch
   ;; for current branch is in fast-forward state i.e. current branch
   ;; is direct ancestor of corresponding upstream branch, and the file
   ;; was modified upstream.  But we can't check that without a network
@@ -220,21 +231,16 @@ matching the resulting Git log output, and KEYWORDS is a list of
   ;; This assumes that status is known to be not `unregistered' because
   ;; we've been successfully dispatched here from `vc-state', that
   ;; means `vc-git-registered' returned t earlier once.  Bug#11757
-  (let ((diff (vc-git--run-command-string
-               file "diff-index" "-p" "--raw" "-z" "HEAD" "--")))
-    (if (and diff
-             (string-match ":[0-7]\\{6\\} [0-7]\\{6\\} [0-9a-f]\\{40\\} [0-9a-f]\\{40\\} \\([ADMUT]\\)\0[^\0]+\0\\(.*\n.\\)?"
-                           diff))
-        (let ((diff-letter (match-string 1 diff)))
-          (if (not (match-beginning 2))
-              ;; Empty diff: file contents is the same as the HEAD
-              ;; revision, but timestamps are different (eg, file
-              ;; was "touch"ed).  Update timestamp in index:
-              (prog1 'up-to-date
-                (vc-git--call nil "add" "--refresh" "--"
-                              (file-relative-name file)))
-            (vc-git--state-code diff-letter)))
-      (if (vc-git--empty-db-p) 'added 'up-to-date))))
+  (let ((diff-letter (or (vc-git--state-letter file t)
+			 (vc-git--state-letter file nil))))
+    (if (not diff-letter)
+	;; Empty diff: file contents is the same as the HEAD
+	;; revision, but timestamps are different (eg, file
+	;; was "touch"ed).  Update timestamp in index:
+	(prog1 'up-to-date
+	  (vc-git--call nil "add" "--refresh" "--"
+			(file-relative-name file)))
+      (vc-git--state-code diff-letter))))
 
 (defun vc-git-working-revision (file)
   "Git-specific version of `vc-working-revision'."

  reply	other threads:[~2013-11-10 20:30 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-07 17:08 Two feature ideas for diffs Tom
2013-11-07 17:25 ` nhs
2013-11-07 17:39   ` Tom
2013-11-07 17:58     ` Dmitry Gutov
2013-11-07 18:24       ` Tom
2013-11-07 19:09       ` Stefan Monnier
2013-11-07 19:30         ` Dmitry Gutov
2013-11-07 20:00           ` Stefan Monnier
2013-11-08 22:58       ` Michael Heerdegen
2013-11-09  2:30         ` Óscar Fuentes
2013-11-09  2:59           ` Michael Heerdegen
2013-11-09 13:34             ` Stefan Monnier
2013-11-09 22:58               ` Michael Heerdegen
2013-11-09 13:37           ` Stefan Monnier
2013-11-09 15:02             ` Óscar Fuentes
2013-11-10 13:24               ` Stefan Monnier
2013-11-10 20:30                 ` Óscar Fuentes [this message]
2013-11-10 21:26                   ` Git conflict VC state detection Dmitry Gutov
2013-11-10 22:19                     ` Óscar Fuentes
2013-11-11  0:16                       ` Stefan Monnier
2013-11-11  0:53                         ` Óscar Fuentes
2013-11-11  2:13                           ` Stefan Monnier
2013-11-11 23:16                       ` Dmitry Gutov
2013-11-07 18:11 ` Two feature ideas for diffs Dmitry Gutov
2013-11-07 18:33   ` Tom
2013-11-08  1:29   ` Ivan Andrus
2013-11-07 19:11 ` Stefan Monnier

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

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

  git send-email \
    --in-reply-to=87wqkgyp7z.fsf_-_@wanadoo.es \
    --to=ofv@wanadoo.es \
    --cc=dgutov@yandex.ru \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.