Branches are cheap to make and to delete
Branch hygiene is the housekeeping that keeps a repo readable a year in. The principle: make new branches without ceremony, but delete them once the work has landed. A repo with 200 stale branches is functionally a junk drawer; a repo with the active dozen is a workspace. The rule scales: project, team, and personal repos all benefit.
Naming pulls weight here. Most teams use prefix-based namespaces: feature/, bugfix/, hotfix/, release/, chore/, experiment/. The shape feature/short-summary reads in git branch -a output and groups well in tools. Add an issue or ticket reference when you have one: feature/142-oauth-github. Avoid generic names like my-changes, fix, or test — they collide and tell you nothing.
Deletion has two flavors. git branch -d feature/login deletes only if the branch is fully merged into its upstream — Git checks for you. git branch -D force-deletes regardless. Use -d by default; -D is for branches you intentionally abandoned without merging. After deleting locally, push the deletion to keep the remote tidy: git push origin --delete feature/login. GitHub also has an "auto-delete head branches after merge" setting that does this for PR-based workflows.
Pruning is the cleanup nobody schedules but everybody needs. git remote prune origin removes remote-tracking refs whose upstream branches no longer exist on origin. git fetch --prune does the same as part of normal fetch — set git config --global fetch.prune true and forget about it. git branch --merged main lists local branches fully merged into main, perfect candidates for deletion. Run that occasionally and the repo stays readable.