Here's my thoughts from teaching half a dozen people git recently: Minimal newbie command set -------------------------- The complete set of "newbie commands" for useful development work should be as small as possible, for fast learning. People can always look up new things when they want to, but if they don't get the simple things going quickly they will forever see git as "that overcomplex thing I tried to use once". Concretely: explain the indexless "git commit -a" case first, so people don't need update-index right away. Most new docs are pretty good at this, already. Fix the cases where "git commit -a" is not enough. Here's a case I ran into: - Jack is a beginning user of git and does not (want to) understand the index (right now). - Jack works on branch X, say his HEAD points to X1. He has an edited, uncommitted files with the names A, B and C. - Jack wants to pull new changes made by others to his branch. There are merge conflicts in files D, E, ..., Z. - Jack resolves the merge conflicts and is ready to commit the resulting merge. Note files A, B and C should not be committed. 1. if Jack says "git commit -a", then A, B and C will be committed also. 2. if Jack says "git commit", then the current state of the index will be committed. That is, the commit will not contain the proper merged state of files D, E, ..., Z. 3. if Jack says "git commit D E ... Z", things work correctly. But Jack does not want to type or copy-paste that much, and that's horribly error-prone anyway. If the leaves one file out, or accidentally adds B there too, the merge goes wrong. 4. if Jack says "git update-index --refresh" and then "git commit", things work correctly. But Jack doesn't (want to) know about the index. My best idea so far is to add a "git commit -A" option, that essentially does the "update-index --refresh". Whenever index has a file state != HEAD, update-index it. The modified unrelated files will have index state == HEAD. Or altering "git commit -a" to do that. Except, trying to solve usability problems by _adding_ options is just insane. I'd really like to see a way to use git without caring about the index, and just having things work. I can appreciate the index is useful, and possibly even necessary to work on projects the size of the Linux kernel, but I really wish it would default to being _only_ an optimization, not the central bit of user interface to prepare commits. Basic git use _should_ be as easy as basic svn/bzr/hg use. Anything else will just mean git is not used outside of what codebases Linus has dictatorship over. (At least not after bzr is more done or hg more well known; right now git has a very nice feature set, but the others are catching up fast.) This is a part that Subversion got right. Basic use needs to be simple. (If you catch me in agitated mood, I'd claim it's the _only_ part Subversion got right;-) And to reply to a comment on IRC I missed at the time: (21:05:35) gitster: as gittus said much earlier, refusing index is like refusing git. We might be able to implement "index-less" mode in which things like merge and am refuse to operate when you have any change from HEAD in the working tree. Then new users can always do "commit -a". (21:06:04) gitster: "git-repo-config core.newuser yes" perhaps? If you do it that way, you only make git unnecessarily hard to use for newbies. For example, we had a case where we absolutely _had_ to keep an ugly workaround in the tree, in a file not otherwise edited, but we definitely did not want to commit the kludge, at least not to the branch that was really being worked on. So such restricted mode would just have meant either people could not merge, or they had to use index anyway. That's a point where people who have a choice make on, and stop trying to use git. (21:08:34) ***gitster personally considers getting more users a very high priority but agrees that from usability point of view, having a mode to expose "stripped down" set of features for simple needs would be beneficial. That I can 100% agree with. Branch management ----------------- "master" and "origin" are good enough for the really simple use, but that starts to fail fast when you add in more branches. The remotes/* branch support is really nice, but should be used better. Here's a bunch of wild ideas: - When cloning a repository, just clone all the non-remote heads to local remotes/* heads. See what name the remote HEAD points to, store that locally also as a refs/heads/master, set local HEAD to it. Note, origin is gone, and is now called remotes/master. - Alternatively (and I think I like this more): When cloning a repository, just clone all the non-remote heads to local remotes/* heads. See what the remote HEAD points to, store that locally also as a refs/heads/* head, set local HEAD to it. Note, origin and master are both gone, and accessible via remotes/X and refs/heads/X (where X is the name remote HEAD pointed to). - Currently, when people start tracking a new remote branch, they end up editing .git/remotes/origin and adding new Pull: lines. If they intend to work on the branch, they also clone the branch locally, and add a Push: line. Make this simpler. Here's a rough sketch: "git track [--read-only] REMOTE [BRANCH | --all]" Without --all, git track would: - abort if refs/remotes/foo exists - add "Pull: foo:remotes/foo" to .git/remotes/origin (or the equivalent config file) - if --read-only is not given: - add "Push: foo:foo" to .git/remotes/origin - fetch foo from origin to remotes/foo - if --read-only is not given: - run "git branch foo remotes/foo" With --all, it would do the same, but for everything the REMOTE has in refs/remotes/. Exactly when to abort is a bit harder to define, but still.. - Or, if that's too much, at least make peek-remote understand .git/remotes/* shortcuts, so finding out what branches exist is a bit simpler. - : 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