Table of contents
🔈 Three-way Merge
Three-way merge is a common merging strategy used in Git to combine changes from two different branches or commits into a single unified result. It is designed to handle situations where multiple branches have made conflicting changes to the same file or lines of code.
When performing a three-way merge, Git identifies three versions of the code:
The common ancestor: This is the version of the file that both branches originally diverged from. It serves as the reference point for comparing the changes made in each branch.
The "ours" version: This represents the changes made in the branch where the merge is being performed. It includes any modifications or additions made to the file.
The "theirs" version: This refers to the changes made in the branch being merged into the current branch. It includes any modifications or additions made to the file in that branch.
Git uses these three versions of the code to intelligently merge the changes. It compares the differences between the common ancestor and the "ours" version and also between the common ancestor and the "theirs" version. Then, it combines these changes, considering both sets of modifications, to create a merged version of the file.
During the merge process, if there are conflicting changes (i.e., changes that overlap and cannot be automatically merged), Git will mark those conflicts and pause the merge. It prompts the user to manually resolve the conflicts by editing the affected file(s) to choose which changes to keep. Once the conflicts are resolved, the user can complete the merge by committing the changes.
The three-way merge strategy in Git helps to ensure that conflicting changes are handled properly and allows for an automated merging process in many cases. However, it may require manual intervention when conflicts occur, enabling developers to make informed decisions on how to merge conflicting changes.
So, basically after creating the Child Branch if the Parent Branch also contains some new commits then GIT will perform Three-way Merge.
🏷️ Practical
Create a new directory named “threewayMerge”. And move inside that directory using the command cd
.
Now, initialize that directory using the command git init
Create two empty files “a.txt” & “b.txt” using the command touch
.
We’ll use the command touch <file1> <file2>
In our case, it’ll be touch a.txt b.txt
Add the file “a.txt” to the Staging Area and then Commit that file to the Local Repository.
We’ll use the command git add a.txt; git commit -m "Commit 1"
And after that add the file “b.txt” to the Staging Area and then Commit that file to the Local Repository.
We’ll use the command git add b.txt; git commit -m "Commit 2"
Now, there are two commits available at the Master Branch. To confirm that we’ll check the log using the command git log --oneline
And also confirm the total no. of files available in the Working Directory of the Master branch using the command ls
So, there will be 2 files available.
Now, let's consider we have to work on a feature of the application, so we’ll create a child branch named “feature”.
Now, we’ll create a child branch and switch to that branch using the command git checkout -b <branch name>
In our case, it’ll be git checkout -b feature
We’ll now confirm the total no. of branches and whether we switched to the new Child Branch “feature” or not. To confirm both, we’ll use the command git branch
We’ll see there are total two branches
master
feature <Child Branch>
And we’ll also see the position of the star “*” on the “feature” i.e. Child Branch; This indicates that we have been switched to the Child Branch.
Now, Create two empty files in that directory named “x.txt” & “y.txt”. To create the empty files, we’ll use the command touch
Syntax: touch x.txt y.txt
Now, check the status of the files. To check the status of the files, we’ll use the command git status
Add a file “x.txt” to the Staging Area and then Commit that file to the Local Repository.
Command:
git add x.txt; git commit -m "Child Commit 1"
And after that add the file “y.txt” to the Staging Area and then Commit that file to the Local Repository.
Command:
git add y.txt; git commit -m "Child Commit 2"
Now, we’ll check the total no. of files on the Feature Branch using the command ls
There will be a total of four files in the working directory. Two files “a.txt” & “b.txt” from the Master Branch that got inherited from the Parent Branch while creating the Child Branch.
And the other two files “c.txt” & “y.txt” have been created in the Child branch.
Now, if we’ll check the logs using the command git log --oneline
Then there will be a total of four commits.
Both HEAD will point to the last commit in the Child Branch (feature).
Two commits from the Master Branch & the other two commits from this branch i.e. the child branch.
So, now we’ll switch back to the Master Branch, as we are on the Child Branch “feature”. So, to switch the branch, we’ll use the command git checkout <Branch Name>
In our case, it’ll be git checkout master
Now, we’ll create an empty file “c.txt” again on the Master Branch using the command touch
We’ll use the command touch c.txt
Add the file “c.txt” to the Staging Area and then Commit that file to the Local Repository.
We’ll use the command git add c.txt; git commit -m "Commit 3"
Now, we’ll check the total no. of commits in the Master Branch. So, There will be three commits available at the Master Branch. To confirm that we’ll check the log using the command git log --oneline
Both HEAD & master are pointing to the last commit in the Master Branch.
Now, we’ll check the total no. of files on the Master Branch using the command ls
There will be a total of three files.
Now, here we can see, both the Child & Parent Branch are Updated.
So, GIT will perform Three-Way Merge.
If we try to merge the Child Branch (feature) to the Master Branch, then a new commit will be created. That commit is considered as the merge Commit.
And, both the pointer i.e. HEAD & master will move to that new commit i.e. merge commit.
And then both the branch master & Child Branch will merge to the merge commit.
🏷️ Proof:
Now we’ll merge the feature Branch to the Master Branch. So, as Master Branch requires these changes, therefore we have to execute the command i.e. we’ll merge the Child branch to the Master Branch by staying/switching to the Master Branch.
To merge the Child Branch with the Master Branch we’ll use the command git merge <Branch Name>
In our case, it’ll be git merge feature
An editor will open showing a default message
“Merge branch ‘feature’ ”.
If we want, we can change the message according to us. Here we’ll keep it the same.
We’ll now exit from the editor (nano) by pressing ^x
Once we exit from there, we’ll see that the feature branch has been merged.
Now, after the merging operation if we’ll check the log on the Master Branch using the command git log --oneline
We’ll see now we are having a total of 6 commits.
The commit message “Merge branch ‘feature’” is the same as we saw/saved while we were merging the Child Branch (feature) to the Master Branch (parent).
HEAD & master are pointing to the Last commit i.e. Merge Commit.
Now, we’ll check the total no. of files on the Master Branch using the command ls
There will be a total of five files.
3 from Master Branch.
2 from the Child branch.
Here, the files on both branches were different, that’s why we didn’t get any Conflict. But if the Master Branch & Child Branch modify the same file, then there will be a chance of getting Conflict.
If we want to display the log graphically, then we’ll use the commandgit log --oneline --graph
Next Article: Merge Conflicts And Its Resolution