Back to Blog
Developer ToolsGitCollaborationTutorial

Git Workflow for Teams -- Branching, PRs, and Merge Strategies That Actually Work

Published on April 4, 202613 min read

Git Workflow for Teams -- Branching, PRs, and Merge Strategies That Actually Work

Every team that uses Git eventually runs into the same problems. Merge conflicts that take hours to resolve. A main branch that is broken half the time. Nobody knows which branch has the latest working code. Pull requests that sit open for weeks.

These are not Git problems. They are workflow problems. This guide covers branching strategies, pull request practices, and merge approaches that keep teams moving fast without breaking things.


Choosing a Branching Strategy

There is no single "best" branching strategy. The right one depends on your team size, release cadence, and how much process you can tolerate.

Trunk-Based Development

Best for: Small teams (2-8 developers), continuous deployment, teams that deploy multiple times per day.

The idea is simple. Everyone commits to a single branch (main/trunk), either directly or through very short-lived feature branches that last hours, not days.

Rules:

  • Feature branches live for less than 24 hours
  • Every commit to main must pass CI
  • Use feature flags instead of long-lived branches for incomplete features
  • Keep changes small -- one logical change per commit

Advantages:

  • Almost zero merge conflicts
  • Always-deployable main branch
  • Forces small, reviewable changes
  • No "integration hell" when merging long-lived branches

GitHub Flow

Best for: Medium teams (5-20 developers), projects that deploy frequently but want code review on every change.

GitHub Flow adds one layer on top of trunk-based development: every change goes through a pull request.

Rules:

  • Main is always deployable
  • Create a feature branch from main for every change
  • Open a pull request when the work is ready for review
  • After review and CI passes, merge to main
  • Deploy from main

This is what most modern teams use. It is simple enough that everyone follows it, but structured enough that nothing sneaks into main without review.

GitFlow

Best for: Large teams, projects with scheduled releases, mobile apps that go through app store review.

GitFlow uses multiple long-lived branches: main, develop, feature branches, release branches, and hotfix branches. It provides structure for teams that cannot deploy continuously.

Rules:

  • Main always contains production-ready code
  • Develop is the integration branch for features
  • Feature branches are created from develop and merged back into develop
  • Release branches are created from develop when preparing for a release
  • Hotfix branches are created from main for emergency fixes

The downside: GitFlow is complex. Most teams that adopt it end up simplifying it over time because the overhead of managing all those branches outweighs the benefits.


Branch Naming Conventions

Consistent branch names make it easy to understand what a branch does at a glance. Pick a convention and enforce it:

feature/add-user-authentication

fix/login-page-crash-on-empty-email

chore/update-dependencies

docs/add-api-documentation

refactor/simplify-payment-processing

The pattern is: type/short-description-with-hyphens

Common prefixes:

  • feature/ -- new functionality
  • fix/ -- bug fixes
  • chore/ -- maintenance, dependency updates, CI changes
  • docs/ -- documentation changes
  • refactor/ -- code restructuring without behavior changes
  • test/ -- adding or updating tests

Include the ticket number if your team uses a project tracker:

feature/PROJ-123-add-user-authentication

fix/PROJ-456-login-crash


Writing Good Pull Requests

A pull request is not just a code delivery mechanism. It is a communication tool. Good PRs make reviews faster, reduce back-and-forth, and create a useful history.

The Title

Keep it under 72 characters. Start with a verb. Be specific.

Bad: "Updates", "Fix bug", "Changes to auth"

Good: "Add email verification to signup flow", "Fix crash when user submits empty form", "Replace bcrypt with argon2 for password hashing"

The Description

Every PR description should answer three questions:

  1. 1What does this change do?
  2. 2Why is this change needed?
  3. 3How can the reviewer test it?

A simple template:

> ## What

> Added rate limiting to the /api/login endpoint.

>

> ## Why

> We were getting hit with brute force attempts. This limits each IP to 5 attempts per minute.

>

> ## How to Test

> 1. Start the server locally

> 2. Hit /api/login more than 5 times in a minute

> 3. Verify you get a 429 response on the 6th attempt

Keep PRs Small

The most important rule of pull requests: keep them small. Research consistently shows that review quality drops dramatically as PR size increases.

  • Under 200 lines: reviewed carefully, merged quickly
  • 200-500 lines: reviewed with decreasing attention
  • Over 500 lines: skimmed at best, rubber-stamped at worst

If your feature requires more than 500 lines, break it into multiple PRs. Ship the data model first, then the API, then the UI.


Code Review Best Practices

For Reviewers

  • Review within 24 hours. Stale PRs kill momentum. If you cannot review today, say so and suggest another reviewer.
  • Focus on what matters. Logic errors, security issues, and architectural problems are worth discussing. Nitpicking variable names and formatting is not (use a linter for that).
  • Ask questions instead of making demands. "What happens if this API call times out?" is better than "Add error handling here."
  • Approve with comments. If you have minor suggestions that do not block the PR, approve it and note them as optional. Do not block PRs over style preferences.

