# [RFC] git status oddity

3 messages from 2008-04-12 to 2008-04-12. Participants: Sverre Rabbelier, Junio C Hamano.
Thread: https://gitlist.dev/t/13079

## Sverre Rabbelier, 2008-04-12 15:43

Subject: [RFC] git status oddity
Message-ID: <bd6139dc0804120843m2dd2ec3k69a3ba2809f1e955@mail.gmail.com>
URL: https://gitlist.dev/e/bd6139dc0804120843m2dd2ec3k69a3ba2809f1e955%40mail.gmail.com

```
Heya,

I have a directory structure that groups files together in such a way
that usually when I change files in the same directory I commit all
those in one go. As such I am a great fan of 'git diff .' and 'git
commit .' because they allow me to make such partial commits. Sadly,
'git status' does not play along well with this workflow. What I would
expect is 'git status .' to return changes made in the current
directory. More general, I expect 'git status <filter>' to perform
it's magic on only the files that match the filter. What I deduct from
the man page however, 'git status' is merely a 'dry run' of git
commit. While this make sense when using it as part of git commit (to
generate a commit msg), it does not make a lot of sense when using it
as a first-class citizen.

I suggest changing this behavior to be more intuitive (e.g., matching
'git diff' and 'git commit's filtering behavior). As a result commands
that assume 'git status' is a dry run of 'git commit' would have to be
changed to pass an additional argument to 'git status' to tell it to
perform it's old behavior. Even better, a '-d' (for --dry-run) switch
could be added to 'git commit' which would make it act as 'git status'
does currently.

Proposed:
1. Add a '-d'/'--dry-run' switch to 'git commit' which makes it behave
as 'git status' does currently
2. Improve git status to instead take a path argument on which it will
filter it's output.
3. From here on additional improvements to 'git status' can be made
without having to worry about breaking 'git commit' dry-run capability
since that functionality has been put where it belongs, that is, in
'git commit -d'.

This would break programs and scripts that assume 'git status' is a
dry-run of 'git commit', as such I realize this would probably not be
integrated anytime soon. Also, I would like to know whether the
community agrees that current 'git status' behavior does not make
sense when using it as a first-class citizen. Of course, I assume here
that 'git status' is indeed a first-class citizen, if this assumption
is wrong please explain why.

Below is a trivial workflow example.

ubuntu@ubuntu:~/code/StatusExample$ git init
Initialized empty Git repository in .git/
ubuntu@ubuntu:~/code/StatusExample$ mkdir dir1 dir2
ubuntu@ubuntu:~/code/StatusExample$ touch dir1/foo dir1/bar dir2/foobar
ubuntu@ubuntu:~/code/StatusExample$ git add .
ubuntu@ubuntu:~/code/StatusExample$ git commit -m "Initial"
Created initial commit 35dc187: Initial
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 dir1/bar
 create mode 100644 dir1/foo
 create mode 100644 dir2/foobar
ubuntu@ubuntu:~/code/StatusExample$ echo "1" >> dir1/foo
ubuntu@ubuntu:~/code/StatusExample$ echo "2" >> dir1/bar
ubuntu@ubuntu:~/code/StatusExample$ echo "3" >> dir2/foobar
ubuntu@ubuntu:~/code/StatusExample$ cd dir1/
ubuntu@ubuntu:~/code/StatusExample/dir1$ git status .
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   dir1/bar
#       modified:   dir1/foo
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#       modified:   dir2/foobar
#

The above result would be the output of 'git commit -d .'
Expected output:
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#       modified:   dir1/bar
#       modified:   dir1/foo
#


Thank you for your time,

Sverre Rabbelier

```

## Junio C Hamano, 2008-04-12 21:16

Subject: Re: [RFC] git status oddity
Message-ID: <7vabjyhiys.fsf@gitster.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vabjyhiys.fsf%40gitster.siamese.dyndns.org
In-Reply-To: <bd6139dc0804120843m2dd2ec3k69a3ba2809f1e955@mail.gmail.com>

```
"Sverre Rabbelier" <alturin@gmail.com> writes:

> ... when I change files in the same directory I commit all
> those in one go. As such I am a great fan of 'git diff .' and 'git
> commit .'

The command in such a work flow for "What has been changed here" is not
"git status", but is "git diff <diff args> HEAD .", if "git commit ." is
how you make your commits.  --name-status, --name-only or --stat may be
a good option to give in that command line.

As "git status" is a Porcelain just like "git commit" is, its output
format is not holy.  It is not meant to be parsed by scripts and we are
free to change its behaviour for human users typing at it and reading from
it, provided if the change is worth making.  However, for this particular
case, I doubt changing the existing "git status" that is a preview of the
next commit is necessary nor has much merit.

Not because I think your workflow is minority (I don't), but simply
because "git status" is not what you need in this case (you may think it
is what you "want", but notice that I said what you "need").

This is because "git status <paths>" these days is much less useful than
it was originally, after we made --only the default mode for "git commit".

It used to be that the default for "git commit" was --include.  If you say
"git commit foo" when you have some changes already staged, the commit
will include what has already been staged plus the latest contents you
have in "foo".  With such a system, "git status foo" _was_ a very useful
way to remind yourself what changes _other than_ you are naming from the
command line are going to be committed.  It still is the default when you
are recording a merge commit, as the typical use case is that most of the
paths have already been resolved, you fixed up the conflicted ones in your
work tree, and you say "git commit <these I fixed up>".  You do not want
to record a new commit that ignores what is staged in this case.

These days, --only is the default mode of operation.  "git commit foo"
commits _only_ the changes made to what you named from the command line,
disregarding what you have already staged in the index so far.  Because
you are already naming what you want to commit, the value in reminding
what others will also be committed, as there is none, has diminished
greatly, compared to the days when --include was the default.  It still
has value that reminds you what you meant by the dot in "git commit ."
(which is essentially what "git diff --name-only HEAD ." is).  It also
has value that reminds you what you may need/want to commit after making
this commit in this directory.  But it has less information than the old
days, because you already know "what will be committed" will not include
what you did not name from the command line (in your _particular_ use
case, "the current directory"), and "what could be committed" will only
consists of the rest (in your _particular_ use case, "outside the current
directory").

We could special case and make it not report anything that will be left in
the work tree that is different from the resulting commit when --only is
in effect, which is what you seem to "want".  But even that should not be
the default but be an option, as that mode is robbing from users (other
than yourself) the information "what other changes I may still need to
commit after this".  But if you are going to give that option and say
"git status --commit-only ." there is already existing tool to ask the
question you are asking in a more direct way.

```

