# TODO
> Thoughts on what to do next
---
## Bugs
- [x] Completions not working after running `source <(git stk completions bash)` in shell - the `_git_stk`
shim called the clap completer without the positional args `complete -F` normally passes, so its command
dispatch never matched. Fixed; the shim now passes command/cur/prev
- [x] `git stk -h` works but `git stk --help` shows "No manual entry for git-stk" - git intercepts
`<cmd> --help` and runs `man git-<cmd>`. Fixed via `git stk setup`, which installs the man page to
`~/.local/share/man/man1` and wires shell completions; `upgrade` re-renders assets via the new binary
(`setup --refresh`) after each upgrade
- [x] Completions don't include flags: was a clap_complete static-script bug with dashed binary names
(dispatch built `git__stk__subcmd__submit` but case labels said `git__subcmd__stk__subcmd__submit`).
Resolved by switching to clap_complete's dynamic completion (`CompleteEnv` + `COMPLETE=bash git-stk`) - the
static script generator is no longer used, so the bug is moot. Flags now complete; regression
test asserts `submit --<TAB>` yields `--dry-run --stack`
- [x] `git stk bump` next-step instructions don't work as printed: `git tag vX.Y.Z` creates a LIGHTWEIGHT
tag, and `git push --follow-tags` only pushes ANNOTATED tags (confirmed: `git cat-file -t v0.3.0` ->
`commit`, not `tag`). Fixed: printed steps now use `git tag -a vX.Y.Z -m vX.Y.Z`
- [x] `git-stk --version` errors - clap's version flag was never enabled. Fixed with `#[command(version)]`
## Handle more cases / types of merges
- [x] Squash-merge detection - solved by tracking fork points instead of detecting squashes: each branch
records `branch.<name>.stackBase`, restack rebases with `--onto` so only a branch's own commits replay,
and cleanup records the child's fork point off the merged parent before retargeting. Also makes amended
or rebase-merged parents restack cleanly
- [ ] Parent PR closed without merging: decide what `cleanup`/`status` should say (currently the merged-only
fallback lookup means closed-unmerged reviews report as "no review found")
- [ ] Parent branch deleted remotely after merge: use PR metadata to discover the old base when retargeting
## More helpful PR management tools
- [ ] Refresh stack overview notes during the merge cycle: `cleanup` should update the marker section in the remaining
PRs' descriptions (drop merged entries, re-point the base), since mid-merge the overview still lists
already-merged PRs until the next `submit --stack`
- [x] Graphite is really nice in how it comments on PRs directly to show the stack and where this PR sits in it.
Done via the PR description: `submit --stack` maintains a marker-delimited section at the end of every
body with the full stack as linked bullets (title + number), leaf-first, a pointing emoji on the PR
being viewed, the trunk in backticks at the bottom, and a "Stack managed by git-stk" footer link. The
markup self-repairs if a user hand-edits or deletes the markers
- [x] Simpler version first: "Depends on #123" style links in PR bodies on `submit --stack` - maintained in a
marker-delimited section (`<!-- git-stk:stack -->`) so resubmits update in place; the full Graphite-style
stack visualization above can reuse those markers later
- [x] `git stk list --markdown`: print the stack in a copy-paste format for sharing with reviewers in
Slack/etc. Done: summary line ("2 PRs, base `main`, 1 open / 1 merged"), then the PRs as an ordered
bottom-to-top (merge order) list with linked title + number and state. Works from anywhere in the
stack via the root walk, and degrades to backticked branch names without reviews or a provider CLI
- [ ] PR description note polish: do NOT drop merged/closed PRs from the stack overview - keep every
entry, with strikethrough text for merged/closed ones and an appended "(merged)" / "(closed)" after
the link. Replace the markdown bullets with status emojis at the left: purple circle for merged,
green circle for open, red circle for closed. Requires the note pass to look up review state for all
entries (it already has them) and pairs naturally with refreshing notes during the merge loop (item
above) - `merge`/`sync` would be the trigger points
- [ ] Better github/gitlab issues support - if a branch name in the stack references an issue number, we
could include the "Closes <issue>" comment in PR/MR description that I think works to close related
issues
## Stack ergonomics
- [x] Tab completion for branch-name arguments - done via clap_complete dynamic completion with custom
`ArgValueCompleter`s: branch args complete from local branches with prefix filtering, and `down <TAB>`
is stack-aware (offers only the current branch's children). The shell asks the binary at completion
time, so candidates are always live. bash + zsh shims keep `git stk <TAB>` working through git's
completion; elvish/fish/powershell get binary-form completion
- [ ] `status`/`list` should hint at what's next: e.g. "feature/b is 2 commits behind its parent - run
`git stk restack`", "review #5 base is stale - run `git stk submit`", "parent review merged - run
`git stk cleanup feature/a`". The data is already fetched; the hints make the tool teach its own loop
- [ ] Silence git noise when it isn't actionable: rebase progress ("Rebasing (1/1)"), `branch -d` upstream
warnings, etc. currently pass through raw because we use `Stdio::inherit` for status() calls. Capture
stderr and surface it only on failure (or behind `--verbose`); keep our own one-line summaries as the
primary output
- [ ] `top` / `bottom` navigation commands
- [ ] Better multi-child UX on `down` (interactive pick instead of erroring)
- [x] `repair` command: rebuild/verify local metadata from provider state in one shot. Done - and it
implements the full original priority chain (review base -> nearest-ancestor inference -> report for
manual `adopt`), verifies/re-derives stale fork points, never touches the trunk, and degrades
gracefully without a remote or provider CLI. Motivated by the great config-wipe incident
- [x] Ancestry-inference fallback for parent discovery - folded into `repair` (see above); per-command
fallback is unnecessary now that one command rebuilds everything
- [ ] Handle branch renames (metadata under `branch.<old>.stackParent` goes stale)
- [x] `submit --stack` AND `restack` should work from anywhere in the stack, like Graphite. Done via the
`stack_root` walk: both commands now operate on root + descendants regardless of position. The root
is excluded only when it is the trunk; an unanchored root still fails validation with the adopt/sync
hint. WIP-upstack scoping (`--downstack`) remains future work. (Bit us three times before landing:
the v0.4.0 merge ceremony, the one-switch loop, and a one-branch submit from the leaf)
- [x] One-shot merge-loop advance command - done by absorbing it into `sync` (Graphite precedent:
`gt sync`), avoiding a new verb that would conflate with `continue`/`up`. `git stk sync` now: fetches
the trunk (checkout-aware, `fetch main:main` when elsewhere / `pull --ff-only` on trunk), refreshes
metadata from open reviews (the old sync), cleans up provider-verified merged branches, moves you off
any branch being deleted (onto the new bottom - "the next one up"), restacks + pushes per
`stk.pushOnRestack`, and prints `next up: <branch> -> #N <url>` or `stack complete`. Scope changed
from all-local-branches to the current stack. NOT yet included: refreshing stack overview notes
during the loop (see the cleanup-notes item above - still open)
- [ ] `git stk guide` command to provide an example to try the tool out?
- [ ] More color in CLI all over the place to make it feel more professional
## More git automation
- [x] Should we handle pushing so it's not a manual step or doesn't have to be? Done: `submit --push` /
`--no-push` with `stack.pushOnSubmit` config fallback pushes the submitted branches with
`-u --force-with-lease` before any provider calls (review creation needs the branch remotely anyway).
Combined with `restack --push`, no part of the stack workflow requires a manual `git push`
- [x] Same question for `restack`: offer `--push` / config to force-with-lease push rebased branches.
Done: `restack --push` / `--no-push` with `stack.pushOnRestack` config fallback force-pushes (with
lease) every rebased branch, including after a conflicted restack finishes via `continue` (the state
file now carries the full branch list). Without it, restack prints the exact push command - the
stale-PR-diff trap from the first merge cycle is now impossible to hit silently
- [x] `cleanup --delete-branch` uses `git branch -d`, which can REFUSE after a squash merge (commits are not
ancestry-merged; it only worked for us because the branch matched its un-pruned upstream). Fixed: uses
`-D` now, justified by provider-verified merge state - strictly better information than git's ancestry
heuristic. Regression test does a real squash merge and proves `-d` would refuse
- [ ] Should `--delete-branch` be the default (with `--keep-branch` to opt out)? Cases for keeping: wanting
to inspect the old commits post-squash, reusing the branch name, or distrust while the tool is young.
Revisit once `-D` semantics above are in
## Automate completion setup
- [ ] Could installer include optional step (y/n) prompt the user asking if we can add the completion sourcing
script to their shell?
- [ ] Regardless, we should always print what the user should do after install/upgrade to get shell completions
for their detected shell
- [ ] Can completion docs and future automations include a guard to make sure `git stk` is valid or completion
files exist before sourcing completions?
## Providers
- [ ] Self-hosted GitLab support (`stack.gitlab.host` or similar config; detection only matches gitlab.com today)
- [ ] Low-noise "new version available" hint (check at most once/day on a common command, cache the result)
## Clearer docs / what needs to be cared about or is referenced in .gitconfig that the user would manage
- [x] If we have our own config section, it'd be `[stk]` I figure. Done as a clean break (0 users, no
migration): `stk.provider`, `stk.remote`, `stk.pushOnRestack`, `stk.pushOnSubmit`, and per-branch
`branch.<name>.stkParent` / `branch.<name>.stkBase`. Every tool-owned config key now greps for `stk`
- [x] Call out any "normal" git config settings we care about - resolved by eliminating the category:
restack now reads `stk.updateRefs` instead of git's `rebase.updateRefs`, so the tool reads NO git-owned
config at all. README has a Configuration section documenting every `[stk]` setting with defaults, and
`git stk config` prints all settings (set or default) plus per-branch metadata
- [ ] Document the install receipt (`~/.config/git-stk/`) and how `upgrade` uses it; `--head` leaves the receipt
version stale by design
## More release automation
- [x] Can `cargo publish` happen in our release.yml action automatically at the end? Done - dist 0.31 has
no built-in cargo publisher (only homebrew/npm), so it uses a custom publish job:
`publish-jobs = ["./publish-crates"]` invokes our reusable workflow after all release builds succeed
and the GitHub Release is hosted, so a broken build can never burn an immutable crates.io version.
Needs the `CARGO_REGISTRY_TOKEN` repo secret
- [ ] Consider musl Linux targets instead of/alongside gnu for portability on older-glibc distros
- [ ] Homebrew tap via cargo-dist once there are non-cargo users; Debian/WinGet/AUR only if usage justifies it
- [ ] Verify `cargo binstall git-stk` finds release artifacts (should work for free with cargo-dist naming)
---
## Done
- [x] Chore - re-organize other docs/temp docs into here (chat exports, old README draft, and RELEASING.md
deleted; everything actionable from them lives above)
- [x] `git stk upgrade` (+ `--head`, `--force`) via axoupdater; first real upgrade 0.1.1 -> 0.2.0 worked
- [x] `completions` subcommand + bash `_git_stk` shim so `git stk <TAB>` completes
- [x] Installer one-liner at `larakelley.com/sh/git-stk` (stable wrapper served by the website)
- [x] cleanup bug: merged PRs invisible to `gh pr list` default state (fixed with merged-state fallback)
- [x] Linear history rewrite; mirror workflow force-pushes main
- [x] `just bump` version helper (dev-tools feature-gated binary)