Let us look at an example of a 3-way merge. In this example, the Feature branch is two commits ahead of the Master branch.
Before we merge it with Master, let us say we have added an additional commit to the Master as shown in the below diagram.
Due to the commit performed on the Master branch, both our branches Master and Feature are now diverged.
This means we have some changes in the Master branch that is not present in the Feature branch. If we perform a merge in this case, Git cannot move the master pointer towards the Feature branch.
If git simply moves the Master pointer to the Feature pointer, then the latest commit C6 performed on the Master branch will be lost.
So how do we perform a merge if the branches are diverged?
When we want to merge the branches that are diverged, Git creates a new commit (Merge Commit) and combines the changes of these two branches as shown in the below diagram.
The reason it is called a 3-way merge is because the Merge Commit is based on 3 different commits.
The common ancestor of our branches, in this case commit number C3. This commit contains code before we diverge into different branches.
The tip of the Master branch, that is the last commit performed on the Master branch - C6
The tip of the Feature branch, the last commit performed on the Feature branch - C5
To merge the changes from both the branches, Git looks at the three different snapshots - the before snapshot and the after snapshots. Based on these snapshots, Git combines the changes by creating the new commit called the Merge Commit.
$ git init $ echo one>1.txt $ git add . $ git commit -m 'c1' $ echo two>2.txt $ git add . $ git commit -m 'c2' $ echo three>3.txt $ git add . $ git commit -m 'C3' $ git branch feature $ git switch feature $ echo four>4.txt $ git add . $ git commit -m 'c4' $ echo five>5.txt $ git add . $ git commit -m 'c5' $ git switch master $echo six>6.txt $ git add . $ git commit -m 'c6' $ git merge feature $ git log --oneline --all --graph
hint: Waiting for your editor to close the file... unix2dos: converting file E:/git_clone/test_repo/.git/MERGE_MSG to DOS format... dos2unix: converting file E:/git_clone/test_repo/.git/MERGE_MSG to Unix format... Merge made by the 'recursive' strategy. 4.txt | 1 + 5.txt | 1 + 2 files changed, 2 insertions(+) create mode 100644 4.txt create mode 100644 5.txt * e1ce060 (HEAD -> master) Merge branch 'feature' |\ | * 3435c89 (feature) c5 | * 7e7761b c4 * | 5618675 c6 |/ * 6ad93bf C3 * 9031c20 c2 * 3f68f83 c1