C.W.K.
Stream
Lesson 01 of 05 · published

origin, upstream, and Remote-Tracking Branches

~20 min · remote, fetch

Level 0Untracked Rookie
0 XP0/47 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

origin, upstream, and the remote-tracking shadow

A remote in Git is a named bookmark to another copy of the repository — typically a URL on a server like GitHub, GitLab, or your own gitolite host. By convention the remote you cloned from is named origin; nothing technically privileges it, but every tool and tutorial assumes it. Repos forked from someone else's project usually add a second remote called upstream pointing at the original.

What makes remotes useful is the remote-tracking branch. When you fetch, Git stores the remote's view of each branch under refs/remotes/origin/<branch>. These look like branches and behave like read-only pointers — origin/main is what your machine last saw on the server's main. Your local main can be ahead, behind, or in sync. The whole point of fetch is to keep this shadow accurate so you can compare your local work against it without guessing.

"Tracking" is a separate, optional configuration: a local branch can be set to track a remote-tracking branch, which makes git pull and git push default-correct without arguments. git switch feature/login on a remote-only branch creates a local branch that tracks origin/feature/login automatically (Git 2.23+). For new branches, git push -u origin feature/x sets up tracking on first push.

The mental model: there is a real server somewhere; origin/main is your snapshot of what it had at last fetch; main is your local work; upstream/main (if you have an upstream) is the original project. Fetch updates the snapshots without touching your work; merge or rebase integrates work into a snapshot or vice versa; push uploads your work to a server. Confusion almost always comes from forgetting the snapshot exists.

Code

Inspect and configure remotes·bash
# What remotes does this repo know about?
git remote -v

# Add a second remote (typical for forks):
git remote add upstream https://github.com/original/repo.git

# Rename, remove, change URL:
git remote rename origin github
git remote remove old-remote
git remote set-url origin git@github.com:user/repo.git

# Show every ref including remote-tracking ones:
git branch -a
git for-each-ref refs/remotes/
Compare local against the remote-tracking shadow·bash
# Update remote-tracking refs without touching working tree:
git fetch origin

# What does origin have that I do not?
git log main..origin/main --oneline

# What do I have that origin does not?
git log origin/main..main --oneline

# Symmetric: divergence on both sides
git log --left-right --oneline main...origin/main

External links

Exercise

On any cloned repo, run git remote -v, git branch -a, and git for-each-ref refs/remotes/. Now run git fetch origin followed by git log main..origin/main and git log origin/main..main. Predict each output before viewing it; verify. Note in writing what each command revealed about local-vs-remote divergence.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.