git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".

From
Junio C Hamano <junkio@cox.net>
Date
Nov 29, 2006, 03:06 UTC
Message-ID
<7virgzuf38.fsf@assigned-by-dhcp.cox.net>
In-Reply-To
<871wnnwi3k.wl%cworth@cworth.org>
Carl Worth <cworth@cworth.org> writes:
Show 11 quoted lines
>> The problem I have with the new behaviour is that it goes
>> against the mental model when I start doing anything nontrivial
>> (I would not use words as strong as "totally breaks the mental
>> model", but it comes close).  I am not sure how well I can
>> express this, but the short of it is that "grokking index" is
>> not about understanding how the index works, but about trusting
>> that git does the right thing to the index and you do not have
>> to worry about it all the time.
>
> Frankly, I do not currently trust git to always do the right thing
> with the index.

This clearly shows that I did not express myself well. You are correct that there are commands that ignore the index by default (a notable example "git apply" has been given by both of us), and you do have to know about what the commands you use do to the index.

What I meant by "do not have to worry about" is not about the index operations each command invocation involves. Of course you need to know (unless you will do a "commit -a" at the end) that git apply without --index will leave the index out of sync relative to your working tree, for example.

What you do _not_ have to worry about all the time is the local changes you do not want to go in your next commit but still want to keep in your working tree. Although it probably is not kosher from the purist point of view, it is very convenient to be able to keep truly local changes (say, my GIT-VERSION-GEN, everybody's change to Makefile to set "prefix=/usr/local", or "#define DEBUG 1" in one of the C files you are currently mucking with) that you have no intention of committing, while you want to record the changes to the paths you worked on so far with patch application, merging and edit + update-index in your next commit. You record the latter in the index using git tools to build what you want to have in your next commit in the index in each step (again, each step you may have to be aware what you are doing). After you update the index, you can forget about them -- because the index remembers them for you. They are in the state you tentatively decided is good for the next commit. You do not have to worry about the local changes you still have that you do not want to have in the commit because you do not run update-index on them, and you can trust that git does not automatically do so either, so they stay local.

Show 11 quoted lines
>> Once I am done, I can ask "git diff" and expect it to show my
>> local changes I have no intention of committing for now
>> (e.g. GIT-VERSION-GEN in the working tree has v1.4.5-rc1.GIT
>> long before I plan to start the rc1 cycle to constantly remind
>> me what the next version will be, which is a trick I picked up
>> from Linus), and "git diff --cached" would show exactly what I
>> will commit.
>
> I understand the trick, and I'm not proposing anything that would
> preclude it. But I really don't find it a compelling argument for the
> default behavior of git-commit.

The above paragraph is not the important part of my message. What was much more important is what immediately followed it, which you did not quote:

    And at that point, I trust "git commit" to do the right thing --
    the damn thing I just checked with "git diff --cached" _is_ what
    will be committed.

Like it or not, git was designed by and for people who use the index to work in a dirty worktree. The "-a" option to "git commit" is politely explained as the "--all" option, but its true pronunciation is "screw the index -- I rightfully haven't been paying attention to the index (my workflow did not require me to) because I know all the changes in my worktree are what I want in the next commit" option.

The "screw the index" attitude is not a wrong thing per-se. It is perfectly a good habit to always work in a worktree that exactly matches HEAD after each commit, and the only index manipulation you would (unfortunately) need to do between your own two commits are "git add" (for this use pattern, "git rm" is an unnecessary thing to do -- just saying "rm" is enough). Then "git diff" (without --cached but perhaps with paths) would serve as a preview for your next commit because you are going to do the "screw the index" commit (except that unfortunate "git add" thing, which we _could_ fix with "intent to add" entries in the index) and you would be happy with the similarity to CVS.

Once you use "I care about the index" workflow, however, you will see more areas where git's index shine. For example, "git diff" starts to take a more useful role. "I care about the index" attitude means you let the index be the incremental staging area for your next commit, and when you reach a good "snapshot" point you update the index with various means provided by git. "git diff" will show "what could further be added to the next commit" without talking about what you already decided are good earlier and updated the index with. As we already discussed, "git merge" will update the index for cleanly merged paths to let you concentrate on more interesting cases (i.e. merge conflicts). To people who care about the index, the next commit preview is "git diff --cached", not "git diff HEAD". What git promises to them is not to update-index the local changes they have without being told and without their knowing.

This is where "git commit" that does "-a" by default goes quite against the underlying mental model of git. You staged what should appear in the next commit in the index because you did not want to worry about the local changes you still want to keep in your working tree. Doing the "screw the index" commit by default to these people is slap in the face. You do not want to get your index suddenly screwed at the final moment of making the commit, which happened to me when I did "commit --amend" with the version with those two patches applied.

Don't get me wrong. I know there are cases that it is useful to always commit with "-a", but that really has to be opt-in. When I work in my alternate "trivial fixes only" repository, I use the "screw the index" workflow myself. When I run git apply and the patch does not apply, I use "git apply --reject" and fix the mess by hand, and at that point I do not care if that operation updates the index for the paths involved or not (although I do check if the patch tries to add new paths -- they need to be told to git even whey you take the "screw the index" attitude), and I do not bother running update-index on them either. But that is possible only because I know I am going to commit the final result with "screw the index" option.

"grokking the index" is not about knowing how the index could be used in your workflow. It is about actually using the index to stage your next commit. Somebody a bit smarter than me once said that if you deny the index you are denying git. Although I would not say it that strongly, because "screw the index" is also a valid workflow to use (arguably part of) git, "screw the index" at the commit time _has_ _to_ be a conscious act.

Next: Nicolas Pitre
Message 1 of 76 in “Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".”
  1. Junio C HamanoNov 29, 2006
  2. Nicolas PitreNov 29, 2006
  3. Junio C HamanoNov 29, 2006
  4. Nicolas PitreNov 29, 2006
  5. Jakub NarebskiNov 29, 2006
  6. Steven GrimmNov 29, 2006
  7. Jakub NarebskiNov 29, 2006
  8. Junio C HamanoNov 29, 2006
  9. Steven GrimmNov 29, 2006
  10. Johannes SchindelinNov 29, 2006
  11. Junio C HamanoNov 29, 2006
  12. xdl_merge(), was Re: [PATCH 0/2] Making "git commit" to mean "git commit -a".Johannes Schindelin, Nov 29, 2006
  13. Seth FalconNov 30, 2006
  14. Carl WorthNov 29, 2006
  15. Johannes SchindelinNov 29, 2006
  16. Junio C HamanoNov 30, 2006
  17. Junio C HamanoNov 30, 2006
  18. Steven GrimmNov 30, 2006
  19. Sam VilainNov 30, 2006
  20. Junio C HamanoNov 30, 2006
  21. Johannes SchindelinNov 30, 2006
  22. Linus TorvaldsNov 30, 2006
  23. Johannes SchindelinNov 30, 2006
  24. Andreas EricssonNov 30, 2006
  25. Linus TorvaldsNov 30, 2006
  26. Theodore TsoNov 30, 2006
  27. Linus TorvaldsNov 30, 2006
  28. Nicolas PitreNov 30, 2006
  29. Carl WorthNov 30, 2006
  30. Jakub NarebskiNov 30, 2006
  31. Carl WorthNov 30, 2006
  32. Andreas EricssonDec 1, 2006
  33. Han-Wen NienhuysDec 1, 2006
  34. Carl WorthNov 30, 2006
  35. Linus TorvaldsNov 30, 2006
  36. Nicolas PitreNov 30, 2006
  37. Linus TorvaldsNov 30, 2006
  38. Jakub NarebskiNov 30, 2006
  39. Carl WorthNov 30, 2006
  40. Michael K. EdwardsNov 30, 2006
  41. Carl WorthNov 30, 2006
  42. Jakub NarebskiNov 30, 2006
  43. Johannes SchindelinNov 30, 2006
  44. Josef WeidendorferNov 30, 2006
  45. Johannes SchindelinNov 30, 2006
  46. Nicolas PitreNov 30, 2006
  47. Nicolas PitreNov 30, 2006
  48. Junio C HamanoNov 30, 2006
  49. Andy ParkinsDec 1, 2006
  50. Alan ChandlerDec 1, 2006
  51. Junio C HamanoNov 30, 2006
  52. Nicolas PitreNov 30, 2006
  53. Junio C HamanoNov 30, 2006
  54. Linus TorvaldsNov 30, 2006
  55. Carl WorthDec 1, 2006
  56. Linus TorvaldsDec 1, 2006
  57. Carl WorthDec 1, 2006
  58. Linus TorvaldsDec 1, 2006
  59. Carl WorthDec 1, 2006
  60. Linus TorvaldsDec 1, 2006
  61. Carl WorthDec 1, 2006
  62. Michael K. EdwardsDec 1, 2006
  63. Junio C HamanoDec 1, 2006
  64. Jakub NarebskiDec 1, 2006
  65. Nicolas PitreDec 1, 2006
  66. Andreas EricssonDec 1, 2006
  67. Alan ChandlerDec 1, 2006
  68. Robert ShearmanNov 30, 2006
  69. Jakub NarebskiNov 30, 2006
  70. Shawn PearceDec 1, 2006
  71. Marco CostalbaDec 2, 2006
  72. Carl WorthNov 30, 2006
  73. Linus TorvaldsNov 30, 2006
  74. Daniel BarkalowNov 30, 2006
  75. Nicolas PitreNov 30, 2006
  76. Johannes SchindelinNov 30, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.