Subject: Re: Status of all files (was: Re: How can I tell if a file is ignored by git?

From: Eric Raymond <[email-masked]>
Date: Fri, 9 Apr 2010 09:20:37 -0400

Randal L. Schwartz <[email-masked]>:
> A lot of these don't make sense for git and other DVCS.  How have
> hg and bzr interpreted these "canonical" states?

That asks the question the wrong way around.  These state codes
are used to change how VC *itself* performs when you fire various
commands; the VCSes called by the VC back ends never have to
'interpret' them.

It is not expected that every VCS will report all of them; in
particular, as you say, some only make sense in locking systems.  
When VC knows it's dealing with a merging system, it will never go
down a logic path where a locking-related state is checked for.

I deleted two of the locking-system-only states from what you saw, but
may have missed others; I don't completely understand all the states,
because at least eleven other people hacked on VC during the 15 years
I was doing other things and added several that were not in my
original design.

(There is some excuse for this. Emacs VC is probably unique in that
its ontology has to be rich enough to accomodate *every VCS there
is*. Nothing else even attempts that, AFAIK.)

But to answer your question at least in part, here is a piece of code
mapping status codes from Mercurial's hg status -A command to Emacs
state codes.

    (when (eq 0 status)
        (when (null (string-match ".*: No such file or directory$" out))
          (let ((state (aref out 0)))
            (cond
             ((eq state ?=) 'up-to-date)
             ((eq state ?A) 'added)
             ((eq state ?M) 'edited)
             ((eq state ?I) 'ignored)
             ((eq state ?R) 'removed)
             ((eq state ?!) 'missing)
             ((eq state ??) 'unregistered)
             ((eq state ?C) 'up-to-date) ;; Older mercurials use this
             (t 'up-to-date)))))))

This is failing to report at least one interesting state, 
which is 'conflict.  But otherwise it looks pretty complete.

What I'm really looking for is a git functional equivalent of hg status -A.
The git backend presently uses diff-index and interprets the output in
a way that I fear is rather brittle.

I'm inclined to think you are right that 'need-update and 'need-merge
don't make any sense in a tree-oriented VCS.  On the other hand, SVN 
and Monotone both report them.  On the gripping hand, I'm not certain these
qualify as "tree-oriented" in quite as strong a sense as hg and git do.
I need to understand this better.

If nothing else, perhaps this discussion will lead to me being able to
document Emacs statuses more completely.  There is a fair amount of
murk around them now, because the mode did a lot of growing by
accretion that I have not completely cleaned up yet.

> Eric>   'removed         Scheduled to be deleted from the repository
> Eric>                    on next commit.
> 
> Not useful in git.

I disagree.  At least, git status reports "removed" files before a commit.
This seems like the logical state for a file after it has been subjected 
to "git rm' but before commit.
 
> Eric>   'missing      The file is not present in the file system, but the VC
> Eric>                 system still tracks it.
> 
> Not available in git.  (If it's not a real file, it can't be tracked. :)

What about a file that has been deleted from the working copy with ordinary
rm (as opposed to git rm) so it's still in the index?  Wouldn't that qualify?

> Eric>   'ignored      The file showed up in a dir-status listing with a flag
> Eric>                 indicating the version-control system is ignoring it,
> 
> Eric>   'unregistered The file is not under version control.
> 
> These two would be identical in git.

Certainly not.  If I have "*.o" in my .gitignore, and two untracked files
foo.c and foo.o in my directory, both are unregistered, but only
foo.o is ignored.  Emacs wants to see foo.c -> 'unregistered but 
foo.o -> 'ignored.
-- 
		<a href="http://www.catb.org/~esr/">Eric S. Raymond</a>