Forks & Keeping in Sync

Fork Workflow (open source)

A fork is not the same thing as a clone, even though the two are easy to confuse at first. Cloning copies a repo onto your local machine. Forking copies a repo on the hosting platform itself (GitHub/GitLab), creating a completely separate repository under your own account that you fully own and control - which you then clone locally like any other repo. You fork when you don't have write access to the original repo (for example, contributing to an open-source project) but still need somewhere of your own to push branches to.

upstream (original)  ──fork──▶  origin (your fork)  ──clone──▶  your laptop
        ▲                                                          │
        └────────────────── Pull Request ◀───────────────────────┘

To keep contributing over time, you add the original repository as a second remote, conventionally named upstream, alongside your fork (which is your origin), and periodically pull the original project's new commits into your own fork:

$ git remote add upstream https://github.com/original/project.git
$ git fetch upstream
$ git switch main && git merge upstream/main   # or: git rebase upstream/main
$ git push origin main                          # update your fork on GitHub too
Tip: origin = your fork, the one you have write access to and push branches/PRs from. upstream = the original project, which you only ever read from (fetch/merge), never push to directly. Keep your fork's main in sync with upstream/main before starting each new piece of work, so your branch starts from the latest code and you avoid painful, avoidable conflicts later.
Warning: A common mixup: after forking, people sometimes keep working directly against upstream out of habit (e.g. accidentally cloning the original URL instead of their fork's URL) and then can't understand why git push is rejected - it's rejected because they don't have write access to upstream. Double-check git remote -v shows origin pointing at your fork before you start pushing.