| 1 | --- |
| 2 | name: git |
| 3 | description: Git workflow rules for this repository. |
| 4 | allowed-tools: Read, Write, Edit, Glob, Grep, AskUserQuestion |
| 5 | user-invocable: true |
| 6 | --- |
| 7 | |
| 8 | # Git skill |
| 9 | |
| 10 | ## Core rule |
| 11 | |
| 12 | - Use `--no-ff`. Important. |
| 13 | |
| 14 | ## What this means in practice |
| 15 | |
| 16 | - Do not fast-forward merge feature branches, release branches, or hotfix branches. |
| 17 | - Prefer explicit merge commits so the branch history stays visible. |
| 18 | - Release prep goes through `development` on its way to `main`, with `--no-ff` at every hop. |
| 19 | - Tag the merge commit that contains the final release state. |
| 20 | |
| 21 | ## Branch flow |
| 22 | |
| 23 | Feature branches merge into `development`. Releases go: |
| 24 | |
| 25 | ``` |
| 26 | release/vX.Y.Z -> development -> main |
| 27 | ``` |
| 28 | |
| 29 | Never merge a release branch straight into `main` — `development` has to carry the |
| 30 | release state too, or the next feature branch starts from a base that is missing it. |
| 31 | |
| 32 | ## Release guidance |
| 33 | |
| 34 | ```bash |
| 35 | # 1. cut the release branch from development, commit the version bumps |
| 36 | git checkout development |
| 37 | git checkout -b release/vX.Y.Z |
| 38 | git commit -am "Prepare vX.Y.Z" |
| 39 | |
| 40 | # 2. release branch -> development |
| 41 | git checkout development |
| 42 | git merge --no-ff release/vX.Y.Z -m "Merge release prep for vX.Y.Z" |
| 43 | |
| 44 | # 3. development -> main |
| 45 | git checkout main |
| 46 | git merge --no-ff development -m "Merge development for vX.Y.Z" |
| 47 | |
| 48 | # 4. tag the main merge commit, then push |
| 49 | git tag vX.Y.Z |
| 50 | git push origin development |
| 51 | git push origin main |
| 52 | git push origin vX.Y.Z |
| 53 | ``` |
| 54 | |
| 55 | The tag belongs on the step-3 merge commit on `main`, not on the release branch and not |
| 56 | on `development`. Pushing the tag is what triggers the wrapper publish workflows, which |
| 57 | read the version from the tag. |
| 58 | |
| 59 | If the work is already on `main`, make a normal commit and tag that commit. Do not rewrite history just to avoid a merge commit. |
| 60 | |
| 61 | ## Avoid |
| 62 | |
| 63 | - `git merge --ff` |
| 64 | - `git pull --ff-only` as a default recommendation for this repo's merge policy |
| 65 | - Tagging a branch tip that has not been merged into `main` when the intended release source of truth is `main` |
| 66 | - Merging a release branch directly into `main`, skipping `development` |
| 67 | |
| 68 | ## Why |
| 69 | |
| 70 | The repo wants explicit history. Release commits should be easy to find, easy to audit, and clearly connected to the branch that introduced them. |