|$ curl https://forge-ai.dev/api/markdown?path=docs/git/pull-requests
$cat docs/git-—-pull-requests-&-code-review.md
updated Recently·40 min read·published

Git — Pull Requests & Code Review

GitCollaborationIntermediate
Introduction

Pull requests (PRs) are the cornerstone of collaborative code review on GitHub, GitLab, and Bitbucket. A PR is a proposal to merge changes from one branch into another, accompanied by discussion, review, and automated checks.

Effective PR workflows combine technical Git practices with human processes — clear descriptions, focused changes, respectful reviews, and automated validation. This section covers the complete lifecycle from creation to merge.

Pull Request Workflow

The standard PR workflow moves through distinct stages from local development to production merge.

terminal
Bash
1# Stage 1: Create a feature branch from main
2git checkout main
3git pull origin main
4git checkout -b feat/user-authentication
5
6# Stage 2: Make changes with atomic commits
7git add src/auth/
8git commit -m "Add JWT token validation middleware"
9git add src/api/
10git commit -m "Add login endpoint with rate limiting"
11
12# Stage 3: Keep branch up to date
13git fetch origin
14git rebase origin/main
15# Resolve conflicts if any
16
17# Stage 4: Push and create PR
18git push -u origin feat/user-authentication
19
20# Stage 5: Address review feedback
21# ... make changes, add commits ...
22git add .
23git commit -m "Address PR feedback: fix error handling"
24git push
25
26# Stage 6: Squash before merge (if required)
27git rebase -i origin/main
28# ... squash fixup commits ...
29
30# Stage 7: Merge (via GitHub UI or CLI)
31gh pr merge --squash

info

Use the GitHub CLI (gh) to create and manage PRs from the command line. gh pr create --fill creates a PR using your branch name and commit messages as the title and body. It streamlines the workflow without leaving the terminal.
Creating Great PRs

A well-crafted PR reduces review time, catches issues earlier, and serves as documentation for future developers. Follow these practices for every PR.

PR Title & Description

The title should be a clear, concise summary. The description should explain the what, why, and how.

PR-TEMPLATE.md
MARKDOWN
1## Title format:
2feat: Add JWT authentication to API endpoints
3
4## Description template:
5### Summary
6Implements JWT token-based authentication for all
7protected API routes. Replaces the previous session-based
8auth for better scalability.
9
10### Changes
11- Add JWT middleware for token validation
12- Create login/signup endpoints
13- Add token refresh mechanism
14- Update all protected routes
15
16### Testing
17- Unit tests for middleware: npm test auth/middleware
18- Integration tests for login flow
19- Manual testing with Postman collection
20
21### Screenshots
22[Link to screenshots or screen recording]
23
24### Related Issues
25Closes #123, #456

PR Size Guidelines

PR size directly impacts review quality. Smaller PRs get reviewed faster and find more bugs.

PR-GUIDELINES.md
MARKDOWN
1# Ideal PR characteristics:
2- Single concern (one feature, fix, or refactor)
3- Under 400 lines changed (ideally < 200)
4- Less than 10 files modified
5- No unrelated formatting changes
6- Includes tests for new code
7
8# When PRs get too large:
9400-800 lines → Schedule a review session
10800+ lines → Break into multiple PRs
111500+ lines → Team rarely reviews thoroughly

best practice

If your PR exceeds 400 lines, consider splitting it. A large PR signals that the change should be broken into smaller, independently reviewable pieces. Use stacked PRs — multiple small PRs that build on each other — for complex features.
The Review Process

Code review is a collaborative quality gate. Both authors and reviewers have responsibilities to make the process effective and respectful.

Reviewer Checklist

Does the code solve the right problem?
Are there edge cases or error conditions not handled?
Is the code testable and are there adequate tests?
Does it follow the project&apos;s style and conventions?
Are there security concerns (injection, auth, data exposure)?
Will this scale? Are there performance implications?
Is the documentation updated (README, API docs, inline comments)?
Are there unnecessary dependencies or code duplication?

Review Etiquette

