feat: virtual-branch workspace prototype (per-file/hunk assignment, drag & drop, persistence) - #361
Open
angeousta wants to merge 7 commits into
Open
Conversation
The benchmark's hash_branch_sidebar_rows match was not exhaustive after adding BranchSidebarRow::VirtualBranchesHeader and ::VirtualBranchItem, which broke the benches CI job (cargo bench --features benchmarks --bench performance --no-run) on all platforms.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces a virtual-branch workspace: a way to work on several logically-separate changes in the working tree at the same time, before they become real Git commits/branches, by assigning individual files (or even individual diff hunks) in the working tree to lightweight, in-progress "virtual branches." It is a first, deliberately scoped prototype of a workflow popularized by tools like GitButler — applied here specifically to GitComet's own data model and UI, not a port of another tool's code.
Why
Git's working tree is single-stream by construction: everything you've touched sits together in one undifferentiated pile of changes, and splitting that pile into several clean, independent commits/branches after the fact is manual, error-prone work — you have to remember which edit belonged to which idea, stage hunks by hand, and hope you don't accidentally mix two unrelated changes into the same commit.
In practice, this shows up constantly during normal development: you set out to fix one bug, and along the way you also touch a couple of unrelated files (a small cleanup here, an unrelated fix there) because that's where you happened to be working. At commit time you're now stuck manually untangling those changes with
git add -por a similar dance, or you give up and ship them together in one oversized, thematically-mixed commit — which then makes for a worse PR and a worsegit log.This feature moves that separation earlier and makes it continuous rather than a one-time cleanup step: as you edit, you assign each changed file (or a specific hunk within a file, see "Move hunk to virtual branch" below) to the virtual branch it conceptually belongs to, while you're still working, rather than reconstructing that grouping afterward from memory. When you're done, each virtual branch already represents one clean, coherent set of changes, ready to be committed and turned into a real branch/PR with no untangling step.
What's included
This PR bundles five commits that build up the feature incrementally — each is a complete, working step on top of the previous one, and the branch is intended to be reviewed and merged as a whole (see "Why one PR" below), but the commit history is kept intact and readable rather than squashed:
gitcomet-state) that tracks which paths belong to which virtual branch, independent of the actual Git index/worktree.Scope and status
This is explicitly a prototype-stage feature: it covers the core loop (assign files/hunks to virtual branches, see them grouped in the sidebar, clean up empty ones, persist across sessions) but does not yet include turning a virtual branch into an actual Git commit/branch, or reconciling a virtual branch's parked patches against upstream changes — those are natural, separately-scoped follow-ups once this foundation is in. We think landing the foundation on its own, reviewable as one coherent unit, is preferable to holding it back until the entire end-to-end workflow is done.
Why one PR for five commits
The five commits are sequentially dependent — each one only makes sense with the state model and UI surface the previous ones introduced (there is no clean intermediate state where, say, drag-and-drop assignment is useful without file-assignment already existing). Splitting them into five separate PRs would mean reviewing four of them in a state that doesn't build toward anything usable on its own. The commits are kept separate (rather than squashed into one) so each can still be reviewed and, if needed, bisected independently.
Testing
cargo check --workspacepasses cleanly on the final state of the branch.cargo fmt --all -- --checkpasses cleanly.gitcomet-statevirtual-branch test suite passes in full: 22/22 tests (covering assignment, hunk-move/reverse-apply, stale-branch detection, and session persistence/restore round-trips).Notes for reviewers
This PR was prepared from a fork's branch that had diverged from
devfor a while. Porting it forward required resolving real conflicts against upstream changes to several shared UI files (theme token renames, sidebar/status-row helpers that had since changed shape) — those adaptations are folded into the relevant commits so each one still compiles and passes its tests on its own, on top of currentdev.