Lesson 50 of 6815 min read

Upstream vs Origin: Forking Vocabulary Explained

Understand the fork-based contribution model and the vocabulary — origin and upstream — used to manage the two remotes it typically involves.

Author: CodersNexus

Upstream vs Origin: Forking Vocabulary Explained

Contributing to a project you don't have direct write access to — the vast majority of open-source projects, for instance — follows a specific model built around GitHub's 'Fork' feature. This workflow introduces its own vocabulary, most importantly the distinction between your `origin` (your own personal copy) and an `upstream` remote (the original project you're contributing to), and understanding this distinction is essential for anyone looking to contribute to open source.

Learning Objectives

  • Explain what a GitHub 'fork' is and why it's used for external contributions.
  • Distinguish between the origin remote (your fork) and the upstream remote (the original repository).
  • Add an upstream remote to a locally cloned fork.
  • Understand how to keep a fork synchronized with its upstream source over time.

Key Terms to Know Before Learning Upstream vs Origin

  • Fork: A personal, independent copy of someone else's repository, created on GitHub under your own account, that you have full write access to.
  • origin (in a fork workflow): The conventional name for the remote pointing to YOUR OWN fork — the repository you actually cloned and can push to directly.
  • upstream: The conventional name for a second remote, added manually, pointing to the ORIGINAL repository that was forked — used to fetch and stay in sync with its ongoing changes.
  • Fork-and-pull-request workflow: The standard contribution model on GitHub, where a contributor forks a repository, makes changes on their fork, and opens a pull request proposing those changes be merged into the original repository.

How the Fork-Based Upstream/Origin Workflow Actually Works

Most open-source repositories don't grant direct write access to anyone who wants to contribute — that would be an obvious security and quality-control risk. Instead, GitHub (and similar platforms) support a **fork-and-pull-request workflow**. Clicking 'Fork' on someone else's repository creates a complete, independent copy of it under your own GitHub account — you now own this copy entirely and have full push access to it, even though you have no direct access to the original.

When you clone *your fork* to your local machine, Git automatically sets up `origin` to point at your fork, exactly as with any normal clone:

```
git clone https://github.com/your-username/some-project.git
# origin now points to YOUR fork
```

This is where the second important remote comes in. To keep your fork updated with changes happening on the *original* repository (which other people are actively contributing to, independent of your fork), you manually add a second remote, conventionally named `upstream`, pointing at the original project:

```
git remote add upstream https://github.com/original-owner/some-project.git
```

After this setup, your local repository has **two remotes with distinct purposes**:

- **`origin`** — your own fork, which you have full push access to. This is where you push your own feature branches and commits.
- **`upstream`** — the original repository, which you typically only *fetch* from (to stay in sync with its ongoing changes) but never push to directly, since you don't have write access to it.

A typical contribution workflow looks like this: fetch from `upstream` to get the latest changes from the original project, merge (or rebase) those changes into your local main branch to stay current, create a new feature branch for your contribution, make your changes, push that branch to your own `origin` (your fork), and then open a **pull request** on GitHub proposing that your changes (from your fork's branch) be merged into the original repository's branch. The project's maintainers review your pull request and, if satisfied, merge it into the original project — at which point your contribution becomes part of the upstream project's actual history.

This `origin`/`upstream` naming is, once again, purely a strong convention (as with `origin` itself, from earlier in this module) rather than a strict technical requirement — but it's followed so consistently across the open-source world that deviating from it in your own fork setup would likely just confuse anyone else looking at your remote configuration.

Origin vs Upstream in a Forked Repository: Visual Walkthrough

Draw three boxes: 'Original Repository (owned by maintainer)' on the left, 'Your Fork (owned by you, on GitHub)' in the middle, 'Your Local Clone' on the right. Draw an arrow from 'Original Repository' to 'Your Fork' labeled 'GitHub Fork button (one-time copy)'. Draw a bidirectional arrow between 'Your Fork' and 'Your Local Clone' labeled 'origin (push/pull — you have full access)'. Draw a one-directional arrow from 'Original Repository' to 'Your Local Clone' labeled 'upstream (fetch only — you have no push access)'. Add a final arrow from 'Your Fork' back to 'Original Repository' labeled 'Pull Request (proposing your changes be merged in)'.

Origin vs Upstream: Key Differences

Aspectoriginupstream
Points toYour own forkThe original repository you forked from
Push access?Yes — full write accessNo — typically fetch-only
Typical usePush your feature branches and commitsFetch/merge to stay in sync with the original project's changes
Set up automatically by clone?Yes, when cloning your own forkNo — must be added manually with git remote add upstream

Setting Up Origin and Upstream: Command Syntax and Examples

# 1. Clone YOUR fork (origin is set up automatically)
git clone https://github.com/your-username/some-project.git
cd some-project

# 2. Manually add the ORIGINAL repository as a second remote, conventionally named 'upstream'
git remote add upstream https://github.com/original-owner/some-project.git

# 3. Confirm both remotes are configured
git remote -v
# origin    https://github.com/your-username/some-project.git (fetch)
# origin    https://github.com/your-username/some-project.git (push)
# upstream  https://github.com/original-owner/some-project.git (fetch)
# upstream  https://github.com/original-owner/some-project.git (push)

# 4. Stay in sync with the original project over time
git fetch upstream
git merge upstream/main

# 5. Push your own contribution branch to YOUR fork (origin), then open a pull request on GitHub
git push -u origin feature/my-contribution

Breaking Down the Origin/Upstream Setup Example

Cloning your own fork automatically sets up `origin` pointing at it, exactly like any standard clone. Step 2 manually adds `upstream`, pointing at the original repository you forked from — a step that never happens automatically and must always be done deliberately. `git remote -v` confirms both are now configured, each with its own distinct URL. `git fetch upstream` followed by `git merge upstream/main` shows the routine sync step, keeping your local main branch current with the original project's ongoing changes. Finally, pushing a feature branch to `origin` (your own fork) — not `upstream`, which you generally cannot push to — sets up the branch for opening a pull request back to the original repository on GitHub's website.

How the Fork-Based Workflow Is Used in Real Open-Source Projects

  • The overwhelming majority of contributions to major open-source projects on GitHub — from small documentation fixes to significant new features — follow exactly this fork, branch, push-to-origin, pull-request-to-upstream workflow.
  • GitHub's own web interface includes a 'Sync fork' button that performs roughly the same function as fetching from upstream and merging, for contributors who prefer not to manage the upstream remote manually via the command line.
  • Open-source maintainers commonly document this exact origin/upstream setup step by step in a project's CONTRIBUTING.md file, since it's often unfamiliar to newer contributors coming from more traditional, single-remote workflows.
  • Companies sometimes use this same fork-based model internally, even for private repositories, specifically to enforce that all changes go through a reviewed pull request rather than being pushed directly to a shared main repository.

Upstream vs Origin Interview Questions and Answers

Q1. What is a GitHub fork, and why is it used?

A fork is a personal, independent copy of someone else's repository, created under your own GitHub account with full write access. It's used to contribute to projects you don't have direct write access to, since you can freely make changes on your own fork and then propose merging them back via a pull request.

Q2. What is the difference between the origin and upstream remotes in a typical fork-based workflow?

origin conventionally points to your own fork, which you have full push access to and use for pushing your own feature branches. upstream conventionally points to the original repository you forked from, which you typically only fetch from to stay in sync with its ongoing changes, since you don't have direct push access to it.

Q3. How would you keep your fork up to date with the original repository's ongoing changes?

Add the original repository as a remote named upstream (git remote add upstream <url>), then periodically run git fetch upstream followed by a merge (or rebase) of upstream's main branch into your own local main branch, keeping your fork's history current before starting new contributions.

Upstream vs Origin Quiz: Test Your Understanding

1. In a typical fork-based contribution workflow, what does 'origin' conventionally point to?

  1. The original repository you forked from
  2. Your own personal fork of the repository
  3. A backup server
  4. The GitHub company's main servers

Answer: B. Your own personal fork of the repository

Explanation: When you clone your own fork, Git automatically sets up 'origin' to point at that fork, which you have full push access to.

2. What does 'upstream' conventionally point to in this workflow?

  1. Your own fork
  2. The original repository that was forked
  3. A remote CI/CD server
  4. A deleted branch

Answer: B. The original repository that was forked

Explanation: 'upstream' is the conventional name given to a manually added remote pointing at the original repository, used to fetch and stay in sync with its ongoing changes.

3. In a standard fork-based workflow, where do you typically push your own new feature branches?

  1. To upstream
  2. To origin (your own fork)
  3. Directly to the original repository's main branch
  4. Nowhere — forks cannot be pushed to

Answer: B. To origin (your own fork)

Explanation: You push your own contributions to origin (your fork), since you have full write access there, and then open a pull request proposing those changes be merged into the original (upstream) repository.

Common Mistakes With Upstream and Origin Remotes

  • Attempting to push directly to upstream, not realizing you typically don't have write access to the original repository in a fork-based workflow.
  • Forgetting to add the upstream remote at all, making it difficult to keep a fork in sync with the original project's ongoing changes over time.
  • Confusing origin and upstream's roles, accidentally fetching from or merging the wrong remote.
  • Letting a fork go stale for a long time without syncing from upstream, leading to a large, more conflict-prone divergence once a contribution is finally attempted.

Upstream vs Origin: Exam-Ready Quick Notes

  • Fork: a personal, independent copy of someone else's repository, created under your own GitHub account with full write access.
  • origin: conventionally your own fork (full push access). upstream: conventionally the original repository (typically fetch-only).
  • upstream must be added manually with git remote add upstream <url> — it is never set up automatically by cloning your fork.
  • Standard workflow: fetch/merge from upstream to stay current, push feature branches to origin, open a pull request to upstream.

Upstream vs Origin: Key Takeaways

  • Forking creates a personal, fully writable copy of a repository you don't have direct access to, forming the basis of most open-source contribution.
  • origin and upstream are simply strong conventions for naming the two remotes involved — your own fork, and the original project, respectively.
  • Regularly syncing from upstream keeps a fork current and minimizes painful divergence before eventually proposing a contribution via pull request.

Frequently Asked Questions About Upstream vs Origin

Q1. What is a fork on GitHub?

It's a personal, independent copy of someone else's repository, created under your own GitHub account, giving you full write access to make changes freely, even though you don't have direct access to the original repository.

Q2. What is the difference between origin and upstream?

origin conventionally refers to your own fork, which you can push to directly. upstream conventionally refers to the original repository you forked from, which you typically only fetch from to stay in sync, since you usually don't have push access to it.

Q3. How do I add the upstream remote to my locally cloned fork?

Run git remote add upstream <original-repository-url>, using the URL of the original repository you forked from. This is a manual step that doesn't happen automatically when you clone your own fork.

Q4. How do I keep my fork up to date with the original project?

Periodically run git fetch upstream to get the latest changes from the original repository, followed by merging (or rebasing) upstream's main branch into your own local main branch to stay current.

Q5. Can I push directly to the upstream remote?

Generally, no. In a typical fork-based workflow, you don't have write access to the original repository, so contributions are made by pushing to your own fork (origin) and then proposing the changes via a pull request to the upstream repository.

Summary

Contributing to a project you don't have direct write access to typically follows GitHub's fork-and-pull-request workflow: forking creates a personal, independent copy of the repository under your own account, with full write access. Cloning your own fork automatically sets up `origin` pointing at it. A second remote, conventionally named `upstream`, is added manually to point at the original repository, used to fetch and stay in sync with its ongoing changes — since you typically cannot push directly to it. The standard contribution cycle involves syncing from `upstream`, creating a feature branch, pushing it to your own `origin`, and opening a pull request proposing your changes be merged into the original, upstream repository. This `origin`/`upstream` vocabulary is a strong, near-universal convention across the open-source world, not a strict technical requirement.

Frequently Asked Questions

It's a personal, independent copy of someone else's repository, created under your own GitHub account, giving you full write access to make changes freely, even though you don't have direct access to the original repository.

origin conventionally refers to your own fork, which you can push to directly. upstream conventionally refers to the original repository you forked from, which you typically only fetch from to stay in sync, since you usually don't have push access to it.

Run git remote add upstream <original-repository-url>, using the URL of the original repository you forked from. This is a manual step that doesn't happen automatically when you clone your own fork.

Periodically run git fetch upstream to get the latest changes from the original repository, followed by merging (or rebasing) upstream's main branch into your own local main branch to stay current.

Generally, no. In a typical fork-based workflow, you don't have write access to the original repository, so contributions are made by pushing to your own fork (origin) and then proposing the changes via a pull request to the upstream repository.