Code Safari

Chapter 103·Beginner·9 min read

Git Remotes: Push, Pull, and Fetch

A plain-English guide to Git remotes — how your local repository syncs with a shared one on GitHub or elsewhere. What 'origin' is, the difference between fetch and pull, what push really does, remote-tracking branches, and why Git works offline. The bridge from solo to team.

July 16, 2026

Everything so far has happened on your own machine. Commits, branches, staging — all local, all offline. That's by design: Git is distributed, and your repository is complete on its own. But software is a team sport, and at some point your history has to meet everyone else's. That's what remotes are for. This chapter is the bridge from working alone to working together — how your local repository syncs with a shared one, and what push, pull, and fetch actually do.

What a remote actually is

A remote is simply another full copy of your repository, living somewhere else — most often a shared copy hosted on GitHub, GitLab, or a company server. It's not a special "master" version in any technical sense; it's an ordinary Git repository that everyone agrees to treat as the meeting point.

Because Git is distributed, there's a subtle but important truth here: you and the remote each have the complete history. Syncing isn't downloading pieces of a project you only partly have — it's two complete repositories exchanging the commits the other is missing.

Your local repository (full history)
Remote repository (full history)
Sync: exchange missing commits
Both converge
Your local repo and the remote are both complete — syncing exchanges what each lacks

When you first clone a repository, Git copies the whole thing to your machine and remembers where it came from, giving that source a nickname: origin. So origin isn't a magic word — it's just the default name Git assigns to "the remote I cloned from," so you can type origin instead of a long URL every time.

Fetch: look before you leap

There are two ways to bring down new work from the remote, and the difference between them is the single most clarifying thing in this chapter.

Fetch downloads new commits from the remote into your local repository — but it does not touch your working files or the branch you're on. It's the cautious move: "show me what's new on the remote, but don't change anything I'm doing." After a fetch, the new commits are on your machine, sitting safely to the side, and you can inspect them, compare them, and decide what to do — all before integrating anything.

Where do those fetched commits go? Into remote-tracking branches — local bookmarks like origin/main that record "here's where main was on the remote last time I checked." They're read-only snapshots of the remote's state, kept separate from your own main so the two never get confused.

Pull: fetch, then merge

Pull is fetch with one extra step bolted on: after downloading the new commits, it immediately merges them into the branch you're currently on. So pull = fetch + merge. It's the convenient everyday command for "get the latest and bring it into my work," and most of the time it does exactly what you want.

The reason it's worth knowing that pull is two steps is that the merge half is where surprises happen. If the remote's main and your main have both moved on, pull triggers the same three-way merge from the branching chapter — and if you both changed the same lines, you'll get a merge conflict to resolve. Pull didn't do anything mysterious; it fetched, then merged, and the merge is the part that occasionally needs you.

Fetch: download new commits to origin/main
Merge origin/main into your current branch
Your working files now include the new work
Pull is just fetch and merge, run back to back

Push: send your work upward

Push is the mirror image: it uploads your local commits to the remote so everyone else can see and build on them. Until you push, your commits exist only on your machine — perfectly real, but private. Pushing is the act that turns your private history into shared history.

Push has one firm rule worth internalizing: Git won't let you push if the remote has commits you don't have yet. If a teammate pushed while you were working, the remote is ahead of you, and Git rejects your push to stop you from silently burying their work. The fix is exactly what you'd expect: pull first (fetch their commits and merge them with yours), then push the combined result. That rejection isn't Git being difficult — it's Git protecting the shared history from being overwritten.

Why offline still works

One last payoff of the distributed design: because your repository is complete on its own, nearly everything works with no network at all. You can commit, branch, merge, and browse your entire history on a plane. Only the three commands in this chapter's title — the ones that sync with another copy — need a connection, because those are the only operations that involve the remote. Everything else is local by nature.

The picture to keep

A remote is another full copy of the repo, nicknamed origin by default. Fetch downloads new commits without disturbing your work; pull does that and merges them in; push sends your commits up to be shared. Remote-tracking branches like origin/main are your local memory of where the remote stood. Hold that model and syncing stops being guesswork. It also sets up the two chapters ahead: what to do when a pull or merge reports a conflict, and how teams turn pushed branches into reviewed, deliberate changes through pull requests.

Git Remotes: Push, Pull, and Fetch | Code Safari