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'."