Skip to content

Forks and Open-Source Contributions

When you have write permission in a team repository, you can create and push a feature branch there. In many open-source projects you have no permission to push to the original repository. A fork gives you your own hosted copy under your account so you can publish work and propose it back.

Action Where it happens Result
Fork Hosting platform A separate repository under another account, connected to the original as a fork
Clone Your computer A local Git repository copied from a hosted repository
Branch Within a repository Another movable name for a line of commits

Forking does not create a local folder. Cloning does. A branch does not create a separate GitHub repository. GitHub fork relationships are platform metadata; ordinary Git itself does not have a git fork command.

Some private repositories forbid forking, and organization policies may restrict where a fork can be created. A fork is not a permission bypass: you can push to your copy, not automatically to the original.

Suppose the original project is acme-learning/order-api and your account is YOU:

  1. Use GitHub’s Fork action to create YOU/order-api.
  2. Clone your fork. The new origin points to your repository.
  3. Add the original project as upstream so you can fetch its new commits.
  4. Create a task branch, commit, test, and push it to your fork.
  5. Open a PR from your fork’s task branch into the original project’s intended base branch.
Terminal window
git clone https://github.com/YOU/order-api.git
cd order-api
git remote add upstream https://github.com/acme-learning/order-api.git
git remote -v

Expected relationships:

Your computer
├── origin → YOU/order-api (your fork: you can push)
└── upstream → acme-learning/order-api (original: normally fetch)

These are conventional remote names, not reserved Git keywords. A project might name them differently.

Update your local base from the original before starting new work:

Terminal window
git fetch upstream
git switch main
git merge --ff-only upstream/main
git switch -c fix/payment-validation

Make and test the change:

Terminal window
git add src/PaymentService.cs tests/PaymentServiceTests.cs
git commit -m "fix: reject invalid payment currency"
dotnet test
git push -u origin fix/payment-validation

On GitHub, open a PR whose head is YOU:fix/payment-validation and whose base is the appropriate branch of acme-learning/order-api. The maintainers may review, request changes, or close the PR. Having a fork does not guarantee acceptance.

The original project’s main keeps moving. Your hosted fork and local clone do not update themselves automatically. A straightforward path, if your local main has no independent commits:

Terminal window
git fetch upstream
git switch main
git merge --ff-only upstream/main
dotnet test
git push origin main

The fetch updates your local knowledge of the original. The merge advances local main. The push updates your hosted fork. You may instead use GitHub’s Sync fork interface to update the hosted fork, then fetch or pull locally. Either route requires deliberate coordination between the three repositories.

If the fast-forward fails, your local main has diverged. Inspect the graph and decide how to integrate; do not immediately use a hard reset or force push. Keep original-project work and personal feature work on separate branches whenever possible.

Sometimes maintainers ask contributors to update their PR branch with the latest base. That is distinct from merely syncing your fork’s main and may involve a merge or a carefully scoped rebase.

Situation Usual path
You have write permission in the shared repository Create a feature branch there, push it, open a PR
You lack write permission to the original Fork, clone your fork, push a branch there, open a cross-repository PR
You only want to read or run a public project Clone; no fork is required

Even collaborators may choose forks for isolation or policy reasons. The table is a common pattern, not a hard Git rule.

  • Saying fork and clone are the same operation.
  • Assuming origin always means the original open-source repository.
  • Pushing to upstream when you have no permission.
  • Opening a PR against your own fork when you meant to contribute to the original.
  • Assuming the fork automatically follows original-project updates.
  • Force-resetting a diverged fork without checking personal commits.
  • Treating a public fork as private; its visibility and permissions need review.

A fork is a separate hosted repository, a clone is a local repository, and a branch is a line of work within one repository. In a common open-source setup, origin names your fork and upstream names the original. Fetch upstream updates your local knowledge; merge or rebase updates a local branch; push origin updates your hosted fork. A PR proposes the final change to the original maintainers.

  1. Which action creates a repository under your GitHub account?
  2. After cloning your fork, where does origin normally point?
  3. What does git fetch upstream change locally, and what does it not update on GitHub?
  4. Which branch and repository should a contribution PR target?
  5. Why can git merge --ff-only upstream/main refuse during fork sync?