Git Merge and Merge Conflicts

Bring a branch's work into main with git merge, understand fast-forward merges and fix merge conflicts.

Lesson 7 of 30Beginner17 min read

Branches let you work on something separately. Merging is how that work comes back together. When your feature branch is finished, you merge it into main, and main gains all of its commits.

Most merges are completely automatic. Git compares the two branches and combines the changes for you. Occasionally both branches change the same lines of the same file in different ways, and Git can't know which version you want. That's a merge conflict, and you resolve it by choosing the right content yourself.

Conflicts sound scary, but they're a normal part of working with Git. In this lesson you'll merge branches, learn the two kinds of merge, and resolve a conflict calmly, step by step.

Merging a branch

You merge into the branch you're currently on. To bring dark-mode into main:

Terminal
git switch main
git merge dark-mode

After the merge, main contains everything from dark-mode. The dark-mode branch still exists; delete it with git branch -d dark-mode once you no longer need it.

Fast-forward and merge commits

  • If main hasn't changed since you created the branch, Git simply moves the main label forward to the branch's latest commit. This is a fast-forward merge, and no new commit is created.
  • If both branches have new commits, Git creates a merge commit that has two parents, joining the two lines of history. Git opens your editor with a ready-made message such as "Merge branch 'dark-mode'"; save and close to accept it.

Both are normal. git log --oneline --graph shows the difference: a fast-forward keeps a straight line, and a merge commit shows two lines joining.

When a conflict happens

If both branches changed the same lines, Git stops and tells you which files are in conflict. Inside each one, it marks the clashing section:

Text
<<<<<<< HEAD
<h1>Welcome to Sam's site</h1>
=======
<h1>Hello and welcome!</h1>
>>>>>>> new-heading
  • Between <<<<<<< HEAD and ======= is the version from your current branch.
  • Between ======= and >>>>>>> new-heading is the version from the branch you're merging.

The rest of the file, where nothing clashed, has already been merged for you.

Resolving a conflict

  1. Open each conflicted file (VS Code highlights them and offers buttons such as "Accept Current" and "Accept Incoming").
  2. Edit the section so it contains exactly what you want: one version, the other, or a mix.
  3. Delete all three marker lines: <<<<<<<, ======= and >>>>>>>.
  4. Stage the fixed file with git add.
  5. Finish the merge with git commit.

If you'd rather stop and try again later, git merge --abort puts everything back the way it was before the merge.

Git Merge Syntax

Merge commands

git switch main
git merge <branch>
git status              # lists conflicted files
git add <file>          # after fixing a conflict
git commit              # completes the merge
git merge --abort       # cancel the merge

Git Merge Summary

  • Switch to the target branch, then run git merge <branch>.
  • A fast-forward just moves the label; a merge commit joins two histories.
  • A conflict happens when both branches change the same lines.
  • Fix conflicts by editing the file, removing the markers, then git add and git commit.
  • git merge --abort cancels a merge in progress.

Git Merge Examples

Each example shows the code, the output it produces and what each part does.

Example 1

A fast-forward merge

Terminal
git switch main
git merge dark-mode
Output
Switched to branch 'main'
Updating 9d41e07..52ac9e1
Fast-forward
 styles.css | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
Line-by-line explanation
  1. Line 1Go to the branch that should receive the changes.
  2. Line 2main hadn't moved, so Git just fast-forwards it to the dark-mode commit.
Example 2

A merge that creates a merge commit

Both main and footer-links gained new commits in different files.

Terminal
git merge footer-links
git log --oneline --graph -4
Output
Merge made by the 'ort' strategy.
 footer.html | 6 ++++++
 1 file changed, 6 insertions(+)
*   e7d0b3c (HEAD -> main) Merge branch 'footer-links'
|\
| * a51f8c2 (footer-links) Add social links to footer
* | 0c3b9d4 Fix typo on home page
|/
* 52ac9e1 Add dark colour scheme
Line-by-line explanation
  1. Line 1The histories had split, so Git creates a merge commit. "ort" is the name of Git's merge method.
  2. Line 2The graph shows two lines of work joining at the merge commit.
