Subject: Re: bug#26066: 26.0.50; vc-git-status gives wrong result

From: [email-masked]
Date: Sun, 09 Apr 2017 22:58:11 -0400

Jonathan Ganc <[email-masked]> writes:

>  
> +(defun vc-git--git-status-to-vc-state (code-list)

> +  (setq code-list (remq nil code-list))
> +  (pcase code-list
> +    ('nil 'up-to-date)

You seem to be handling nil in 2 different ways.

> +       ;; have only seen this with a file that is only present in the
> +       ;; index. let us call this `removed'

Comments should be full sentences (start with uppercase, end with
period), and sentences should be separated with double spaces.

>  (defun vc-git-state (file)
>    "Git-specific version of `vc-state'."
> +  
> +  (save-match-data
> +    (let* ((default-directory (file-name-directory (expand-file-name file)))
> +           (status
> +            (vc-git--run-command-string file "status" "--porcelain" "-z"
> +                                        "--untracked-files" "--ignored" "--"))
> +           code-list)

> +      (while (string-match "^\\(..\\)[^\0]+\0\\(\\(?:a\\|[^a]\\)*\\)$" status)

I think you're missing a space after the first 2 characters.

    alternate -z format recommended for machine parsing. [...] Second, a
    NUL (ASCII 0) follows each filename, [...] (but a space still
    separates the status field from the first filename).

> +        (add-to-list 'code-list (match-string 1 status) t 'ignore)

Don't use `add-to-list' on local variables.  The usual idiom for
collecting a series of items in a list would be

    (let ((code-list nil))
      (while ...
        (push ... code-list))
      (setq code-list (nreverse code-list)))

> +        (setq status (match-string 2 status)))

Instead of matching the rest of the string in the regexp, just set a
position variable to (match-end 0), and then pass that position as the
string-match's START parameter.