preface
Branch is one of the most core operations in Git. Understanding the basic operations of branch can greatly improve the efficiency of project development. This tutorial introduces some common operations of branches and their basic principles.
First, branch overview
In development, division of labor is often required. For example, Xiao Hong develops A function, Xiao Ming develops B function, and Xiao Gang develops C function. How do you develop all three in parallel? Git provides us with the branch function to achieve this requirement, as shown in the following figure:
During actual development, the Master branch is used to release stable versions of the project. New functionality is usually developed on a new branch, and only after the new functionality has been developed and tested to be stable will it be merged into the Master branch for version updates. This allows new features to be developed at the same time as a software release.
Git branches in remote repositories are usually the master branch, test branch, Develop branch, and possibly hotfix branch for emergency bug fixes. However, there can be many local branches; This article focuses on the local branch of Git.
2. View the local branch
1.git branch
View all branches in the current repository:
* indicates the branch currently in the master branch.
When you initialize a Git repository with Git init, Git automatically creates a master branch. However, if you switch to another branch without making any commit on the master branch, the master branch will be destroyed at the time of the switch. Also, you cannot view branches that have no committed records, as shown below:
2.git branch -a
View all local branches, including local and local remote branches:
3.git branch -v
To view the most recent commit on all local branches:
However, the directive cannot view the local remote branch:
4.git branch -r
The -r argument is used to view local remote branches separately:
5.git branch -av
This command not only displays all local branches, including local remote branches, but also the latest commit information on the corresponding branch:
6.git branch -vv
-vv displays the association between all local branches and remote branches. As shown in the figure, the local master branch is associated with the local remote branch origin/ Master, indicating that it has been associated with the remote master branch.
The local remote branches mentioned above will be covered in more detail in the next lecture.
Create a local branch
1.git branch <branch_name>
To create a new branch new_branch, run the following command:
Because the new_branch is created on the master branch, the new_branch shares part of the commit history with the master branch. So, files on the master branch, new_branch. However, new_branch files added on the new_branch branch do not exist on the master branch:
At this point, the states of the two branches are:
2.git branch -b <branch_name>
To create and switch to the new_branch branch, run the following commands:
As shown in the figure, the original branch is master and there is no new_branch. After executing the above command, the new_branch branch is created and switched to.
4. Switch local branches
1.git checkout <branch_name>
For example, switch to new_branch:
2.git checkout -
Switch back to the branch of the previous operation:
Rename the local branch
1.git branch -m <oldName> <newName>
Rename the local branch master to master2 as shown below:
Delete the local branch
1.git branch -d new_branch
Delete the new_branch branch:
Note:
- Cannot delete the current branch;
- When the branch that needs to be deleted has
master
Content that the branch does not have and was not merged before deletion (merge
), an error will be reported:
In this case, you can run the git branch -d new_branch command to forcibly delete branches without merging them.
Merge branches
Note: The branch referred to here refers to the branch with A common commit node, as shown in the dev and Master branches below, and commit node A is their common commit node:
When the two branches have no common submission nodes, as shown in the figure below, rebase should be used to merge, which will be described in detail later:
1.git merge <branch_name>
-
First, create and switch to a new branch dev and add content dev1 to the test.txt file:
-
Note: This change on the dev branch must be committed to the repository for subsequent merges. Because it is a chain of submitted objects that is merged, see the merging principle explained below:
-
Git merge dev merges the contents of the dev branch into the master branch. TXT file on dev/master/test.txt
2. Principle of branch merging
The merge of Git branches adopts the principle of three-party merge: find the common parent node C of the two branches that submitted A and B recently, and merge it into node D based on these three nodes. This node D contains everything on both branches:
The nature of branching
Branch: Points to onecommit
A pointer to a chain of objects or a line of work records;
Snapshot A to SNAPSHOT D indicate four commit times respectively. The commit sequence is A -> B -> C -> D:
As you can see from the graph, the commit id of the last commit is stored in each commit object. Therefore, all commit objects can be connected to form a chain (like a one-way list). This chain forms a complete branch information:
-
When there is only one branch in the repository: the latest commit of that branch contains all the contents of the entire branch, representing the current state of the repository. For example, snapshot D in the figure above contains all the contents of snapshots A to C. In this case, snapshot D is the contents of the entire version library:
-
When there are multiple branches in the repository: the latest commit on each branch contains all the contents of the branch, merge the latest commit from each branch. The merged node contains the contents of all branches, that is, the current version library itself; D1, m2, t3 in the following figure contain all contents of the dev, master, and test branches respectively:
1. Branch= =
Pointer to the
Scene 1:
As can be seen from the figure:
HEAD
Is a pointer to the current branch;master
Also a pointer: to commit;
Scene two:
Dev is the new branch created on the master branch.
git
When you create a new branch, the file itself does not change; you only need to create oneRepresents the new branch and points to the current branch; As shown in figure ofdev
withmaster
Pointing to the same commit, nothing has changed in the file;HEAD
Point to thedev
Branch: indicates that the current branch isdev
, equivalent to executing:git checkout -b dev
The state after;
As you’ve probably noticed, HEAD is always a pointer to the current branch;
2.HEAD
identifier
The HEAD file is a reference identifier to the current branch, also known as a pointer, and its relationship to the branch looks like this:
To viewHEAD
The HEAD file does not contain the SHA1 value (the COMMIT ID for each commit), but a pointer to another reference. Git HEAD:
You can see that HEAD points to the current master branch;
Git checkout -b dev -b git checkout -b dev -b git checkout -b dev -b git checkout
HEAD always points to the current branch;
When git commit is executed, Git creates a commit object (see figure D below). The parent pointer of the commit object will point to the commit to which the HEAD refers (i.e. C), thus forming a commit chain:
Git reflog records any changes we make to the HEAD:
However, if you manually modify the HEAD file, this information will not be recorded, so it is not recommended to manually modify git-related configuration files. Instead, you should try to use the command line to modify.
Modify theHEAD
In fact, you can modify the contents of the HEAD file with git’s underlying command symbolic-ref;
Commands in Git can be divided into two types: high-level commands and low-level commands. Git add, etc., are advanced commands;
Read:
Writing:
Note the format: refs/heads/develop;
View the ORIG_HEAD file:
SHA1 = SHA1; SHA1 = SHA1;
As you can see, the SHA1 value in ORIG_HEAD is the latest SHA1 value submitted.
Check the FETCH_HEAD file:
There are two pieces of information, one is the commit ID of the latest commit and the other is the commit information.
Therefore, the COMMIT ID is a very important piece of information for Git, and this SHA1 value can be used to track back or find the commit you want.
3.git merge
The principle of
Process diagram
-
Commit on the new branch
The figure above shows a commit on the dev branch, at which point:
- branch
master
The submission records are from:A
,B
andC
Composition; - The branch
dev
The submission history ofA
,B
,C
andD
Composition;
- branch
-
Merge the two branches
Git merge dev merges the contents of the dev branch to the master branch. This method is called “fast-forward”. There is no conflict, only the master pointer is changed.
The detailed process
Before performing the merge operation:
- in
master
To view the commit record of the branch:
- in
dev
To view the commit record of the branch:
As you can see, the dev branch has only one more commit (dev1) than the master branch. The status of the two branches is as follows:
Perform the merge operation:
Git merge dev git merge dev
It can be seen that the fast-forward mode is used to merge, and the status of the two branches after merging is as shown in the figure below:
After the merge, HEAD points to both the master and dev branches; And the commit history of the Master and dev branches is exactly the same; If a branch merge is performed using a fast-forward method, only the branch pointer to the master branch will be changed.
4.Fast-forward
- By default, when merging branches
git
Will useFast-forward
Mode; - In this mode, deleting branches discards branch information;
- Added when performing branch merge operations
--no-ff
Parameter is disabledFast-forward
In this way, there will be an additional submission record;
Ff stands for fast-forward.
Specific demonstration is as follows:
useFast-forward
First, look at the last 3 commits on the master branch:
At this point, the states of the two branches are:
Then add a new commit on the dev branch: dev2. View the latest 3 commits on the dev branch:
At this point, the states of the two branches are:
Go back to the master branch and run git merge dev to merge the dev branch. By default, the fast-forward mode is used:
As you can see, after the merge, the master points directly to dev’s latest commit without producing a new commit. The status of the two branches after merging is as follows:
This verifies that the fast-forward mode only changes the point of the branch pointer.
disableFast-forward
The merge can be done through:
git merge --no-ff dev
Copy the code
The fast-forward mode is disabled.
-
Continue to add a commit to the dev branch: dev3. Then look at the last three commits on the dev branch:
-
Do not modify the master branch to view its last 3 commits:
At this point, the states of the two branches are:
-
The dev branch is then merged on the master branch without using fast-forward. The merge command uses:
git merge --no-ff dev Copy the code
After execution, the following VIM editor interface is displayed and we are required to fill in submission notes:
This indicates that a commit is triggered if the branches are not merged in fast-forward mode. After the merge is complete, check the commit record of the master branch:
You can see that merging with fast-forward disabled results in one more commit than the dev branch: Merge branch ‘dev’, even though the merged content is the same. At this point, the states of the two branches are:
This verifies that if the fast-forward mode is disabled, there will be an additional commit record representing the merge.
5. Merge conflicts
Only one of the merged branches was changed, and one of the branches was created based on the other. For example, if the master and dev branches are not bifurcated, there will be no merge conflict. Git automatically completes the merge using the fast-forward method.
However, bifurcation occurs when both branches of the merge change, as shown in the figure below. At this point, it is necessary to resolve the conflict and manually merge the branches:
Specific demonstration is as follows:
Before the merger
First, modify the test. TXT file on the two branches and submit the modification to the respective branches.
- in
master
Make a new commit on the branch:mas3
“And then look at the filetest.txt
Content and branch submission records:
- in
dev
Make a new commit on the branch:dev1
“And then look at the filetest.txt
Content and branch submission records:
The commit records of the two branches are different only for the latest commit:
After the merger
Git merge dev merges the dev branch with git merge dev, causing merge conflicts in the test. TXT file, as shown in the following figure:
The reason for the conflict is that both branches have modified the same file, test.txt. Git merge does not know which branch’s modification is the standard. Therefore, you cannot use the fast-forward mode to automatically merge data. You need to resolve conflicts and manually merge data.
Manual merge procedure
The manual merge operation is performed in the following three steps:
- Step 1: Select the content to be retained and manually resolve merge conflicts.
Test.txt file where merge conflict occurred:
A typical collision rendering occurs (HEAD points to the master branch), where:
<<<HEAD
with>>>dev
Content between: on two branchestest.txt
Differences in documents;<<<HEAD
with= = =
The content between represents: current branchmaster
righttest.txt
File modification;= = =
with>>>dev
Between the contents of:dev
The branch oftest.txt
File modification;
TXT, for example, save all changes made to test. TXT from both branches and delete lines 3, 5, and 7.
Git mergetool (vimdiff), vim (vim), vim (vim), vim (vim), vim (vim)
In real development, merging is rarely done manually, but with the help of tools.
- Step 2: Use
git add test.txt
Will manually resolve conflicts when pairedtest.txt
Submit the changes to the staging area;
After editing, you can see that we are still MERGING. Git add test. TXT add test. TXT to the staging area to merge the test. TXT file.
- Step 3: Pass
Git commit -m
Will manually resolve conflicts when pairedtest.txt
To complete the merge operation;
If you need to fill in a lot of merge comments, you can use git commit to enter the VIm editor to edit them. Once committed, complete the manual merge process.
After manually merging the branches, view the commit history of both branches:
master
Commit history on branch:
dev
Commit history on branch:
It can be found that the two branches change into a form that can be merged in the Fast Forward mode, as shown in the figure:
- Before manually resolving conflicts:
-
After manual conflict resolution:
Synchronize two branches
Git merge Master if you want to synchronize the dev and master branches, use git merge master in the dev branch. In this case, the fast-forward method can be used to merge, and the merge result is as shown in the figure below:
Validation:
After the merge, check the commit history of the dev branch:
We can see that HEAD points to dev and master at the same time, i.e., all three Pointers point to the latest commit, which is consistent with the above analysis.
From the above discussion, it is easy to see that merging branches is essentially merging different commits and moving the HEAD and branch Pointers.