Git Workflow for Python: Branches, Hooks, and Quality Gates
I set up a disciplined Git workflow for Python work with a proper .gitignore, feature branches, and pre-commit hooks running ruff and pytest. Automated gates blocked unlinted or failing code from ever reaching a commit.
Objective & Context
Version control discipline prevents broken history and accidental secret commits. This lab pairs branch-per-change workflow with pre-commit automation so quality checks run locally before code is shared, the foundation for the DevOps CI labs.
Environment & Prerequisites
- Git 2.4x; a Python project with a venv.
- pre-commit, ruff, and pytest installed.
- A remote repository for push/PR flow.
flowchart LR
B[feature branch] --> E[edit + add]
E --> H{pre-commit
ruff + pytest} H -->|fail| E H -->|pass| C[commit] C --> PR[push + PR]
ruff + pytest} H -->|fail| E H -->|pass| C[commit] C --> PR[push + PR]
Step-by-Step Execution
1. Ignore venv and caches
printf ".venv/\n__pycache__/\n*.pyc\n.env\n" > .gitignore2. Install pre-commit hooks
pre-commit install && pre-commit run --all-files3. Work on a feature branch
git switch -c feat/parser && git commit -am "add argument parser"ruff.....Passed
pytest...Passed
[feat/parser 9c2a1f] add argument parser
Validation & Testing
Introduce a lint error and a failing test, then attempt a commit. Pass criteria: the commit is blocked by the hook, and only passes once both ruff and pytest are green; .venv and .env never appear in git status.
Advanced: Troubleshooting
- Hooks not running: re-run
pre-commit installafter cloning. - Secret committed: add it to .gitignore and rewrite history with filter-repo.
- Slow hooks: scope pytest to changed files in CI, full suite on push.
Key Results
- Blocked 100% of unlinted/failing commits via pre-commit gates.
- Prevented venv and secret files from entering version control.
- Standardized branch-per-change with PR review.
- Cut review churn by catching issues before push.