Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm learning git and I've noticed that it has a two-step commit process:

  1. git add <files>
  2. git commit

The first step places revisions into what's called a "staging area" or "index".

What I'm interested in is why this design decision is made, and what its benefits are?

Also, as a git user do you do this or just use git commit -a?

I ask this as I come from bzr (Bazaar) which does not have this feature.

share|improve this question
1  
+1 for asking. I use Tortoise SVN, which has the same approach and I never understood why. –  DPD Apr 18 '11 at 10:34
    
The staging area isn't that unusual. The equivalent in, say, TFS would be checking or unchecking the box next to a file before checking in. Only the checked files get committed. The difference with Git is that if you use git add -p, you can choose to commit one piece of a file while not committing another piece of the same file. –  Kyralessa Sep 30 '11 at 3:57

4 Answers 4

up vote 34 down vote accepted

Split work into separate commits. You've probably many times opened a file to write a single-line fix, but at the same time you spotted that the formatting was wrong, some documentation could be improved, or some other unrelated fix. With other RCSes you'd have to write that down or commit it to memory, finish the fix you came for, commit that, and then return to fix the other stuff (or create a ball-of-mud commit with unrelated stuff). With Git you just fix all of it at once, and stage+commit the single line separately, with git add -i or git-gui.

Don't break the build. You're working on a complicated modification. So you try different things, some of which work better than others, some which break things. With Git you'd stage things when the modification made things better, and checkout (or tweak some more) when the modification didn't work. You won't have to rely on the editor's undo functionality, you can checkout the entire repo instead of just file-by-file, and any file-level mistakes (such as removing a file that has not been committed or saving+closing after a bad modification) does not lead to lots of work lost.

share|improve this answer
2  
Coming from a DVCS (bzr) that does not have this feature, that sounds a lot like what I currently achieve with a combination of liberal use of my editor's "undo" buffers, the "revert <file>" command and selective commits ("commit <file>"). Sounds like this feature of git has the potential to be more methodical. –  thomasrutter Apr 19 '11 at 6:21

One of the benefits for me is the ability to "add" files progressively. Before committing I review each file. Once the file is reviewed, I add it. When I git status or git diff, git shows me only the files that have been modified and have not been added yet. When I have reviewed all the files and added them, then I can commit.

So yes, I find the staging area very helpful.

And no, I never use git commit -a. However, I often use git add -u. This way I can still visualize what's to be committed.

share|improve this answer
1  
Exactly. The advantage is much more fine grained control over exactly what you are comitting. –  Josh K Apr 18 '11 at 16:27

The benefit is quite simple: it gives you full control over which files you want to commit when. For that matter, you can use git add -p to control which lines you want to commit.

share|improve this answer
    
I've always wondered about how to do this. I wish there was a file .gitignorelines so you could make local changes to individual lines that could survive commits, and remain intact. –  alex gray Sep 29 '13 at 15:48
    
Ignoring local per-line changes and ensuring that your code differs from everyone else's in ways only you know about at the line level? That sounds like an anti-feature to me. –  Rein Henrichs Sep 29 '13 at 22:43
    
@ReinHenrichs, think about config files that need changing by each developer. –  Ian Apr 28 at 10:56
    
@Ian So part of the file changes infrequently and is shared and part of the file changes often, in incompatible ways, and isn't shared? Supporting this false connascence definitely sounds like an anti-feature. –  Rein Henrichs Apr 29 at 16:58
    
@ReinHenrichs, yes and it is very common when the file contains the name of the database server and each dev has there own database. –  Ian Apr 29 at 18:43

One of the benefits that I like is the ability to commit a portion of a change. Ie., by using git add -e. I do not commit as often as I should sometimes, and the git add -e command lets me unravel my changes to an extent.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.