The “Why is "git commit -a" not the default?” entry in the Git FAQ explains the most common reasons.
The index is useful for committing only some of the changes from the working tree.
Consider the following scenario:
- You are working a new piece of functionality; you have made several edits to the working tree files while working towards this new feature.
- You spot a bug that needs to be fixed; you go ahead and make the edit(s) to fix the new bug.
- You now have a working tree that has two types of changes: “new feature”, and “bugfix”.
You can use the index to make a commit that contains only the “bugfix” changes without having to stash away your “new feature” changes. You can even use
git add -p to stage only a portion of the changes from each changed file.
Some people avoid this particular technique because it lets you commit something that could not have been fully and independently tested (commit == “bugfix”, but working tree (and testing environment) == “bugfix”+“new feature”). Practically, if you are sure the “bugfix” and “new feature” changes are independent, then you should be able to effectively test the “bugfix” changes even though your working tree also has the “new feature” changes.
A potentially less objectionable use case involves carrying “local-only” changes around in a working tree without having to commit them. Say a repository includes a configuration file that needs to be slightly altered in your working environment (changing a username, an email address, etc.). You can use the index to stage and commit everything except your local-only configuration changes. The mechanism is the same as the prior use case; the difference is that it is usually easier to convince yourself that your local-only configuration changes are not dependent on any other possible change you might be making.