5. Handling Changes¶
5.1. Procedure¶
When we’re talking about “committing changes”, we mean adding changes to the local Git repository. This is achieved in 2 separate steps:
Changes are staged, which means they’re added to a staging area
The changes in the staging area (i.e. changeset) are then committed to the local Git repository
Hint
This 2-step procedure with the staging area helps us to bundle different changes (e.g. file content changes) into a complete changeset, which can then be committed as a commit.
Unstaged changes are will not be committed to the repository at that point. However, they stay in place and will not be affected (e.g. deleted, reverted or alike).
5.2. File Lifecycle¶
Each file will go through different lifecycles, which are crucial to understand when working with Git commands:
First of all, Git makes a distinction between the following two “global states”:
Untracked: Files which were not added to the Git repository (yet)
Tracked: Files which are tracked by Git, because they were added to the Git repository before
The tracked files can have one of the following states:
Unmodified: File wasn’t modified since last commit
Modified: File was modified since last commit, but not added to the staging area
Staged: File was modified since last commit, and added to the staging area
5.3. Status¶
To check the status of your files, the following command can be used:
git status
When there are no open changes, the command will output something like this:
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
When you start working, a more realistic output can be something like this:
On branch my-feature
Your branch is ahead of 'origin/my-feature' by 4 commits.
(use "git push" to publish your local commits)
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: path/to/a/modified/staged/file.txt
new file: path/to/a/new/staged/file.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: path/to/a/modified/file.txt
modified: path/to/another/modified/file.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
path/to/an/untracked/file.txt
Hint
Please note the different 3 sections above (staged, unstaged & untracked).
Git’s also your buddy, because it will tell you which commands you need to do certain actions directly in the git status
output.
5.4. Stage Files & Folders¶
To stage new files, use the following command:
git add {FILE OR DIRECTORY}
Hint
You don’t need to specify -r
for a directory or alike.
5.5. Stage Patch Hunks¶
Git also allows you to add only hunks of patches to the staging area. This feature can be used if you did multiple changes in a single file, but you only want to commit a subset of it.
To add only hunks to the staging area, use the following command:
git add -p {FILE OR DIRECTORY}
Git will then open up your preferred CLI editor, shows you a single hunk and asks you to make a decision:
(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?
The explanation of the letters can be shown by putting in a question mark ?
:
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
g - select a hunk to go to
/ - search for a hunk matching the given regex
e - manually edit the current hunk
? - print help
5.6. Restore Files & Folders¶
To restore a modified (unstaged) file or folder, use the following command:
git restore {FILE OR DIRECTORY}
In case the file is already staged and you want to unstage it, use this command instead:
git restore --staged {FILE OR DIRECTORY}
Hint
The git restore
command was introduced with Git 2.23.0.
Before that, git reset …
respectively git checkout …
was used.
5.7. Diff¶
To see what you’ve changed but not yet staged, use the following command:
git diff
In case you want to see the staged changes, use the following command:
git diff --staged
5.8. Commit¶
When you’re happy with your staged changes (see Status), you can commit this changeset. This is usually achieved by the following command:
git commit
When hitting enter, this will open up an editor in which you can enter the Git message. You can also use the shortcut and define the message on the CLI itself. This works, but I wouldn’t recommend it:
git commit -m {MESSAGE}
Important
Remember to write a decent message, as described in A Proper Message.
Hint
If you want to change the editor, have a look at the Editor config.
5.9. Ignore Files¶
You can ignore files in Git which results in:
The files not showing up in the Status
The files can’t be committed
Hint
This is usually done with files which should not end up in the repository, such as:
OS files (e.g.
.DS_Store
,.Trash
, )Caching files (e.g.
*.pyc
,__pycache__/
)Built files (e.g.
build/
,.venv
)
To ignore files, add file & directory patterns to the .gitignore
file in your repository.
The rules for the patterns you can put in the .gitignore file are as follows [1]:
Blank lines or lines starting with
#
are ignored.Standard glob patterns work, and will be applied recursively throughout the entire working tree.
You can start patterns with a forward slash (
/
) to avoid recursivity.You can end patterns with a forward slash (
/
) to specify a directory.You can negate a pattern by starting it with an exclamation point (
!
).
Hint
GitHub has a collection of .gitignore templates.
Note
After completing this chapter, you should be able to execute the Committing Is Fun exercise.