Your first pull request: fork, branch, PR, review

Learn how to make your first GitHub pull request step-by-step: fork a repo, create a branch, write clean commits, and navigate code reviews like a pro.

By Asahluma Tyika

What is a Pull Request (and why should you care?)

Opening your first pull request (PR) can feel intimidating. You are taking code you wrote on your private laptop and submitting it for review to another project—sometimes a project run by complete strangers on the other side of the world.

A pull request is simply a formal proposal. You tell the project maintainer: “I took a copy of your project, made a specific improvement or bug fix on my own branch, and now I’d like you to pull these changes into your project.”

PRs are the universal currency of open-source collaboration and modern software engineering teams. They give teams a shared space to:

  • Review code line-by-line before it breaks production.
  • Run automated tests (CI/CD pipelines) to verify your changes.
  • Discuss architectural choices and maintain code quality.

This tutorial is written for beginners who know basic Git commands (git add, git commit) but have never submitted changes to someone else’s GitHub repository. Let’s break down the whole process from fork to merge.


Part 1: The Core Mental Model

Before running commands, it helps to visualize where your code lives at each stage. Many beginners get confused between forking, cloning, and branching.

Here is how the four key concepts fit together:

Concept Where it lives What it actually does
Fork Remote (Your GitHub account) Creates a server-side copy of someone else’s repository under your account.
Clone Local (Your computer) Downloads a repository from GitHub to your hard drive so you can edit files.
Branch Local & Remote An isolated workspace inside a repo where you make changes without touching main.
Pull Request Remote (Original GitHub repo) A request asking the original project owners to merge your branch into theirs.

The Flow of Code

[Original Repo: upstream] 
       │ (Fork via GitHub UI)
       ▼
[Your Fork: origin]
       │ (git clone)
       ▼
[Your Computer: local workspace]
       │ (git checkout -b my-feature)
       │ (make edits + git commit)
       │ (git push origin my-feature)
       ▼
[Your Fork: origin/my-feature]
       │ (Open Pull Request)
       ▼
[Original Repo: merged into main!]

Part 2: Open-Source Etiquette

Writing the code is only half the job. How you present your PR determines whether maintainers merge it with a smile or ignore it for months.

1. Check for Existing Issues

Before writing code, search the repository’s Issues tab. Has someone already reported this bug? Has someone already submitted a fix? If you are planning a large change, open an issue first to ask maintainers if they are open to your approach.

2. Keep Your PR Small and Atomic

Do not fix three bugs, refactor the database layer, and fix five typos in a single PR. A PR should do one thing. Small PRs get reviewed and merged quickly; massive 50-file PRs sit in review queues forever.

3. Write Meaningful Commit Messages

Avoid commit messages like:

  • fixed stuff
  • update
  • asdfghjk

Instead, write concise, imperative messages describing the intent:

  • fix: correct typo in installation instructions
  • feat: add email validation to signup form

Hands-on Example: Your First Pull Request

Let’s walk through an end-to-end example. For this walk-through, assume you want to contribute to an open toy repository named community-board owned by an organization called octo-org.

Step 1: Fork the Repository

  1. Navigate to the project page on GitHub: https://github.com/octo-org/community-board.
  2. In the top-right corner, click the Fork button.
  3. Select your personal account as the destination. GitHub will create a copy at https://github.com/YOUR-USERNAME/community-board.

Step 2: Clone Your Fork to Your Local Machine

Open your terminal and clone your fork (replace YOUR-USERNAME with your actual GitHub username):

git clone https://github.com/YOUR-USERNAME/community-board.git
cd community-board

When you clone your fork, Git automatically sets your fork as a remote named origin. You also want a reference to the original project (conventionally called upstream) so you can pull future updates.

Check your current remotes:

git remote -v

Output:

origin  https://github.com/YOUR-USERNAME/community-board.git (fetch)
origin  https://github.com/YOUR-USERNAME/community-board.git (push)

Now, add the original repository as upstream:

git remote add upstream https://github.com/octo-org/community-board.git

Run git remote -v again to verify:

origin    https://github.com/YOUR-USERNAME/community-board.git (fetch)
origin    https://github.com/YOUR-USERNAME/community-board.git (push)
upstream  https://github.com/octo-org/community-board.git (fetch)
upstream  https://github.com/octo-org/community-board.git (push)

Step 4: Create a Dedicated Feature Branch

Never make your changes directly on main. Always create a new branch with a descriptive name:

git checkout -b add-tyika-profile

The -b flag creates the branch and switches you to it immediately.


