I stared at my terminal, confused.

I had just merged a PR on GitHub. The green “Merged” button was right there. The commits were in main. Everything looked perfect on the GitHub web interface.

But when I ran git log locally, my merge commit was nowhere to be found.

My local main branch was stuck in the past. Three commits behind. Like it didn’t know the merge happened.

For a moment, I thought Git was broken.

It wasn’t. I was just missing a fundamental concept that took me two years to truly understand.

The Mental Model That Changes Everything

Think of Git like two separate notebooks.

Notebook 1: Your local repository. It lives on your computer. You write in it, make changes, create branches.

Notebook 2: The remote repository (GitHub). It lives on a server. Other people can write in it too.

The critical insight: These notebooks don’t automatically sync.

When you merge a PR on GitHub, you’re writing in Notebook 2. Your local Notebook 1 has no idea this happened. It can’t read minds. It doesn’t have a constant internet connection checking for updates.

This is intentional. This is the power of distributed version control.

Why Git Works This Way

Git was designed for a world where:

  1. You might not have internet. Developers work on planes, in coffee shops, in basements with spotty WiFi. Git lets you commit, branch, and work completely offline.

  2. Remote changes shouldn’t surprise you. Imagine if every time someone pushed to main, your local files automatically changed. You’d lose unsaved work. Your tests would break mid-run. Chaos.

  3. You decide when to sync. You’re in control. You pull changes when you’re ready. Not when GitHub decides.

This design choice has saved countless developers from merge hell. But it creates a learning curve.

The Three Commands That Connect Both Worlds

1. git fetch - Download Without Changing

git fetch origin

This command says: “Hey remote, what’s new? Download everything, but don’t touch my local files.”

After running this, you have the latest information about the remote. But your local branches haven’t changed. You’re just… informed.

Think of it as checking your email without opening any messages.

2. git pull - Download and Merge

git pull origin main

This command says: “Get the latest changes from remote main, and merge them into my current branch.”

It’s essentially git fetch + git merge combined.

Use this when you’re ready to incorporate remote changes into your work.

3. git push - Upload Your Changes

git push origin main

This command says: “Take my local commits and send them to the remote.”

The remote updates. Other people can now see your work.

The Timeline of a Merged PR

Let me walk you through exactly what happens when you merge a PR on GitHub:

Step 1: You create a feature branch locally

git checkout -b feature/new-thing
# make changes
git add .
git commit -m "Add new feature"
git push -u origin feature/new-thing

Your local and remote now both have feature/new-thing.

Step 2: You open a PR and merge it on GitHub

You click “Merge pull request” on GitHub. The server creates a merge commit. The feature branch is merged into main.

What happened on the remote:

  • main branch now includes your commits
  • A merge commit was created
  • The branch history shows the merge pattern

What happened locally:

  • Nothing.
  • Your local main still points to the old commit.
  • Your local doesn’t know the merge happened.

Step 3: You sync your local

git checkout main
git pull origin main

Now your local main matches the remote. The merge commit appears in your history. The branch pattern is visible in git log --graph.

The Commands I Run After Every PR Merge

After years of confusion, this is my muscle memory:

# Switch to main branch
git checkout main

# Download and merge remote changes
git pull origin main

# Delete the feature branch locally (optional but clean)
git branch -d feature/new-thing

# Verify everything is synced
git log --oneline -5

Takes 10 seconds. Saves hours of confusion.

Common Mistakes and How to Avoid Them

Mistake 1: Expecting automatic sync

Wrong assumption: “I merged on GitHub, so my local is updated.”

Reality: Local and remote are independent until you explicitly sync.

Fix: Always git pull after merging PRs.

Mistake 2: Working on outdated main

What happens: You create a new branch from local main, but local main is 10 commits behind remote main.

Result: Your new branch is based on stale code. Merge conflicts await.

Fix: Always git pull origin main before creating new branches.

Mistake 3: Confusion about where changes live

Symptom: “I pushed my changes but my teammate can’t see them.”

Possible causes:

  • You pushed to a branch, not main
  • You forgot to push entirely
  • Your teammate hasn’t pulled

Fix: Use git status religiously. It tells you exactly what’s committed, what’s staged, and what’s different between local and remote.

The Git Status Command Is Your Friend

Seriously. Run it constantly.

git status

It tells you:

  • Which branch you’re on
  • If you’re ahead or behind the remote
  • What files are staged, modified, or untracked

Sample output after merging a PR remotely:

On branch main
Your branch is behind 'origin/main' by 3 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Git is literally telling you what to do. Listen to it.

Advanced: Visualizing the Branch History

After syncing, you can see the full merge pattern:

git log --oneline --graph -15

This shows:

*   a1b2c3d Merge pull request #42 from feature/new-thing
|\
| * d4e5f6g Add new feature
| * h7i8j9k Fix bug in feature
|/
* k1l2m3n Previous commit on main

That beautiful branching pattern only appears after you pull the merge commit locally.

The Bigger Picture: Distributed Systems

This Git behavior mirrors a fundamental truth about distributed systems:

Nodes are independent until they communicate.

Your computer is a node. GitHub is a node. Each maintains its own state. Synchronization requires explicit action.

This is the same principle behind:

  • Database replication
  • CDN cache invalidation
  • Microservice architectures

Understanding Git’s distributed nature prepares you for thinking about larger distributed systems. The mental model transfers.

Your Action Items

Today:

  1. Run git status on your current project
  2. Check if your local main is behind remote
  3. If so, run git pull origin main

This week:

  1. Create a cheat sheet of these commands
  2. Make git pull a habit before creating new branches
  3. Use git log --graph to visualize your branch history

Going forward: You’ll never wonder why your local doesn’t reflect a GitHub merge again.

The Commands Reference

# Check current state
git status

# Download remote info without changing files
git fetch origin

# Sync local branch with remote
git pull origin main

# View branch history visually
git log --oneline --graph -15

# See what's on remote that you don't have
git log --oneline main..origin/main

# Push local changes to remote
git push origin main

One Last Thing

Every senior developer I know has been confused by this at some point. It’s a rite of passage.

The difference is, now you understand why Git works this way. You’re not just memorizing commands. You’re understanding a distributed system.

That understanding will serve you for the rest of your career.


Found this helpful? Share it with a developer who’s still wondering why their local branch doesn’t update after merging PRs. We’ve all been there.