{"thread":{"id":"13079","subject":"[RFC] git status oddity","startedAt":"2008-04-12T15:43:11Z","lastAt":"2008-04-12T21:39:25Z","messageCount":3,"participants":["Sverre Rabbelier","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"74214","messageId":"bd6139dc0804120843m2dd2ec3k69a3ba2809f1e955@mail.gmail.com","threadId":"13079","inReplyTo":null,"subject":"[RFC] git status oddity","fromName":"Sverre Rabbelier","fromEmail":"alturin@gmail.com","sentAt":"2008-04-12T15:43:11Z","receivedAt":"2008-04-12T15:43:11Z","isPatch":false,"sender":{"key":"alturin@gmail.com","avatar":null},"body":"Heya,\n\nI have a directory structure that groups files together in such a way\nthat usually when I change files in the same directory I commit all\nthose in one go. As such I am a great fan of 'git diff .' and 'git\ncommit .' because they allow me to make such partial commits. Sadly,\n'git status' does not play along well with this workflow. What I would\nexpect is 'git status .' to return changes made in the current\ndirectory. More general, I expect 'git status <filter>' to perform\nit's magic on only the files that match the filter. What I deduct from\nthe man page however, 'git status' is merely a 'dry run' of git\ncommit. While this make sense when using it as part of git commit (to\ngenerate a commit msg), it does not make a lot of sense when using it\nas a first-class citizen.\n\nI suggest changing this behavior to be more intuitive (e.g., matching\n'git diff' and 'git commit's filtering behavior). As a result commands\nthat assume 'git status' is a dry run of 'git commit' would have to be\nchanged to pass an additional argument to 'git status' to tell it to\nperform it's old behavior. Even better, a '-d' (for --dry-run) switch\ncould be added to 'git commit' which would make it act as 'git status'\ndoes currently.\n\nProposed:\n1. Add a '-d'/'--dry-run' switch to 'git commit' which makes it behave\nas 'git status' does currently\n2. Improve git status to instead take a path argument on which it will\nfilter it's output.\n3. From here on additional improvements to 'git status' can be made\nwithout having to worry about breaking 'git commit' dry-run capability\nsince that functionality has been put where it belongs, that is, in\n'git commit -d'.\n\nThis would break programs and scripts that assume 'git status' is a\ndry-run of 'git commit', as such I realize this would probably not be\nintegrated anytime soon. Also, I would like to know whether the\ncommunity agrees that current 'git status' behavior does not make\nsense when using it as a first-class citizen. Of course, I assume here\nthat 'git status' is indeed a first-class citizen, if this assumption\nis wrong please explain why.\n\nBelow is a trivial workflow example.\n\nubuntu@ubuntu:~/code/StatusExample$ git init\nInitialized empty Git repository in .git/\nubuntu@ubuntu:~/code/StatusExample$ mkdir dir1 dir2\nubuntu@ubuntu:~/code/StatusExample$ touch dir1/foo dir1/bar dir2/foobar\nubuntu@ubuntu:~/code/StatusExample$ git add .\nubuntu@ubuntu:~/code/StatusExample$ git commit -m \"Initial\"\nCreated initial commit 35dc187: Initial\n 0 files changed, 0 insertions(+), 0 deletions(-)\n create mode 100644 dir1/bar\n create mode 100644 dir1/foo\n create mode 100644 dir2/foobar\nubuntu@ubuntu:~/code/StatusExample$ echo \"1\" >> dir1/foo\nubuntu@ubuntu:~/code/StatusExample$ echo \"2\" >> dir1/bar\nubuntu@ubuntu:~/code/StatusExample$ echo \"3\" >> dir2/foobar\nubuntu@ubuntu:~/code/StatusExample$ cd dir1/\nubuntu@ubuntu:~/code/StatusExample/dir1$ git status .\n# On branch master\n# Changes to be committed:\n#   (use \"git reset HEAD <file>...\" to unstage)\n#\n#       modified:   dir1/bar\n#       modified:   dir1/foo\n#\n# Changed but not updated:\n#   (use \"git add <file>...\" to update what will be committed)\n#\n#       modified:   dir2/foobar\n#\n\nThe above result would be the output of 'git commit -d .'\nExpected output:\n# On branch master\n# Changed but not updated:\n#   (use \"git add <file>...\" to update what will be committed)\n#\n#       modified:   dir1/bar\n#       modified:   dir1/foo\n#\n\n\nThank you for your time,\n\nSverre Rabbelier\n"},{"id":"74231","messageId":"7vabjyhiys.fsf@gitster.siamese.dyndns.org","threadId":"13079","inReplyTo":"bd6139dc0804120843m2dd2ec3k69a3ba2809f1e955@mail.gmail.com","subject":"Re: [RFC] git status oddity","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-04-12T21:16:43Z","receivedAt":"2008-04-12T21:16:43Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Sverre Rabbelier\" <alturin@gmail.com> writes:\n\n> ... when I change files in the same directory I commit all\n> those in one go. As such I am a great fan of 'git diff .' and 'git\n> commit .'\n\nThe command in such a work flow for \"What has been changed here\" is not\n\"git status\", but is \"git diff <diff args> HEAD .\", if \"git commit .\" is\nhow you make your commits.  --name-status, --name-only or --stat may be\na good option to give in that command line.\n\nAs \"git status\" is a Porcelain just like \"git commit\" is, its output\nformat is not holy.  It is not meant to be parsed by scripts and we are\nfree to change its behaviour for human users typing at it and reading from\nit, provided if the change is worth making.  However, for this particular\ncase, I doubt changing the existing \"git status\" that is a preview of the\nnext commit is necessary nor has much merit.\n\nNot because I think your workflow is minority (I don't), but simply\nbecause \"git status\" is not what you need in this case (you may think it\nis what you \"want\", but notice that I said what you \"need\").\n\nThis is because \"git status <paths>\" these days is much less useful than\nit was originally, after we made --only the default mode for \"git commit\".\n\nIt used to be that the default for \"git commit\" was --include.  If you say\n\"git commit foo\" when you have some changes already staged, the commit\nwill include what has already been staged plus the latest contents you\nhave in \"foo\".  With such a system, \"git status foo\" _was_ a very useful\nway to remind yourself what changes _other than_ you are naming from the\ncommand line are going to be committed.  It still is the default when you\nare recording a merge commit, as the typical use case is that most of the\npaths have already been resolved, you fixed up the conflicted ones in your\nwork tree, and you say \"git commit <these I fixed up>\".  You do not want\nto record a new commit that ignores what is staged in this case.\n\nThese days, --only is the default mode of operation.  \"git commit foo\"\ncommits _only_ the changes made to what you named from the command line,\ndisregarding what you have already staged in the index so far.  Because\nyou are already naming what you want to commit, the value in reminding\nwhat others will also be committed, as there is none, has diminished\ngreatly, compared to the days when --include was the default.  It still\nhas value that reminds you what you meant by the dot in \"git commit .\"\n(which is essentially what \"git diff --name-only HEAD .\" is).  It also\nhas value that reminds you what you may need/want to commit after making\nthis commit in this directory.  But it has less information than the old\ndays, because you already know \"what will be committed\" will not include\nwhat you did not name from the command line (in your _particular_ use\ncase, \"the current directory\"), and \"what could be committed\" will only\nconsists of the rest (in your _particular_ use case, \"outside the current\ndirectory\").\n\nWe could special case and make it not report anything that will be left in\nthe work tree that is different from the resulting commit when --only is\nin effect, which is what you seem to \"want\".  But even that should not be\nthe default but be an option, as that mode is robbing from users (other\nthan yourself) the information \"what other changes I may still need to\ncommit after this\".  But if you are going to give that option and say\n\"git status --commit-only .\" there is already existing tool to ask the\nquestion you are asking in a more direct way.\n"},{"id":"74232","messageId":"bd6139dc0804121439u3a29f004o8cb6583c5cd5bfa1@mail.gmail.com","threadId":"13079","inReplyTo":"7vabjyhiys.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC] git status oddity","fromName":"Sverre Rabbelier","fromEmail":"alturin@gmail.com","sentAt":"2008-04-12T21:39:25Z","receivedAt":"2008-04-12T21:39:25Z","isPatch":false,"sender":{"key":"alturin@gmail.com","avatar":null},"body":"[Apologies for sending it twice, I keep forgetting to hit 'reply to\nall' instead of 'reply']\n\nOn Sat, Apr 12, 2008 at 11:16 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> \"Sverre Rabbelier\" <alturin@gmail.com> writes:\n>\n>  > ... when I change files in the same directory I commit all\n>\n> > those in one go. As such I am a great fan of 'git diff .' and 'git\n>  > commit .'\n>\n>  The command in such a work flow for \"What has been changed here\" is not\n>  \"git status\", but is \"git diff <diff args> HEAD .\", if \"git commit .\" is\n>  how you make your commits.  --name-status, --name-only or --stat may be\n>  a good option to give in that command line.\n\nThat is nice indeed, I didn't use 'git diff' for that as it gave me\n_too much_ information (the diff, whereas I'm only interested in\none-liners like those in '--name-status' (even --stat is too much).\n\n>  As \"git status\" is a Porcelain just like \"git commit\" is, its output\n>  format is not holy.  It is not meant to be parsed by scripts and we are\n>  free to change its behaviour for human users typing at it and reading from\n>  it, provided if the change is worth making.  However, for this particular\n>  case, I doubt changing the existing \"git status\" that is a preview of the\n>  next commit is necessary nor has much merit.\n\nAh, I didn't realize this but it does make sense now that you\nexplained it, thank you.\n\n>  Not because I think your workflow is minority (I don't), but simply\n>  because \"git status\" is not what you need in this case (you may think it\n>  is what you \"want\", but notice that I said what you \"need\").\n\nThat is of course a possibility, it was more that since it's task is\n\"Show the working tree status\" I thought it was what I need. I don't\nmind using another command for what I need, although 'git diff\n--name-status .' for example is a lot longer to type than 'git status\n.'.\n\n>  This is because \"git status <paths>\" these days is much less useful than\n>  it was originally, after we made --only the default mode for \"git commit\".\n>\n>  It used to be that the default for \"git commit\" was --include.  If you say\n>  \"git commit foo\" when you have some changes already staged, the commit\n>  will include what has already been staged plus the latest contents you\n>  have in \"foo\".  With such a system, \"git status foo\" _was_ a very useful\n>  way to remind yourself what changes _other than_ you are naming from the\n>  command line are going to be committed.  It still is the default when you\n>  are recording a merge commit, as the typical use case is that most of the\n>  paths have already been resolved, you fixed up the conflicted ones in your\n>  work tree, and you say \"git commit <these I fixed up>\".  You do not want\n>  to record a new commit that ignores what is staged in this case.\n\nI didn't know about this previous behavior, the current situation\nmakes more sense after this little bit of history, sweet.\n\n>  These days, --only is the default mode of operation.  \"git commit foo\"\n>  commits _only_ the changes made to what you named from the command line,\n>  disregarding what you have already staged in the index so far.  Because\n>  you are already naming what you want to commit, the value in reminding\n>  what others will also be committed, as there is none, has diminished\n>  greatly, compared to the days when --include was the default.  It still\n>  has value that reminds you what you meant by the dot in \"git commit .\"\n>  (which is essentially what \"git diff --name-only HEAD .\" is).  It also\n>  has value that reminds you what you may need/want to commit after making\n>  this commit in this directory.  But it has less information than the old\n>  days, because you already know \"what will be committed\" will not include\n>  what you did not name from the command line (in your _particular_ use\n>  case, \"the current directory\"), and \"what could be committed\" will only\n>  consists of the rest (in your _particular_ use case, \"outside the current\n>  directory\").\n\nI would agree, except that (after trying out just now), I noticed that\n\"git diff --name-only HEAD .\" does not list new files. In my workflow\nI am definitely interested in new files, is there a way to have 'git\ndiff --some-switch-here HEAD .' show those too?\n\n>  We could special case and make it not report anything that will be left in\n>  the work tree that is different from the resulting commit when --only is\n>  in effect, which is what you seem to \"want\".  But even that should not be\n>  the default but be an option, as that mode is robbing from users (other\n>  than yourself) the information \"what other changes I may still need to\n>  commit after this\".  But if you are going to give that option and say\n>  \"git status --commit-only .\" there is already existing tool to ask the\n>  question you are asking in a more direct way.\n\nWell, it's not just 'git status .' that I would be interested in,\npretty much anything that reduces the size of 'git status' would be\nuseful indeed. Being able to limit the output of 'git status' (or 'git\ndiff --names-only', with whatever switch needed to make it show new\nfiles) with an arbitrary filter is pretty much what I want. I\nunderstand better now what other people use 'git status' for now, and\nI agree that changing it's behavior in the way I described would mean\nrobbing them of information. Even so, I still think it makes more\nsense to have that information in \"git commit -d\" but I guess that's\nmore personal preference than anything (plus I'm biased).\n\nThank you for your explanation,\n\nSverre\n"}]}