DEV Community

Cover image for From Fork to Merge: What It Really Takes to Land Your First Open-Source Contribution
Sumit Mishra
Sumit Mishra

Posted on

From Fork to Merge: What It Really Takes to Land Your First Open-Source Contribution

proof of work

You’ve probably watched a video on GitHub explaining how to create a Pull Request.

Fork the repository.
Create a branch.
Make some changes.
Commit.
Push.
Open a PR.

Done, right?

Not quite.

Creating a Pull Request is only one part of contributing to open source. The harder part is understanding what to do before the PR, what maintainers expect inside it, and what happens after you submit it.

Your first contribution isn't simply:

Code → PR → Merge

It's more like:

Find a project → Understand the community → Choose an issue → Fork → Branch → Code → Commit → Push → PR → CI/CD → Review → Changes → Approval → Merge

And every step exists for a reason.

If you're wondering why your perfectly working PR isn't getting merged, you might be missing something that has nothing to do with your code.

This guide will walk through the complete journey of making your first open-source contribution, including forks, commits, branches, PRs, assignees, community guidelines, CI/CD, code reviews, and—most importantly—why each of these things exists.


Before You Write a Single Line of Code

The first mistake many beginners make is opening an issue, choosing a task, and immediately starting to code.

Don't.

First, understand the project.

Look for:

  • README.md
  • CONTRIBUTING.md
  • CODE_OF_CONDUCT.md
  • Issue templates
  • Pull Request templates
  • Development/setup instructions
  • Existing issues
  • Open Pull Requests

Why?

Because every open-source project has its own culture and workflow.

One project might say:

"Comment on the issue before working on it."

Another might require:

"Wait until a maintainer assigns the issue."

Another might welcome direct PRs for small documentation fixes.

If you ignore these instructions, you can end up solving the wrong problem or submitting a PR that doesn't follow the project's process.

The fastest way to contribute isn't always to start coding faster. It's to understand the rules before coding.


Step 1: Find Something to Contribute

Your first contribution doesn't have to be a huge feature.

Look for:

  • Bug fixes
  • Documentation improvements
  • Tests
  • Typo fixes
  • Small enhancements
  • Examples
  • Accessibility improvements
  • Developer tooling

You may also find labels such as:

good first issue
beginner
help wanted
documentation
bug
enhancement
Enter fullscreen mode Exit fullscreen mode

These labels can help you discover tasks, but don't assume that every good first issue is automatically easy. Read the issue carefully and check its current status.

Why start small?

Your first contribution is also an opportunity to learn the project's workflow.

A small change lets you learn:

Git
+
GitHub
+
Project structure
+
Testing
+
Code review
+
CI/CD
Enter fullscreen mode Exit fullscreen mode

without simultaneously dealing with a massive feature.


Step 2: Understand the Issue and Assignee

Suppose you find:

Issue #123

Fix incorrect validation when username contains spaces.
Enter fullscreen mode Exit fullscreen mode

Before starting, check whether someone is already assigned.

You might see:

Assignees:
@developer123
Enter fullscreen mode Exit fullscreen mode

An assignee generally indicates who is working on the issue.

Why does an assignee matter?

Imagine ten contributors see the same issue and all start implementing it.

You could end up with:

10 contributors
10 implementations
1 issue
Enter fullscreen mode Exit fullscreen mode

That's wasted effort.

An assignment can signal:

"Someone is already working on this."

However, assignment policies differ between projects. Some projects don't use assignees at all.

Always follow the repository's contribution guidelines.


Step 3: Fork the Repository

Suppose the original repository is:

github.com/project-owner/project
Enter fullscreen mode Exit fullscreen mode

If you don't have permission to push directly to it, you can create a fork:

github.com/your-name/project
Enter fullscreen mode Exit fullscreen mode

Think of it as your own remote copy of the project.

Original Repository
        │
        │ fork
        ↓
Your Repository
Enter fullscreen mode Exit fullscreen mode

Why?

The original repository belongs to the project maintainers.

Your fork gives you a place where you can safely push your changes without requiring write access to the original repository.


Step 4: Clone Your Fork

A fork exists remotely. Now bring it to your computer:

git clone https://github.com/YOUR_USERNAME/project.git
cd project
Enter fullscreen mode Exit fullscreen mode

You now have:

GitHub
   ↓
Your fork
   ↓
Your computer
Enter fullscreen mode Exit fullscreen mode

Why?

Because you need a local environment where you can:

  • Edit files
  • Run the application
  • Run tests
  • Run linters
  • Debug
  • Build the project

Step 5: Create a Branch

Don't immediately start working on main.

Create a branch:

git switch -c fix-username-validation
Enter fullscreen mode Exit fullscreen mode

Now:

main
 │
 └── fix-username-validation
Enter fullscreen mode Exit fullscreen mode

Your changes go into the new branch.

Why?

Branches keep different pieces of work separate.

Imagine you're working on:

