跪拜 Guibai
← All articles
Backend

The Git Workflow Rules That Keep Hundreds of Devs From Breaking Production

By 苏三说技术 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

A team that outgrows ad-hoc Git habits pays the cost in merge conflicts, untraceable regressions, and manual release toil. Adopting even a lightweight version of these conventions—structured commits, a simple branching model, and mandatory review—cuts incident-resolution time and makes onboarding measurable.

Summary

Three branching strategies dominate large-scale development: Git Flow for versioned releases, GitHub Flow for continuous delivery, and Trunk-Based Development for teams that merge to main at least daily. Most large orgs run a hybrid, stripping out release branches and enforcing short-lived feature work. Branch names carry ticket IDs and semantic prefixes so that a branch alone answers who, what, and why.

Commit messages follow the Conventional Commits spec—`feat(scope): description`—because structured messages feed automated changelogs, speed up code review, and make `git blame` useful during incidents. The spec is enforced by Commitlint and Husky hooks; a commit that breaks the format never reaches the remote.

Code review is not advisory. Branch protection rules block direct pushes to main, require at least two approvals, and demand CI passes before merge. Pre-commit hooks run formatters and linters, while CI pipelines gate on compilation, test coverage ≥80%, and security scans. The toolchain removes self-discipline from the equation—if the pipeline says no, the code doesn't ship.

Takeaways
Git Flow, GitHub Flow, and Trunk-Based Development are the three dominant models; large teams often run a hybrid that drops the release branch and uses tags instead.
Branch names should follow `<type>/<ticket>-<description>` so that the branch itself links to a task and states its purpose.
Conventional Commits (`feat`, `fix`, `refactor`, etc.) are the industry standard because they enable automated changelogs and make `git blame` actionable.
Commitlint plus Husky rejects commits that violate the message format before they leave a developer's machine.
Branch protection rules block direct pushes to main, require at least two approving reviews, and demand passing CI before a merge.
CI quality gates enforce compilation, unit-test coverage ≥80%, linting, and security scanning; any failure prevents the merge.
Semantic versioning (`MAJOR.MINOR.PATCH`) tied to annotated Git tags is the default release-signaling mechanism.
A single commit should address one concern and stay under roughly 300 lines; pull requests should not exceed 500–800 lines.
Standardized PR templates and review checklists ensure every merge carries a change description, linked ticket, test evidence, and a self-check for secrets.
Start with three steps: enforce Conventional Commits, adopt a minimal branching model (main + develop + feature/*), and require at least one review per merge.
Conclusions

The prescription is not "pick one branching model"; it is "pick the lightest model your release cadence can support and enforce it with tooling." The article's recommended starting point—main, develop, feature/*—is effectively a simplified Git Flow that works for most teams.

Commit message format is treated as the highest-ROI change because it feeds every downstream automation: changelogs, version bumps, and incident forensics all depend on structured, parseable messages.

The insistence on tool-enforced gates rather than team agreements reflects a hard-won lesson: at scale, process that depends on human memory or goodwill decays immediately. The pipeline is the policy.

Requiring ticket IDs in branch names is a small rule with outsized impact—it closes the loop between a production change and the original requirement or bug report without any extra tooling.

Concepts & terms
Conventional Commits
A specification for commit messages that structures them as `type(scope): description`, where type is a fixed set like `feat`, `fix`, or `refactor`. It enables automated changelog generation and semantic versioning.
Trunk-Based Development
A branching strategy where all developers commit to a single trunk (main) through short-lived feature branches that live no more than 1–3 days. Feature flags hide incomplete work, keeping main always deployable.
Git Flow
A branching model with two permanent branches (main and develop) and three temporary branch types (feature, release, hotfix). It suits projects with scheduled version releases and multiple maintained versions.
Semantic Versioning (SemVer)
A versioning scheme of MAJOR.MINOR.PATCH where MAJOR increments for breaking API changes, MINOR for backward-compatible features, and PATCH for backward-compatible fixes.
Commitlint
A tool that lints commit messages against a configurable spec (typically Conventional Commits). Combined with Husky Git hooks, it rejects non-conforming commits locally before they are pushed.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