Team Development Workflow - Complete GitHub Flow Guide
Working alone lets you move freely, but as soon as you join a team, rules become necessary. “Someone’s change broke my code,” or “I can’t tell which branch is up to date” — these problems are exactly what a team development workflow prevents.
This article explains the standard practices for working as a team on GitHub.
What Is GitHub Flow?
Section titled “What Is GitHub Flow?”GitHub Flow is a simple branching strategy centered around the main branch. It avoids complex branch management and enables frequent releases.
The GitHub Flow Cycle
Section titled “The GitHub Flow Cycle”1. Create a new branch from main
2. Commit changes on the branch
3. Open a Pull Request
4. Receive a code review
5. Merge into main
6. DeployRepeat this cycle. There are no complex rules.
GitHub Flow vs. Git Flow
Section titled “GitHub Flow vs. Git Flow”Another well-known branching strategy is Git Flow. Here is a comparison of the two:
| Comparison | GitHub Flow | Git Flow |
|---|---|---|
| Number of branches | main + feature branches | main, develop, feature, release, hotfix — 5 types |
| Complexity | Simple | Complex |
| Release frequency | Continuous (suited for continuous deployment) | Planned releases |
| Best for | Web services, SaaS | Libraries and apps requiring versioned releases |
GitHub Flow is recommended for most web service development. If your release process is complex and requires careful scheduling, consider Git Flow.
Branch Naming Conventions
Section titled “Branch Naming Conventions”Branch names should make it immediately clear what work is being done on that branch. Consistent naming helps the entire team understand the state of the project at a glance.
Common Prefixes
Section titled “Common Prefixes”| Prefix | Purpose | Example |
|---|---|---|
feature/ | New feature development | feature/user-authentication |
fix/ | Bug fixes | fix/login-button-not-responding |
hotfix/ | Emergency fixes for production | hotfix/payment-error |
chore/ | Tests, configuration, dependency updates | chore/update-dependencies |
docs/ | Documentation updates | docs/api-reference |
refactor/ | Refactoring (no behavior change) | refactor/auth-module |
Good vs. Bad Branch Names
Section titled “Good vs. Bad Branch Names”| Rating | Example | Reason |
|---|---|---|
| Good | feature/add-search-function | Clearly states what will be done |
| Good | fix/issue-42-null-pointer | Issue number makes it easy to trace |
| Bad | test | Content is unclear |
| Bad | john-branch | A person’s name tells you nothing about the content |
| Bad | fix | Does not say what is being fixed |
| Bad | new feature | Spaces in branch names can cause problems |
Use lowercase letters, numbers, and hyphens in branch names. Avoid spaces and non-ASCII characters.
Commit Message Conventions
Section titled “Commit Message Conventions”Commit messages are the history of your code changes. A good message conveys not just “what changed” but “why it changed.”
Conventional Commits
Section titled “Conventional Commits”Conventional Commits is a specification for standardizing commit message formats.
Format: <type>(<scope>): <description>
| Type | Meaning | Example |
|---|---|---|
feat | New feature | feat: add user search functionality |
fix | Bug fix | fix: login button not responding |
docs | Documentation change | docs: add setup instructions to README |
style | Code formatting (no behavior change) | style: fix indentation |
refactor | Refactoring (no behavior change) | refactor: extract auth logic into function |
test | Adding or fixing tests | test: add unit tests for login feature |
chore | Build config, dependency updates | chore: update eslint to v8 |
ci | CI configuration changes | ci: fix GitHub Actions workflow |
Writing Good Commit Messages
Section titled “Writing Good Commit Messages”# Good example
feat(auth): add password reset feature
Added the ability for users to request a password reset link
by entering their email address.
Closes #78
# Bad examples
fix
update
asdfghjklCommit Granularity
Section titled “Commit Granularity”Each commit should contain exactly one logical change. Combining “add login feature” and “change header design” in the same commit makes it difficult to track issues later.
Pull Request Best Practices
Section titled “Pull Request Best Practices”Keep PRs Small
Section titled “Keep PRs Small”The smaller a PR, the better. Large PRs overwhelm reviewers and lead to lower-quality reviews.
| PR Size | Approximate Line Count | Reviewability |
|---|---|---|
| Small (ideal) | Up to 200 lines | Easy to review with full focus |
| Medium (acceptable) | 200–400 lines | Reviewable with careful reading |
| Large (caution) | 400+ lines | Creates a significant burden on reviewers |
PR Description Template
Section titled “PR Description Template”## What Changed
- Added user search feature
- Added a component to display search results
## Why This Change
Addressing the user request in Issue #42.
Users lacked a way to search for other users by name.
## How to Test
1. Start the application
2. Type a name into the search bar in the header
3. Confirm that search results appear
## Screenshots
(Before) (After)
## Related Issue
Closes #42The Importance of Self-Review
Section titled “The Importance of Self-Review”Before opening a PR, review your own changes first. Looking at the diff in the “Files changed” tab often reveals typos or leftover debug code.
Code Review Culture
Section titled “Code Review Culture”The purpose of code review is to improve code quality and share knowledge across the team. It is not about finding fault.
Writing Review Comments
Section titled “Writing Review Comments”| Type | Style | Example |
|---|---|---|
| Required change | [must] or direct request | [must] This has a SQL injection vulnerability |
| Suggestion | [nit] or a question | [nit] A more specific variable name might make this easier to read |
| Question | Ask what/why | What scenario does this condition handle? |
| Praise | Positive comment | This approach is clean and simple! |
Approve vs. Request Changes
Section titled “Approve vs. Request Changes”| Action | Meaning | When to Use |
|---|---|---|
| Comment | Comment only | You have questions or suggestions, but do not want to block the merge |
| Approve | Approved | Ready to merge as-is or after minor fixes |
| Request changes | Changes required | Must be fixed before merging |
Reviewer Mindset
Section titled “Reviewer Mindset”- Critique the code, not the person
- Explain why something is a problem
- Actively praise good code
- Aim to respond within 24 hours
Reviewee Mindset
Section titled “Reviewee Mindset”- Do not take review comments personally
- Reply “fixed” to let the reviewer know about changes
- It is fine to discuss disagreements
- You can merge once you receive an Approve
Branch Protection Rules
Section titled “Branch Protection Rules”Branch protection rules prevent accidental or unauthorized changes to the main branch. Rules like “no merge without a review” or “no merge if tests fail” are automatically enforced.
How to Configure
Section titled “How to Configure”Go to “Settings” → “Branches” → “Add branch protection rule.” Enter main in the “Branch name pattern” field and configure the following settings.
Common Settings
Section titled “Common Settings”| Setting | Description | Recommendation |
|---|---|---|
| Require a pull request before merging | A PR is required to merge | Enable |
| Required number of approvals | Minimum number of Approvals | At least 1 |
| Dismiss stale pull request approvals when new commits are pushed | New commits reset existing Approvals | Enable |
| Require status checks to pass before merging | CI tests must pass | Enable |
| Require branches to be up to date before merging | Branch must be up to date before merging | Enable |
| Do not allow bypassing the above settings | Administrators cannot bypass rules | Consider enabling |
| Allow force pushes | Permit force pushes | Disable |
Setting Up CODEOWNERS
Section titled “Setting Up CODEOWNERS”CODEOWNERS is a mechanism that automatically assigns the right people as reviewers when files they own are changed.
Writing .github/CODEOWNERS
Section titled “Writing .github/CODEOWNERS”# Format: <pattern> <GitHub username or team>
# Assign @alice to all file changes
* @alice
# frontend/ changes require review from @bob and @carol
frontend/ @bob @carol
# Core backend logic is owned by @backend-team
src/core/ @myorg/backend-team
# Documentation changes go to @docs-team
*.md @myorg/docs-team
# Security-sensitive files always require @security-team review
.github/workflows/ @myorg/security-teamWhen combined with the “Require review from Code Owners” branch protection setting, important files are guaranteed to be reviewed by their designated owners.
Choosing a Merge Strategy
Section titled “Choosing a Merge Strategy”When merging a PR, GitHub offers three options. Agree on one as a team to keep your history readable.
| Merge Strategy | Characteristics | Best For |
|---|---|---|
| Merge commit | All commits are preserved; a merge commit is created | When you want to retain the full history of every change |
| Squash and merge | All commits on the branch are squashed into one | When you want a clean, readable history on main |
| Rebase and merge | No merge commit; creates a linear history | When you want to keep main history perfectly linear |
“Squash and merge” is recommended for beginner teams. It keeps work-in-progress commits (like “WIP” or “fix typo”) off main, resulting in a cleaner history.
Release Management
Section titled “Release Management”Using Milestones
Section titled “Using Milestones”A Milestone is a feature for grouping Issues and PRs toward a specific release or deadline.
Create one at “Issues” → “Milestones” → “New milestone.” Set a title (e.g., v1.0.0 Release) and a due date, then attach related Issues to the milestone.
A progress percentage is displayed, giving you an at-a-glance view of how much work remains before the release.
Writing Release Notes
Section titled “Writing Release Notes”Good release notes include the following:
## v1.2.0 (2026-03-21)
### New Features
- Added user search (#42)
- Dark mode support (#55)
### Bug Fixes
- Fixed login button not responding in certain environments (#61)
- Fixed profile image not displaying correctly (#63)
### Breaking Changes
- Minimum supported Node.js version is now v18Anti-Patterns in Team Development
Section titled “Anti-Patterns in Team Development”These are practices to avoid in team development.
Direct Pushes to main
Section titled “Direct Pushes to main”# Never do this
git push origin mainDirect pushes to main are forbidden. Always create a branch and merge through a PR. Branch protection rules can physically prevent this.
Oversized PRs
Section titled “Oversized PRs”A PR with over 1,000 lines is practically impossible to review effectively. Split features into smaller, separate PRs.
Merging Without a Review
Section titled “Merging Without a Review”Skipping a review because you are “in a hurry” is dangerous. Many production incidents originate from unreviewed changes.
Opening a PR With Unresolved Conflicts
Section titled “Opening a PR With Unresolved Conflicts”Pull the latest main changes into your branch and resolve any conflicts before opening a PR.
Meaningless Commit Messages
Section titled “Meaningless Commit Messages”Messages like “fix,” “update,” or “asdf” make it impossible to understand what changed later.
Force Pushing to a Shared Branch
Section titled “Force Pushing to a Shared Branch”Do not use git push --force on branches shared with others. It can overwrite teammates’ commits. If unavoidable, use --force-with-lease and notify your team in advance.
Q. Should I choose GitHub Flow or Git Flow?
Section titled “Q. Should I choose GitHub Flow or Git Flow?”GitHub Flow is recommended for most web service development. Git Flow has many branches to manage and a steeper learning curve. Start with GitHub Flow, and consider Git Flow only if you need to maintain multiple versions simultaneously.
Q. Is it okay to write commit messages in a language other than English?
Section titled “Q. Is it okay to write commit messages in a language other than English?”As long as your team agrees, any language is fine. However, English is the standard for open source projects and international teams. The Conventional Commits format (feat:, fix:, etc.) can be used regardless of language.
Q. What should I do when reviewers disagree?
Section titled “Q. What should I do when reviewers disagree?”Try to resolve the disagreement through written discussion first. If that does not work, discuss it verbally or in a meeting. Keep the focus on the shared goal of improving code quality, not on personal opinions.
Q. I set up branch protection rules and now no one can merge.
Section titled “Q. I set up branch protection rules and now no one can merge.”If “Require approvals” is set to 1 or more and no one has Approved the PR, merging is blocked. Have another team member Approve the PR. If you are a solo developer, set the required number of approvals to 0 or adjust the branch protection settings accordingly.
Q. Does squash and merge delete my commit history?
Section titled “Q. Does squash and merge delete my commit history?”The original branch still exists unless you delete it. The individual commits will no longer appear in main’s history, but you can still view them on the original branch or from the PR page.