| |

Git 4f 🧩 Forking and Pull Requests

⏱️ Estimated read: 10 min | |

On a shared repository, contributors who have write access can push branches directly. But on most open-source projects, contributors don’t have that access. Forking solves this — you make your own copy of the repository, push changes there, and then ask the original project to pull them in via a pull request.

Key point: A fork is a personal copy of someone else’s repository, hosted on your account. A pull request is a request to merge changes from one branch (usually yours) into another (usually the project’s main branch). Together they enable contribution without granting write access.


The forking workflow

The forking workflow is a collaborative approach used on platforms like GitHub, GitLab, and Bitbucket. Contributors create a personal copy — a fork — of an existing repository, make changes, and propose them back to the original.

It’s used when you don’t have direct write access to the target repository — the norm in open source, and often the case in large organizations too.

Key benefits:

  • No direct write access — contributors can’t accidentally break the main codebase
  • Isolated development — changes happen in a separate environment
  • Flexible contribution — developers work at their own pace
  • Review process — all changes go through a formal review

The workflow steps:

  1. Fork the original repository
  2. Clone your fork locally
  3. Create a branch for your changes
  4. Make changes and commit them
  5. Push to your fork
  6. Create a pull request (or merge request)
  7. Participate in code review
  8. Make additional changes if requested
  9. Get approval and merge

The flow is: copy → branch → commit → push → request → review → merge.

Why the fork matters: Without it, contributors would need write access to the main repository just to propose changes. The fork keeps contributions isolated and reviewable.


Creating and reviewing pull requests

A pull request (PR) is the mechanism for proposing changes. It’s also the discussion platform where review happens. A “merge request” is the same concept — GitLab’s name for it.

PR components:

ComponentPurpose
TitleClear, descriptive summary
DescriptionWhat changed and why
ChangesThe actual diff
ConversationComments, review, discussion

Code review best practices:

Before submitting:

  1. Ensure your code works — test thoroughly before submitting
  2. Follow project conventions — coding standards, style guides, existing patterns
  3. Write clear commit messages — explain what and why
  4. Keep commits focused — one issue per commit

During review:

  1. Be constructive — focus on the code, not the person
  2. Ask questions — clarify unclear parts
  3. Check edge cases — comprehensive testing
  4. Verify documentation — update READMEs and comments
  5. Look for consistency — align with existing patterns

After review:

  1. Address feedback promptly
  2. Communicate changes — explain why you made them
  3. Re-request review when changes are complete
  4. Learn from feedback — reviews are a learning opportunity

Why review matters as much as code: A pull request isn’t just a merge request — it’s a conversation. Quality reviews catch bugs, spread knowledge, and keep the codebase consistent. A good PR makes the reviewer’s job easy.


Step-by-step example: contributing to an open source project

Scenario: Fixing a typo in a documentation repository.

Repository: github.com/octocat/Spoon-Knife
Issue: Typo in the API documentation.

Step 1: Fork the repository

  1. Navigate to github.com/octocat/Spoon-Knife
  2. Click Fork
  3. Choose your personal account as the destination

You now have a copy at github.com/yourusername/Spoon-Knife.

Step 2: Clone your fork locally

git clone https://github.com/yourusername/Spoon-Knife.git
cd Spoon-Knife

You’re working on your own copy — not the original.

Step 3: Create a new branch

git checkout -b fix-typo-in-docs

A dedicated branch keeps your work separate from main.

Step 4: Make the fix

Open api-reference.md, find paramater, correct it to parameter. Save.

Step 5: Commit your changes

git add .
git commit -m "Fix typo in API documentation: 'paramater' -> 'parameter'"

The commit message describes the change precisely.

Step 6: Push to your fork

git push origin fix-typo-in-docs

The branch is now on your GitHub fork.

Step 7: Create a pull request

  1. Go to your fork on GitHub
  2. Click Compare & pull request
  3. Fill in:
    • Title: “Fix typo in API documentation”
    • Description: “Corrected ‘paramater’ to ‘parameter’ in api-reference.md”
  4. Submit the PR

