The GitHub Pull Request (PR) workflow is designed to make merging code a collaborative and safe process, but it’s not magic. It relies on a series of checks and balances that, if misunderstood or bypassed, can lead to integration nightmares.

Let’s see it in action. Imagine you’re working on a feature branch, feature/add-user-profile, and your colleague, Alice, is working on bugfix/login-issue.

Here’s a simplified view of what happens when Alice wants to merge her fix:

  1. Alice creates a Pull Request: She pushes her bugfix/login-issue branch to the origin remote and then clicks "New pull request" on GitHub. She selects bugfix/login-issue as the "compare" branch and main (or master) as the "base" branch.

  2. Automated Checks (CI/CD): GitHub triggers a series of automated checks, often called a Continuous Integration (CI) pipeline. This might include:

    • Linting: Tools like ESLint or Flake8 check for code style violations and potential syntax errors.
    • Unit Tests: Frameworks like Jest or Pytest run a suite of tests to ensure individual components of the code function as expected.
    • Integration Tests: These tests verify that different parts of the application work together correctly.
    • Build Process: Compiling code, bundling assets, etc.

    If any of these checks fail, the PR is marked with a red 'X', and Alice gets a notification. She can’t proceed until these are green.

  3. Code Review: Team members are assigned to review Alice’s code. They look for:

    • Logic errors: Does the code actually fix the bug?
    • Security vulnerabilities: Is there any sensitive data exposed or insecure handling of input?
    • Maintainability: Is the code readable, well-documented, and easy to understand for others?
    • Adherence to project standards: Does it fit with the rest of the codebase?

    Reviewers can leave comments, request changes, or approve the PR.

  4. Resolving Conflicts: If the main branch has changed significantly since Alice started her branch, there might be "merge conflicts." This happens when Alice’s changes overlap with changes made by others on main. GitHub highlights these, and Alice (or whoever is merging) needs to manually resolve them.

  5. Merging: Once all automated checks pass and reviewers approve, the PR can be merged. Common merge strategies include:

    • Create a merge commit: This preserves the history of the feature branch and creates a distinct merge commit on main.
    • Squash and merge: This takes all the commits from the feature branch, squashes them into a single commit, and applies it to main. This keeps main history cleaner but loses the granular commit history of the feature branch.
    • Rebase and merge: This replays the commits from the feature branch onto the latest main branch, creating a linear history.

The core problem this workflow solves is preventing broken code from entering the main development line. By forcing automated validation and human oversight, it acts as a gatekeeper. The "surprising" aspect is how much raw technical debt can accumulate if these gates are consistently bypassed or poorly configured. For instance, a CI pipeline that only runs a superficial check might pass code that fails in production due to an edge case not covered by the tests.

When you’re reviewing a PR, you’ll often see discussions around specific lines of code. For example, a reviewer might comment: "Consider using async/await here instead of .then() callbacks for better readability and error handling." Or, regarding a test: "This unit test for userService.getUser(id) doesn’t cover the case where id is null. Can we add a test for that?" These interactions are the lifeblood of the collaborative aspect, ensuring not just correctness but also quality and shared understanding.

A subtle but crucial part of the PR workflow involves understanding the difference between requiring status checks and protecting branches. In your repository settings, under "Branches," you can configure branch protection rules. You can make it mandatory for all status checks (like your CI build or tests) to pass before a PR can be merged. You can also require at least one approved review. Without these, a developer could technically merge a PR even if their tests failed or no one reviewed it. It’s the combination of these enforced rules that truly makes the PR workflow a safety net.

The next step in mastering this workflow is understanding how to manage complex merge conflicts and how to leverage advanced CI/CD integrations to automate more sophisticated checks like security vulnerability scanning.

Want structured learning?

Take the full Github course →