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.
Fast-Forward vs Three-Way Merge FAST-FORWARD no commits on your branch since the split 0 1 2 3 master feature (before) feature (after fast-forward) pointer just slides from 1 to 3 no new commit is created THREE-WAY MERGE both branches added commits since the split 0 A master B feature M new commit 2 parents both tips feed into one new commit git log --graph shows two lines joining
Fast-forward just slides the branch pointer forward along the same line; a three-way merge joins two diverged tips into one new commit with two parents.

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.

Fetch → Checkout → Merge → Verify 1 FETCH git fetch origin remote-tracking refs update; working tree untouched 2 CHECKOUT git checkout feature HEAD moves; files on disk switch to that branch's version 3 MERGE git merge origin/master master's commits fold into the checked-out branch 4 VERIFY git log --oneline -5 git status confirms a clean merge commit or a fast-forwarded tip
Four commands, one direction — fetch updates refs, checkout switches HEAD, merge folds master in, verify confirms a clean commit or fast-forward.

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.

Merge Always Lands on the Currently Checked-Out Branch B — checked out, receiving side you are here A — source, stays unchanged checkout B, then git merge A
"Merge A into B" always means: check out B first, then merge A into it — A never moves, and B is always whatever git branch --show-current reports.

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.

Two-Dot vs Three-Dot Diff: Different Questions TWO-DOT git diff main HEAD main HEAD diff (two-dot) everything different, both directions shows every line that differs THREE-DOT git diff main...HEAD merge-base main HEAD highlighted segment is the only thing shown only what main gained since the split
Two-dot compares both tips directly, in either direction; three-dot diffs against the merge-base, so it isolates only what main gained since the branches split — the actual merge diff.

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.

Anatomy of a Merge Conflict Block <<<<<<< HEAD const timeout = 5000; ======= const timeout = requestTimeoutMs; >>>>>>> origin/master opening marker your branch's version starts here divider boundary between the two versions closing marker incoming branch's version ends here all three marker lines must be deleted once the conflict is resolved
The HEAD marker opens your branch's version, the divider splits the two, and the branch-name marker closes the incoming version — none of the three lines is real code, so all three go away.

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.

Three Ways a Merge Can Land FAST-FORWARD pointer moves forward no merge commit git merge NO-FAST-FORWARD merge commit, 2 parents recorded git merge --no-ff SQUASH main + S feature — untouched git merge --squash
Fast-forward moves the pointer with no new commit; --no-ff always records a two-parent merge commit; --squash writes one new commit on the target while the source branch's own commits stay untouched.

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-current before merging any time there's doubt.
  • Merging a stale local master instead of the remote-tracking ref. git merge master without a recent git fetch merges whatever your machine last knew, silently missing anything pushed since. git fetch origin followed by git merge origin/master avoids 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/--theirs pick or a botched manual edit slips through. The preview step above and a final glance at git diff --staged before 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.