Git Best Practices
A condensed summary of the 25 most important Git practices for Python teams - clean history, reviewable commits, and CI-aligned hooks.
Search across all documentation pages
A condensed summary of the 25 most important Git practices for Python teams - clean history, reviewable commits, and CI-aligned hooks.
main is always integration truth: Every merged PR passes ruff, pytest, and typecheck; never leave main broken overnight (Essential Git Commands).
Commit the lockfile: uv.lock (or poetry.lock) required for reproducible uv sync --frozen in CI - never gitignore it.
Ticket IDs in every commit: feat(billing): tax line [BILL-42] - cherry-picks to release/* depend on traceable messages.
Squash merge features to main: One ticket, one commit on integration branch when team policy allows.
Short-lived feature branches: Target 1-3 days; rebase main daily to avoid lockfile and Alembic conflicts.
Cut release/x.y for coordinated trains: API + worker + migration ship together; new features land on main until tag.
Release branch accepts bugfixes only: Enforce with branch protection during freeze windows.
Cherry-pick to release/*, never merge main into release/*: Merging pulls unvetted features into the release candidate.
Tag from release/* after staging sign-off: v2.6.0 triggers release pipeline; tag message lists deployables.
Merge release/* back to main after rollout: Preserve train boundary; delete release branch when complete.
Hotfix branches from production tags: git checkout -b hotfix/2.5.1 v2.5.0 - not from main when it is ahead of production.
Backport every hotfix: Cherry-pick fix SHA to main and open release/* if still active.
Never force-push shared branches: main, release/*, hotfix/* history is audit evidence.
pre-commit mirrors CI: ruff check, ruff format, quick pytest - same commands as GitHub Actions (Git Configuration).
PR template requires migration note: Alembic revisions need rollback plan or expand-contract strategy.
Branch protection requires status checks: Policy beats honor system for required workflows.
Never commit .env or secrets: .env.example only; production via platform secret inject.
Do not commit .venv/, __pycache__/, or dist/: Artifacts belong in CI/CD, not git.
Conventional commits for changelog automation: Pair with semantic-release or custom changelog script if adopted.
Tag creation restricted: Tags trigger production - rulesets or release manager role.
Monorepo: document tag strategy: One monorepo tag vs per-service tags - pick one and document.
API + worker schema changes linked: Event contract drift breaks async flows - one PR or explicitly linked PRs.
Review lockfile diffs on dependency PRs: Unexpected new transitive deps are supply-chain red flags.
Document rollback in release notes: Image digests, migration down plan, feature flag kill switch.
Interactive rebase on private feat/* only: --force-with-lease before PR review; never on shared branches.
Most Python service teams use trunk + release/hotfix - simpler than long-lived develop unless org mandates GitFlow.
Enforce ticket id and imperative mood; conventional type scope when changelog automation depends on it.
Auto-merge patch bumps when CI green; minor/major needs human review of lockfile diff.
Follow Git for Data/Notebooks - nbstripout mandatory.
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 16, 2026