What is Merging in Git?
Merging in Git is the process of integrating changes from one branch into another.
This is how you combine work done independently on different features, fixes, or updates, so everything comes together smoothly in the main project.
Common git merge Options
- git merge – Merge a specified branch into your current branch.
- git merge --no-ff – Always create a merge commit, even if a fast-forward merge is possible, to keep history clearer.
- git merge --squash – Combine all the changes from the merged branch into a single new commit, rather than keeping individual commits.
- git merge --abort – Cancel an ongoing merge and return to the state before it started.
Merging Branches (git merge)
To bring changes from one branch into another, you use git merge.
Typically, you first switch to the branch you want to update (often main or master), and then run the merge command with the name of the branch you want to bring in.
Step 1: Switch to the master branch
git checkout master
Switched to branch 'master'
Step 2: Merge the changes from the emergency-fix branch
git merge emergency-fix
Updating 09f4acd..dfa79db
Fast-forward
index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
In this case, since the emergency-fix branch was created directly from master and no other changes were made to master in the meantime, Git can perform a fast-forward merge.
This means Git simply moves the master pointer forward to the latest commit of emergency-fix, making them both point to the same commit.
Non-Fast-Forward Merge (git merge --no-ff)
Normally, if Git can merge by just moving the branch pointer forward (fast-forward), it won’t create a separate merge commit.
But if you want to force a merge commit—so your history always shows where branches were merged—use:
git merge --no-ff feature-branch
Output might look like:
plaintext
Merge made by the 'recursive' strategy.
index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Squash Merge (git merge --squash)
To combine all changes from a branch into one new commit on the current branch (instead of keeping every individual commit):
git merge --squash feature-branch
Output:
plaintext
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
Then you manually create the single commit:
git commit -m "Add feature from feature-branch as a single commit"
This helps keep your history clean.
Aborting a Merge (git merge --abort)
If you start a merge and something goes wrong (e.g., too many conflicts) and you want to cancel it and go back to how things were before:
git merge --abort
This stops the merge and resets the branch to its pre-merge state.
What is a Merge Conflict?
A merge conflict happens when Git can’t automatically combine changes from different branches because those changes affect the same part of a file.
It’s like two people editing the same sentence in a document in different ways—Git needs you to choose which version to keep.
How to Resolve a Merge Conflict
When a conflict occurs, Git highlights it in the file using special markers:
plaintext
<<<<<<< HEAD
Your changes
=======
Other branch's changes
>>>>>>> branch-name
To fix it:
- Open the file and decide what the final content should look like.
- Remove the conflict markers (<<<<<<<, =======, >>>>>>>).
- Stage the resolved file with git add.
- Commit your changes.
Troubleshooting & Tips
- To cancel an ongoing merge: git merge --abort
- Always commit or stash your changes before starting a merge.
- Use git status to see which files still need attention.
- Read the conflict markers carefully to understand what each side changed.
- If you’re not sure how to resolve a conflict, ask a teammate or look up the specific error message.
Merge Conflict Example
We’re going to work on the hello-world-images branch to add a new image.
Step 1: Switch to the branch
git checkout hello-world-images
Switched to branch 'hello-world-images'
Step 2: Edit index.html
We add a new image (img_hello_git.jpg) so the file now looks like this:
html
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
<link rel="stylesheet" href="bluestyle.css">
</head>
<body>
<h1>Hello world!</h1>
<div><img src="img_hello_world.jpg" alt="Hello World from Space" style="width:100%;max-width:960px"></div>
<p>This is the first file in my new Git Repo.</p>
<p>A new line in our file!</p>
<div><img src="img_hello_git.jpg" alt="Hello Git" style="width:100%;max-width:640px"></div>
</body>
</html>
Step 3: Stage and commit the changes
bash
git add --all
git commit -m "Add new image"
[hello-world-images 1f1584e] Add new image
2 files changed, 1 insertion(+)
create mode 100644 img_hello_git.jpg
Step 4: Merge into master
Switch to the master branch and merge:
bash
git checkout master
git merge hello-world-images
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Step 5: Check the status
bash
git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Changes to be committed:
new file: img_hello_git.jpg
new file: img_hello_world.jpg
Unmerged paths:
(use "git add ..." to mark resolution)
both modified: index.html
This shows there’s a conflict in index.html, but the image files are staged and ready.
Step 6: Fix the conflict
Open index.html, and you’ll see:
html
<<<<<<< HEAD
<p>This line is here to show how merging works.</p>
=======
<p>A new line in our file!</p>
<div><img src="img_hello_git.jpg" alt="Hello Git" style="width:100%;max-width:640px"></div>
>>>>>>> hello-world-images
Update it to keep both changes:
html
Copy
Edit
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
<link rel="stylesheet" href="bluestyle.css">
</head>
<body>
<h1>Hello world!</h1>
<div><img src="img_hello_world.jpg" alt="Hello World from Space" style="width:100%;max-width:960px"></div>
<p>This is the first file in my new Git Repo.</p>
<p>This line is here to show how merging works.</p>
<div><img src="img_hello_git.jpg" alt="Hello Git" style="width:100%;max-width:640px"></div>
</body>
</html>
Step 7: Stage and finish the merge
bash
git add index.html
git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Then commit:
bash
git commit -m "Merge hello-world-images into master after resolving conflict"
[master e0b6038] Merge hello-world-images into master after resolving conflict
Step 8: Delete the feature branch
bash
git branch -d hello-world-images
Deleted branch hello-world-images (was 1f1584e).
Now you’ve successfully merged changes, resolved a conflict, and cleaned up the branch.