Bug fix
Documentation
New feature
Enter fullscreen mode Exit fullscreen mode

If everything happens directly on main, those changes can become mixed together.

A focused branch makes your contribution easier to understand, test, review, and eventually merge.


Step 6: Make the Change

Now you actually write code.

Suppose the bug is caused by whitespace in usernames.

You modify the appropriate validation logic and add a test.

But here's an important rule:

Don't fix five unrelated things in the same PR.

Avoid turning:

Fix username validation
Enter fullscreen mode Exit fullscreen mode

into:

Fix username validation
+ redesign UI
+ upgrade dependencies
+ rename 40 variables
+ rewrite documentation
Enter fullscreen mode Exit fullscreen mode

Why?

A Pull Request should ideally have a clear purpose.

The easier it is to understand what your PR is trying to accomplish, the easier it is for maintainers to review it.


Step 7: Test Before Creating the PR

This is where many beginners make a mistake.

They think:

"I'll open the PR and let GitHub tell me whether it works."

Don't use CI as your personal debugger.

Run the project's checks locally first.

For example:

pytest
Enter fullscreen mode Exit fullscreen mode

or:

npm test
Enter fullscreen mode Exit fullscreen mode

or whatever the project's CONTRIBUTING.md specifies.

You may also need:

npm run lint
Enter fullscreen mode Exit fullscreen mode

or:

npm run build
Enter fullscreen mode Exit fullscreen mode

Why?

CI consumes project resources and, more importantly, maintainers' attention.

Finding a simple formatting or test failure locally is much easier than discovering it after opening a PR.


Step 8: Commit Your Changes

Once your changes work:

git status
git add .
git commit -m "Fix username validation"
Enter fullscreen mode Exit fullscreen mode

A commit records a snapshot of your work.

Why do commits exist?

Imagine trying to understand a project where the entire history is:

"updated stuff"
"more changes"
"final"
"final 2"
"done"
Enter fullscreen mode Exit fullscreen mode

Not useful.

Good commits provide meaningful history.

For example:

Fix username validation
Add regression test for whitespace
Update validation documentation
Enter fullscreen mode Exit fullscreen mode

The exact commit style depends on the project.

Some projects prefer one clean commit. Others are happy with multiple logical commits.

Check the project's contribution rules instead of assuming there is one universal Git style.


Step 9: Push Your Branch

Your commit currently exists on your computer.

Push it to your fork:

git push origin fix-username-validation
Enter fullscreen mode Exit fullscreen mode

Now GitHub can see your branch.

Your computer
      │
      │ push
      ↓
Your fork
      │
      │ Pull Request
      ↓
Original repository
Enter fullscreen mode Exit fullscreen mode

Step 10: Create the Pull Request

Now we finally reach the part you've probably seen in those GitHub tutorials.

Open a Pull Request from:

your-name:fix-username-validation
Enter fullscreen mode Exit fullscreen mode

to:

project-owner:main
Enter fullscreen mode Exit fullscreen mode

Your PR should explain:

What changed?

Fixed username validation for leading and trailing whitespace.
Enter fullscreen mode Exit fullscreen mode

Why?

Users entering accidental whitespace were receiving
an invalid validation response.
Enter fullscreen mode Exit fullscreen mode

How was it tested?

Added a regression test and ran the existing test suite.
Enter fullscreen mode Exit fullscreen mode

Step 11: Write a Useful PR Title

Don't write:

Fix
Enter fullscreen mode Exit fullscreen mode

or:

Changes
Enter fullscreen mode Exit fullscreen mode

Instead:

Fix username validation for whitespace
Enter fullscreen mode Exit fullscreen mode

If the project uses Conventional Commits or another naming convention, follow it:

fix(auth): handle whitespace in usernames
Enter fullscreen mode Exit fullscreen mode

Why does the title matter?

Maintainers may have dozens of open PRs.

A useful title immediately tells them what the PR is about.

It also makes the project's history easier to understand later.


Step 12: CI/CD Takes Over

After opening your PR, you might see:

Build          ✓
Lint           ✓
Unit tests     ✓
Integration    ✓
Enter fullscreen mode Exit fullscreen mode

Or:

Build          ✓
Lint           ✗
Enter fullscreen mode Exit fullscreen mode

This is CI — Continuous Integration.

CI automatically runs checks against your changes.

A simplified pipeline looks like:

Push
  ↓
Build
  ↓
Lint
  ↓
Test
  ↓
Security checks
  ↓
Report result
Enter fullscreen mode Exit fullscreen mode

Why?

Humans shouldn't have to manually perform the same checks every time someone submits a change.

Automation can catch:

  • Broken builds
  • Failing tests
  • Formatting problems
  • Lint errors
  • Some security problems
  • Compatibility issues

But remember:

Passing CI doesn't automatically mean a PR should be merged.

CI checks what it has been configured to check.


Step 13: Code Review

Now a maintainer reviews your PR.

They might say:

"Can you add a test for this case?"

