How to Implement and work with the merge command in Git

Source: Internet
Author: User

How to Implement and work with the merge command in Git

Imagine the following situation: there are two branches in the code library, and each branch has been modified. Finally, you want to merge one of them into another branch.

What is the process of merging? Does Git operate on each branch according to its historical data in serialization, or does it only merge the last version of the file in each branch? This is a problem. I want to analyze the merge operations of git.

Recall that the internal structure of the Git version library is organized to a directed acyclic graph (directed acyclic graph): Each commit generates a snapshot of the version tree (snapshot ), in addition, this snapshot saves a reference pointing to its parent node (the last snapshot submitted for this branch) (usually only one parent node is currently submitted, but no parent node exists for the snapshot submitted in the initial test, A merge operation has two or more parent nodes ). In this way, each commit recursively creates references for certain node sets pointing to the parent node. Sometimes, when we consider comparing the differences between the parent node submission tree and the current node submission tree (diff), we think of one commit as one patch) it helps us understand the working mechanism of git. In this way, we can think that the commit tree is integrated with patches for all parent nodes. A tree that performs merge operations on two branches. Therefore, it can be considered that the two branches have applied all their parent node patches, and then perform a Union operation.

But that is not the real execution method of git merge, because, first of all, if you work that way, the execution will be very slow !, In addition, during the execution process, it will re-process all the conflicts caused by the previous merge. So, how does git merge actually operate?

I like to think in A mathematical way: Given two commits A and B, the combined commit operation A commit B can be described as follows: [A between B] = [A] + [B] − [C] Here C is the merging item of A and B (the Part shared by the ancestor of the recently submitted tree ), we must "Subtract" C, because if this is not the case, we will have two A then B. This operation x + y −z is called a three-way merge. You can consider the execution path to apply x-z to x or x-z to y.

In fact, the diff and patch operations do not follow the above operations. Instead, they are implemented using the longest common subsequence algorithm. The difference between x−w and x is the value assigned when we know the longest common subsequence (the public part of the two sequences may be removed in the middle ). In order to construct a three-way merge of x + y −w, we assign values to x and w when finding public subsequences, and assign values to y and w when finding public subsequences, then, each output is either:
• The common part of the three sequences, or
• The part that appears in x but does not exist in y and w, or
• Content that appears in y but does not exist in x and w

At the same time, we need to delete those sequences, either:
• Appears in y and w, but not in x, or
• It appears in x and w, but not in y.

For example, the following is the result of performing the merge operation on x, y, and z:
1. x: w: y: merged:
2. milk
3. juice
4. flour
5. sausage sausagegit
6. eggs
7. butter

The row order of x, y, and w may only indicate a partial order relationship on the output rows of a three-way merge. If so, because of the same block w, between x and y, they are edited in different ways. Therefore, we say that a merge conflict will output this information, which can be solved manually. When git shows you a merge conflict, by default, you will see the conflict block between x and:

However, conflicting blocks become easier to solve when you can see the merging benchmark w. I recommend that you enable or disable this function:

~ /. Gitconfig

By setting merge. conflictstyle to diff3

Git config -- global merge. conflictstyle diff3

Now you can see the solution:
1. I had two eggs and three sausages for breakfast.

(Note that this operation is symmetric (w is exchanged with the result, so you really need to check w). There are two other cases to consider. Possible behavior:
• It appears in x and y, but not in w.
• Appears in w, but not in x and y

Some three-way merge algorithms often mark such rows as conflicting rows. However, Git will elegantly output or directly Delete the row, assuming that the row has not changed. This effect is called accidental cleaning and merging. Sometimes some situations are very useful in practical applications, especially when users screw up the version and merge two different versions of the same patch. However, I think it is not a good way to hide this mistake. I hope this behavior can be disabled. Try to avoid using it because of its advantages.

If you carefully and observe, you may have discovered A vulnerability in the above description: Because commit submits A and B, they may each contain commit, their recent common ancestor may not be the only one! In general, they are most likely to have the most recent common ancestor C1, C2, C3, C4, ⋯ Ck −1, Ck. In this case, the git merge operation will be performed recursively: it first constructs and merges C = C1 1_c2 1_c3 1_ck −1 then Ck, this serves as the base for merging [A] + [B] −[ C] in three directions ). This is why Git's default merge policy is called recursion. Assume that two branches are shown in. A, B, C, D, and E are historical snapshots of the master Branch (snapshot); A, B, X, Y, Z is the historical snapshot of the feature molecule.

Command

Git merge feature

First, find the common ancestor of "master" (current Branch) and "feature. It is more or less equivalent to the following command:

Git merge-base master feature

In our example, their common ancestor is B. If there is no conflict in the C, D, E and X, Y, Z commits, git will create a "merge commit" merge commit with two or more fathers. The new graph will look like the following.

Each git commit generates a tree, one or more "Father's Day", author's name, email, date and Submitter's name, email, and date. The only difference between a merge commit and a normal commit is the number of ancestors.

In the second figure, the merge commit is marked as M. If a conflict exists in the submission, the user will be asked to resolve the conflict and manually create a merge submission. After the conflict is resolved

Git commit-

Merge and submit will be created. This command has no special syntax. Git already knows that the user is merging (the user is already trying to merge ).

GitHub tutorials

Git tag management details

Git branch management

Git remote repository details

Git local Repository (Repository) Details

Git server setup and Client installation

Git Overview

Git authoritative guide PDF

Git details: click here
Git: click here

This article permanently updates the link address:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.