GitContributing to Open Source

Contributing to Open Source with Git

Contributing to open source is one of the best ways to sharpen your Git skills, build a public portfolio, and give back to the tools you use every day. The Git workflow for open-source contribution is slightly different from internal team work — you will not have push access to the original repository, so you work through a fork. This guide walks you through every step, from finding a project to having your pull request merged.

Finding a Project to Contribute To

The best first contribution is to a project you already use. When you hit a bug or a missing feature in a library you depend on, that is your entry point.

Ways to find beginner-friendly issues:

  • github.com/explore — trending repositories with beginner-friendly issues.

  • Search GitHub: label:good-first-issue language:javascript — filter by language and label.

  • Search GitHub: label:"help wanted" is:open — maintainers explicitly asking for help.

  • goodfirstissue.dev — curates beginner-friendly issues across thousands of projects.

  • up-for-grabs.net — another curated list of beginner-friendly issues.

  • Your own node_modules or requirements.txt — every dependency you use is maintained by people who would welcome a fix.

Signal

Good sign

Warning sign

Last commit

Within last 3 months

More than 1 year ago

Issue response time

Maintainers reply within days

Issues ignored for months

PR merge rate

Many merged PRs from external contributors

Only maintainer commits

CONTRIBUTING.md

Detailed guide exists

No contribution guide

Code of Conduct

CoC file present

No CoC

Test coverage

CI runs tests on PRs

No CI, no tests

Fork the Repository

A fork is your personal copy of a repository on GitHub. You have full write access to your fork — you can push branches, experiment, and break things without affecting the original project.

Click the Fork button on the top-right of the repository page on GitHub. GitHub creates github.com/you/project as a copy of github.com/org/project.

Note
You only need one fork per repository, even if you make many contributions over time. A fork stays in sync with the upstream by adding the upstream as a remote (shown below).
Clone Your Fork

Clone your fork (not the original)

Bash
# Clone YOUR fork — you have push access here
git clone git@github.com:you/project.git
cd project

# Confirm the remote is your fork
git remote -v
# origin  git@github.com:you/project.git (fetch)
# origin  git@github.com:you/project.git (push)
Add the Upstream Remote

The "upstream" is the original repository you forked from. You need it to stay in sync with new commits made by the project maintainers.

Add upstream and verify both remotes

Bash
git remote add upstream https://github.com/org/project.git

git remote -v
# origin    git@github.com:you/project.git (fetch)
# origin    git@github.com:you/project.git (push)
# upstream  https://github.com/org/project.git (fetch)
# upstream  https://github.com/org/project.git (push)
Tip
Convention: `origin` is always your fork (you have push access); `upstream` is always the original project (read-only for external contributors). This naming is standard across the open-source community.
Create a Feature Branch

Always branch from a fresh main

Bash
# Make sure your local main is up to date first
git fetch upstream
git checkout main
git merge upstream/main --ff-only
# Fast-forward merged

# Now create your branch
git checkout -b fix/typo-in-readme
# Switched to a new branch 'fix/typo-in-readme'
Warning
Never commit directly to your fork's `main` branch. If you do, syncing with upstream becomes messy because your `main` will have diverged. Always use a dedicated branch per contribution.
Make Changes and Commit

Follow the project's contribution conventions exactly. Read CONTRIBUTING.md before writing a single line of code.

  • Run the project locally and verify it works before making changes.

  • Write the smallest change that addresses the issue — no refactoring unrelated code.

  • Add or update tests if the project has a test suite.

  • Follow the project's code style (run their linter if one is configured).

  • Use the project's commit message format — some use Conventional Commits, others have their own style.

Commit following the project conventions

Bash
git add README.md
git commit -m "docs: fix typo in installation section

'recieve' -> 'receive' in the npm install step.

Fixes #1234"

# For a larger change:
git add src/parser.js src/parser.test.js
git commit -m "fix(parser): handle empty input without throwing

Previously `parse('')` threw a TypeError. Added an early return
for empty or nullish input that returns an empty AST node.

Fixes #789"
Sync with Upstream Before Pushing

Open-source projects move fast. By the time you finish your change, the upstream main may have new commits. Rebase your branch on top of the latest upstream before pushing to keep the history clean and avoid conflicts in the PR.

Fetch upstream and rebase

Bash
git fetch upstream
# From https://github.com/org/project
#  * branch            main -> FETCH_HEAD
#  + abc1234...def5678 main -> upstream/main

git rebase upstream/main
# Successfully rebased and updated refs/heads/fix/typo-in-readme.

# If there are conflicts during rebase:
# 1. Fix the conflict in the affected file
# 2. git add <file>
# 3. git rebase --continue
# (or git rebase --abort to start over)
Push to Your Fork and Open a PR

