During the last three years that I've used git, I've learned to mostly make relatively small commits. In the typical case, once I've completed a largish change in my local repo, I sit down for another hour or more, and split it into a set of small commits. This message briefly describes how I do that. 1. Split changes among multiple commits ======================================= Let's assume that I have a largish number of changes in my local repo, after the latest commit. Some of these changes are typically refactorings needed to implement a new feature, others are simple fixes on things that I've noticed and fixed on the fly, and some changes are parts of the new feature. I find it a prudent practise to create separate commits from the small changes, from the refactorings (often several of those), and the actual new feature. Typically the first commits are relative small, preparing for the big change, and the last one adding some new functionality is then a larger one. The first thing is to commit changes selectively. For this, I use "git commit -p", which asks interactively whether I want to stage each change. In that way I can stage some changes from a while while leaving others still unstaged. It is often necessary to split (s) the changes to separate those changes that I want to stage and those I don't. Sometimes I also slightly edit some changes before staging them, in order to stage only a part of the change. Note that such editing doesn't change the file in the working area, so none of the existing changes are lost. "git status" and "git diff" and "git diff --staged" are also very useful at this phase. Once I think I have the desired changes staged, I review them once more with "git diff --staged", selectively fixing and repeating git add -p <file> if needed. Once I'm happy, I simply commit the change, usually from the command line with "git commit -m 'Message'". I have adopted the Linux convention of writing the commit messages in present tense style, explaining what the commit does. So the idea is that the message would continue the sentence "This commit ...", like "... 'Refactors the foobar interface to facilitate zap' where the actual commit message starts with the predicate (verb) of the sentence. Please review my commits to learn the style. Feel free to use "Adds" instead of "Add"; I'd actually prefer the present tense, but forget it myself too often. Of course, this same process is repeated a few times, until all of the wanted changes are committed, in a series of commits. However, especially in the beginning when you are not super-confident of yourself (as I am :-), it is a good idea to test each commit separately. 2. (optional) Test a commit while there are additional changes ============================================================== Consider now a situation where you have just create a commit of some changes, while leaving a number of changes still there at your working area. It is a good idea to test now the new commit, at least to test that it compiles (i.e. has no syntax or other similar errors.) The way to do is to _stash_ the remaining changes from the working area, with "git stash". That saves all the changes in the working area into a temporary commit called stash, into a stash list. After that you can then test the latest commit, and revise it if needed. Once you are happy with the commit, use "git stash pop" to redo your previously saved changes to your working area. Please note that if there are any conflicts between your new local changes after saving into the stash and those saved into the stash, there will be conflicts when you pop the stash. So far I haven't found any very good way of dealing with that, as it happens so rarely. However, if you notice that after "git stash pop" you have some changes already staged, you most probably are in such a situation. I think this stackoverflow explains the situation and resolution pretty well: http://stackoverflow.com/questions/7751555/how-to-resolve-git-stash-conflict-without-commit 3. Amending a commit if you notice that you missed something on the latest commit ================================================================================= While testing your commit, you may notice that it does not compile, or that there is some other problem with it. In that case the best approach is to fix those things, and then *amend* the commit. That is, you add your changes to the staging area as if you were doing a new commit. Then, instead of giving a "git commit -m ..." command, you give "git commit --amend". That *adds* (amends) the new changes from the staging area to the latest commit on the top of your branch. 4. Amending a commit when it is not on the top of the branch ============================================================ Sometimes it also happens that you notice only later, once you have already done a few more commits, that you should have added some changes to a commit that is already somewhat deeper in the stack. That is a slightly trickier situation. I'm not sure what is the best way to handle it, but currently I stash my changes, roll back to the commit that I want to amend with "git reset <sha1>", then amend the commit, and then cherry pick the other commits. However, let's return to this only once you are more confident with the simpler processes above. ---------- Questions, comments and suggestions for improvement very welcome! --Pekka