Forking Repositories
A fork is a personal, server-side copy of someone else’s repository, living under your own GitHub (or GitLab) account. Forking is how you contribute to projects where you don’t have push access: you fork the project, push your changes to your fork, and then open a Pull Request asking the original maintainers to pull your work back into theirs.
Fork vs clone vs branch
These three operations get confused constantly. Here’s the cheat sheet:
Operation | Where it lives | Who can push to it | Typical use |
|---|---|---|---|
Fork | Server-side copy under YOUR account | You | Contributing to projects you don’t own |
Clone | Full copy on your local machine | You locally | Working on any repo you have access to |
Branch | A pointer inside one repo | Anyone with push access | Isolating a feature within a repo |
Why forks exist
You want to contribute to an open-source project but you’re not a maintainer.
You want to experiment with a project without affecting the original.
You want to maintain a long-running custom variant (a soft fork).
You want a personal sandbox version of a public repo to play with.
The standard fork workflow
Almost every open-source contribution follows the same five steps. Memorise this loop — it’s the entire game.
Fork-based contribution flow
upstream (original) origin (your fork) local (your laptop)
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ acme-co/widget │ ◄──── │ you/widget │ ◄──── │ widget/ │
└────────▲─────────┘ └────────▲─────────┘ └────────┬─────────┘
│ │ │
│ 5. open Pull Request │ 3. git push origin │ 1. clone
└──────────────────────────┴──────────────────────────┘ 2. branch + commit
4. push to originStep 1 — Fork on GitHub
Click the Fork button at the top-right of any repo. GitHub creates github.com/your-username/repo-name instantly. You can rename it and pick which branches to copy.
Step 2 — Clone your fork
Clone YOUR fork, not the original
git clone git@github.com:your-username/widget.git cd widget # Add the original as 'upstream' so you can pull updates from it git remote add upstream git@github.com:acme-co/widget.git # Verify git remote -v # origin git@github.com:your-username/widget.git (fetch) # origin git@github.com:your-username/widget.git (push) # upstream git@github.com:acme-co/widget.git (fetch) # upstream git@github.com:acme-co/widget.git (push)
Step 3 — Branch, commit, push
Normal feature-branch workflow
git switch -c fix-typo-in-readme # ... edit files ... git commit -am "Fix typo in README" git push -u origin fix-typo-in-readme
Step 4 — Open a Pull Request
After pushing, GitHub shows a yellow banner with a Compare & pull request button. The PR’s base is the upstream repo’s default branch; the compare is your fork’s feature branch. See the dedicated Creating a Pull Request page for the full walkthrough.
Syncing your fork with upstream
Your fork doesn’t auto-update. While you work, the original repo keeps moving. Pull those changes in before starting new branches so you don’t branch off stale code.
Three-step upstream sync
# 1. Grab the latest commits from the original repo git fetch upstream # 2. Move your local main to match upstream/main git switch main git merge upstream/main # or: git rebase upstream/main # 3. Push the updated main back to your fork git push origin main
Fetch upstream button on your fork’s homepage. Click it to sync `main` without leaving the browser — Git work for non-Git people.Keeping a feature branch in sync
Rebase your branch onto fresh upstream/main
git fetch upstream git switch my-feature git rebase upstream/main git push --force-with-lease origin my-feature
Deleting a fork
Go to your fork’s Settings → General.
Scroll to the Danger Zone at the bottom.
Click Delete this repository and type the repo name to confirm.
Open PRs from the fork are automatically closed when the fork is deleted.
Limitations and quirks
One fork per user per repo. Need a second copy? Use a different account or use the duplicate trick (clone, push to a new repo).
Forks of private repos stay private and inherit the parent’s access rules.
Issues and wikis don’t fork by default — only the code and branches.
Forks share storage with the parent on GitHub, so they’re cheap and instant even for huge repos.
You can’t fork a repo you already own — GitHub won’t let you fork acme-co/widget if you ARE acme-co.
Detached forks — GitHub can sever the parent link via support if you really need an independent project.
Common errors
"This branch is N commits behind upstream/main" — run a sync; it’s harmless but signals you should rebase before opening a PR.
"Push rejected, non-fast-forward" on your fork — usually means you rebased; use
--force-with-lease.Maintainer can’t push to your PR branch — re-open the PR with "Allow edits by maintainers" ticked.