Step 5: Make Your Change and Test It

Open the repository in your code editor. Suppose the project has a file named members.md. Add your entry to the list:

# Community Members

- Ada Lovelace (@ada) - London, UK
- Alan Turing (@alan) - Wilmslow, UK
- Asahluma Tyika (@asahluma) - Cape Town, South Africa

Save the file. Check your changes with git status and git diff:

git status

Output:

On branch add-tyika-profile
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
	modified:   members.md

Step 6: Stage, Commit, and Push

Stage the modified file and write a descriptive commit message:

git add members.md
git commit -m "docs: add Asahluma Tyika to community roster"

Push your new branch up to your fork (origin):

git push -u origin add-tyika-profile

The -u flag sets upstream tracking so that future pushes on this branch only require git push.


Step 7: Open the Pull Request on GitHub

  1. Open your browser and go to your fork: https://github.com/YOUR-USERNAME/community-board.
  2. GitHub will automatically detect the recently pushed branch and display a yellow banner: “add-tyika-profile had recent pushes… Compare & pull request”. Click that button.
  3. Verify the branch targets:
    • base repository: octo-org/community-board base: main
    • head repository: YOUR-USERNAME/community-board compare: add-tyika-profile
  4. Fill out the title and description:
### Summary of Changes
Adds my profile entry to the `members.md` roster.

### Related Issue
Closes #14

### Verification
- [x] Alphabetical order maintained
- [x] Markdown renders correctly
  1. Click Create pull request.

Step 8: Navigating the Code Review

Once your PR is submitted, maintainers or automated bots might leave feedback.

If a maintainer asks: “Could you format your city name to include the country code?”, you don’t need to close the PR and start over. You simply:

  1. Make the change in your local file (members.md).
  2. Commit the change locally:
    git add members.md
    git commit -m "style: standardize country format"
    
  3. Push to the same branch:
    git push origin add-tyika-profile
    

GitHub automatically updates your existing Pull Request with your new commit. Once the maintainer approves, they will merge your PR, and your code becomes an official part of the project!


Common Mistakes and Troubleshooting

  • Mistake 1: Committing directly to your local main branch.
    • Symptom: You open a PR from YOUR-USERNAME:main to upstream:main. When you want to start another PR later, your main is polluted with unmerged changes.
    • Fix: Always branch off before editing: git checkout -b branch-name. If you already committed to main, run git branch new-feature-name, then git reset --hard upstream/main to restore your local main.
  • Mistake 2: Your fork is out of date with the original repo.
    • Symptom: GitHub warns that your branch has conflicts that must be resolved.
    • Fix: Fetch the newest changes from the original project and rebase your branch:
      git checkout main
      git fetch upstream
      git merge upstream/main
      git checkout your-feature-branch
      git rebase main
      
  • Mistake 3: Pushing with git push upstream instead of git push origin.
    • Symptom: Git throws remote: Permission to octo-org/community-board.git denied to YOUR-USERNAME.
    • Fix: You don’t have write access to the upstream repo. You must always push your branches to your own fork (origin): git push origin your-feature-branch.
  • Mistake 4: Committing unintended files (e.g., .DS_Store, node_modules, .env).
    • Symptom: Your PR diff includes system files or secrets.
    • Fix: Add those patterns to a .gitignore file immediately. To untrack an accidentally staged file without deleting it: git rm --cached <filename>, then commit.

Try It Yourself

Put these steps into practice without bothering a real maintainer:

  1. Create a dummy test repository on your GitHub account called pr-practice.
  2. Invite a friend or use a second test GitHub account to fork it.
  3. On that second account, clone the fork, create a branch named test-contribution, add a file called hello.txt, and push it.
  4. Submit a pull request back to pr-practice.
  5. Switch back to your primary account, review the diff, request a change, make that change from the secondary branch, and merge it!

What’s Next

Congratulations—you now know the standard development workflow used by software teams around the globe.

To take your Git skills to the professional tier, keep an eye out for our upcoming guides:

  • Resolving Git Merge Conflicts without Panic: How to read conflict markers (<<<<<<<, =======, >>>>>>>) and resolve overlapping changes cleanly.
  • Git Rebase vs. Git Merge: When to rebase to keep a linear history and when a merge commit is better.
  • Writing Effective GitHub PR Templates: Standardizing PR descriptions for your own repositories using .github/PULL_REQUEST_TEMPLATE.md.

Bookmark this guide so you have a quick command reference ready for your next open-source contribution!

Share: X (Twitter) Facebook LinkedIn