We have been using
git add every time we want to
commit a change, separate from
git commit. Why? We will demystify this now,
and learn how to keep organized.
Git forces you to create version history and commit messages, and if these are clear then you are a long way to organized code.
b135ec8 now feature A should work 72d78e7 feature A did not work and started work on feature B bf39f9d more work on feature B 49dc419 wip 45831a5 removing debug prints for feature A and add new file bddb280 more work on feature B and make feature A compile again 72e0211 another fix to make it compile 61dd3a3 forgot file and bugfix
There are multiple things that are not so stellar in this version control history.
A better example would be:
6f0d49f implement feature C fee1807 implement feature B 6fe2f23 implement feature A
We want to have nice commits. But we also want to “save often” (checkpointing) - how can we have both?
Note: the “staging area” has also alternatively been referred to as the index and the cache.
Files can be untracked, modified, staged, or committed, and we have a variety of commands to go between states:
$ git add <path> # stages all changes in file $ git add -p <path> # stages while letting you choose which lines to take $ git commit # commits the staged change $ git diff # see **unstaged** changes $ git diff --staged # see **staged** changes $ git rm # removes a file $ git reset # unstages staged changes $ git checkout <path> # check out the latest staged version ( or committed # version if file has not been staged )
git addevery change that improves the code.
git checkoutevery change that made things worse.
git commitas soon as you have created a nice self-contained unit (not too large, not too small).
$ git add file.py # checkpoint 1 $ git add file.py # checkpoint 2 $ git add another_file.py # checkpoint 3 $ git add another_file.py # checkpoint 4 # ... further work on another_file.py ... $ git diff another_file.py # diff w.r.t. checkpoint 4 $ git checkout another_file.py # oops go back to checkpoint 4 $ git commit # commit everything that is staged
Exercise: Using the staging area
- In your recipe example, make two different changes to
instructions.txtwhich do not go together.
git addto stage one of the changes.
git statusto see what’s going on, and use
git diff --stagedto see the changes.
- Feel some regret and unstage the staged change.
(Optional) Interactive staging
One option to help us create nice logical commits is to stage interactively with
git add -p(you can also directly commit interactively with
git commit -p):
- Modify multiple lines in
instructions.txt. Make sure that they are separated by at least one unmodified line.
git add -p instructions.txt.
?and Enter to get an explanation of what the different options mean.
- See if you can use the
noptions to include only a subset of your modifications in the staging.
- When you’re done, inspect the situation with
git diff --staged.
- If you want, you can try repeating the procedure above but use
git commit -pinstead of
git add -pto commit directly.
Test your understanding
- When is it better to “save” a change as commit, when is it better to “save” it with
- Is it a problem to commit many small changes?
- What types of problems can occur in other version control systems without a staging area?
The staging area helps us to create well-defined commits.