A merge unifies two or more commit history branches. Most often, it merges two branches, but Git supports merging more than two branches at once. When doing a merge. the currently checked out branch will always be the target branch that receives the merge commit.

If there are no conflicts between branches, Git computes a merge result and creates a new commit that reflects the unified state. If there were changes to the same line on the same file in both branches, the Git marks the contentious changes as "unmerged" in the index and leaves reconciliation to you.

A good rule to follow that makes your life easier is to always do a merge with a clean working directory and index (do not have any modified files or staged changes).

A useful alternative to graphical tools such as gitk for dumb terminals is the git log --graph command.

Although a Git merge is a symmetrical operation, it makes sense to say "I merged this branch into this one" because only one branch gets the merge commit.

A merge with a conflict


When you need to resolve a merge conflict, once you are happy with the resolution, you git add the file to the index and then commit the merge using git commit. Git will open an editor with a template message to alter the commit message, and when you exit the editor, Git indicates the successful creation of a new merge commit.

Merge strategies


The git merge-base command can be used to find the merge base between branches.

The two common degenerate scenarios that lead to merges are called already up-to-date and fast-forward. Neither of these scenarios introduce a new merge commit.

Already up-to-date mean that all the commits from the other branch are already present in the target branch.

Fast-forward happens when your branch is already fully present and represented in the other branch. Git simply tacks on the new commits to HEAD and then moves HEAD to point to the final, new commit. This case is common on tracking branches.

Resolve, recursive, and octopus are merge strategies that all produce a final commit added to your branch that represents the combined state of the merge.

Resolve joins two branches and locates the common ancestor as the merge base and applies changes from the merge base to the tip of the other branch HEAD onto the current branch.

Recursive also only joins two branches but handles the scenario when there is more than one merge base. It forms a temporary merge of all the common merge bases and uses that as the base from which to derive the resulting merge using the same algorithm as resolve.

Octopus is for merging more than two branches and internally uses the recursive strategy once for each branch being merged. It cannot handle any merge that requires any form of conflict resolution.

The two special merge strategies are ours and subtree.

Ours merges in any number of branches, but discards changes from all branches but the current branch. The result of the merge is identical to the current HEAD.

Subtree merges a branch in but everything in it is merged into a particular subtree of the current tree, which is determined automatically by Git.

How Git Thinks About Merges


In most VCSs, a commit can only have one parent. In Git, the merge yields a new tree object with the merged files, and it also introduces a new commit object, but on only the target branch. The merged tree object symmetrically represents both source branches equally. The branch onto which the merge happened gets a commit that has a parent commit from each branch in the merge.

Squash merges


With Git, since both branches being merged are considered equal, it does not make sense to squash the commits from one branch. It can with the --squash option to git merge or git pull, if you want it to.

Why Not Just Merge Each Change One by One?


Why is it not preferable to have a simple, linear history? An important observation about Git commit histories is that each revision is real. If you apply a sequence of commits on top, this creates a series of entirely new versions, and these new intermediate versions never actually existed. Having states that never really existed loses the reason for having a detailed history in the first place. If you do want Git to work like this, it can do that; the process is called rebasing.

Article notes

What Git operation unifies two or more branches?
Does Git support merging more than two branches at the same time?
When a Git merge happens, what branch gets the merge commit?
What should you always make sure before you do a merge with Git?
What option can you pass to git log to see a nice visual that is an alternative to graphical tools such as gitk?
What Git command can find the merge base between branches?
What are the two degenerate merge scenarios that do not introduce a new merge commit?
What is the degenerate Git merge scenario where all the commits from the other branch are already present in the target branch?
What is the degenerate Git merge scenario where your branch is already fully present in the other branch and so the new commits are tacked on to the current branch?
What are the three normal merge strategies that produce a merge commit added to the currently checked out branch?
What is the normal merge strategy that locates the merge base and applies changes from the merge base to the top of the other branch HEAD onto the current branch?
What is the normal merge strategy that merges two branches but can work when there is more than one possible merge base?
What is the normal merge strategy that temporarily merges the possible merge bases to use as the merge base to derive the resulting merge?
What is the normal merge strategy that internally uses the recursive strategy but can merge more than two branches at once?
When can the octopus Git merge strategy not work?
What are the two special merge strategies discussed in the Version Control with Git book?
Does a merge commit represent any branch more than any other branch when they are merged together?
What is a reason why it is probably preferable to do a merge rather than create a linear history (rebase) according to the Version Control with Git book?
Previous Next