On Mon, 27 Nov 2006 22:59:52 -0800, Junio C Hamano wrote: > I've been playing with a "private edition" git to see how it > feels like to use "git commit" that defaults to the "-a" > behaviour, using myself as a guinea pig, for the rest of the > evening. Thanks already for the documentation improvements and the patches. I will immediately start using these and use myself as a guinea pig as well. > Confession time. I've had a "purist me" deep inside, who always > thought that people who play contributor role (that is to say > "99.9% of people") should make no commits other than the "-a" > kind [*1*]. ... > *1* The reason to favor "-a" commit is not about hiding the > index but about discipline. I agree with your comments on discipline, (and honestly, I don't really see why they wouldn't apply to anybody). It just plain makes sense to commit code as it existed and as it has been tested. And I think this is really the same motivation for the users whose complaints I've been representing in this thread. I know people who have read all of the "hide the index" debates on the git list and still find the "staged commit" features of the index useless, (because they already have the discipline of never committing a state that didn't actually exist in their working tree). > Judging from my experience so far, although I really wanted to > like this, I am still hesitant to recommend this for inclusion. I'm glad you were willing to try yourself out as a guinea pig on this. That's definitely worthwhile. But I don't think your negative experience here is good evidence against changing the default. My proposal was not that old-time, index-loving git users should adapt to a new default. I think that it should be made very straight-forward for experienced users to drop in an alias or a configuration option such that all the old defaults are preserved. With that, all of the complaints you ran into, (which are all of the form "things act differently than I'm used to"), go away. > 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. Part of that is that some commands are inconsistent with respect to updating the index or not. For example, the following two operations: git cherry-pick -n <something> git am < something are conceptually very similar, (apply some change without creating a new commit), but the first updates the index and the second does not. (This is something you already pointed out in your message and said that perhaps "apply --index" should be the default. I'll come to a different conclusion below.) So things like "git diff" and others work very differently in the above two situations, and the user has to stay well-aware of what's happening in the index or not. So I do find myself having to "worry about it all the time". Another example is how to "undo" a modification of a file such that it is restored to its state as in the last commit. I'd like to be able to teach users a single, reliable command for operations like this. It would be tempting to just say: git checkout some/file which will often work, but not in the case of an updated index, (whether manual or due to something like "cherry-pick -n" or an in-progress merge). In those cases various suggestions might be offered such as: git reset git checkout some/file or: git cat-file -p HEAD:some/file > some/file at which point we can send users screaming again. (I think there's yet another option that was discussed on the list recently, but if I recall correctly, it involved an even more obscure option to some git command than any of the above). So a simple operation like this "undo" requires the user to understand the index and adapt the workflow based on its state. But there's no advantage being offered to the user at all in a case like this. (And whether the change being undone came through something like "cherry-pick -n" or "git-am" is totally irrelevant to the work the user is attempting to get (un)done). All of the above is just to point out that there are times when the notion of the index does get in the way. The user has to mentally track what's happening in the index even when there's no advantage. My goal is to reduce the set of operations where the user is forced to do that. If users want to take advantage of the index, then by all means, it's there and can be taken advantage of. And when the index does its job of taking care of things so the user doesn't have to think about it, that's definitely a good thing. > The same thing can be said about "git merge" (or "git pull ."). > The index is updated for cleanly merged paths so I do not have > to worry about the details -- the only thing I have to know is > that index keeps track of the state and cleanly merged paths are > taken care of for me automatically, so I do not have to worry > about them. "git diff" and "git ls-files -u" will give me > conflicting paths and I can only concentrate on them. Sure. The behavior of "git diff" during a conflicted merge is actually quite intuitive. And that's even intuitive to someone who has no idea what the index is. So the index is doing a fine job here of taking care of things so the user doesn't have to think about them. We should have more of that. The "git diff" behavior would really only be surprising to someone who doesn't totally grok the index if the index got updated other than during a commit or merge. So I think it would be great if that only happened when the user passed the word "index" on the command line as in "update-index" or "apply --index". In fact that rule of them would argue for leaving "git apply" alone and instead solving the inconsistency I pointed out above by making "cherry-pick -n" not update the index, (unless passed a new "--index" option). > 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. I don't see why the correct next value for the version is easier to compute at one time vs. another. Linus argued that it helped him not forget to update the version, but I would think this kind of thing would train users to leave uncommitted stuff around which could lead to mistakes, (and the user _still_ has to remember "Oh, this is that special commit where I _don't_ leave that uncommitted stuff around anymore, but I actually commit it."). So I don't personally see any gain to the trick. > Probably new people who are not used to the index do not have > this problem, but I suspect I am not alone among old time > gitters. Sure, so put an alias or config option in place so you don't have to change your ways at all. > I lost about half an hour after saying "git commit --amend", > without thinking, because I wanted to amend only the commit > message, and much later I noticed that it swallowed unrelated > changes I had in the working tree because it now implied the > "-a" behaviour, and I should have said "git commit -i --amend". I definitely commiserate on that one. I myself often use "commit --amend" to change just a commit message. But at the same time, I also very often use "commit --amend" to fix up the tree itself in the most recent commit. And I've also last the same half hour by forgetting to do "commit -a" or "update-index" when doing that more than once in the past. I think the real fix for this particular issue is to add a little more "stack" functionality to git itself rather than just the one-step-back functionality of "--amend". For example, one simple thing that might help would be a command to edit the commit message of any commit. That would at least be easy to implement as it wouldn't introduce any user-interface concerns about dealing with conflicts while replaying history. -Carl
Attachment:
pgplKqPr9ox4l.pgp
Description: PGP signature