Step 8: Participate in the review

  1. Wait for reviewers to comment
  2. Address feedback by making additional commits on the same branch
  3. Re-request review when complete

Step 9: Merge

Once approved, a maintainer (or you, depending on the repo) merges the PR. The change is now in the main repository.

Why the branch matters: The PR is tied to the branch, not the fork. Keeping the fix on a dedicated branch means main stays clean and multiple PRs can coexist.


Common issues and solutions

1. Conflicts — your fork diverged from upstream.

Solution: Rebase or merge upstream changes into your branch before continuing.

2. Review delays — waiting on maintainers.

Solution: Be patient. If it’s been a long time, a polite follow-up is reasonable.

3. Unaddressed feedback — you responded but the reviewer didn’t.

Solution: Politely follow up after a reasonable period.

4. PR not merged — approved but not merged.

Solution: Check the repository’s policies. Some projects batch merges; others expect maintainers to do it manually.

5. Branch out of date — upstream moved on.

Solution: Rebase on upstream/main periodically, or use GitHub’s “Update branch” button.

Why conflicts happen so often: Your fork doesn’t auto-sync with upstream. If the original project keeps moving while you work, your branch drifts. Sync before submitting to reduce conflicts.


Complete Example Session

# ============================================
# PART 1: FORK (on GitHub UI)
# ============================================

# Navigate to github.com/octocat/Spoon-Knife
# Click "Fork"
# Result: github.com/yourusername/Spoon-Knife

# ============================================
# PART 2: CLONE YOUR FORK
# ============================================

git clone https://github.com/yourusername/Spoon-Knife.git
cd Spoon-Knife

# ============================================
# PART 3: ADD UPSTREAM REMOTE
# ============================================

git remote add upstream https://github.com/octocat/Spoon-Knife.git

git remote -v
# [ origin    https://github.com/yourusername/Spoon-Knife.git (fetch) ]
# [ origin    https://github.com/yourusername/Spoon-Knife.git (push) ]
# [ upstream  https://github.com/octocat/Spoon-Knife.git (fetch) ]
# [ upstream  https://github.com/octocat/Spoon-Knife.git (push) ]

# ============================================
# PART 4: SYNC WITH UPSTREAM
# ============================================

git fetch upstream
git checkout main
git merge upstream/main

# ============================================
# PART 5: CREATE A BRANCH
# ============================================

git checkout -b fix-typo-in-docs

# ============================================
# PART 6: MAKE THE FIX
# ============================================

# edit api-reference.md

# ============================================
# PART 7: COMMIT AND PUSH
# ============================================

git add api-reference.md
git commit -m "Fix typo in API documentation: 'paramater' -> 'parameter'"

git push origin fix-typo-in-docs
# [ Enumerating objects: 5, done. ]
# [ To https://github.com/yourusername/Spoon-Knife.git ]
# [  * [new branch]      fix-typo-in-docs -> fix-typo-in-docs ]

# ============================================
# PART 8: OPEN PULL REQUEST (on GitHub UI)
# ============================================

# Go to your fork
# Click "Compare & pull request"
# Title: "Fix typo in API documentation"
# Description: "Corrected 'paramater' to 'parameter' in api-reference.md"
# Submit

# ============================================
# PART 9: REVIEWER ASKS FOR A CHANGE
# ============================================

# Make the change
git add api-reference.md
git commit -m "Address review: also fix similar typo on line 42"
git push origin fix-typo-in-docs

# ============================================
# PART 10: MERGE
# ============================================

# Maintainer merges the PR
# Your branch is now part of main on upstream

# ============================================
# PART 11: CLEAN UP
# ============================================

git checkout main
git branch -d fix-typo-in-docs
git push origin --delete fix-typo-in-docs

Quick Reference

Forking Workflow

StepCommand / Action
ForkGitHub UI: “Fork” button
Clonegit clone URL
Add upstreamgit remote add upstream ORIGINAL_URL
Syncgit fetch upstream && git merge upstream/main
Branchgit checkout -b NAME
Commitgit commit -m "msg"
Pushgit push origin NAME
PRGitHub UI: “Compare & pull request”

