Git Configuration
Aliases, hooks, and sensible Git defaults for Python teams using uv, ruff, and pytest locally and in CI.
Recipe
git config --global user.name "Ada Lovelace"
git config --global user.email "ada@acme.com"
git config --global pull.rebase true
git config --global fetch.prune true
git config --global alias.lg "log --oneline --graph -20"When to reach for this:
- New laptop setup for developers
- Standardizing team git behavior via docs + template config
- Adding pre-commit hooks matching GitHub Actions
- Enabling commit signing or GPG/SSH signatures
Working Example
# ~/.gitconfig (excerpt)
[user]
name = Ada Lovelace
email = ada@acme.com
[pull]
rebase = true
[fetch]
prune = true
[init]
defaultBranch = main
[alias]
st = status -sb
sync = "!git fetch origin && git rebase origin/main"
cleanup = "!git branch --merged main | grep -v main | xargs git branch -d"# .pre-commit-config.yaml (repo)
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.0
hooks:
- id: ruff
- id: ruff-format
- repo: local
hooks:
- id: pytest-quick
name: pytest quick
entry: uv run pytest -q tests/unit
language: system
pass_filenames: falseWhat this demonstrates:
- Global identity and rebase-on-pull defaults
- Short aliases for daily sync
- pre-commit mirrors CI lint and fast unit tests
defaultBranch = mainfor new repos
Deep Dive
How It Works
- Config levels - system < global < local < worktree; local overrides global per repo.
- Hooks - Scripts in
.git/hooks/or managed by pre-commit framework. - Attributes -
.gitattributesfor nbstripout, LFS, linguist-generated. - Signing - SSH commit signing (
gpg.format ssh) on modern Git.
Recommended Settings
| Setting | Value | Why |
|---|---|---|
pull.rebase | true | Linear feature integration |
fetch.prune | true | Remove stale remote branches |
rebase.autoStash | true | Rebase with dirty tree (careful) |
core.autocrlf | input on mac/linux | Avoid CRLF noise in Python |
init.defaultBranch | main | Consistent primary branch name |
Python Notes
# Repo-local identity for work laptop
git config user.email "ada@acme.com"
# Ensure hooks run
uv run pre-commit install
uv run pre-commit run --all-filesGotchas
- Global hooks blocking WIP commits - Full pytest on every commit slows flow. Fix: quick unit subset locally; full suite in CI.
- autoStash surprise - Hidden stash entries after rebase. Fix:
git stash listhygiene. - Wrong email on commits - Breaks CLA and audit. Fix:
git config user.emailper repo for contractors. - Skipping hooks with
--no-verify- Bypasses ruff on emergency commit. Fix: allow only break-glass; fix before merge. - Windows line endings - Mixed CRLF fails ruff. Fix:
.gitattributes* text=auto eol=lf. - Commit signing misconfigured - Rejected pushes. Fix: test
git commit -S -m "test"on one branch first.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Husky (Node teams) | Monorepo with JS + Python | Pure Python - pre-commit is native fit |
| CI-only gates | Hooks politically blocked | Developers push failing ruff often |
git config --global includeIf | Work vs personal repos on one laptop | Single employer machine |
| Manual checklist | Tiny team | Scale beyond ~5 developers |
FAQs
Global or repo pre-commit?
Repo .pre-commit-config.yaml committed - everyone shares hooks; pre-commit install per clone.
SSH commit signing setup?
git config gpg.format ssh and user.signingkey to public key path - GitHub verifies SSH signatures.
Alias for current branch PR?
gh pr view --web or alias pr = "!gh pr view --web" after push.
Credential helper on macOS?
Osxkeychain stores HTTPS tokens; prefer SSH for git operations.
Template gitconfig for onboarding?
Link from Environment Setup Checklist with copy-paste block.
core.excludesfile global ignore?
~/.gitignore_global for .DS_Store, IDE files - supplements repo .gitignore.
Blame ignore revs?
.git-blame-ignore-revs for mass format commits - cleaner archaeology.
Submodule config?
Rare in Python services - if used, submodule.recurse for clone/pull behavior.
Large repo performance?
feature.manyFiles true and partial clone git clone --filter=blob:none for huge monorepos.
Disable rebase pull for one repo?
git config pull.rebase false local override when merging release branches frequently.
Related
- Essential Git Commands - commands aliases wrap
- Git for Data/Notebooks - nbstripout attributes
- Linting & Formatting - ruff in hooks
- Environment Setup Checklist - new dev setup
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+.