or:

"This implementation doesn't match the existing pattern. Could you use the helper function instead?"

or:

"Can you update the documentation?"

This is normal.

Why?

Code review isn't just about finding syntax errors.

A maintainer also considers:

  • Does the change solve the actual problem?
  • Does it fit the project's architecture?
  • Is it maintainable?
  • Are there enough tests?
  • Does it introduce compatibility problems?
  • Is the documentation accurate?

Your code can work perfectly and still need changes before it fits the project.


Step 14: Don't Take Review Personally

This is one of the biggest mindset changes when moving from personal projects to open source.

On your personal project:

"It works, ship it."

In an open-source project:

"It works, but does it fit the project?"

A review comment such as:

Please simplify this function.
Enter fullscreen mode Exit fullscreen mode

is about the proposed change.

Treat technical feedback as part of the contribution process.

If you disagree, explain your reasoning with evidence.

For example:

I used this approach because it avoids an additional database
query. I can change it to the existing helper if consistency
is more important here.
Enter fullscreen mode Exit fullscreen mode

That's a productive technical discussion.


Step 15: Make the Requested Changes

Suppose the maintainer asks for a test.

You add it:

git add .
git commit -m "Add validation regression test"
git push
Enter fullscreen mode Exit fullscreen mode

The existing PR automatically receives the new commit.

You usually don't create another PR for every review comment.

The workflow becomes:

PR
 ↓
Review
 ↓
Changes requested
 ↓
Modify code
 ↓
Commit
 ↓
Push
 ↓
CI runs again
 ↓
Review again
Enter fullscreen mode Exit fullscreen mode

This loop can happen multiple times.


Step 16: Keep an Eye on CI

After pushing changes, CI may run again.

For example:

Tests       ✓
Lint        ✓
Build       ✓
Enter fullscreen mode Exit fullscreen mode

If something fails, read the actual error.

Don't blindly change code until the red check becomes green.

Find out:

What failed?
Why did it fail?
Did my change cause it?
What does the project expect?
Enter fullscreen mode Exit fullscreen mode

Why?

A green CI check is useful only if you understand what it actually verifies.


Step 17: Merge

Once the project requirements are satisfied, the maintainer may merge the PR.

The journey becomes:

Issue
  ↓
Fork
  ↓
Branch
  ↓
Code
  ↓
Commit
  ↓
Push
  ↓
PR
  ↓
CI
  ↓
Review
  ↓
Changes
  ↓
Approval
  ↓
Merge
Enter fullscreen mode Exit fullscreen mode

And that's your first contribution.


The Bigger Picture

The Git commands themselves are not the difficult part.

You can memorize:

git clone
git switch
git add
git commit
git push
Enter fullscreen mode Exit fullscreen mode

in a few minutes.

The real skill is understanding the collaboration system around Git.

Concept What it does Why it exists
Repository Stores project Central place for collaboration
Fork Creates your remote copy Lets you work without direct write access
Clone Downloads repository Gives you a local workspace
Branch Isolates work Prevents unrelated changes from mixing
Commit Records changes Creates useful project history
Push Uploads your branch Makes your work available remotely
Issue Describes a task/problem Coordinates work
Assignee Indicates responsibility Reduces duplicated effort
PR Proposes changes Enables review before integration
CI Automatically checks changes Catches repeatable problems
Code review Human evaluation Checks correctness and project fit
Community guidelines Defines behavior Keeps collaboration productive
Merge Integrates changes Adds approved work to the project

Your First Contribution Checklist

Before opening your first PR:

[ ] Read the README
[ ] Read CONTRIBUTING.md
[ ] Read the Code of Conduct
[ ] Check existing issues
[ ] Check existing PRs
[ ] Confirm the issue isn't already being worked on
[ ] Understand the project's branch conventions
[ ] Fork the repository if required
[ ] Clone your fork
[ ] Create a focused branch
[ ] Make the change
[ ] Add/update tests where appropriate
[ ] Run the project's checks locally
[ ] Create meaningful commit(s)
[ ] Push your branch
[ ] Write a descriptive PR title
[ ] Explain what changed
[ ] Explain why it changed
[ ] Explain how you tested it
[ ] Watch CI
[ ] Respond to review comments
[ ] Fix CI failures
[ ] Wait for approval
[ ] Follow the project's merge process
Enter fullscreen mode Exit fullscreen mode

Final Thought

You probably don't need another tutorial showing you where the "Create Pull Request" button is.

You need to understand what happens before and after that button.

Because creating a PR is easy.

Getting a contribution understood, reviewed, accepted, and merged is the real workflow.

Once you understand the reasoning behind forks, branches, commits, issues, assignees, community guidelines, CI/CD, and code review, open source stops looking like a collection of random GitHub buttons.

It becomes a system:

Understand → Change → Explain → Test → Review → Improve → Merge.

And that's what turns your first Pull Request into your first real open-source contribution.

Top comments (0)