Fork vs Branch

AspectForkBranch
LocationSeparate repositorySame repository
PermissionNo write access neededRequires write access
UseOpen sourceTeam collaboration
MergingVia PR across forksVia PR within repo
SyncManual upstream syncShared with team

Remote Setup for Forks

RemotePoints to
originYour fork
upstreamThe original repo

PR Checklist

Before submittingDuring reviewAfter review
Tests passConstructiveAddress feedback
Follow conventionsAsk questionsExplain changes
Clear commit messagesCheck edge casesRe-request review
Focused commitsVerify docsLearn from feedback

Syncing Your Fork

StepCommand
Fetch upstreamgit fetch upstream
Switch to maingit checkout main
Merge upstreamgit merge upstream/main
Push to forkgit push origin main

Common Issues

IssueSolution
ConflictsRebase or merge upstream
DelaysBe patient, follow up
PR not mergedCheck policies
Branch staleUpdate from upstream
Feedback unaddressedFollow up politely

Best Practices

✅ Do This:

# Add upstream right after cloning
git remote add upstream URL                          # ✅

# Sync before creating a branch
git fetch upstream && git merge upstream/main        # ✅

# Work on a dedicated branch
git checkout -b fix-typo                             # ✅

# Write clear commit messages
git commit -m "Fix typo in API docs"                 # ✅

# Keep PRs small and focused
# One feature or fix per PR                          # ✅

# Respond to review comments promptly
# Push updates on the same branch                    # ✅

# Re-request review after changes
# Use the GitHub UI                                  # ✅

❌ Don’t Do This:

# Don't push directly to main on your fork
git checkout main
git commit -m "changes"                              # ⚠️  hard to manage

# Don't submit huge PRs
# Split into smaller, reviewable changes             # ❌

# Don't ignore review feedback
# Address every comment                              # ⚠️

# Don't force-push after review starts
git push --force                                     # ❌ reviewers lose context

# Don't submit PRs without testing
# Run tests locally first                            # ❌

# Don't create a new PR for each review change
# Update the existing branch                         # ⚠️

# Don't mix unrelated changes
# One PR, one purpose                                 # ⚠️

Common Pitfalls

PitfallProblemSolution
No upstream remoteCan’t syncgit remote add upstream
Committing to mainMessy historyUse a branch
Large PRsHard to reviewSplit into smaller
Force-push after reviewLoses review commentsPush normal updates
Ignoring feedbackPR stallsAddress every comment
Stale branchConflictsSync with upstream
Wrong target branchWrong baseCheck the base branch
Missing testsRejected PRTest before submitting

Real-World Examples

1. Fork on GitHub

Click Fork on the repository page. Your copy appears under your account.

2. Clone your fork

git clone https://github.com/yourusername/repo.git

3. Add upstream

git remote add upstream https://github.com/original/repo.git

4. Sync with upstream

git fetch upstream
git checkout main
git merge upstream/main

5. Create a branch

git checkout -b feature/login

6. Commit changes

git add file.js
git commit -m "Add login validation"

7. Push to your fork

git push origin feature/login

8. Open a pull request

GitHub UI: Compare & pull request → fill title and description → submit.

9. Address review feedback

Make changes on the same branch, commit, push — the PR updates automatically.

10. Keep the PR up to date

git fetch upstream
git checkout feature/login
git rebase upstream/main
git push --force-with-lease origin feature/login

11. Clean up after merge

git checkout main
git branch -d feature/login
git push origin --delete feature/login

12. Check PR status

On GitHub: PR page shows checks, reviews, and merge readiness.

13. Re-request review

After pushing fixes, click Re-request review next to the reviewer’s name.

14. Close a PR without merging

If the change is no longer needed, click Close pull request.

15. Cherry-pick from a PR

If only one commit is needed, cherry-pick it into your branch.


Visual: The Forking Workflow

