Carl Worth <cworth@xxxxxxxxxx> writes: >> 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. >> 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. - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html