Illustrated Git Guide
Category Programming Techniques
Basic Usage
The four commands above copy files between the working directory, the staging area (also known as the index), and the repository.
git add
places the current file into the staging area.git commit
creates a snapshot of the staging area and commits it.git reset --
is used to undo the lastgit add
, and you can also usegit reset
to undo all files in the staging area.git checkout --
copies the file from the staging area to the working directory to discard local modifications.
You can enter interactive mode with git reset -p
, git checkout -p
, or git add -p
.
You can also skip the staging area and directly retrieve files from the repository or directly commit code.
git commit -a
is equivalent to runninggit commit
to make a commit that includes the last commit plus a snapshot of the files in the working directory. And the files are added to the staging area.git checkout HEAD --
rolls back to the last commit.
Conventions
The following form is used for images in the following text.
The green five-character string represents the ID of the commit, pointing to the parent node respectively. Branches are displayed in orange, pointing to specific commits. The current branch is marked with a HEAD attached to it. This picture shows the last five commits, with ed489 being the latest commit. The master branch points to this commit, and another maint branch points to the grandparent commit node.
Command Details
Diff
There are many ways to view the changes between two commits. Here are some examples.
Commit
When committing, git creates a new commit with the files in the staging area and sets the current node as the parent node. Then it points the current branch to the new commit node. In the figure below, the current branch is master. Before running the command, master points to ed489. After committing, master points to the new node f0cec and takes ed489 as the parent node.
Even if the current branch is the grandparent node of a commit, git will operate in the same way. In the figure below, a commit is made on the grandparent node of the master branch, the maint branch, generating 1800b. In this way, the maint branch is no longer the grandparent node of the master branch. At this point, merging (or rebasing) is necessary.
If you want to change a commit, use git commit --amend
. Git will make a new commit with the same parent node as the current commit, and the old commit will be canceled.
Another example is a detached HEAD commit, which will be discussed later.
Checkout
The checkout command is used to copy files from historical commits (or the staging area) to the working directory, and can also be used to switch branches.
When a file name is given (or the -p option is opened, or both the file name and the -p option are opened at the same time), git will copy the file from the specified commit to the staging area and the working directory. For example, git checkout HEAD~ foo.c
will copy the foo.c
from the commit node HEAD~ (i.e., the parent node of the current commit node) to the working directory and add it to the staging area. (If no commit node is specified in the command, the content will be copied from the staging area.) Note that the current branch will not change.
When no file name is specified, but a (local) branch is given, then the HEAD identifier will move to that branch (that is, we "switch" to that branch), and the contents of the staging area and the working directory will be consistent with the commit node corresponding to HEAD. All files in the new commit node (a47c3 in the figure below) will be copied (to the staging area and the working directory); files that only exist in the old commit node (ed489) will be deleted; files that do not belong to the above two will be ignored and unaffected.
If neither a file name nor a branch name is specified, but a tag, a remote branch, a SHA-1 value, or something like master~3 is given, an anonymous branch is obtained, called a detached HEAD (a detached HEAD identifier). This makes it convenient to switch between historical versions. For example, if you want to compile the 1.6.6.1 version of git, you can run `git checkout v1.6.6