Be specific — reference exact lines and suggest concrete alternatives
Explain why — not just &apos;this is wrong&apos; but &apos;this causes a race condition because...&apos;
Separate nitpicks from blockers — mark style suggestions with a prefix like &apos;nit:&apos;
Praise good code — reviews should not only point out problems
Respond to reviews promptly — ideally within 4 working hours
Assume good intent — ask questions before assuming mistakes
Use GitHub&apos;s suggestion feature for small fixes
Don&apos;t let perfect be the enemy of good — approve reasonable solutions
review-example.md
MARKDOWN
1# Example review comment
2**Reviewer:**
3> src/auth/middleware.ts:45 — The token blacklist check
4> here creates a database query on every request. Since
5> blacklisted tokens are rare, consider using an in-memory
6> cache (Redis) instead. This will keep latency under 5ms.
7
8**Author response:**
9Good catch. Switched to Redis cache with 10-minute TTL.
10Updated in commit a1b2c3d.
11
12**Reviewer:**
13nit: src/utils/format.ts:12 — Use template literals
14instead of string concatenation for consistency with
15the rest of the codebase.
16
17**Author:**
18Fixed in e4f5g6h.

best practice

Use GitHub's "Request Changes" sparingly. Reserve blocking reviews for correctness, security, and architecture issues. Use "Comment" for questions and suggestions, and "Approve" when you trust the author to address non-blocking feedback. This keeps the review process fast and collaborative.
Merge Strategies

GitHub offers three merge strategies when merging a PR. Each affects the base branch's history differently.

StrategyHistoryWhen to Use
Create merge commitPreserves all commits, adds merge commitFeature branches with meaningful commits
Squash and mergeCombines all commits into oneMessy WIP commits, single-feature PRs
Rebase and mergeApplies commits individually onto baseLinear history preference
terminal
Bash
1# Squash and merge (GitHub UI) - all commits become one
2# Before: feat/* ----a----b----c
3# After: main ----a----b----c----[squash commit]
4
5# Rebase and merge (GitHub UI) - individual commits
6# Before: feat/* ----a----b----c
7# After: main ----a----b----c
8
9# Manual squash via interactive rebase:
10git rebase -i origin/main
11# Change "pick" to "squash" for fixup commits
12# Write a clean commit message
13
14# Manual merge with --squash:
15git checkout main
16git merge --squash feature-branch
17git commit -m "Add login feature"
18
19# Require linear history (GitHub setting):
20# Settings > Branches > Require linear history

info

Configure your repository to "Require linear history" in branch protection rules if your team prefers rebase/squash merges. This prevents merge commits on the base branch while still allowing them in feature branches.
Handling PR Conflicts

Merge conflicts on GitHub occur when your branch and the target branch have diverged. GitHub highlights conflicted files in the PR UI, but resolution must happen locally.

terminal
Bash
1# When GitHub shows "This branch has conflicts" ...
2
3# Option 1: Rebase your branch onto target
4git checkout feat/user-auth
5git fetch origin
6git rebase origin/main
7# Fix conflicts, then:
8git add resolved-file.ts
9git rebase --continue
10git push --force-with-lease
11
12# Option 2: Merge target into your branch
13git checkout feat/user-auth
14git fetch origin
15git merge origin/main
16# Fix conflicts, then:
17git add resolved-file.ts
18git commit
19git push
20
21# Option 3: Use GitHub's web editor
22# For simple conflicts, GitHub offers a web-based
23# conflict editor under "Resolve conflicts" button.
24# Only suitable for small, straightforward conflicts.

warning

If your branch has conflicts, rebase (git rebase origin/main) is usually better than merge (git merge origin/main). Rebasing produces a cleaner history by applying your commits on top of the latest main, avoiding unnecessary merge commits. However, remember you will need to force-push after rebasing.
CI Status Checks

Continuous Integration (CI) checks run automatically on every PR push. They validate code quality, test coverage, security vulnerabilities, and build success before merging.

pr-checks.yml
YAML
1# Example GitHub Actions workflow for PR checks
2name: PR Checks
3on: pull_request
4
5jobs:
6 lint:
7 runs-on: ubuntu-latest
8 steps:
9 - uses: actions/checkout@v4
10 - run: npm ci
11 - run: npm run lint
12
13 test:
14 runs-on: ubuntu-latest
15 steps:
16 - uses: actions/checkout@v4
17 - run: npm ci
18 - run: npm test
19 - run: npm run test:coverage
20
21 build:
22 runs-on: ubuntu-latest
23 steps:
24 - uses: actions/checkout@v4
25 - run: npm ci
26 - run: npm run build

best practice

Configure branch protection rules to require CI checks to pass before merging. Require at least one approval, ensure branches are up to date, and prevent pushes to protected branches. These settings prevent common integration failures and enforce team workflow.
Draft PRs & Early Feedback

