mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-11-09 00:22:38 -06:00
4.3 KiB
4.3 KiB
Git, plans, worktrees
Commits
- Conventional Commits (
feat: add foo,fix: correct bar). Changelogs are generated from them. - Lint before committing and fix what it reports:
- backend changes:
mage lint:fix - frontend changes:
cd frontend && pnpm lint:fix - CSS/SCSS or Vue
<style>changes: alsopnpm lint:styles:fix
- backend changes:
- Never commit edits to
pkg/swagger/; CI regenerates it after commit.
Plans
When asked to create a plan, write it to plans/<kebab-case-name>.md (e.g. fix-position-healing.md). plans/ is gitignored; never force-add it.
Worktrees
To implement a plan in isolation, invoke the prepare-worktree skill.
Stacked PRs
- One session owns a stack and does every rebase from its own worktree. Don't check out a stack branch in another worktree: git refuses to rebase a branch checked out elsewhere, and
gh stack rebaseaborts. - Cascade with recorded tips: note each layer's tip before a fix round, then
git rebase --onto <new lower tip> <recorded old lower tip>per layer, and push with--force-with-lease=<branch>:<old tip>. Never derive the old base frommerge-baseonce a lower layer was rebased; it replays the lower layer's commits into the upper one. - After rebasing a stack onto
main, search for imports of modules the stack deletes. New files onmaincan reference them without causing a conflict. - When a stack merges as a whole, intermediate PRs may depend on later ones. Say so in each PR body so reviewers don't report those states as bugs.
- Add a layer with
gh stack addorgh stack link, never plaingh pr create; that PR doesn't join the stack. - A new helper shared across resources gets its own PR at the bottom of the stack, and that PR moves every existing copy onto it. Never add it inside a resource PR or leave the old and new pattern side by side.
Reviewable PRs
- Keep mechanical changes and behaviour changes in separate commits. A mechanical commit (renames,
projectIdtoproject_id, swapping one type for its replacement) contains no logic change; a line that needs different behaviour waits for the next commit, even if that leaves a type error in between. Mark the subject:refactor(project-views): switch consumers to generated types (mechanical). - Commits in a PR don't need to build individually; the history shows the real sequence of work.
- Produce mechanical changes with a script where possible (sed, ts-morph) and put the exact command in the commit body, so the reviewer can check the script and re-run it instead of reading the diff.
- Renames of data fields must not touch i18n keypaths or
$t()keys. Grep the diff forkeypath=andt('before committing; thesharedBytoshared_byrename rendered raw keys. - Order commits the same way in every PR: tests pinning current behaviour, shared test harness, new query module, mechanical consumer switch, behaviour changes, deletion of the replaced code.
- While a PR is a draft, record corrections as
git commit --fixup <sha>. Before marking it ready, fold them in withgit rebase -i --autosquashso reviewers read the final commits, not the iteration history. This is the one exception to never amending or rewriting commits, and it applies only to PRs nobody has reviewed yet. - A fixup that touches a test file targets the source commit owning the module, not the test commit. Autosquash moves fixups next to their target, so a fixup of the test commit lands before later source fixups on the same file and conflicts. Dry-run
GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash <base>in a throwaway worktree after each fix round. - Before merge: rebase the whole stack onto
origin/mainfirst, then autosquash each layer onto the squashed layer below. Checkgit diff --numstat <base>..<tip>per layer is unchanged by the rebase and the tree is identical before and after the squash. - Start the PR body with a short review guide: which commits are mechanical and can be skimmed, the few decisions that need real review, deviations from the plan, and any intermediate state that is knowingly broken.
- One resource per PR. When a PR starts carrying a neighbouring migration, split that into its own PR in the stack.
Refactors
- Find the consumers of a module by import path (
rg "components/misc/Subscription"), not by component tag or local name; components are often imported under an alias.