To understand the difference between git commit and git commit -a , you need to know about index in git, also known as staging area .
In the main index, the state of each file is saved, which will go to the next commit. (By “state” here I mean the exact contents of a file that git identifies by its hash.) When you enter git commit without any other parameters, git will do a new git commit in which the states of all files are exactly the same as in the index. This can be very different from your working tree and the useful git function, as I will explain below.
What git add really does is "stage" the file or add its current state to the index. It doesn’t matter whether it was initially tracked or not, you say "in the next commit, I want this file to be present with this particular content." It’s important to understand that this writes the content that you want to add, not the file name — this means that if you continue to make changes to the file after you put it with git add , you will see the output from git status , which sometimes confuses people coming from other version control systems:
$ git status [...] # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # modified: foo.txt # # Changed but not updated: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: foo.txt
... but it makes sense if you know about the index. You can see the changes that you have already made (i.e., the difference between the state of the files in the index and HEAD, which is usually the last commit in the branch you are working on):
$ git diff --cached
... and you can see all the changes that have not yet been made (i.e. the difference between your working copy and index):
$ git diff
So why is it so helpful? In essence, the idea is that the history of your project is most useful when each commit contains only a logically grouped set of changes that provide a well-defined improvement to the project. The less you can make these commits, the better, as later on, the wonderful git bisect tool can quickly help you keep track of which change has made an error. If you are not extraordinarily disciplined, during the error correction process you will often edit other files that you really do not need to fix this problem, or may ultimately fix two logically different problems before deciding to make your changes. In these cases, the index can help you highlight these changes - just git add each file containing the changes you want in the first commit, run git commit , then do the same to create the second commit. [1]
If you get used to it as a workflow, you will eventually just want to make some changes to the file, not others, in which case you will want to learn about git add -p (and then its interactive options s and e !)
However, to get back to the original question - what does git commit -a do something else? Essentially, he says: "Before creating this commit, also create every file that has been modified (or deleted) in its current state." So, if you do not think that you need to carefully process the files in the index before committing, you can just use "git commit -a" all the time. However, I think one of the nice things about using git is that it encourages the creation of beautiful commits, and actively using this index is a big help for that. :)
Notes:
To simplify the above explanation, some statements are somewhat approximate (for example, I did not mention that the index also preserves the (un) executable state of the file, that it can have several versions during merging, etc.).
[1] You have to be careful if you want to make sure that every commit in your story has been checked correctly - if this is important in your project, you should test the tree with every new commit before clicking ...