Draft pull requests signal that work is in progress and not ready for final review. They are useful for early design feedback, previewing CI results, and collaborating on complex changes.

terminal
Bash
1# Create a draft PR via GitHub CLI
2gh pr create --draft --title "WIP: Auth refactor" --body "Early design feedback wanted"
3
4# Mark a PR as ready for review
5gh pr ready
6
7# Draft PR characteristics:
8# - Cannot be merged
9# - Does not request reviews automatically
10# - CI checks still run
11# - Clearly marked as "Draft" in the UI
12# - Team members can still comment
13
14# When to use draft PRs:
15# - Design exploration: "Is this approach right?"
16# - CI preview: "Check if tests pass on this idea"
17# - Collaborative WIP: "Help me finish this"
18# - Blocked PR: "Waiting on dependency, but code is visible"
🔥

pro tip

Create draft PRs early in development — even on the first commit. This gives your team visibility into what you are working on, allows CI to run continuously, and enables lightweight feedback before the review phase.
PR Automation

GitHub Actions and other tools can automate PR management tasks, keeping the workflow efficient and enforcing team policies.

pr-automation.yml
YAML
1# Auto-label PRs based on branch prefix
2name: PR Labeler
3on:
4 pull_request:
5 types: [opened]
6
7jobs:
8 label:
9 runs-on: ubuntu-latest
10 steps:
11 - uses: actions/labeler@v5
12 with:
13 repo-token: ${{ secrets.GITHUB_TOKEN }}
14
15# PR checklist automation
16name: PR Checklist
17on:
18 pull_request:
19 types: [opened, edited]
20
21jobs:
22 checklist:
23 runs-on: ubuntu-latest
24 steps:
25 - uses: mheap/require-checklist-action@v2
26 with:
27 requireChecklist: true
28
29# Auto-merge when conditions met
30name: Auto Merge
31on:
32 pull_request_review:
33 types: [submitted]
34
35jobs:
36 automerge:
37 runs-on: ubuntu-latest
38 if: github.event.review.state == 'approved'
39 steps:
40 - run: gh pr merge --auto --squash "$PR_URL"
41 env:
42 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 PR_URL: ${{ github.event.pull_request.html_url }}
Code Review Best Practices

For Authors

Keep PRs small and focused on a single concern
Write clear commit messages that explain the why, not just the what
Self-review your own PR before requesting others
Respond to feedback constructively — every comment is an opportunity to improve
Do not take criticism personally — reviews target the code, not you
Add screenshots or screen recordings for UI changes
Include test cases that demonstrate the change works
Link related issues and dependencies in the PR description
Rebase regularly to keep the branch up to date and avoid conflicts
Mark resolved conversations explicitly so reviewers know what changed

For Reviewers

Review within 24 hours — fast feedback keeps momentum
Start with the big picture (architecture, design) before nitpicking style
Ask clarifying questions instead of making assumptions
Provide code suggestions when you know the fix
Distinguish between blockers and nice-to-haves
Look for test coverage — is there enough? Are the tests meaningful?
Check for security issues: injection, auth leaks, data exposure
Verify the PR description matches the actual changes
Use GitHub&apos;s &quot;View changes&quot; in split or unified mode as preferred
Approve when you trust the author to handle remaining non-blocking feedback
🔥

pro tip

Establish a team PR SLA (Service Level Agreement). Example: "All PRs must receive initial review within 4 working hours. Authors should respond to feedback within 2 hours during working hours. PRs open for more than 48 hours should be escalated." Clear expectations prevent stalled PRs.
Common Pitfalls

✗ Giant PRs

+2,500 additions, 85 files changed

Large PRs get superficial reviews. Break them into logical chunks (200-400 lines each). Use stacked PRs for sequential dependencies.

✗ Lazy commit messages

git commit -m "fix stuff" / "update" / "changes"

Commit messages in PRs become part of the permanent history. Write descriptive messages. Squash and rewrite before merging if needed.

✗ Review burnout

10 open PRs, 5 unreviewed for 3 days

Set aside dedicated review time daily. Rotate reviewers to share context. Consider a "no PR left behind" policy with daily standup check-ins.

✗ Merging without CI passing

Bypassing branch protection rules

Broken PRs that bypass CI create cascading failures. Require all checks to pass in branch protection settings. Allow admin bypass only for emergencies with documented exceptions.

$Blueprint — Engineering Documentation·Section ID: GIT-04·Revision: 1.0