git merge master into branch takes every commit that's landed on master since your branch split off and folds it into the branch you currently have checked out — one operation, though the number of ways people phrase it is longer: git merge branch master into branch, merge main into branch, git merge branch into another branch, merge develop. This guide covers the full path — fetching before merging, main vs master naming, remote branches, GitHub and GitLab's UI equivalents, reading and previewing a diff before you commit to it, and resolving conflicts when they show up. If the branch you need doesn't exist on your machine yet, checking it out from the remote is the step before any of this applies.
The Fast Answer: Merge Master Into Your Branch in Three Commands
Three commands cover how to merge two branches in git for the standard case: fetch the latest master, switch to the branch that should receive it, and merge.
# 1. Update your local view of the remote without touching any files
git fetch origin
# 2. Stand on the branch that should receive master's changes
git checkout my-feature-branch
# 3. Merge master into it
git merge origin/master
That third command is the one search engines see phrased a dozen different ways — git merge master
into branch, git merge branch master into branch, merge master into branch — and they all mean the
same thing: pull every commit that exists on master but not on your current branch, and combine them
here. If your default branch is named main instead of master (GitHub's
default since October 2020), swap the name and nothing else changes. git fetch origin
first matters more than it looks — skip it and a plain git merge master merges whatever
your local, possibly stale, master branch last knew about, not what's actually sitting
on the remote.
If step 3 stops with conflict markers instead of a clean merge commit, jump straight to reading merge conflicts. If you'd rather see what's about to land before committing to it, previewing the merge first is worth the extra 30 seconds.
What Does Git Merge Do?
git merge takes the commits that exist on one branch and folds them into the branch you
currently have checked out, then records the result as a new commit. What does git merge do
mechanically depends entirely on how far the two branches have diverged, and Git picks one of two
strategies without asking:
- Fast-forward. If your current branch hasn't moved since master was created from it — no commits of your own since the split — Git just slides your branch pointer forward to match master's tip. No new commit, no merge; the history stays a straight line.
- Three-way merge. If both branches have commits the other doesn't, Git compares three points — the common ancestor, your branch's tip, and master's tip — computes the combined diff, and writes a new merge commit with two parents. This is what most people mean when they ask how does git merge work in practice: it's not a commit-by-commit replay, it's a single diff computed from three snapshots.
The merge commit is the artifact that makes a three-way merge different from every other way Git
combines history — it's the only commit type with two parents, and git log --graph is
where that becomes visible as two lines converging into one. Fetching first and merging a
remote-tracking ref — what people usually mean by git merge origin main — uses the exact same
three-way logic; the only difference is which ref supplies the incoming side, origin/master
or origin/main. Git's own Basic
Branching and Merging chapter in the Pro Git book documents both paths from the plumbing level up.
How to Merge Master Into Your Branch, Step by Step
The three-command fast answer above is how to merge two branches in git for the common case. Here's what each step in how to git merge is actually doing, plus what changes if your branch doesn't exist locally yet or your default branch is named differently.
1. Fetch, don't pull, until you've checked out the right branch.
git fetch origin git fetch downloads every new commit and updates your remote-tracking refs
(origin/master, origin/main) without touching your working tree or local
branches. git pull fetches and merges in one step, but on the wrong branch that merges
master into whatever you happen to have checked out at the time — a common way people end up needing
this guide in the first place. Fetch first, decide, then merge.
2. Confirm which branch you're standing on.
git branch --show-current This matters because of the single rule that trips up more people than anything else here: git merge always merges into whatever branch is currently checked out. Not sure your branch even exists locally yet — say, a teammate pushed it and you never checked it out yourself? Listing branches and confirming which one you're on is worth doing before any merge you're not fully certain about.
3. Merge.
# If your default branch is named master
git checkout feature/login-form
git merge origin/master
# If it's named main
git checkout feature/login-form
git merge origin/main
Everything above applies identically to git merge main into branch, merge main into branch, or
merge main into feature branch — main and master are just branch names, and GitHub switched its own
default from master to main in October 2020. Nothing about how the merge itself behaves changes
based on which one your team uses. This is also where git merge master into feature branch and
merge master into feature branch phrasing comes from — same operation, just naming the target
branch explicitly instead of assuming you're already standing on it. git merge origin/master
merges the remote-tracking ref directly, which is almost always what you want right after a fresh
fetch; git merge master merges your local master branch,
which is only current if you've checked it out and pulled it recently yourself.
4. Verify.
git log --oneline -5
git status
A clean merge leaves git status reporting nothing to commit and git log
showing either a fast-forwarded tip or a fresh two-parent merge commit at the top. That's the whole
sequence — fetch, checkout, merge, verify — whether you're asking how to merge git branch in the
abstract, how to merge 2 branches in git for the first time, or repeating it for the hundredth time
on a long-lived feature branch.
Merging Any Branch Into Any Other Branch
Master and main are just the two most common source branches — git merge branch into another
branch, git merge branch to branch, and merging any two branches in general work identically no
matter what either one is named. This guide leads with master because it's the case most people
search for; merging develop into a release branch, or one feature branch into another,
is the exact same three commands with different names.
git checkout release/2.4
git fetch origin
git merge origin/develop One mental model resolves most of the confusion behind git merge branch into another and git merge one branch into another: you always merge into the branch you currently have checked out. "Merge A into B" in plain English translates to "checkout B, then git merge A" — never the reverse. Get this backwards once — checkout master and merge your feature branch into it by accident — and unfinished feature work lands on master instead of the other way around.
git merge another-branch and git merge another branch into current describe the same
command from two angles: "current" is whatever git branch --show-current reports, and
that's always the receiving side. Merge from branch to branch is a direction, in other words, and
the direction is always toward the branch you're standing on — the source is named on the command
line and never moves. Uncommitted local changes block a merge outright if they overlap
with incoming changes — stashing them first and popping the stash
once the merge lands is the standard workaround, rather than committing half-finished work just to
clear the way.
Merge develop comes up often enough to name on its own: teams running a develop/release/master flow
run git merge develop against a release branch to cut a release candidate, then merge
that release branch into master once it ships. Same three commands, run twice, in sequence.
Merging a Remote Branch Into a Local One
Everything above already merges a remote branch — origin/master and
origin/main are remote-tracking refs, local read-only copies of what the server held as
of your last fetch. git merge remote branch into local is really asking about the same
three-command sequence, just naming the source explicitly as remote rather than local.
git fetch origin
git merge origin/master
The distinction that matters here is git fetch versus git pull.
git fetch updates origin/master to match the server and stops there — your
working tree and local master branch don't move. git pull is shorthand for
git fetch followed immediately by a merge (or, with --rebase, a rebase
instead) into whatever branch is currently checked out. Running git pull while standing
on a feature branch merges the remote's version of that same feature branch — not master — which is
a different operation from what this guide covers.
The slash matters. People write the query as git merge origin main, but that is not a spelling
variant of git merge origin/main — it's a different command. With a space, Git reads
origin and main as two separate refs to merge at once, producing an octopus
merge of your branch with both; with a slash, origin/main is a single remote-tracking ref
and you get the ordinary two-branch merge you actually wanted. Always use the slash form. The ref
being merged should be the remote-tracking one fetch just updated, not a plain local
branch of the same name. If your local master is stale — not checked out or pulled in a
while — merging it directly instead of the remote-tracking ref silently drops whatever landed on the
server since your last pull. Once the merge lands and you're ready to share it,
pushing the result back follows the same fetch-first
discipline in reverse.
Preview the Merge Before You Run It
Every guide up to this point in the genre stops at "run git merge and resolve conflicts if any show up." What they skip: you can see exactly what a merge is about to bring in before you commit to it, and for anything beyond a trivial branch, that check is worth running every time.
Two-dot vs three-dot diff — they answer different questions.
# Two-dot: everything different between the two tips, in either direction
git diff main HEAD
# Three-dot: only what HEAD would gain from merging main — the actual merge diff
git diff main...HEAD git diff main HEAD (two-dot) compares the two branch tips directly — every line that
differs between them, including changes your branch made that master doesn't have. git diff
main...HEAD (three-dot) instead diffs against the merge base — the commit where the branches
split — so it shows only what's unique to main since the split, which is precisely the
set of changes a merge would introduce. For previewing an incoming merge, three-dot is almost always
the one you want; two-dot answers a different question ("how do these two tips differ overall") that
happens to look similar on the surface.
A real dry run, not just a diff.
git merge --no-commit --no-ff origin/master
# Inspect the result: git status, git diff --staged, run your tests
# Happy with it:
git commit
# Not happy with it:
git merge --abort --no-commit performs the merge and stages the result without creating the merge commit,
so you're standing in the merged state with everything still reversible. --no-ff forces
a real merge to happen even in cases that would otherwise fast-forward, which matters here because a
fast-forward has nothing to inspect — the branch pointer would just move. Bailing out at this point
is a single command — git merge --abort undoes the whole in-progress merge and puts you
back exactly where you started.
Two narrower questions worth knowing separately.
# What master has that your branch doesn't, commit by commit
git log --oneline HEAD..main
# The exact commit both branches diverged from
git merge-base HEAD main git log --oneline HEAD..main lists the actual commits a merge would pull in, one per
line, before you've touched a single file — useful for a quick "is this a big merge or three typo
fixes" gut check. git merge-base finds the common ancestor Git uses internally for
every three-way merge; knowing that commit explicitly is what makes three-dot diffs, bisecting a
merge, and diagnosing an unexpectedly large diff all possible in the first place.
None of this needs a GUI, but reading a large three-dot diff in a raw terminal is where most people give up and just run the merge blind. A fast way to actually read it: pull the exact file versions from both sides as plain text and put them side by side.
git show main:src/app.ts > /tmp/main-version.ts
git show HEAD:src/app.ts > /tmp/branch-version.ts
Diff Checker, a free Chrome extension (also usable directly at diffchecker.pro), doesn't know what a
commit is and can't read your repository — there's no git integration to speak of — but it's exactly
the right tool for the two files that command just produced. Paste main-version.ts into
one editable pane and branch-version.ts into the other, and it renders a live
side-by-side or unified diff with syntax highlighting across 17 languages. Ignore Whitespace strips
out reformatting noise that would otherwise bury the real change, and "Show Diff Only," with a
context-lines picker (0, 1, 2, 3, or 5), collapses everything that didn't change so what master is
actually about to bring in is the only thing on screen. It's a manual step — paste in, read, paste
the next file — but for the one file you're genuinely worried about before a big merge, that's often
faster and clearer than scrolling a 200-line terminal diff. For diffs you compare this way regularly,
the full rundown of git diff flags and
how to read unified diff output cover the CLI side;
VS Code's built-in diff viewer is the equivalent
inside an editor instead of a browser tab.
Merge Conflicts: Why They Happen and How to Read Them
A merge conflict happens when the same region of a file was changed differently on both branches, and Git has no principled way to pick a winner — it stops mid-merge and asks you to decide instead. Changes to different files, or to different, non-overlapping parts of the same file, merge automatically; only genuinely overlapping edits conflict.
$ git merge origin/master
Auto-merging src/auth/login.ts
CONFLICT (content): Merge conflict in src/auth/login.ts
Automatic merge failed; fix conflicts and then commit the result. git status right after that lists every file with unresolved conflicts under "Unmerged
paths," and opening one of them shows Git's conflict markers inline, wrapped around both versions of
the disputed lines:
<<<<<<< HEAD
const timeout = 5000;
=======
const timeout = requestTimeoutMs;
>>>>>>> origin/master
Everything between the HEAD marker and the ======= divider is your
branch's version; everything between the divider and the origin/master marker is what
came from the branch you're merging in. Both blocks are real, valid code from their respective
branches — the markers themselves are the only thing that isn't — and resolving the conflict means
editing the file down to what it should actually say, markers included in the deletion. git
diff during a conflicted merge shows a specialized combined-diff format for conflicted files,
marking which side each change came from, which is worth a look before diving into a large conflict
by eye.
Resolving Merge Conflicts Step by Step
Once you can read a conflict, resolving it is a short, repeatable loop: edit each conflicted file down to what it should say, stage it, then commit.
# 1. See which files still need attention
git status
# 2. Open each one, delete the markers, keep the correct code
# (editors like VS Code render this as an inline "Accept Current /
# Accept Incoming / Accept Both" prompt instead of raw markers)
# 3. Mark it resolved
git add src/auth/login.ts
# 4. Once every conflicted file is staged
git commit
Git refuses git commit while any file still has unresolved markers left in the index,
so there's no way to accidentally commit half-merged code — the commit either completes cleanly or
Git tells you exactly which paths are still pending. For conflicts too large or too numerous to
resolve by hand comfortably, git mergetool launches whatever three-way merge GUI you've
configured (VS Code, Meld, KDiff3, and others all work) instead of raw text markers.
Two shortcuts worth knowing for conflicts where you actually just want one side, wholesale, rather than a blended result:
# Keep your branch's version for this file, discard the incoming one
git checkout --ours src/auth/login.ts
git add src/auth/login.ts
# Keep the incoming version, discard yours
git checkout --theirs src/auth/login.ts
git add src/auth/login.ts --ours and --theirs skip the manual edit entirely for that file — useful
for generated files, lockfiles, or anything where one side is simply correct and merging line-by-line
would be pointless. Use them file by file, not as a blanket policy, since guessing wrong silently
discards real work with no conflict marker left behind to catch it.
If a conflict turns out to be more than you want to deal with right now — wrong branch, wrong time,
or you need more context first — git merge --abort backs out of the entire in-progress
merge and restores your branch to exactly where it stood before you ran git merge,
conflicts and all. The full behavior, including what it does and doesn't undo once you've already
resolved some files, is covered in the dedicated guide to
aborting a merge.
Merging on GitHub and GitLab
Everything above is the CLI path. Both major hosts also offer a UI (and API) way to land the same merge without running any of it locally, and the phrasing splits cleanly by platform: branch merge github questions are almost always about the pull request flow, gitlab merge master to branch and gitlab merge main into branch about merge requests.
GitHub. Opening a pull request that targets master already sets up the merge; the "Merge pull request" button, with a dropdown for merge commit, squash, or rebase, performs it server-side once checks pass. github merge master into branch specifically usually means keeping a feature branch current with master mid-review — for that, GitHub shows an "Update branch" button on the PR whenever master has moved ahead, which runs the same merge this guide covers, just triggered from the browser instead of a terminal. The CLI equivalent, via GitHub's own CLI documentation:
gh pr merge 42 --merge # or --squash / --rebase GitLab. The gitlab merge command most people are actually looking for is the merge request's "Merge" button in the UI, with a "Squash commits when merging" checkbox alongside it. GitLab also supports merging directly from the CLI or API without opening the web UI at all:
glab mr merge 42
# or, via the REST API
curl --request PUT --header "PRIVATE-TOKEN: <token>" \
"https://gitlab.example.com/api/v4/projects/1/merge_requests/42/merge" Both platforms apply the merge to the target branch server-side and never touch your local checkout, so the local three-command sequence and the platform's merge button are two independent ways to reach the same result — pick whichever fits the workflow, and use the CLI path from this guide when a change needs local verification first. GitLab's merge request documentation covers the full set of merge options, including fast-forward-only merges enforced project-wide.
Merge vs Rebase: Which to Use When
git merge and git rebase both combine work from two branches, but they
produce different history and carry different risk once anything is shared with other people.
| Approach | What Happens to History | New Commit Created? | Safe on a Shared Branch? | Best For |
|---|---|---|---|---|
git merge | Both branches' commits stay exactly as they were; a merge commit joins them | Yes, unless fast-forwarded | Yes — never rewrites existing commits | Bringing master into a long-lived or shared branch |
git rebase | Your branch's commits are replayed on top of master, one by one, with new hashes | Yes — every replayed commit is new | No, if already pushed and shared | Keeping your own unshared branch linear before review |
git merge --squash | Incoming commits collapse into one new commit on the target; source branch untouched | Yes — exactly one | Yes on the target; source branch keeps its own history | Landing a finished feature branch as a single, clean commit |
The practical rule: merge master into your branch to pick up upstream changes — it never rewrites
commits, so it's safe no matter who else has the branch. Rebase your own branch onto master when you
want a clean, linear history before opening a review, but only while that branch is still yours
alone; rebasing something already pushed and shared forces every collaborator into a force-push
reconciliation. When the goal is landing a whole feature as one tidy commit rather than keeping a
branch current, that's a different operation with its own tradeoffs — the full breakdown, including
interactive rebase and git reset --soft as alternatives, is in the dedicated guide to
squashing commits.
Atlassian's
merge-vs-rebase comparison covers the history-shape tradeoffs in more depth than fits here.
Fast-Forward, No-Fast-Forward and Squash: Three Ways a Merge Can Land
Beyond merge vs rebase as a whole, git merge itself has three landing modes, controlled
by flags, that change what the resulting history looks like even when you're always running the same
base command.
# Default — fast-forwards when possible, three-way merge commit otherwise
git merge origin/master
# Force a real merge commit even when a fast-forward is possible
git merge --no-ff origin/master
# Collapse the incoming branch into a single new commit, no merge commit at all
git merge --squash origin/master
git commit -m "Bring in latest master" --ff (the default) takes the fast path whenever it can — if nothing new has landed
on your branch since it split from master, Git just moves your branch pointer forward, no merge
commit, no two-parent node in the graph. --no-ff disables that shortcut and always
records a merge commit, even for a fast-forwardable case, which some teams enforce project-wide
specifically so every merge leaves a visible marker in git log --graph instead of
disappearing into a straight line. --squash is a different animal entirely: it
stages the combined diff of everything on the incoming branch but writes zero commits until you run
git commit yourself, and the two branches never get formally linked in history the way
an ordinary merge records it. A fourth flag, --ff-only, refuses the merge outright
unless it can fast-forward, which is how teams enforce a strictly linear main branch; the complete
list is in Git's
git-merge reference documentation.
For the specific case this guide is about — pulling master's changes into a branch you're actively
developing on — plain git merge (fast-forward when possible, merge commit otherwise) is
the right default. Reach for --no-ff when your team's convention wants every merge
visible regardless of shape; reach for --squash only when you explicitly want to
discard the incoming branch's individual commit boundaries, which is rare for pulling master into a
feature branch and far more common in the other direction — landing a finished feature onto master.
Common Git Merge Mistakes and How to Avoid Them
Merges rarely go wrong on the merge itself. They go wrong on the habits around it — the branch you forgot to check, the fetch you skipped, the resolution you didn't re-read. These are the ones that cost the most time:
- Merging in the wrong direction. Checking out master by habit and merging your
feature branch into it, instead of the reverse, ships unfinished work to master. Run
git branch --show-currentbefore merging any time there's doubt. - Merging a stale local master instead of the remote-tracking ref.
git merge masterwithout a recentgit fetchmerges whatever your machine last knew, silently missing anything pushed since.git fetch originfollowed bygit merge origin/masteravoids this entirely. - Merging with uncommitted changes still in the working tree. Git blocks the merge outright if those changes overlap with incoming ones; stash them first rather than committing throwaway work just to clear the way.
- Committing a conflict resolution without re-checking it. Resolving markers by
eye and committing immediately, without diffing the result or running tests, is how a wrong
--ours/--theirspick or a botched manual edit slips through. The preview step above and a final glance atgit diff --stagedbefore committing both catch this. - Force-pushing after a merge to "clean up." Ordinary merges don't rewrite history, so there's no reason to force-push one — if a force-push feels necessary after a merge, something else (an accidental rebase, an amend) happened along the way and is worth investigating before overwriting the remote.
- Panicking instead of using the safety net. A completed but unpushed merge commit you regret is one git reset --hard away from undone, back to exactly where the branch stood before the merge — reflog keeps it recoverable for a while even after that. Once you're confident the merge landed correctly and the feature branch is fully absorbed, deleting it keeps the branch list from accumulating dead references.
Every one of those is a habit problem rather than a Git problem, and the same four steps — fetch, checkout, merge, verify — head off all of them. That holds whether you're running git merge master into branch on a repo that never renamed anything, or git merge main into branch on one that switched its default years ago.
Frequently Asked Questions
What is a git merge conflict?
A merge conflict happens when the branch you're merging in and your current branch both changed
the same lines of the same file in different ways, and Git can't automatically decide which
version is correct. Git pauses the merge, marks the file as unmerged, and inserts conflict
markers around both versions so you can resolve it by hand, with git mergetool, or
with --ours/--theirs for a whole-file decision.
Git merge vs rebase — which should I use?
Use git merge to bring master's changes into a branch, especially one other people
are also working on — it never rewrites existing commits, so it's safe regardless of who else
has the branch. Use git rebase to clean up your own branch's history into a
straight line before opening it for review, but only while the branch is still unshared;
rebasing commits that are already pushed forces a force-push and a reconciliation for anyone who
already pulled them.
How do I merge a branch to master?
The direction just reverses the target: checkout master, fetch, then merge the feature branch
into it — git checkout master && git fetch origin && git merge
origin/feature-branch. On GitHub or GitLab, opening a pull or merge request against
master and using the platform's merge button does the same thing server-side, usually with
review and CI checks gating it first.
Can I undo a merge after committing it?
Yes, with different tools depending on whether it's been pushed. Locally and unpushed,
git reset --hard HEAD~1 removes the merge commit and returns the branch to exactly
where it stood before. Already pushed and shared, git revert -m 1 <merge-commit>
creates a new commit that undoes the merge's changes without rewriting history anyone else
already has.
Can I preview a merge before running it?
Yes — git diff main...HEAD (three-dot) shows exactly what a merge would introduce
without touching anything, git log --oneline HEAD..main lists the incoming commits,
and git merge --no-commit --no-ff performs the merge into your working tree and
index without creating the commit, so you can inspect, test, and either commit or git
merge --abort out of it cleanly.