What is git merge Command?
As the name suggests, the merge command is used to join the histories of two or more developments.
The
git merge
command in Git is used to integrate changes from one branch into another.
For example, if your main branch is the master branch and you started working on another branch called the feature branch.
You added a new feature e.g. footer for the website in that feature branch.
After completing the work, you want to combine the development into the master branch. This is where the git merge command plays its role in letting you join feature branch work into the master branch.
Executing the merge command in Git
In terms of executing the command, this is how it works at its basic:
Create a new branch based on master:
$ git branch feature
$ git checkout feature
Adding the footer file:
Now, commit the changes:
After the work is done for adding the footer component, you may merge it into the master branch as follows:
$ git checkout master
$ git merge feature
The above command should merge the feature branch commits into the master branch, so both branches are now at the same level.
Still need for explanation? No problems.
The next section explains with some screenshots and more details on how to merge a command, resolve the conflicts, and revert back the merge.
The example of merge git command – step-by-step
To demonstrate how the merge command works, I have created an online repository on the Github website. I have also set up a local repository in a directory with the name m-repo-2.
The local repository is synchronized with the online repo and the master branch on both repositories contains the same files/commits as shown below:
On the remote repository:
For checking the files on the local repo, I ran the $ ls command and see what is displayed:
From this point, you have the task of adding the footer to your project. The file name for the footer is “footer.php”.
For that, we are creating a new branch footer-feature which is based on the master branch by running this command:
The result:
Switched to a new branch 'footer-feature'
Basically, this command is the shorthand for these two commands:
$ git branch footer-feature
$ git checkout footer-feature
Assuming that the work on footer.php is completed, let us add this file to the footer-feature branch.
This is followed by running the commit command:
The output of the commit and after running the $ ls command again gives the following output:
The changes are added in the new branch and this is time to merge this with the master branch – first locally and then pushing in the remote repository.
Merging with the master branch
For merging the new changes with the master branch so it is updated, checkout to master branch again:
Just for the sake of confirming things, I ran the $ ls command for the master branch:
You can see, there is no footer.php file.
Executing the merge command
The result:
Updating 4db7969..2ae5118 Fast-forward footer.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 footer.php
Again executing ls command:
$ ls
6.0_5-Git-revert-commit.png footer.php README.md test.php
You see, our new footer component has been added to the master branch.
Merging remotely
Run the push command as follows for updating the remote repository:
Or, if a simple push command does not work, you may run:
$ git push origin master --force
You can see, the new feature file is also visible in the remote repo:
Use case – What if the master and feature branch conflict while merging?
In this section, we will look into resolving the conflicts that occurred due to the multi-developers environment.
Suppose, two developers are working on the same project pointing to the same remote repository.
A developer is working on the footer component as in the above case while the other developer is given a task to add a sidebar. We will use the following names for active branches and files:
Developer 1:
- Active branch = master
- Feature branch = footer-feature
- File name = footer.php
Developer 2:
- Active branch = Master
- Feature branch = sidebar-component
- File Name = sidebar.php
Both developers have updated their local repositories with the remote Github repo by this command:
Developer 1 completes the task by creating a new footer-feature branch and merged it with the master branch (please see the above section for commands for creating to merge the branches).
Finally, he pushes the changes to the remote repository so it is available to the other team members.
Meanwhile, developer 2 is working on the sidebar.php file under the sidebar-component branch in his local system.
He also completes the work and merges the sidebar-component branch with the master branch in the local repository as follows:
This should create a new branch and be checked out as well.
After creating the sidebar.php in the working directory, now add it to the branch:
Performing a commit:
The output:
[sidebar-component 5bf743a] sidebar added - Commit 1 1 file changed, 5 insertions(+) create mode 100644 sidebar.php
Check out to master branch and perform a merge so that the remote repository can also be updated with the sidebar component based on the master branch.
Merging two branches:
The result:
Updating a772666..5bf743a Fast-forward sidebar.php | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 sidebar.php
As this developer tries to push the work by this command:
The git returns an error message as shown below:
To https://github.com/git-test-jaz/merge-demo2.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'https://github.com/git-test-jaz/merge-demo2. git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
This error can easily be resolved by running the pull command and updating your local repository with the remote as Developer 1 has added the footer.php file whereas your local repository does not.
As you run this command, Git simply asks you to enter a message about why this merge is necessary.
Enter a message in the editor and press: Esc : wq from the keyboard.
The developer 2 local repository should be updated and the local directory should show the footer.php file as well.
Now, if you run the push command again:
It should upload the sidebar.php file in the remote repository as shown below:
Until now, the work has been smooth. Only a simple merging issue was raised and we easily resolved this.
Scenario # 2 – working on the same file
The conflicts arise particularly if developers working on the same file and you try to fetch and merge an updated version into your local repository.
Consider both developers have the same file: footer.php on their local repository.
The file contains the following simple code for the demo only:
<? echo "footer line 1"; echo "Added feature 2 by Developer 1"; ?>
The first developer starts changing the file and adds his code. For example:
<? echo "footer line 1"; echo "Added feature 2 by Developer 1"; /*More changes by developer xxxx //Some code goes here /*Changes ending here*/ ?>
He commits the changes and pushes them to the origin master:
$ git commit -a -m “Developer 1 changes – Commit 2”
$ git push origin master
The operation is successful and the remote repository is updated without any issues.
Meanwhile, developer 2 also started working on that file and after completing the changes has the following code:
<? echo "footer line 1"; echo "Added feature 2 by Developer 1"; //CHanges added by developer yyyy //Code goes here //developer 2 changes ending here ?>
He also commits it to the local branch (master) and then runs the push command to make it online in the remote repository. However, the following error is raised:
The option is to first download the remote branch again by pull command:
And this is the output:
remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0 Unpacking objects: 100% (3/3), done. From https://github.com/git-test-jaz/merge-demo2 * branch master -> FETCH_HEAD 12dfa7f..78bef0f master -> origin/master Auto-merging footer.php CONFLICT (content): Merge conflict in footer.php Automatic merge failed; fix conflicts and then commit the result.
That is, it resulted in a conflict of code in the footer.php file.
If you open the file from the local directory to your editor, you will see code like this:
<? echo "footer line 1"; echo "Added feature 2 by Developer 1"; <<<<<<< HEAD //CHanges added by developer yyyy //Code goes here //developer 2 changes ending here ======= /*More changes by developer xxxx //Some code goes here /*Changes ending here*/ >>>>>>> 78bef0f7e79675a72c86e734a90c4d7a4193192b ?>
So, it contains the code of both developers and Git adds markers to distinguish it wherever conflict occurs.
How to resolve this conflict and merge?
One of the ways to resolve this conflict is to open the filer in the editor or within Git.
Find out the markers that Git identified as conflict and remove those after carefully looking at the code.
You can see three markers in the above graphic. After removing these, add the file and then commit:
$ git add footer.php
$ git commit -a -m “Their and Our changes are fixed – Commit 3”
After that, run the status command:
This should return:
On branch master
nothing to commit, working tree clean
Now, execute the push command for making changes on the remote repo:
After the push is successful, check the online repo. This should display the commit message with the updated file as shown below:
How to revert a merge?
After a merge is done by using the git merge command, you may undo this by using the reset command. For example:
$ git reset --hard HEAD~1
This command will undo the last commit.