since 2005 Since its birth in ,git Already popular in the open source world , Many of us also use it in our jobs . It's a great VCS Tools , It has many advantages , But easy to learn is not one of them . about git If you just memorize commands by rote, it won't be long before you forget , And recite it over and over again , No doubt it's very frustrating , in my opinion , Familiar use git The only way to even start to like it is to understand how it works inside .
git Commands are just abstractions of data storage , If you don't understand git How it works , No matter how much we remember or store in our notes git Command or skill we will still be dealing with git Confused about the use of . and git It uses abstract commands to expose the usage of its data structure .
So we should pay more attention to this article git The internal relationship of - Data model , Of course, this article will not deal with git Source code .
preparation
Initialize the repository
To explain the data model , We first need to initialize an empty... In our working directory git Warehouse
git init
git We will be informed that we have created one in the current directory .git Catalog , Let's take a look at this .git What does it look like .
$ tree .git/
.git
|-- HEAD
|-- config
|-- description
|-- hooks
| |-- applypatch-msg.sample
| |-- commit-msg.sample
| |-- fsmonitor-watchman.sample
| |-- post-update.sample
| |-- pre-applypatch.sample
| |-- pre-commit.sample
| |-- pre-push.sample
| |-- pre-rebase.sample
| |-- pre-receive.sample
| |-- prepare-commit-msg.sample
| |-- update.sample
|-- info
| |-- exclude
|-- objects
| |-- info
| |-- pack
|-- refs
|-- heads
|-- tags
8 directories, 15 files
Some of the files and directories look familiar , Now we mainly look at objects
This directory , Now it's empty , But in a moment we'll change it .
To submit documents
First let's create one Main.java
file
touch Main.java
And then type in part of the content
public class Main {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
And then in the same way prepare a README.md file
touch README.md
Enter the following into the file
this is my first java project!
Now? add also commit They went to the warehouse
git add .
git commit -m 'Initial Commit'
Model creation
Now it doesn't look special , Now let's go back and look at .git/objects
There are already some subfolders and files in the directory
.git/objects
|-- 84
| -- 705622ee44f2afbb21087ca7d81fda01fccded
|-- 95
| -- fc1236534b6f73930367f02895467040f47d4a
|-- b0
| -- 81e51f448387e72a3e3551ba8610eedc172e60
|-- f1
| -- a8b89f50a2fd8287578daa2b0374adf3cad8aa
|-- info
|-- pack
6 directories, 4 files
It should be noted that the directory and file names on your computer are different from mine .
blob object The creation of
stay .git/objects
We notice that the name of each directory is only 2 Character length ,Git Generate one for each object 40 Check sum of characters (SHA-1) Hash , The first two characters of the check sum are used as the directory name , in addition 38 Characters for file ( object ) name .
When we submit some documents ,git The first type of object created is blob object, In our case, there are two , every last blob object For every document we submit :
blob object Contains a snapshot of the file and has file checksums .
tree object The creation of
git Another kind of object created is tree object
, In our case, there is only one , It contains a list of all the files in our project , It contains the... Assigned to them blob object The pointer to ( This is it. git How to combine documents with blob object Related to )
commit object The creation of
Last git Also created a commit object, The object has tree object The pointer to ( And some other information )
)
This time I'm looking at the following objects The structure of the directory is much clearer
.git/objects
|-- 84
| -- 705622ee44f2afbb21087ca7d81fda01fccded
|-- 95
| -- fc1236534b6f73930367f02895467040f47d4a
|-- b0
| -- 81e51f448387e72a3e3551ba8610eedc172e60
|-- f1
| -- a8b89f50a2fd8287578daa2b0374adf3cad8aa
|-- info
|-- pack
Verify the accuracy of the model
There's a model on it , But do you think I guessed this model by myself ? How do I know which is blob object? Which is tree object? Which is commit object What about ? And then it's time to witness miracles .
Use git log
Command us to view our submission history
commit f1a8b89f50a2fd8287578daa2b0374adf3cad8aa (HEAD -> master)
Author: zhu.yang <[email protected]>
Date: Tue Jan 8 10:12:06 2019 +0800
Initial Commit
According to the naming convention we mentioned earlier , We can do it in objects Found in f1a8b89f50a2fd8287578daa2b0374adf3cad8aa
This object .
We can't simply use cat
command , Because these are not plain text files , But fortunately, git It provides us with a cat-file command
git cat-file commit f1a8b89f50a2fd8287578daa2b0374adf3cad8aa
You can get commit object The content in
tree 95fc1236534b6f73930367f02895467040f47d4a
author zhu.yang <[email protected]> 1546913526 +0800
committer zhu.yang <[email protected]> 1546913526 +0800
Initial Commit
You can see from above commit Point to tree object And we can use git ls-tree
Command to check what's in it
git ls-tree 95fc1236534b6f73930367f02895467040f47d4a
As we said we expected , It includes pointing to blob object List of files
100644 blob 84705622ee44f2afbb21087ca7d81fda01fccded Main.java
100644 blob b081e51f448387e72a3e3551ba8610eedc172e60 README.md
If you want to see Main.java The content in the is used in cat-file
Command is enough
git cat-file blob 84705622ee44f2afbb21087ca7d81fda01fccded
We can see that it's coming back Main.java The content of the document
public class Main {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
That's what happens when we create and submit some files . At the same time, it also verifies the accuracy of our model .
Model changes when modifying files
Now let's revise main.java Submit it again
As we can see ,git In the form of a snapshot Main.java
I've created a new one blob object, because README.md
Not modified , So no new... Will be created for it blob object. and git Will reuse existing blob object.
Now? , When git Create a tree object when , Assigned to Main.java
Of blob The pointer will be updated , And assigned to README.md
Of blob The pointer will remain the same as in the previous commit tree .
)
In the end ,git Create a commit object And point to it tree object. There is also a pointer to its parent commit object ( Each submission has at least one parent submission in addition to the first submission )
So far we have known git How to deal with the addition and editing of files , The only thing left is how to deal with the deletion , Let's delete Main.java:
Notice the red line above , We found that deleting is also very simple , Just delete tree object Point to blob object The pointer of . In this case, we deleted... In the new submission Main.java, So our submitted tree objects no longer have a pointing representation Main.java Of blob object The pointer to .
How the model handles the folder
The data model we provide has an additional function -tree object Can be nested ( They can point to other tree objects ), You can think like this : Every blob object For a file , Each tree object represents a directory , So if we have nested directories , We have nested tree object.
Because the above figure has been drawn after submitting results for many times , If you draw the structure on the basis of the above, it will not be so clear , This time I reinitialize a repository to demonstrate , The existing data in the warehouse is as follows :
|-- README.md
`-- app
`-- user.json
And then submit , Finally, you can see the following data model
Git Use blob object as well as tree object To reproduce the folder structure of the project . I'm sure you are right here git We have a more in-depth understanding of the data model , It's really simple , I believe in learning based on it Git It must be twice the result with half the effort .
summary
- When creating a submission git Will the new blob object,tree object,commit object And it will form a link diagram
- Nested tree object Used to represent a folder
- git From reuse blob object
- Except for the first submission , Each submission has a parent submission