On Fri, 01 Dec 2006 09:36:00 -0800, Carl Worth wrote: > To finish off, I'd like to propose descriptions of the commands to > allow the user to use the "without staging" commands as a complete set > while being able to easily ignore any of the staging capabilities. > This does trigger a need for a semantic change in the "add" > command. Here are the proposed descriptions: By the way, back when we used to call it the "index" one of the things that was often mentioned as a reason not to "hide the index" is that the index ends up being so important during the process of resolving a merge. This is extremely true, and this is where git really starts to shine. I've seen people get really put off by the index when they first encounter "commit -a" or a messages instructing them to "update-index" something. But, if people are properly presented with what git offers for helping with conflict resolution then I think they will fall in love with it. But I think "hide the index" vs. "celebrate the index" frames the debate entirely wrong. It's not a matter of "working tree" vs. "index" being the king. The king is what the user wants to accomplish and what does git offer to help with that. So, for example, in the case of conflict resolution, what git offers in an iterative process involving: git diff Shows what still needs to be resolved git resolve Indicate to git that conflicts are resolved in the specified files (Yes, I'm assuming a future "resolve" synonym for update-index here) And finally, "git commit" when complete. This is a fantastic sequence since it fits what the user wants to do and helps the user do it, (and the incremental nature of it is helpful for large conflicts). Note that I don't think it's important whether the final "git commit" executes a "commit -a" or a mode traditional commit-the-index. It would be exceedingly rare for someone to want to make a partial, staged commit during conflict resolution. So I think that special case can be entirely ignored when considering the user-interface. So git provides tools well suited to the job here. One thing it doesn't do well is to advertise them to the user. It would probably be helpful to print some small section of advice and guidance when the conflict happens. Right now, git spews a lot of scary internal state that definitely gives the impression of things going wrong, and doesn't tell the user much about what to do. It would be nice to say something more along the lines of "A conflict occurred during the merge attempt. That's nothing to worry about---it happens sometimes. And here are some tools that git offers to help you fix things up:..." And there are other lovely things that git provides, such as: git log -p --merge Shows commits that contributed to this conflict git diff --ours Show changes in working tree compared to our latest commit for unresolved files git diff --theirs Show changes in working tree compared to the commit being merged in for unresolved files To tell the truth, I hadn't really played with "diff --ours" and "diff --theirs" much before. They're right handy! I can't find any documentation for them, (it might exist somewhere deep in the plumbing documentation but I can't find it). It would be great to have examples in the "git diff" page showing these off, and maybe some hints in the message that comes from the conflicted merge. So the above commands are wildly useful. But there not useful because "the index is an essential part of git", they're useful because they help the user get information related to what the user is doing. One command that I didn't find in my experimentation was how to see the multi-parent diff after resolving the conflict. I found that I can do a single-parent thing with: git diff --cached Show changes in staging area compared to our latest commit. But I didn't figure out how to get the multi-parent thing there yet. After I make the commit object I _can_ see the result I want with "git show", but it would be nice to be able to see that before the commit. Surely there's a command-line option somewhere that does this, with a name like -cc or -C or something, but it's something that I would argue should acquire a different name---that is, if I were doing conflict resolution often. As it stands now, I rarely have any conflicts to resolve, so any user-interface warts that git has here haven't rubbed me the wrong way yet. Other than the conflict spew which gives the impression of "Git tried (multiple ways) and failed to merge this mess. You're on your own now." -Carl PS. Here's the example I just used to experiment with conflict resolution. It's something like this that would be nice to have in something like "git tutorial conflict-resolution" which would run the following sequence of commands for the user and then invite the user to play with things like "git diff --ours" and "git diff --theirs". The commands below look really ugly, so we definitely don't want the tutorial reader to ever have to go through all this state-creation. But the end result---what the user sees in "git diff" is so intuitive that it would be wonderful to have this kind of thing readily available at the command-line. A more ambitious example might setup conflict in multiple files to teach the incremental nature of using "git diff" and "git resolve" together. mkdir git-tutorial-conflict-resolution cd git-tutorial-conflict-resolution git init-db echo 'vvv Context paragraph 1 vvv This is a paragraph that exists for context. It will be unmodified in both branches. ^^^ Context paragraph 1 ^^^ This is a paragraph that I will modify in master and delete in other. vvv Context paragraph 2 vvv This is a second paragraph that exists for context. It too, will be unmodified in both branches. ^^^ Context paragraph 2 ^^^ This is a paragraph that I will delete in master and modify in other. vvv Context paragraph 3 vvv This is the third paragraph that exists for context. Again, it will be unmodified in both branches. ^^^ Context paragraph 3 ^^^ This is a paragraph that I will modify in two different ways in master and other. ' > file git add file git commit -m "add file" git branch other echo 'vvv Context paragraph 1 vvv This is a paragraph that exists for context. It will be unmodified in both branches. ^^^ Context paragraph 1 ^^^ This is a paragraph that I have modified in master. vvv Context paragraph 2 vvv This is a second paragraph that exists for context. It too, will be unmodified in both branches. ^^^ Context paragraph 2 ^^^ vvv Context paragraph 3 vvv This is the third paragraph that exists for context. Again, it will be unmodified in both branches. ^^^ Context paragraph 3 ^^^ This is a paragraph that I have modified in master. ' > file git commit -a -m "master modifications" git checkout other echo 'vvv Context paragraph 1 vvv This is a paragraph that exists for context. It will be unmodified in both branches. ^^^ Context paragraph 1 ^^^ vvv Context paragraph 2 vvv This is a second paragraph that exists for context. It too, will be unmodified in both branches. ^^^ Context paragraph 2 ^^^ This is a paragraph that I have modified in other. vvv Context paragraph 3 vvv This is the third paragraph that exists for context. Again, it will be unmodified in both branches. ^^^ Context paragraph 3 ^^^ This is a paragraph that I have modified in other ' > file git commit -a -m "other modifications" git checkout master git pull . other
Attachment:
pgpaAR50rTCEa.pgp
Description: PGP signature