datarekha

The GitHub Flow & Pull Requests

How teams ship changes together without chaos — the GitHub Flow loop, what a pull request really is, and how to choose between merge, squash, and rebase.

9 min read Intermediate Git Lesson 13 of 15

What you'll learn

  • The GitHub Flow loop: branch → commit → push → PR → review/CI → merge → delete
  • What a pull request is: a merge request plus a review surface plus a CI gate
  • Merge options on GitHub: when to pick squash-and-merge over a plain merge commit

Before you start

The loop at a glance

GitHub Flow is deliberately minimal. It has exactly one rule: main is always deployable. Everything else follows from that constraint.

The loop looks like this:

  1. Branch off main.
  2. Do your work in commits on that branch.
  3. Push the branch to GitHub.
  4. Open a pull request (PR) targeting main.
  5. Teammates review; CI runs automated checks.
  6. Address feedback with more commits on the same branch.
  7. Merge when approved and green.
  8. Delete the branch.

Repeat.

BranchCommitPushOpenPRReview+ CI ✓MergeDeletebranch
The GitHub Flow pipeline — one loop, repeated for every change.

What a pull request actually is

A pull request is three things bundled together:

  • A merge request. It says: “please merge branch feat/login into main.”
  • A review surface. Teammates can comment on individual lines, approve, or request changes.
  • A CI gate. GitHub runs status checks (tests, linters, security scans) against the PR branch before anyone can merge.

Nothing about a PR is magic. Under the hood it is just two branch names and a diff. The power comes from making the conversation and the checks happen before the code touches main.

Walking through the loop

1. Create a branch off main

git switch main
git pull                          # make sure you start from the latest
git switch -c feat/add-dark-mode  # short, descriptive name

Branch names are cheap. Use them freely.

2. Commit your work

# ... edit files ...
git add src/theme.ts
git commit -m "add dark-mode token set"

# ... more edits ...
git add src/toggle.tsx
git commit -m "wire ThemeToggle to token set"

Keep commits focused. Each one should leave the code in a working state.

3. Push the branch

git push -u origin feat/add-dark-mode

The -u flag sets the upstream so future git push calls on this branch need no arguments.

4. Open a pull request

GitHub prints a URL to open a PR immediately after your first push. Click it, or use the GitHub CLI:

gh pr create \
  --base main \
  --title "Add dark-mode support" \
  --body "Closes #42. Adds token set and wires the toggle."

Write a PR description that explains why, not just what. Reviewers who understand the context give faster, better feedback.

5. Review, CI, and iteration

While the PR is open:

  • CI runs your test suite and linters automatically.
  • Teammates leave comments or approve.
  • You push more commits to address feedback — they appear in the same PR automatically.
# Address a reviewer's comment, then push
git add src/toggle.tsx
git commit -m "fix toggle aria-label per review"
git push

You never need to close and reopen the PR. The new commits show up in the existing thread.

6. Merge and delete

Once the PR is approved and all checks are green, merge it on GitHub. Then clean up:

git switch main
git pull                                   # pull the merged commit
git branch -d feat/add-dark-mode           # delete local branch
git push origin --delete feat/add-dark-mode  # delete remote branch

GitHub can be set to delete the remote branch automatically after merge — turn that on in repository settings.

Fork-based contribution

When you do not have write access to a repository — as is common in open source — you cannot push a branch directly. Instead you fork the repo: GitHub copies it under your account, giving you full write access to your copy.

The flow is the same, but the push target is your fork, and the PR targets the original (upstream) repository’s main.

# After forking on github.com:
git clone https://github.com/YOUR-USERNAME/the-project.git
git switch -c fix/typo-in-readme
# ... edit ...
git push -u origin fix/typo-in-readme
gh pr create --repo original-owner/the-project --base main

For repos where you are a collaborator, skip the fork — push your branch directly.

Keeping a PR branch current

If main receives new commits while your PR is open, your branch falls behind. You have two options:

Option A — merge main in (safer, preserves history):

git switch feat/add-dark-mode
git fetch origin
git merge origin/main
git push

Option B — rebase onto main (cleaner history, rewrites commits):

git switch feat/add-dark-mode
git fetch origin
git rebase origin/main
git push --force-with-lease   # required after rebase

For shared PR branches where a teammate may also have pushed, prefer the merge option. Rebase is fine on branches only you are using.

Merge options on GitHub

When you click the merge button, GitHub offers three strategies:

StrategyWhat it doesHistory shape
Merge commitCreates a merge commit with two parentsPreserves every commit from the branch
Squash and mergeCollapses all PR commits into one commit on mainFlat, one commit per PR
Rebase and mergeReplays PR commits linearly onto mainLinear, multiple commits

When to pick squash-and-merge: your PR branch has noisy intermediate commits (“fix typo”, “add back missing semicolon”, “WIP”) and you want main’s history to read as one clean unit of work per feature. Most teams standardize on squash-and-merge for this reason.

When to keep a merge commit: you want the full commit story preserved — useful on projects where git bisect needs granular commits to pinpoint regressions.

Reviewing etiquette

A few practices that make reviews faster and kinder:

  • Reviewer: distinguish blocking feedback (“this will break X”) from suggestions (“we could simplify this, but it works either way”).
  • Author: respond to every comment, even if just to say you pushed a fix or explain why you kept the original approach.
  • Everyone: small PRs review faster. A 200-line diff gets thorough review in minutes. A 2000-line diff gets skimmed.

This connects directly to the merging lesson — understanding fast-forward vs. merge commit behavior there explains exactly what GitHub is doing under each of the three merge buttons here.


Quick check

0/3
Q1What three things does a GitHub pull request combine?
Q2You ran 'git rebase origin/main' on your PR branch and now need to push. Which command is correct?
Q3Your team maintains a library used by many downstream services. A contributor opens a PR with 47 commits including 'oops', 'fix test', and 'try again'. You want main's history to read cleanly. Which merge strategy should you choose?

Sign in to track your progress

Completed lessons, your XP, level, and streak save to your account — it's free and takes a few seconds.

Explore further

Glossary terms
Cheat sheets

Related lessons

Skip to content