Repository navigation
Compare branches: a branch picker in the switcher, with stack-base suggestions - #1
Conversation
…ts stack base A repository's "Compare branches…" row, also in the source picker, turns the switcher into a picker over its local branches, then the bases the picked one can be compared with, opening or resuming the branch review of the pair. Each branch is offered against its stack base (the nearest unmerged branch below it, found for every branch with one git log --simplify-by-decoration ^<default>), else the default branch; a default-branch base stores no base, so it resumes the Branch row's review. Esc steps back. DESIGN §4.1, PLAN §2.2 and §11; state.switcher mode and detail, source_picker.compare; switcher_branches.
|
honestly wasn't expecting anyone to find this let alone make PRs. you seem legit from looking you up and i'm not seeing anything sketchy, so thanks for these. CI is running, i'll fix the conflicts once it's done |
Haha; I was looking to make a similar tool, and decided to see if someone else already had. I really like it and started using it but had to make a few tweaks for my workflow. Much appreciated. Not sure what your intentions/directions are, so please let me know if you aren't a fan of any approach I make. |
main gained repo removal in the switcher (a hover x on the header and Shift Delete). Both stay; removal is the repositories' list's only: the branch picker's header has no x and Shift Delete there removes nothing, since the header is the repository the picker compares in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
only thing left to do was github syncing but i'm still 50/50 on doing it at all, since it works really well for now just local-first. haven't really thought of anything else, it's been pretty good as-is for the last couple weeks |
Summary
A repository's switcher rows end with Compare branches… (also in the source picker
⇄ ▾). It turns the switcher into a two-step picker: a local branch, then the base to compare it with. Picking the pair opens or resumes itsbranchreview.Each branch is offered against its stack base: the nearest unmerged branch below it (
main → feat-a → feat-b:feat-bvsfeat-a), else the default branch. The bases step lists the stack base, then the default branch, then every other local branch. Choosing the default branch stores no base, so it resumes the switcher's existing Branch row's review instead of starting a second one.Why
The CLI can already review any branch against any base (
dv review new --branch feat-b --base feat-a), and PLAN §2.2 hasbranch <b> [vs <base>]as a target. The app could only offer the checked-out branch against the default branch, so reviewing a stack of branches meant leaving the app.How
dv_core::git::branches: local branches (for-each-ref) plus every branch's stack base from onegit log --branches --simplify-by-decoration ^<default>. That keeps only the commits a branch points at outside the default branch and rewrites parents to the nearest such commit, so a branch's first rewritten parent is its stack base. It takes about 50 ms on a 411-branch repo.Reviewsreads them with each row refresh (RepoRow::branches), so the picker is a plain view over loaded data.switcher::branches: the picker is a mode of the switcher (Mode::{Repos, Branches, Bases}), reusing its panel, filter, keys and automation targets. Esc steps back (bases → branches → repos) and closes from the branches step when it was opened from the source picker.state.switcher.modeand each row'sdetail,state.source_picker.compare; documented intests/e2e/README.md.Testing
dv_coretests (stacks, no default branch, branches sharing a tip, ordering), 5 switcher tests (listings, plus keyboard-driven gpui tests that open a stacked review with only that branch's files), e2eswitcher_brancheswith screenshots of both steps in dark and the branches in light.review_chrome.jsonlline 14 now expects the newdetail: null: it compares a whole switcher row exactly.cargo clippyclean in all three shapes,cargo test --workspacepasses, all e2e scenarios pass. Two runs ofscript/checkfailed on differentdv_backendclient::tests::lifecycletests (10 s event timeouts) while the machine was under heavy load. The crate isn't touched here, and those tests pass alone on bothmainand this branch, and in a later full workspace run. A few e2e scenarios needed a rerun after "no frame within 10s" while the window was covered.main → feat-a → feat-b → feat-c, plushotfix).Not run:
script/check --linux/--linux-guiand the Windows gates (no Windows or WSL machine here).