---
name: github-flow
description: Safe Git and GitHub habits for coding agents. Use whenever you are about to change code in a Git repository, start a new task, commit, push, or open a pull request. Puts every task on its own branch, commits in small steps with clear messages, opens a pull request with a summary, and never commits or pushes straight to main.
---

# GitHub flow

Every change you make should be easy to review and easy to undo. Main is the
version that works. You never touch it directly. You work on a branch, save
small snapshots (commits), and ask for your work to be added to main through a
pull request.

## Before you change anything

1. Check you are in a Git repository: `git rev-parse --is-inside-work-tree`.
   If not, ask the user whether to run `git init` before going further.
2. Look at the state you are starting from: `git status` and
   `git branch --show-current`.
3. If there are uncommitted changes you did not make, stop and ask the user
   what to do with them. Do not stash, reset, or discard someone else's work.
4. Find the default branch (usually `main`, sometimes `master`):
   `git symbolic-ref --short refs/remotes/origin/HEAD` or ask the user.
5. Update it if there is a remote: `git fetch origin`.

## One task, one branch

- Create a fresh branch for each task, starting from the latest default branch:
  `git switch -c <type>/<short-name> origin/main`
  (use `main` instead of `origin/main` if there is no remote).
- Name it after the work: `feat/login-page`, `fix/cart-total`, `docs/readme`.
- If you are already on a task branch the user created for this work, keep
  using it. Do not create branches off branches unless asked.
- Never do task work while on `main`. If you notice you are on main with
  changes, create the branch right away (`git switch -c <name>`); the changes
  come with you.

## Commit in small steps

- Commit each time one small, working step is done: a function, a fix, a test.
  A good commit can be explained in one line.
- Stage only the files for that step: `git add <paths>`. Avoid `git add -A`
  unless you have checked `git status` and every file belongs.
- Never commit secrets: `.env` files, API keys, tokens, private keys. If one
  is about to be committed, stop and add it to `.gitignore` instead.
- Write messages as a short summary of what changed and why:
  - Good: `Add email check to signup form`
  - Bad: `update`, `fix stuff`, `wip`
- Run the project's tests or build before committing when they exist. Do not
  commit code you know is broken unless the user asks for a work-in-progress
  commit.

## Push and open a pull request

When the task is done (or the user wants a review):

1. Push the branch: `git push -u origin <branch>`.
2. Open a pull request into the default branch. With the GitHub CLI:
   `gh pr create --base main --title "<what this does>" --body "<summary>"`.
   If `gh` is not installed or not logged in, give the user the compare link
   GitHub prints after the push.
3. The pull request description should say:
   - What changed, in plain words.
   - Why it changed.
   - How you checked it works (tests run, what you tried).
   - Anything the reviewer should look at closely, or that you could not test.
4. Tell the user the pull request link. Merging is their decision unless they
   have told you to merge.

## Hard rules

- Never commit directly to `main` (or `master`, or the default branch).
- Never push to `main`.
- Never force-push (`--force`, `-f`) a shared branch. If history must be
  rewritten on your own branch, ask first and use `--force-with-lease`.
- Never delete branches, tags, or commits you did not create.
- Never use `--no-verify` to skip the project's checks without asking.
- If a command would throw away work (`reset --hard`, `checkout -- .`,
  `clean -fd`), stop and ask.

## When things go wrong

- **Made something worse?** Go back to the last good commit on your branch with
  `git revert <commit>` (safe, keeps history) rather than rewriting history.
- **Merge conflict?** Do not guess. Show the user the conflicting files, explain
  what each side changed, and propose a resolution before applying it.
- **Push rejected?** Run `git fetch` and rebase or merge the default branch into
  your branch, re-run the tests, then push again. Do not force it.
- **Committed to main by mistake (not pushed yet)?** Create a branch at that
  point (`git branch <name>`), then ask the user before moving main back.

## Finish checklist

Before you say the task is done:

- [ ] Work is on a task branch, not main.
- [ ] Commits are small, with clear messages.
- [ ] No secrets or stray files were committed.
- [ ] Tests or build pass, or you said clearly what you could not run.
- [ ] Branch is pushed and a pull request is open, with a summary.
- [ ] You gave the user the pull request link.

---

Free skill from CTO Breakdowns (lesson: GitHub crash course).
More from Henry: odd.community
