Home  >  Article  >  Development Tools  >  Git learning: understanding the git merge command

Git learning: understanding the git merge command

青灯夜游
青灯夜游forward
2022-03-18 19:48:593489browse

This article will help you learn about Git branches and introduce the Git Merge command for using branches. I hope it will be helpful to you!

Git learning: understanding the git merge command

In Git, merge is a way to put the forked commit history back together. The git merge command is used to integrate the branch you created previously using the git branch command and the content developed independently on this branch into one branch.

Please note that all the commands below will merge other branches into the current working branch. The contents of the current working branch will be updated due to the merge operation, but the target branch will not be affected at all. Again, this means git merge is typically used in conjunction with several other git commands, including using the git checkout command to select the current working branch, and using git branch -dCommand to delete merged abandoned branches.

How it works

git merge will merge multiple commit sequences into a unified commit history. In the most common usage scenario, git merge is used to merge two branches. In the remainder of this document, we will focus on this merge scenario. In this scenario, git merge accepts two commit pointers, usually the top commit of the two branches, and then traces forward to the most recent common commit of the two branches. Once this common commit is found, Git creates a new "merge commit" that merges the respective commit sequences on both branches.

For example, we have a feature branch derived from the main branch, and now we want to merge this feature branch back to the main branch.

Git learning: understanding the git merge command

Executing the merge command will merge the specified branch into the current working branch. We assume that the current working branch is main. Git determines its own algorithm for merging commits based on the two branches (discussed in detail below).

Git learning: understanding the git merge command

Merge commit is different from ordinary commit, because merge commit will have two parent commits. When you create a merge commit, Git will try to automatically merge two separate commit histories into one. However, when Git finds that a certain piece of data contains changes in the commit history of both sides, it will not be able to automatically merge it. This situation is called a version conflict. At this time, Git requires manual intervention to continue the merge.

Preparing for Merger

Before the actual merge operation, some preparation steps need to be carried out to ensure that the merge process can proceed smoothly.

Confirm the branch that receives the merge

Execute the git status command to check the status of the current branch, and make sure that HEAD points to the correct branch that receives the merge branch. If not, execute the git checkout command to switch to the correct branch. In our example, execute git checkout main.

Get the latest remote commit

Ensure that both branches involved in the merge operation are updated to the latest status of the remote warehouse. Execute git fetch to pull the latest commit from the remote warehouse. Once the fetch operation is completed, in order to ensure that the main branch is synchronized with the remote branch, the git pull command needs to be executed.

Merge

When the preparations mentioned above are complete, the merger can officially begin. Execute the git merge <branch></branch> command, where is the name of the target branch that needs to be merged into the current branch.

Fast-forward merge

When the submission history between the current working branch and the merge target branch is a linear path, fast-forward merge can be performed. In this case, there is no need to actually merge the two branches. Git only needs to move the top pointer of the current branch to the top of the target branch (that is, fast forward). In this case, the fast-forward merge successfully merges the commit history into one place. After all, the commits in the target branch are now included in the commit history of the current branch. For the process of fast-forward merging the function branch into the main branch, please refer to the figure below:

Git learning: understanding the git merge command

However, the fast-forward merge occurs when the two branches are divided. In the case of cross, execution is not allowed. When the commit history of the target branch relative to the current branch is not linear, Git can only decide how to merge the two branches through the three-way merge algorithm. The three-way merge algorithm requires the use of a dedicated commit to integrate the commit histories of both sides. This term comes from the fact that in order for Git to generate a merge commit, it needs to use three commits: the top commit of the two branches, and their common ancestor commit.

Git learning: understanding the git merge command

Although you can actually choose to use these different merge strategies, most developers prefer fast-forward merging (by utilizing the rebasing command), especially for small feature development or bug fixes; On the other hand, for merging long-term development function branches, the three-way merge method is more preferred. In the second scenario, the merge commit generated by merge will be retained in the commit history as a mark of the merge of the two branches.

Next we use the first example below to show how to perform fast-forward merging. The following command will first create a new branch, make two commits on the new branch, and then use fast-forward merge to merge the new branch back to the main branch.

# Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Merge in the new-feature branch
git checkout main
git merge new-feature
git branch -d new-feature

The workflow in this example is usually used for short-term functional development. This development process is more regarded as a relatively independent development process, and correspondingly it is a long-term development process that requires coordination and management. Feature development branch.

Also note that in this example Git will not issue a warning for the git branch -d command because the content of new-feature has been merged into the main branch.

In some cases, although the commit history of the target branch is linear relative to the current branch and can be fast-forward merged, you still want to have a merge commit to mark that the merge has occurred at this commit, then You can use the --no-ff option when executing the git merge command.

git merge --no-ff <branch>

The above command will merge the specified branch into the current branch, but will always generate a merge commit (even if this merge operation can be fast-forwarded). This command is useful when you need to mark merge events in the repository's commit history.

Three-way merge

The following example is similar to the above, but because the main branch itself also changes as the feature branch moves forward, Therefore, a three-way merge is required when merging. This scenario is quite common when carrying out large-scale feature development or when multiple developers are developing at the same time.

Start a new feature
git checkout -b new-feature main
# Edit some files
git add <file>
git commit -m "Start a feature"
# Edit some files
git add <file>
git commit -m "Finish a feature"
# Develop the main branch
git checkout main
# Edit some files
git add <file>
git commit -m "Make some super-stable changes to main"
# Merge in the new-feature branch
git merge new-feature
git branch -d new-feature

It should be noted that in this case, because there is no way to directly move the top pointer of main to the new-feature branch, Git cannot perform fast forwarding merge.

In most actual work scenarios, new-feature should be a very big function, and the development process lasts for a long time, which inevitably leads to the There are also new commits on the main branch. If your feature branch size is as small as the example above, you can use rebase to rebase the new-feature branch to the main branch, and then perform a fast-forward merge. This will also avoid creating too much redundancy in the project's commit history.

Resolving conflicts

If the two branches to be merged have modified the same part of the same file, Git cannot determine which version of the content should be used. When this happens, the merge process is stopped before the merge commit is committed to give the user a chance to fix these conflicts manually.

The great thing about Git's merge process is that it uses the well-known edit/stage/commit workflow to resolve conflicts. When a merge conflict is encountered, executing the git status command will list which files contain conflicts and need to be resolved manually. For example, when both branches modify the same part of the hello.py file, you will see information similar to the following:

On branch main
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: hello.py

How conflicts are displayed

When Git encounters a conflict during the merge process, it will edit the relevant content in the affected file and add visual markers to show the different content of this part of the conflict. These visual markers are: >>>>>>. To find the specific location where a conflict occurred, it's easy to search for these visual markers in the file.

here is some content not affected by the conflict
<<<<<<< main
this is conflicted text from main
=======
this is conflicted text from feature branch
>>>>>>> feature branch;

Generally speaking, the content before the ====== mark comes from the branch receiving the merge, and the content after it comes from the branch to be merged.

Once the conflicting parts are found, the conflicts can be corrected as needed. When you have completed the conflict repair and are ready to continue merging, you only need to execute the git add command to add the files with resolved conflicts to the staging area and tell Git that these conflicts have been resolved. After this, execute git commit just like submitting the code normally to complete the merge commit. This process is exactly the same as submitting code under normal circumstances, which means that handling conflicts is a piece of cake for ordinary developers.

Also note that merge conflicts can only occur during a three-way merge, and no conflicts will occur during a fast-forward merge.

Summary

This article is an overview of the git merge command. In the process of using Git, merging is a very important operation. This article discusses the mechanics behind merge operations and the differences between fast-forward merges and three-way merges. The key points that readers need to remember are as follows:

  • The Git merge process is to merge different commit sequences into a unified commit history

  • Git There are two main methods in the merge process: fast-forward merge and three-way merge

  • Unless there is a conflict in the two commit sequences, Git can usually merge the commits automatically

Recommended study: "Git Tutorial"

The above is the detailed content of Git learning: understanding the git merge command. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete