Home > Article > Development Tools > Detailed analysis of git-merge (organized and shared)
This article brings you relevant knowledge about Git, which mainly introduces the related issues of git-merge. The git-merge command is used to merge from specified commit(s) to The operation of the current branch, I hope it will be helpful to everyone.
Recommended study: "Git Tutorial"
In the git-merge command , there are the following three parameters:
git merge [-n] [--stat] [--no-commit] [--squash] [--[no- ]edit] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...]
The git-merge command has the following two uses:is used in git-pull to integrate changes in another code repository (ie: git pull = git fetch git merge)
command will be executed on the master branch The separated nodes (that is, the A B C nodes of the topic branch) after the common node (E node) reappear on the master branch until the current commit node of the topic branch (C node), and is located at the top of the master branch. And create a new node along the master branch and topic branch to record the merge results. This node carries the user's information describing the merge changes. 1.3
This command exists for historical reasons and should not be used in new versions It should be replaced with 1.4
This command is only used when conflicts result after merging. will abandon the merge process and try to rebuild the pre-merge state. However, if there are uncommitted files when the merge starts, git merge --abort
will not be able to reproduce the pre-merge state in some cases. (Especially when these uncommitted files will be modified during the merge process)
git-mergeYou get stuck in a situation that will make it difficult for you to back down in a conflict. Therefore, it is highly discouraged to have uncommitted files when using
2. Parametersgit-merge
. It is recommended to use thegit-stash
command to temporarily store these uncommitted files and use them after resolving conflictsgit stash pop
Restore these uncommitted files.
command2.1
--no-commit
parameters cause a commit node of the merged result to be generated after merging. This parameter can override --no-commit
. The --no-commit
parameter causes the merge to not be automatically submitted in order to prevent the merge from failing, giving the user a chance to review and modify the merge result before submission. 2.2
-e
and --no-edit
and -e
are used to call the editor to further edit the automatically generated merge information before successful merge and submission. Therefore, users can further interpret and judge the results of the merger. The --no-edit
parameter can be used to accept automatically merged information (this is generally discouraged).
-mOlder versions of nodes may not allow users to edit merge log information.parameter when merging (described below), use
--edit
(or-e
) is still useful, this will further edit the content contained in-m
in the editor.
2.3--ff
refers to the fast-forward command. When merging using fast-forward mode, a new commit node will not be created. By default, git-merge
adopts fast-forward mode. For a detailed explanation of the fast-forward mode, please see my other article: "About fast forward" section of a successful Git branch model.
2.4
Create a new merge node even if fast-forward mode can be used. This is the default behavior when merges a tag. 2.5
Unless the current HEAD node has been up-to-date (update points to the latest node) or fast-forward mode can be used Merge, otherwise the merge will be rejected and a failure status will be returned. --log[=<n>]
and --no-log
##--log[= When merging and submitting, in addition to the branch name, it will also contain the log information of up to n merged commit nodes.
--no-log will not list this information.
,
-n,
--no-statCommand
--stat The parameter will display the status of file differences at the end of the merge result. The status of file differences can also be configured in merge.stat in the git configuration file.
In contrast, the
-n,
--no-stat parameters will not display this information.
and
--no-squash
--squash When a merge occurs, from The other branch node after the common ancestor node of the current branch and the other branch until the top node of the other branch will be compressed together. The user can submit it after review to generate a new node.
Note 1: This parameter conflicts with##Note 2: The result after using this parameter is similar to Commit a new node on the current branch. This parameter is very useful in some cases, such as when using Git Flow (about Git Flow, please refer to: A successful Git branch model). When the function branch is developing a functional requirement, the developer may submit a large number of locally. And meaningless nodes, when they need to be merged into the develop branch, you may only need to use a new node to represent the modification content of this long list of nodes. At this time, the--no-ff
--squash-scommand will come into play. In addition, if multiple submissions of the feature branch are not trivial but are meaningful, using the
2.8--no-ff
command is more appropriate.--no-squash
has the exact opposite effect.
--strategy=<strategy>
##-s < strategy>--strategy=<strategy> are used to specify the merge strategy. By default, if this parameter is not specified, git will use the default merge strategy according to the following conditions:
When the merge node only contains a single parent node (such as when using fast-forward mode), the recursive strategy will be used ( introduced below).
2.10
--verify-signatures
is used to verify whether the merged node has a GPG signature , and ignore those nodes without GPG signature verification in the merge.
(The following quote is taken from a reprinted article. Since I have not found the original author, I cannot provide the original author information and the original link. If there is any infringement, please let me know via private message or comment, and I will delete the following quote.)
GPG is encryption software. You can use the public key generated by GPG to safely spread your files and codes on the Internet.
Why is there such a need? From development to release to later update iterations of a project, there will definitely be a number of stable versions and development versions (there are instability factors). As project initiators and holders, they have the right to define a stable version that they (they) recognize. This stable version will not allow other developers to make changes. Take Google's repo project as an example. The project owner defines point A in the project development process as the stable version v1.12.3. Then after users download the v1.12.3 version, they will definitely use the projects and products generated by point A. Even if other developers can re-specify v1.12.3 locally and specify it to their modified point B, when the modified version is finally used by users, there will be a problem that GPG signature verification fails, that is to say, this is The modification will not take effect.,—summary
2.11
and
--stat --no-stat is similar and will be removed in a future version.
2.12
-q
operate silently and do not display merge progress information.
-v
and
display detailed merge result information.
--progress
and --no-progress
switch whether to display the merged progress information. If neither is specified, a message will be displayed on the connected terminal when standard error occurs. Note that not all merge strategies support progress reporting.
-S[<keyid>]
and --gpg-sign[=<keyid>]
GPG signature.
-m <msg>
Set the commit information used when creating merge nodes.
If the --log
parameter is specified, the short log of the commit node will be appended to the commit message.
--[no-]rerere-autoupdate
rerere means reuse recorded resolution, reuse the recorded solution. It allows you to ask Git to remember how to resolve a block conflict so that the next time you see the same conflict, Git can automatically resolve it for you.
--abort
Abandon the current merge conflict handling process and try to reconstruct the pre-merge state.
When merging external branches, you should keep your own branches clean, otherwise there will be merge conflicts. It will cause a lot of trouble.
In order to avoid recording irrelevant files when merging commits, the git-pull and git-merge commands will stop if there are any uncommitted files registered in the HEAD node pointed to by index.
Normally branch merge will produce a merge node, but there are exceptions in some special cases. For example, when calling the git pull command to update the remote code, if the local branch does not have any commits, there is no need to generate a merge node. In this case, a merge node will not be generated, and HEAD points directly to the updated top code. This merge strategy is fast-forward merge.
In addition to the fast-forward merge mode mentioned above, the merged branch will be tied to the current branch through a merge node. The merge node will also Have the top node of the current branch before merging and the top node of the other branch, both as parent nodes.
A merged version will make the changes in all related branches consistent, including the commit node, HEAD node and index pointer, and the node tree will be updated. As long as the files in these nodes do not overlap, changes to these files will be modified and updated in the node tree.
If these changes cannot be merged explicitly, the following will happen:
MERGE_HEAD
Pointer Are placed on top of other branchesMERGE_HEAD
. The files in the node tree contain the results of the merge program. For example, the three-way merge algorithm can cause conflicts. git merge --abort
About three-way merge Algorithm:
The three-way merge algorithm is a way to resolve conflicts. When a conflict occurs, the three-way merge algorithm will obtain three nodes: the B node of the local conflict, the C node of the other branch, and the B and C nodes. The common most recent ancestor node A. The three-way merge algorithm will merge based on these three nodes. The specific process is to compare nodes B and C with node A. If a file in node B and C is the same as that in node A, then there will be no conflict; if only one of B or C has changed compared to node A, then The file will adopt the changed version; if B and C have changed compared with A, and the changes are not the same, then you need to merge them manually; if B and C have changed, and the changes are the same, then There will be no conflict and the changed version will be automatically adopted. After the final merger, D node will be generated. D node has two parent nodes, namely B and C.
When merging a tag, Git always creates a merged commit, even if fast-forward mode can be used at this time. The template of the submission information is preset to the information of the tag. Additionally, if the tag is signed, signature detection information will be appended to the commit message template.
When a merge conflict occurs, this part will end with <<<<<<<
, ========
and represent. The part before
=======
is the situation on the current branch, and the part after ========
is the situation on the other side's branch.
After seeing the conflict, you can choose the following two methods:
git merge --abort
is used in this situation. git add
to add it to the index, and then use git commit
to generate a merge node. git mergetool
will call a visual merge tool to handle conflicting merges. git diff
will display the three-way difference (the three-way comparison algorithm used in the three-way merge). git log --merge -p <path>
will display the difference between the HEAD
version and the MERGE_HEAD
version. git show :1:File name
Displays the version of the common ancestor, git show :2:File name
Displays the HEAD version of the current branch, git show :3:File name
Display the MERGE_HEAD
version of the other party's branch. Git can specify the merge strategy by adding the -s parameter. Some merge strategies even have their own parameter options. Use -X<option>
to set the parameter options of these merge strategies. (Don't forget that merging can happen in both git merge and git pull commands, so this merge strategy applies to git pull as well).
Only use the three-way merge algorithm to merge the top nodes of two branches (such as the current branch and another branch you pulled down). This merge strategy follows a three-way merge algorithm, where the HEAD nodes of the two branches and the common child nodes perform a three-way merge.
Of course, what really bothers us is the situation of cross-merge (criss-cross merge). The so-called cross-merging refers to the situation where there are multiple common ancestor nodes. For example, when two branches are merged, it is very likely that there are two common ancestor nodes. At this time, the merger cannot be performed according to the three-way merge algorithm (because Common ancestor nodes are not unique). This is how the resolve strategy handles cross-merge problems. Here is a reference to "Version Control with Git":
In criss-cross merge situations, where there is more than one possible merge basis, the resolve strategy works like this: pick one of the possible merge bases, and hope for the best. This is actually not as bad as it sounds. It often turns out that the users have been working on different parts of the code. In that case, Git detects that it's remerging some changes that are already in place and skips the duplicate changes, avoiding the conflict. Or, if these are slight changes that do cause conflict, at least the conflict should be easy for the developer to handle
Here is a brief translation: In the case of cross-merging, there is more than one merge reference point (common ancestor node). The resolve strategy works like this: select one of the possible merge reference points and expect this to be the most merged reference point. good result. This is actually not as bad as it sounds. Usually users modify different parts of the code, in which case many merge conflicts are actually redundant and repetitive. When using resolve to merge, the conflicts generated are easier to handle, and there are very few cases where code will actually be lost.
Only use the three-way merge algorithm to merge two branches. Different from resolve, in the case of cross merge, this merge method is called recursively. Starting from the different nodes of the two branches after the common ancestor node, the three-way merge algorithm is recursively called to merge. If a conflict occurs, then the file The merge will no longer continue and conflicts will be thrown directly; other files without conflicts will be executed until the top node. Additionally, this approach is able to detect and handle operations involving modification of file names. This is the default merge action for git merging and pulling code.
The recursive merge strategy has the following parameters:
This parameter will force the version of the current branch to be automatically used when a conflict occurs. This merge method will not cause any trouble, and even git will not check the conflict content contained in other branch versions. This method will discard any conflict content in the other branch.
is exactly the opposite of ours.
Both theirs and ours parameters are suitable for merging binary file conflicts.
With this parameter, git merge-recursive
Spend some extra time to avoid missing unimportant lines (such as functions) brackets). If the version branch separation between the current branch and the other branch is very large, it is recommended to use this merge method.
diff-algorithm=[patience|minimal|histogram|myers]
Informationgit merge-recursive
Use a different comparison algorithm .
ignore-space-change
, ignore-all-space
, ignore-space-at-eol
Treat space conflicts according to the specified parameters.
no-renames
Turn off rename detection.
subtree[=<path>]
This option is an advanced form of subtree merge strategy, which will guess the process of merging two node trees. How to move in. The difference is that the specified path will be removed at the beginning of the merge, so that other paths can be matched when looking for subtrees. (See below for details on the subtree merge strategy)
This merge method is used for more than two branches, but it will refuse to merge when conflicts require manual merge. This merge method is more suitable for bundling multiple branches together and is also the default merge strategy for multi-branch merges.
This method can merge any number of branches, but the merged result of the node tree is always the conflicting part of the current branch. This method can be very efficient when replacing older versions. Please note that this method is different from the ours parameter under the recursive strategy.
Subtree is a modified version of the recursive strategy. When merging tree A and tree B, if B is a subtree of A, B first adjusts to match the tree structure of A instead of reading the same node.
When using the three-way merge strategy (referring to the default recursive strategy), if a file (or a line of code) changes in both the current branch and the other branch, but slightly Then it rolls back on one of the branches, then this rollback change will be reflected in the result. This point may confuse some people. This is because during the merge process, git only focuses on the common ancestor node and the HEAD node of the two branches, rather than all nodes of the two branches. Therefore, the merge algorithm will regard the rolled-back part as unchanged, so that the merged result will become the changed part of the other branch.
I have always believed that Git is a very excellent version control tool, but many people in the company find Git difficult to use. A large part of the reason for this situation is that the inertia brought by the previous use of subversion has an impact on accepting new technologies; on the other hand, many people only use Git through the GUI client. For a long time, most people have thought that using GUI is a more convenient way to get started. In fact, this is questionable. According to my personal experience, using GUI can create inertia, and operations can often be completed by clicking a few buttons, making many people think that learning Git commands is a waste of time and energy. But in fact, without a clear understanding of Git commands and ideas, using those simple buttons will actually cause a lot of trouble: many people have no idea what will happen after clicking the button, and the GUI is too smart to let the same button The click event may correspond to commands with different parameters. In the end, it is the poor users who are really hurt because they have no idea what the problem is.
Based on the content of the full text, here is a summary of some of the conventions that individuals abide by when using Git. The so-called agreement refers to a non-forced and voluntary behavior. Failure to adhere to these conventions will not cause any defects, but complying with these conventions may alleviate difficulties and improve efficiency when using Git.
Recommended study: "Git Learning Tutorial"
The above is the detailed content of Detailed analysis of git-merge (organized and shared). For more information, please follow other related articles on the PHP Chinese website!