Example 3

Resolving a conflict

Both branches changed the <h1> in index.html.

Terminal
git merge new-heading
git status
# edit index.html, keep the heading you want, delete the markers
git add index.html
git commit -m "Merge new-heading, keep friendlier title"
Output
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
Unmerged paths:
	both modified:   index.html
[main 4b7e2d1] Merge new-heading, keep friendlier title
Line-by-line explanation
  1. Line 1Git stops and reports the conflict.
  2. Line 2git status lists the conflicted file under "Unmerged paths".
  3. Line 4Mark the file as resolved by staging it.
  4. Line 5Committing completes the merge.

Common Git Merge Mistakes

Merging in the wrong direction

Don't
git switch dark-mode
git merge main      # brings main into dark-mode
Do
git switch main
git merge dark-mode # brings dark-mode into main

You always merge into the branch you're on.

Leaving conflict markers in the file

Don't
<<<<<<< HEAD
<h1>Welcome to Sam's site</h1>
=======
<h1>Hello and welcome!</h1>
>>>>>>> new-heading
Do
<h1>Hello and welcome to Sam's site!</h1>

If the markers are committed, they end up on your live website. Search the file for <<<<<<< before staging it.

Committing before resolving every file

Don't
git commit -m "Merge"   # error: Committing is not possible because you have unmerged files
Do
git status              # check every conflicted file
git add index.html styles.css
git commit -m "Merge"

Git Merge in Real Projects

Merging on real projects

On GitHub, most merges happen through a pull request's green "Merge" button, which runs the same merge on the server. Teams set rules such as "main can only change through a reviewed pull request", so conflicts are resolved and tested before they reach the live site.

Git Merge FAQ

How do I undo a merge I haven't pushed yet?

Right after the merge, git reset --hard ORIG_HEAD moves your branch back to where it was before the merge. --hard also throws away uncommitted changes, so commit or stash anything you want to keep first. If the merge stopped with conflicts and isn't finished, use git merge --abort instead.

How do I undo a merge that's already been pushed?

Use git revert -m 1 <merge-commit>, which adds a new commit undoing the changes the merge brought in. The -m 1 tells Git to keep the first parent, the branch you merged into. Be aware that merging the same branch again later won't bring those changes back unless you first revert the revert.

How do I see which branches are already merged?

git branch --merged lists branches whose commits are all included in your current branch; they're safe to delete. git branch --no-merged lists branches with work your current branch doesn't have yet.

What does "Already up to date" mean when I merge?

It means the branch you asked to merge has no commits that your current branch is missing, so there's nothing to do. Check that you spelled the branch name correctly and, if it lives on a remote, that you ran git fetch first.

What is a squash merge?

git merge --squash feature takes all the changes from feature and stages them as one set, without making a merge commit. You then run git commit to save them as a single new commit. Because the branch isn't recorded as merged, git branch -d feature will complain afterwards and you'll need -D.

Git Merge Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Complete the commands to bring the search branch into main.

git  main
git  search
Multiple choicemedium

When does Git do a fast-forward merge?

Multiple choicemedium

After fixing a conflict in app.js, what do you run before committing?

Predict the outputhard

What happens after git merge --abort during a conflict?

Multiple choicemedium

When can Git do a fast-forward merge?

Git Merge Quiz

5 questions to check what you learned.

  1. Into which branch does git merge feature bring changes?

    • feature
    • Always main
    • A new branch
    • The branch you're currently on
  2. What causes a merge conflict?

    • Merging too many files
    • Both branches changing the same lines in different ways
    • Having more than two branches
    • Not having an internet connection
  3. What does the ======= line separate in a conflict?

    • Your current branch's version from the incoming branch's version
    • Two files
    • Old commits from new commits
    • Comments from code
  4. How many parent commits does a merge commit have?

    • None
    • One
    • Two
    • As many as there are files
  5. Which branch should you be on before running git merge feature?

    • feature
    • Any branch
    • The branch that should receive the changes, such as main
    • A new empty branch