Push your branch to your fork

Bash
git push origin fix/typo-in-readme
# Enumerating objects: 5, done.
# Counting objects: 100% (5/5), done.
# Writing objects: 100% (3/3), 312 bytes | 312.00 KiB/s, done.
# remote: Create a pull request for 'fix/typo-in-readme':
# remote:   https://github.com/org/project/pull/new/fix/typo-in-readme

GitHub will show a banner: "Compare and pull request". Click it to open the PR creation form. Fill in:

  • Title: concise, imperative mood. Match the project's existing PR titles.

  • Description: what the change does, why it is needed, how to verify it, and a link to the issue it closes (Fixes #1234).

  • Screenshots: for UI changes, include before/after screenshots.

  • Do not request reviews from maintainers manually — they monitor their repositories.

Responding to Review Comments

Maintainers are volunteers. Their review comments are almost always constructive — they want your PR to succeed. When you receive feedback:

  • Reply to each comment, either with the fix or a question if you do not understand.

  • Make the requested changes on the same branch and push new commits — GitHub will automatically update the open PR.

  • Do not force-push unless the maintainer explicitly asks you to squash. Force-pushing mid-review disrupts the reviewer's workflow.

  • Be patient. Maintainers often have day jobs and review in their spare time.

  • If a maintainer asks for a change you disagree with, explain your perspective politely. They have the final say.

Push a follow-up commit addressing review feedback

Bash
# After making the requested change:
git add src/parser.js
git commit -m "fix(parser): use nullish coalescing per review feedback"
git push origin fix/typo-in-readme
# GitHub PR will show the new commit automatically
Squashing Commits if Requested

Some maintainers ask you to squash multiple commits into one before merging, to keep the project history clean.

Squash last N commits into one

Bash
# Count your commits on this branch:
git log upstream/main..HEAD --oneline
# abc1234 fix(parser): use nullish coalescing per review feedback
# def5678 fix(parser): handle empty input without throwing

# Squash both into one:
git rebase -i upstream/main
# In the editor, mark the second commit 'squash' (or 's'):
# pick def5678 fix(parser): handle empty input without throwing
# squash abc1234 fix(parser): use nullish coalescing per review feedback
# Save and close — Git opens the commit message editor for the merged commit.

# Force push is required after a rebase that rewrites history:
git push --force-with-lease origin fix/parser-empty-input
Warning
Only squash or rebase after discussing with the maintainer. Some projects prefer to keep the full commit history in PRs. Using `--force-with-lease` is safer than `--force` — it refuses to push if the remote has new commits you haven't seen.
What Happens After Your PR is Merged
  1. The maintainer merges your PR — congratulations! You are now a contributor to the project.

  2. Your commit appears in the project's history with your name and email.

  3. GitHub shows you as a contributor on the repository's contributors page.

  4. Sync your fork's main to remove the divergence: git fetch upstream && git checkout main && git merge upstream/main && git push origin main.

  5. Delete your feature branch locally and on your fork: git branch -d fix/typo-in-readme && git push origin --delete fix/typo-in-readme.

  6. If there is a next issue you want to tackle, create a new branch from the now-updated main.

Full Command Walkthrough: Fork to Merged PR

Complete open-source contribution flow

Bash
# --- ONE-TIME SETUP ---

# 1. Fork on GitHub (click Fork button on github.com/org/project)

# 2. Clone your fork
git clone git@github.com:you/project.git
cd project

# 3. Add upstream
git remote add upstream https://github.com/org/project.git

# --- PER CONTRIBUTION ---

# 4. Sync your local main with upstream
git fetch upstream
git checkout main
git merge upstream/main --ff-only

# 5. Create a feature branch
git checkout -b fix/issue-789-empty-input

# 6. Make changes
# ... edit files ...
git add src/parser.js src/parser.test.js
git commit -m "fix(parser): handle empty input without throwing

Fixes #789"

# 7. Sync with upstream before pushing
git fetch upstream
git rebase upstream/main

# 8. Push to your fork
git push origin fix/issue-789-empty-input

# 9. Open PR on GitHub (follow the banner or go to /compare)

# 10. Address review comments
git add src/parser.js
git commit -m "fix(parser): handle null case per review"
git push origin fix/issue-789-empty-input

# 11. PR is merged! Clean up.
git checkout main
git fetch upstream
git merge upstream/main --ff-only
git push origin main
git branch -d fix/issue-789-empty-input
git push origin --delete fix/issue-789-empty-input
Tip
Write a "first contribution" blog post or tweet after your PR is merged. It reinforces what you learned and inspires others to contribute. Maintainers love to see these.