┌──────────────────────────────────────────────┐
│  Original repository                         │
│  github.com/octocat/Spoon-Knife              │
│                                              │
│  ─── main ───────────────────────────        │
│                                              │
└─────────────────▲────────────────────────────┘
                  │
                  │  Pull request
                  │
┌─────────────────┴────────────────────────────┐
│  Your fork                                   │
│  github.com/yourusername/Spoon-Knife         │
│                                              │
│  ─── main ───────────────────────────        │
│            │                                 │
│            └── feature/fix-typo              │
│                                              │
└──────────────────────────────────────────────┘

Fork → clone → branch → commit → push → PR

Visual: Fork vs Branch

┌──────────────────────────────────────────────┐
│  Same repository (branching)                 │
│                                              │
│  repo/                                       │
│    ├── main                                  │
│    ├── feature/a      ← shared               │
│    └── feature/b                             │
│                                              │
│  Need write access                           │
│                                              │
└──────────────────────────────────────────────┘

┌──────────────────────────────────────────────┐
│  Separate repositories (forking)             │
│                                              │
│  original/repo                               │
│    └── main                                  │
│                                              │
│  yourusername/repo  ← fork                   │
│    └── feature/a                             │
│                                              │
│  No write access needed                      │
│                                              │
└──────────────────────────────────────────────┘

Visual: PR Lifecycle

┌──────────────────────────────────────────────┐
│  Open PR                                     │
│       │                                      │
│       ▼                                      │
│  Automated checks run                        │
│       │                                      │
│       ▼                                      │
│  Reviewers comment                           │
│       │                                      │
│       ▼                                      │
│  Author responds with changes                │
│       │                                      │
│       ▼                                      │
│  Re-request review                           │
│       │                                      │
│       ▼                                      │
│  Approval                                    │
│       │                                      │
│       ▼                                      │
│  Merge                                       │
│                                              │
└──────────────────────────────────────────────┘

Visual: Remotes in a Fork

┌──────────────────────────────────────────────┐
│  Local clone                                 │
│                                              │
│  origin    → yourusername/repo (your fork)   │
│  upstream  → original/repo (the source)      │
│                                              │
│  Push to origin                              │
│  Fetch from upstream                         │
│                                              │
└──────────────────────────────────────────────┘

Visual: PR in the Review Flow

┌──────────────────────────────────────────────┐
│  Author                                      │
│       │                                      │
│       ├──► push to fork                      │
│       ├──► open PR                           │
│       │                                      │
│       ▼                                      │
│  Reviewer                                    │
│       │                                      │
│       ├──► comment                           │
│       ├──► request changes                   │
│       │                                      │
│       ▼                                      │
│  Author responds                             │
│       │                                      │
│       ├──► commit on same branch             │
│       ├──► re-request review                 │
│       │                                      │
│       ▼                                      │
│  Reviewer approves                           │
│       │                                      │
│       ▼                                      │
│  Maintainer merges                           │
│                                              │
└──────────────────────────────────────────────┘

Summary

ConceptMeaning
ForkPersonal copy of a repository
UpstreamThe original repository
OriginYour fork
Pull requestRequest to merge changes
Merge requestSame, on GitLab
ReviewComments and approval
SyncFetch + merge upstream

Key takeaways:

  • Forking creates a personal copy of a repository on your account
  • The upstream remote points to the original; origin points to your fork
  • The workflow is: fork → clone → branch → commit → push → PR → review → merge
  • Pull requests are both merge requests and discussion platforms
  • Sync with upstream regularly to avoid conflicts
  • Write clear commit messages and keep commits focused
  • Small PRs are easier to review and get merged faster
  • Respond to review feedback on the same branch — the PR updates automatically
  • Use --force-with-lease if you must rebase after review starts
  • Don’t commit directly to main on your fork
  • No write access needed — that’s the point of forking
  • Clean up branches after merge

Remember: Forking is how open source works. Copy the repository, work on your copy, propose changes back through a pull request. Keep PRs small, sync with upstream, respond to feedback promptly, and learn from every review. The fork gives you freedom; the pull request gives the maintainer control. Master this workflow, and contributing to any project becomes straightforward.

Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!