Lesson 18 of 29 intermediate 6 min read

Before this:Remotes: clone, fetch, pull & push

Forking & the fork workflow

Key takeaways A fork is your own server-side copy of someone else’s repository, made on GitHub. You fork when you can’t push to the original — typically to contribute to open source. The standard flow is fork → clone your fork → add an upstream remote → branch → push to your fork → open a pull request. Because your fork doesn’t update itself, you keep it current by fetching upstream and merging or rebasing upstream/main, then pushing. GitHub’s Sync fork button does the same from the web.

You can now push and pull against a repo you own. But what about contributing to a project you don’t own — say a popular open-source tool? You can’t push to it directly. Forking is the answer, and it’s the backbone of how open source collaboration works on GitHub.

What a fork is

A fork is a complete copy of a repository placed under your account on GitHub’s servers. You create one by clicking Fork at the top of any repository’s page. GitHub copies the project to github.com/<you>/<repo>, and GitHub remembers the link back to the original (the upstream).

The key point: you have full write access to your fork, even though you have none on the original. That’s what makes contribution possible — you make changes in your copy, then propose them back to the original through a pull request.

Fork vs clone vs branch — when to use each

These three are easy to muddle. Here’s the clean separation:

Action Where it lives Use when
Branch Inside one repo You have write access and want a new line of work
Clone Your local machine You want a local copy of any repo to work in
Fork Your GitHub account You don’t have write access and want to contribute

In your own projects and your team’s, you just branch — no fork needed. You fork specifically when the original repo isn’t yours to push to. And you almost always clone afterward, because you still need a local copy to actually edit.

The standard open-source flow

Here’s the full, time-tested sequence for contributing to a project you don’t own.

1. Fork the project on GitHub (the Fork button). You now have github.com/you/project.

2. Clone your fork to your machine. Cloning sets up origin pointing at your fork:

$ git clone git@github.com:you/project.git
$ cd project

3. Add the original as upstream so you can pull in its updates later:

$ git remote add upstream git@github.com:original-owner/project.git
$ git remote -v
origin    git@github.com:you/project.git (fetch)
origin    git@github.com:you/project.git (push)
upstream  git@github.com:original-owner/project.git (fetch)
upstream  git@github.com:original-owner/project.git (push)

4. Create a branch for your change (never work directly on main):

$ git switch -c fix/typo-in-readme

5. Make your changes, commit, and push to your fork:

$ git commit -am "Fix typo in installation instructions"
$ git push -u origin fix/typo-in-readme

6. Open a pull request from your branch on your fork back to the original project’s main. That’s the next lesson.

  upstream (original)  ◄── pull request ──  origin (your fork)  ◄── push ──  your laptop

Keeping a fork in sync

Here’s the catch with forks: they don’t update themselves. While you work, the original project keeps moving, and your fork’s main slowly falls behind. Before starting new work, refresh it.

First, fetch the latest from upstream:

$ git fetch upstream
remote: Enumerating objects: 47, done.
From github.com:original-owner/project
   3a1f9c2..8b4d6e0  main       -> upstream/main

Switch to your local main and bring in those commits. You can merge:

$ git switch main
$ git merge upstream/main
Updating 3a1f9c2..8b4d6e0
Fast-forward
 src/app.js | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

or rebase for a straight-line history (see rebasing):

$ git rebase upstream/main
Successfully rebased and updated refs/heads/main.

Finally, push the updated main to your fork so origin matches too:

$ git push origin main

Now your fork is current, and new feature branches start from up-to-date code.

The Sync fork button

If you’d rather not touch the command line, GitHub offers a shortcut. On your fork’s page, when it’s behind the original, you’ll see a Sync fork notice with an Update branch button. Clicking it brings your fork’s main up to date with upstream directly on the server.

It’s convenient for keeping the fork current, but remember it only updates the copy on GitHub — you’ll still need to git pull afterward to refresh your local clone. For anything involving conflicts, the command-line flow above gives you more control. (Unsure what “merge” or “rebase” mean here? The glossary has short definitions.)

Quick check: you want to contribute a bug fix to a popular project you don't own. What do you do first?

Recap

  • A fork is your own server-side copy of a repo, made on GitHub when you can’t push to the original.
  • Branch when you have write access; fork when you don’t; clone to get a local copy either way.
  • The flow: fork → clone → add upstream → branch → push to your fork → open a PR.
  • Forks don’t auto-update — git fetch upstream, merge or rebase upstream/main, then push.
  • The Sync fork button updates the fork on GitHub; you still git pull to refresh locally.

Next up: proposing your changes back with pull requests & code review.

Frequently asked questions

What is the difference between forking and cloning?

A fork is a copy of a repository on GitHub’s servers under your own account, created through the GitHub website. A clone is a copy on your local machine, created with git clone. In the standard open-source flow you fork first (server-side copy you can push to) and then clone your fork (local copy to work in). Cloning alone gives you a local copy but no place on the server you’re allowed to push to if you don’t own the original.

When should I fork instead of just creating a branch?

Create a branch when you have write access to the repository — that’s the normal flow for your own projects and teams. Fork when you do NOT have write access, typically when contributing to someone else’s open-source project. The fork gives you a copy you can push to freely, and you then propose your changes back via a pull request.

What is the upstream remote?

When you fork and clone, your fork becomes the origin remote. upstream is the conventional name you give to a second remote pointing at the ORIGINAL repository you forked from. You add it with git remote add upstream so you can fetch the project's latest changes and keep your fork in sync, since origin (your fork) does not update on its own.

How do I keep my fork up to date?

Your fork does not automatically track the original. Add the original as an upstream remote, run git fetch upstream to download its latest commits, merge or rebase upstream/main into your local main, and push the result to your fork. GitHub also offers a Sync fork button on the fork’s page that does the equivalent without the command line.