## Sverre Rabbelier, 2008-04-12 21:39

Subject: Re: [RFC] git status oddity
Message-ID: <bd6139dc0804121439u3a29f004o8cb6583c5cd5bfa1@mail.gmail.com>
URL: https://gitlist.dev/e/bd6139dc0804121439u3a29f004o8cb6583c5cd5bfa1%40mail.gmail.com
In-Reply-To: <7vabjyhiys.fsf@gitster.siamese.dyndns.org>

```
[Apologies for sending it twice, I keep forgetting to hit 'reply to
all' instead of 'reply']

On Sat, Apr 12, 2008 at 11:16 PM, Junio C Hamano <gitster@pobox.com> wrote:
> "Sverre Rabbelier" <alturin@gmail.com> writes:
>
>  > ... when I change files in the same directory I commit all
>
> > those in one go. As such I am a great fan of 'git diff .' and 'git
>  > commit .'
>
>  The command in such a work flow for "What has been changed here" is not
>  "git status", but is "git diff <diff args> HEAD .", if "git commit ." is
>  how you make your commits.  --name-status, --name-only or --stat may be
>  a good option to give in that command line.

That is nice indeed, I didn't use 'git diff' for that as it gave me
_too much_ information (the diff, whereas I'm only interested in
one-liners like those in '--name-status' (even --stat is too much).

>  As "git status" is a Porcelain just like "git commit" is, its output
>  format is not holy.  It is not meant to be parsed by scripts and we are
>  free to change its behaviour for human users typing at it and reading from
>  it, provided if the change is worth making.  However, for this particular
>  case, I doubt changing the existing "git status" that is a preview of the
>  next commit is necessary nor has much merit.

Ah, I didn't realize this but it does make sense now that you
explained it, thank you.

>  Not because I think your workflow is minority (I don't), but simply
>  because "git status" is not what you need in this case (you may think it
>  is what you "want", but notice that I said what you "need").

That is of course a possibility, it was more that since it's task is
"Show the working tree status" I thought it was what I need. I don't
mind using another command for what I need, although 'git diff
--name-status .' for example is a lot longer to type than 'git status
.'.

>  This is because "git status <paths>" these days is much less useful than
>  it was originally, after we made --only the default mode for "git commit".
>
>  It used to be that the default for "git commit" was --include.  If you say
>  "git commit foo" when you have some changes already staged, the commit
>  will include what has already been staged plus the latest contents you
>  have in "foo".  With such a system, "git status foo" _was_ a very useful
>  way to remind yourself what changes _other than_ you are naming from the
>  command line are going to be committed.  It still is the default when you
>  are recording a merge commit, as the typical use case is that most of the
>  paths have already been resolved, you fixed up the conflicted ones in your
>  work tree, and you say "git commit <these I fixed up>".  You do not want
>  to record a new commit that ignores what is staged in this case.

I didn't know about this previous behavior, the current situation
makes more sense after this little bit of history, sweet.

>  These days, --only is the default mode of operation.  "git commit foo"
>  commits _only_ the changes made to what you named from the command line,
>  disregarding what you have already staged in the index so far.  Because
>  you are already naming what you want to commit, the value in reminding
>  what others will also be committed, as there is none, has diminished
>  greatly, compared to the days when --include was the default.  It still
>  has value that reminds you what you meant by the dot in "git commit ."
>  (which is essentially what "git diff --name-only HEAD ." is).  It also
>  has value that reminds you what you may need/want to commit after making
>  this commit in this directory.  But it has less information than the old
>  days, because you already know "what will be committed" will not include
>  what you did not name from the command line (in your _particular_ use
>  case, "the current directory"), and "what could be committed" will only
>  consists of the rest (in your _particular_ use case, "outside the current
>  directory").

I would agree, except that (after trying out just now), I noticed that
"git diff --name-only HEAD ." does not list new files. In my workflow
I am definitely interested in new files, is there a way to have 'git
diff --some-switch-here HEAD .' show those too?

>  We could special case and make it not report anything that will be left in
>  the work tree that is different from the resulting commit when --only is
>  in effect, which is what you seem to "want".  But even that should not be
>  the default but be an option, as that mode is robbing from users (other
>  than yourself) the information "what other changes I may still need to
>  commit after this".  But if you are going to give that option and say
>  "git status --commit-only ." there is already existing tool to ask the
>  question you are asking in a more direct way.

Well, it's not just 'git status .' that I would be interested in,
pretty much anything that reduces the size of 'git status' would be
useful indeed. Being able to limit the output of 'git status' (or 'git
diff --names-only', with whatever switch needed to make it show new
files) with an arbitrary filter is pretty much what I want. I
understand better now what other people use 'git status' for now, and
I agree that changing it's behavior in the way I described would mean
robbing them of information. Even so, I still think it makes more
sense to have that information in "git commit -d" but I guess that's
more personal preference than anything (plus I'm biased).

Thank you for your explanation,

Sverre

```
