Editor's note: this is the fourth article in the "Git Adventures". The first three articles talked about Git add and git commit commands from the beginning. However, there are still a lot of interesting details behind these two commands. This article will introduce them one by one. The following is the original text.
Different Indexes
I think if you have read the first three articles in the Git adventures, you may already know how to use the git add and git commit commands; one of them is to save the files to the index to prepare for the next commit, and the other is to create a new commit (commit ). However, you may not know the interesting details behind their scenes. Please allow me to come here one by one.
Git index is a temporary area between your working directory (working tree) and the Project repository (staging area ). With it, you can submit a lot of content modifications together (commit ). If you create a commit, the commit is generally the content in the temporary storage area, rather than the content in the working directory.
The state of files in a Git project is roughly divided into the following two categories, and the second category is divided into three categories:
1. untracked file)
2. tracked file)
1. modified but not saved files (changed but not updated or modified)
2. files that can be submitted temporarily (changes to be committed or staged)
3. Files not modified since the last submission (clean or unmodified)
We have seen so many rules above. In the old way, we will build a Git test project to test it:
Let's first create an empty project:
$rm -rf stage_proj$mkdir stage_proj$cd stage_proj$git initInitialized empty Git repository in /home/test/work/test_stage_proj/.git/
We also create a file with the content "hello, world:
$echo "hello,world" > readme.txt
Now let's look at the status of the previous job catalog. You can see that readme.txt is not tracked (untracked file ):
$git status# On branch master## Initial commit## Untracked files:# (use "git add ..." to include in what will be committed)## readme.txtnothing added to commit but untracked files present (use "git add" to track)
Add external readme.txt to the temporary storage zone: $ git add readme.txt
Now let's take a look at the status of the current working directory:
$git status# On branch master## Initial commit## Changes to be committed:# (use "git rm --cached ..." to unstage)## new file: readme.txt#
We can see that the status of "readme.txt" is changed to "temporarily saved" and can be submitted (changes to be committed ), this means that we can directly execute "git commit" to submit the file to the local repository.
The staging area is generally stored in the index file (. git/index) under the git directory ). An index is a binary file that stores information related to the currently saved content, including the temporary file name, SHA1 hash string value of the file content, and file access permissions, the content of the entire index file is stored in order by the temporary file name.
But I don't want to submit the file right away. I want to see the content in the staging area. Let's execute the git ls-files command to see it:
$git ls-files --stage100644 2d832d9044c698081e59c322d5a2a459da546469 0 readme.txt
If we read the "ding Jie niu" in the previous article, you will find that "there are more" in the git directory ". git/objects/2d/832d9044c698081e59c322d5a2a459da546469 "and then execute" git cat-file-p 2d832d ", you can see that the content inside is" hello, world ". When Git adds a temporary partition to a file, it not only adds it to the index file (. git/index), and save its content to the "git directory" first.
If we accidentally add unnecessary files to the temporary storage zone when executing the "git add" command, you can run "git rm -- cached filename" to remove the accidentally added files from the temporary storage area.
Now, after modifying the "readme.txt" file:
$echo "hello,world2" >> readme.txt
Let's take a look at the changes in the temporary storage zone:
$git status# On branch master## Initial commit## Changes to be committed:# (use "git rm --cached ..." to unstage)## new file: readme.txt## Changed but not updated:# (use "git add ..." to update what will be committed)# (use "git checkout -- ..." to discard changes in working directory)## modified: readme.txt#
You can see that the command output contains a piece of content: "changed but not updated... modified: readme.txt ". It may be strange to everyone that I didn't add the "readme.txt" file to the temporary storage area. How can I prompt that I have not added it to the temporary storage area (changed but not updated) is Git wrong.
Git is correct. Every time you execute "git add" to add a file to the temporary storage area, it will perform the SHA1 hash operation on the file content and add a new entry to the index file, store the file content in the local "git directory. If the file content is modified after "git add" is last executed, gitwill view the file content in sha1hashield when the "git status command" is executed. At this time, readme.txt "is displayed in two statuses at the same time: modified but not temporarily saved files (changed but not updated), saved files that can be submitted (changes to be committed ). If we submit the file at this time, it will only commit the content of the file temporarily saved for the first "git add.
I am not very satisfied with the modification of "hello, world2". To cancel the modification, run the git checkout command:
$git checkout -- readme.txt
Now let's take a look at the status of the working directory in the repository:
$git status# On branch master## Initial commit## Changes to be committed:# (use "git rm --cached ..." to unstage)## new file: readme.txt#
Okay, now that the project is back to the desired state, I will use the git commit command to submit the modification:
$git commit -m "project init"[master (root-commit) 6cdae57] project init 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 readme.txt
Now let's take a look at the working directory status:
$git status# On branch masternothing to commit (working directory clean)
You can see that "nothing to commit (working directory clean)". If all the modifications in a work tree have been submitted to the current head ), so it is clean, and vice versa, it is dirty ).