For Authors

  • Self-review before requesting review. Read your own diff. You will catch half the issues yourself.
  • Respond to every comment. Even if the response is "Done" or "Good point, fixed." Unanswered comments create ambiguity.
  • Do not take feedback personally. Code review is about the code, not about you. A suggestion to restructure something is not a judgment of your abilities.

Merge Strategies

Merge Commit (git merge --no-ff)

Creates a merge commit that preserves the entire branch history. Your git log shows exactly when branches were created and merged.

Best for: Teams that want a detailed, accurate history of how code was developed.

Squash and Merge

Combines all commits in the branch into a single commit on main. The individual commits in the feature branch disappear from main's history.

Best for: Teams that want a clean, linear main branch history. Every commit on main represents one complete feature or fix.

Rebase and Merge

Replays the commits from the feature branch on top of main, creating a linear history without a merge commit. Each commit is preserved individually.

Best for: Teams that want a linear history but also want to preserve individual commits within a feature.

Which Should You Use?

  • Squash and merge is the most popular choice for most teams. It keeps main clean and makes reverts easy -- one commit equals one feature.
  • Merge commits work well for teams that want to preserve detailed development history.
  • Rebase and merge is for teams that are disciplined about making each commit meaningful and self-contained.

Pick one strategy and use it consistently across the team.


Handling Merge Conflicts

Merge conflicts are inevitable when multiple people work on the same codebase. Here is how to handle them efficiently:

Prevention

  • Pull from main frequently. The longer your branch lives, the more likely conflicts become.
  • Communicate with your team. If two people are editing the same file, coordinate.
  • Keep PRs small. Smaller changes mean smaller conflict surfaces.

Resolution

When you hit a conflict:

> git fetch origin

> git rebase origin/main

Git will pause at each conflict. Open the conflicting file, and you will see:

> <<<<<<< HEAD

> your changes

> =======

> their changes

> >>>>>>> origin/main

Resolve it by keeping the correct code, removing the conflict markers, then:

> git add the-file.ts

> git rebase --continue

If the conflict is too complex, you can always abort:

> git rebase --abort

Tools That Help

  • VS Code has excellent built-in merge conflict resolution. Click "Accept Current Change", "Accept Incoming Change", or "Accept Both Changes."
  • git rerere (reuse recorded resolution) remembers how you resolved a conflict and automatically applies the same resolution if it comes up again. Enable it with: git config --global rerere.enabled true

Protecting Your Main Branch

Set up branch protection rules in GitHub/GitLab to prevent accidental damage to main:

  • Require pull request reviews -- at least one approval before merging
  • Require CI to pass -- no merging if tests fail
  • Require branches to be up to date -- force rebasing before merge to catch integration issues
  • Restrict force pushes -- nobody should force push to main, ever
  • Require signed commits -- optional, but adds accountability

Git Hooks for Quality

Git hooks run scripts automatically at specific points in the Git workflow. Use them to catch problems before they reach the PR:

  • pre-commit -- run linters and formatters on staged files
  • commit-msg -- enforce commit message conventions
  • pre-push -- run tests before pushing

Use a tool like Husky (Node.js) or pre-commit (Python) to manage hooks across the team. These tools install hooks from a config file in your repo, so everyone gets the same checks automatically.


The One Rule

If you remember nothing else from this guide, remember this: keep your branches short-lived and your pull requests small. Every problem in team Git workflows -- merge conflicts, stale PRs, broken main, lost code -- traces back to branches that live too long and changes that are too large.

For more developer productivity guides, check out our blog and explore our free developer tools.

Explore Our Free Tools & Games

Check out our curated collection of completely free browser games, tools, and extensions.

Browse Free Stuff

More Articles

Developer ToolsJSON

Stop Squinting at Messy JSON - Format It Instantly (Free Tool Inside)

Messy JSON is a productivity killer. Learn why formatting matters, common JSON pitfalls developers hit daily, and try our free browser-based JSON Formatter that works instantly with zero sign-ups.

7 min readRead More→
Browser GamesFree Games

Best Free Browser Games You Can Play Right Now in 2025

Discover the top free browser games of 2025 that require no downloads, no installs, and no sign-ups. From puzzle games to multiplayer adventures, these games run right in your browser.

8 min readRead More→
Developer ToolsFree Tools

Free Developer Tools Every Programmer Needs in Their Toolkit

A comprehensive guide to the best free developer tools available online. From JSON formatters to regex testers, these browser-based tools will supercharge your productivity.

10 min readRead More→
Chrome ExtensionsProductivity

10 Free Chrome Extensions That Will Boost Your Productivity

These free Chrome extensions will transform how you browse, work, and manage your time online. From tab management to dark mode, these extensions are must-haves.

7 min readRead More→