Git Merge

Divya Srinivasan

 Understanding Git Merging: A Developer’s Guide to Bringing Code Together

When working on software projects with Git, collaboration and experimentation often lead to multiple branches—each representing a new feature, bug fix, or improvement. At some point, all this separate work needs to come back together. That’s where merging comes in.

What is Merging in Git?

In simple terms, merging means combining changes from one branch into another. It's how you integrate different lines of development. Whether you've been working on a new feature or fixing a bug in a separate branch, merging helps bring that work back into the main codebase—typically the main or develop branch.

Merging is a core part of Git's workflow, especially in collaborative teams where multiple developers contribute simultaneously.

Why Use Git Merge?

  • Merging is essential because it:
  • Keeps development organized
  • Prevents conflicts from snowballing
  • Helps track the history of changes
  • Enables multiple developers to work independently and still stay in sync
Once your feature or fix is complete, merging lets you consolidate your work into the main branch without losing the commit history.

Merging Branches with git merge: A Practical Example

When you're ready to bring changes from one branch into another, the go-to Git command is git merge. This is a fundamental part of version control that helps integrate completed work—like a bug fix or feature—back into the main project line.

Step-by-Step: How to Merge Branches in Git

Let’s walk through a simple, real-world example to show how merging works.

1. Switch to the Target Branch

Before merging, you need to make sure you're on the branch that should receive the changes. Most often, this is your main development branch—usually called main or master.

git checkout master

Output:

Switched to branch 'master'

Now you're on the master branch and ready to merge changes from another branch.

2. Run the Merge Command

Let’s say you've been working on a critical bug fix in a branch called emergency-fix. To bring those changes into master, you'd run:

git merge emergency-fix

Example Output:

Updating 09f4acd..dfa79db
Fast-forward
 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Fast-Forward Merge Explained

In this example, Git performed a fast-forward merge. This happens when the branch you're merging into (master) hasn't had any new commits since the emergency-fix branch was created. Git recognizes this as a linear continuation of the project history and simply "fast-forwards" the master branch pointer to the latest commit on emergency-fix.

In other words, no new merge commit is needed because the history already lines up cleanly.

Summary

  • Use git checkout to switch to the target branch.
  • Use git merge <branch-name> to bring in changes.
  • Git will choose the best strategy—like fast-forward—based on the commit history.
This type of clean, linear merging keeps your Git history simple and easy to follow. But in more complex scenarios where branches have diverged, Git might need to create a merge commit to preserve both histories.

Non-Fast-Forward Merge (git merge --no-ff) Made Simple

By default, when Git merges two branches and no new changes have been made on the main branch, it does a fast-forward merge. This means Git just moves the pointer forward to include the new commits—no extra merge commit is created.

But What If You Want a Clearer History?

Sometimes, you might want to always create a merge commit—even if a fast-forward is possible. This helps make your project history easier to understand, especially when looking back to see when and why a feature was added.
To do that, use the --no-ff option:

git merge --no-ff feature-branch

Example Output:

Merge made by the 'recursive' strategy.
 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

This creates a merge commit, even if Git could have fast-forwarded. That way, it’s clear in your Git history that a separate branch was merged.

Why Use --no-ff?

  • Keeps a record of all feature merges
  • Makes the commit history easier to follow
  • Useful for teams or long-term projects

Squash Merge (git merge --squash)

If you want to bring in all the changes from another branch as a single, clean commit—without keeping its individual commits—you can use:

git merge --squash branchname

This is helpful when you want to simplify your project’s history.

Example:

git merge --squash feature-branch

Git will apply the changes and stage them for commit, but it won’t create a merge commit automatically.
You’ll see a message like:


Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

Then, you finish by creating your single commit:

git commit -m "Add feature from feature-branch"

Aborting a Merge (git merge --abort)

If you start a merge and run into problems—such as conflicts you’d rather not resolve—you can stop the merge and return your branch to its previous state by running:

git merge --abort

Example:

git merge --abort

This cancels the merge in progress and resets your working directory and staging area to how they were before the merge started.

What is a Merge Conflict?

A merge conflict occurs when changes from two branches affect the same part of a file, and Git can’t automatically decide which version to keep.

It’s like two people editing the same sentence differently—Git needs you to review and choose the correct version to complete the merge.

How to Resolve a Merge Conflict

When a conflict happens, Git marks the conflicting parts in your files with special markers like <<<<<<< HEAD, =======, and >>>>>>> branch-name.

To fix it:

  1. Open the file and review the conflicting sections.
  2. Edit the file to keep the changes you want and remove the conflict markers.
  3. Once resolved, stage the file:
                    git add filename

      4.Then commit the changes to complete the merge:

                     git commit

Troubleshooting & Tips

  • To cancel a merge in progress, run:
                   git merge --abort
  • Before starting a merge, always commit or stash any uncommitted changes to avoid conflicts.
  • When resolving conflicts, carefully read and remove all conflict markers (<<<<<<<, =======, >>>>>>>).
  • Use git status to check which files still need to be resolved.
If you’re unsure how to fix a conflict or error, ask a teammate or search for the specific message online for guidance.

Merge Conflict Example

Let’s switch back to the hello-world-images branch from the previous chapter to continue working.

Next, add a new image file (img_hello_git.jpg) and update index.html to display it.

Example:

git checkout hello-world-images
Switched to branch 'hello-world-images'

Merge Conflict Example

Let’s switch to the hello-world-images branch to keep working:

git checkout hello-world-images
Switched to branch 'hello-world-images'
Now, add a new image file (img_hello_git.jpg) and update index.html to show it:

Example index.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>

Now stage and commit the changes:

git add --all
git commit -m "added new image"
[hello-world-images 1f1584e] added new image
 2 files changed, 1 insertion(+)
 create mode 100644 img_hello_git.jpg

Merging into master

We notice that index.html has changes in both the master branch and hello-world-images.
Let’s try merging:

git checkout master
git merge hello-world-images

Git tries to merge but finds a conflict:

Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

Checking the conflict

Use git status to see what’s going on:

git status

Output:

On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Changes to be committed:
  new file:   img_hello_git.jpg
  new file:   img_hello_world.jpg

Unmerged paths:
  both modified:   index.html

This tells us the image files are staged, but index.html has a conflict.

Resolving the conflict

Open index.html and you’ll see something like this:

<p>This is the first file in my new Git Repo.</p>
<<<<<<< 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

Choose what you want to keep and remove the conflict markers (<<<<<<<, =======, >>>>>>>).
For example, final version:

<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>

Finishing the merge

Stage the resolved file:

git add index.html

Check status again:

git status

Output:

On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
  new file:   img_hello_git.jpg
  new file:   img_hello_world.jpg
  modified:   index.html

Commit to complete the merge:

git commit -m "merged with hello-world-images after fixing conflicts"
[master e0b6038] merged with hello-world-images after fixing conflicts

Finally, delete the hello-world-images branch since it’s now merged:

git branch -d hello-world-images
Deleted branch hello-world-images (was 1f1584e).

















Tags
Our website uses cookies to enhance your experience. Learn More
Accept !

GocourseAI

close
send