In developing software , Maybe many people will develop features or fix for the same software at the same time bug, But if all of them are developed in the main branch , The probability of conflict will be greatly increased , And it's not good for maintenance , If you modify more than one at the same time bug What should I do ? Fortunately ,git The branching function of is very good to help us solve this problem , It can help us develop multiple functions and version management at the same time .
Please read this article before , Be sure to read first Explain profound theories in simple language git—— Data model , This will help you understand better git The branch of . Want to know why git A new branch in * * , Is the price so small ? Next, we will uncover the mystery of the branch .
This time I'll just show you commit objects To simplify it. , And to make it easier to understand, I'll give them an alias instead of the original test and . So for submission records , We'll get a picture like this .
Those familiar with graph theory should notice that the above graph is a directed acyclic graph (DAG), This means that starting from one node doesn't pass through the same node along the direction of the edge .
In our example, we can clearly find that there are three different branches , We use red, respectively ( contain A,B,C,D,E), Blue (A,B,F,G), And green (A,B,H,I,J) To mark them
That's a way to define branches - Include all submission lists . But it's not git How to use it ,git Use a simpler and cheaper way ,git Only the last commit on the branch is tracked , Instead of holding all lists of a branch and updating them , Just know the last commit of the branch , Then according to the directed edge of the graph, we can get the whole submission list . For example, to define our blue branch , Just know that the last commit of the blue branch is G, If we need a list of all the submissions contained in the blue branch , From G Traverse along the directed edge of the graph .
This is it. git How to manage branches , By keeping the pointer to the execution commit record , We'll do a demo next .
git init Initialize an empty warehouse , Then check it out .git Files in directory
.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
This time we focus on it
refs This subdirectory , This place is git Where to keep branch pointers . When we don't submit anything ,
refs There are only two empty directories under the directory , Now we are submitting a few documents
echo "Hello Java" > helloJava.txt git add . git commit -m "Hello Java Commit" echo "Hello Php" > helloPhp.txt git add . git commit -m "Hello Php Commit" echo "Hello Python" > helloPython.txt git add . git commit -m "Hello Python Commit"
When we execute
git branch We can see the following output
It means that we are now in the master On the branch ( This is when we first submitted it git Automatically created for us ), here
refs It's in the catalog
.git/refs |-- heads | `-- master `-- tags
We see refs/heads There is a file in the subdirectory , It's named like our branch master, We use cat Command to view the file content
$ cat .git/refs/heads/master 49cd903b2bf247de040118ce60d1931ff587e801
git log Order us to see that our submission record looks like this
commit 49cd903b2bf247de040118ce60d1931ff587e801 (HEAD -> master) Author: zhu.yang <email@example.com> Date: Tue Jan 8 17:48:36 2019 +0800 Hello Python Commit commit dd7c1bc9c125067f5658bcc6bc35567d07bc4f35 Author: zhu.yang <firstname.lastname@example.org> Date: Tue Jan 8 17:48:31 2019 +0800 Hello Php Commit commit c6bd5c991dbcf9c50bbab682796ab3e06672f5a7 Author: zhu.yang <email@example.com> Date: Tue Jan 8 17:48:30 2019 +0800 Hello Java Commit
You can see from the above that a branch is just a text file , It records the last committed checksum of this branch . That is to point commit A pointer to
Now let's build a new
feature Branch and switch to the new branch
git checkout -b feature
Use tree Orders are coming to see .git/refs The appearance of
.git/refs |-- heads | |-- feature | |-- master |-- tags
We use the same cat Command to check .git/refs/heads/feature Check sum of documents
$ cat .git/refs/heads/feature 49cd903b2bf247de040118ce60d1931ff587e801
We'll find out master The contents of the document are consistent , We haven't been there so far feature Branches submit anything
This is it. git The reason for creating a * * branch is fast and convenient ,git It's just creating a file that contains the last commit check sum .
Now we have them in our warehouse 2 It's a branch , however git How to know which branch we are currently detecting ? There is actually a special pointer called HEAD, It's special because it doesn't point to specific commit object, It's a branch ,git Use it to track the most recently checked out branch .
$ cat .git/HEAD ref: refs/heads/feature
If we implement
git checkout master
Then check it out HEAD, You will find that the current branch is master, then HEAD Will point to master
$ cat .git/HEAD ref: refs/heads/master
This is it. git Branch model of , It's simple, but it's important , Understanding it helps to understand other operations on this diagram (merge,rebase,checkout,revert...).