Conversation
…ations Extend the git API with several new capabilities needed for worktree archival and restoration: - Add allow_empty flag to CommitOptions for creating WIP marker commits - Change create_worktree to accept Option<String> branch, enabling detached worktree creation when None is passed - Add head_sha() to read the current HEAD commit hash - Add update_ref() and delete_ref() for managing git references - Add stage_all_including_untracked() to stage everything before a WIP commit - Implement all new operations in FakeGitRepository with functional commit history tracking, reset support, and ref management - Update existing call sites for the new CommitOptions field and create_worktree signature
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
from
April 6, 2026 14:57
0c1eb65 to
c2e9b36
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
from
April 6, 2026 14:57
37af681 to
ee5892b
Compare
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
from
April 6, 2026 15:07
c2e9b36 to
b237dd3
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
2 times, most recently
from
April 6, 2026 15:19
2057637 to
378b44e
Compare
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
2 times, most recently
from
April 6, 2026 15:27
5bb4eca to
74a134d
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
2 times, most recently
from
April 6, 2026 15:34
38563bf to
715cd48
Compare
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
2 times, most recently
from
April 6, 2026 15:51
5e119b8 to
35bdf32
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
2 times, most recently
from
April 6, 2026 15:55
3298aed to
f8f897a
Compare
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
from
April 6, 2026 15:55
35bdf32 to
ff8e591
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
from
April 6, 2026 15:55
f8f897a to
d75ae03
Compare
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
from
April 6, 2026 15:56
ff8e591 to
a00fddb
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
2 times, most recently
from
April 6, 2026 16:12
959f1bb to
d1a406d
Compare
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
from
April 6, 2026 16:12
a00fddb to
253b49a
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
from
April 6, 2026 18:27
d1a406d to
a99d6b5
Compare
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
from
April 6, 2026 18:27
253b49a to
a37b7df
Compare
This argument already gets added when calling git_binary.run()
Now creating a worktree from a detached head also has remote support
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
from
April 6, 2026 20:55
d1063b7 to
1bfc40e
Compare
…s/zed into persist-worktree-1-git-api
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
from
April 6, 2026 21:02
1bfc40e to
8f89b75
Compare
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
2 times, most recently
from
April 6, 2026 21:05
c816b57 to
0fad306
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
from
April 6, 2026 21:05
8f89b75 to
6280b00
Compare
Add the persistence layer for tracking archived git worktrees: - ArchivedGitWorktree struct with staged_commit_hash and unstaged_commit_hash fields to precisely identify WIP commits - DB migrations for archived_git_worktrees and thread_archived_worktrees (join table) tables - CRUD operations: create, link to thread, query by thread, delete - Column impl for deserializing ArchivedGitWorktree from DB rows - Tests for create/retrieve with distinct SHAs, delete cascading through join table, multi-thread linking, and multiple worktrees per thread
- New field on ArchivedGitWorktree struct storing the HEAD SHA from before WIP commits were created during archival. Used as a pre-restore sanity check, fallback reset target, and post-restore verification. - DB migration adding original_commit_hash column, backfilled from the legacy commit_hash column for existing rows. - Updated create_archived_worktree signature, SQL INSERT, and bindings on both ThreadMetadataDb and ThreadMetadataStore. - Updated SELECT query and Column impl to read the new field. - Updated all 4 archived worktree tests.
Connect the git API and archived worktree data model to the sidebar's archive/unarchive flow: - Add thread_worktree_archive module: orchestrates the full archive cycle (WIP commits, DB records, git refs, worktree deletion) and restore cycle (detached worktree creation, reset to recover staged/unstaged state, branch restoration) - Integrate into sidebar: archive_thread now persists worktree state before cleanup; activate_archived_thread restores worktrees via git with targeted path replacement for multi-root threads - Show toast on restore failure instead of silent log - Deserialize persisted project_group_keys on window restore - Guard cleanup_empty_workspaces against dropped entities - Await rollback DB operations instead of fire-and-forget - If worktree already exists on disk when unarchiving, reuse it as-is instead of auto-generating a new path
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
from
April 6, 2026 21:30
bb27cf7 to
b9379b1
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
from
April 6, 2026 21:30
809aa0f to
75c0e9d
Compare
persist_worktree_state: - Read HEAD SHA before creating WIP commits as original_commit_hash - Pass it to create_archived_worktree restore_worktree_via_git: - Pre-restore: verify original_commit_hash exists via resolve_commit; abort with user-facing error if the git history is gone - Worktree-already-exists: check for .git file to detect if path is a real git worktree; if not, call repair_worktrees to adopt it - Resilient WIP resets: track success of mixed and soft resets independently; if either fails, fall back to mixed reset directly to original_commit_hash - Post-reset HEAD verification: confirm HEAD landed at original_commit_hash after all resets - Branch restoration: after switching, verify branch points at original_commit_hash; if it doesn't, reset and create a fresh branch
persist_worktree_state: - Read HEAD SHA before creating WIP commits as original_commit_hash - Pass it to create_archived_worktree restore_worktree_via_git: - Pre-restore: verify original_commit_hash exists via resolve_commit; abort with user-facing error if the git history is gone - Worktree-already-exists: check for .git file to detect if path is a real git worktree; if not, call repair_worktrees to adopt it - Resilient WIP resets: track success of mixed and soft resets independently; if either fails, fall back to mixed reset directly to original_commit_hash - Post-reset HEAD verification: confirm HEAD landed at original_commit_hash after all resets - Branch restoration: after switching, verify branch points at original_commit_hash; if it doesn't, reset and create a fresh branch
persist_worktree_state: - Read HEAD SHA before creating WIP commits as original_commit_hash - Pass it to create_archived_worktree restore_worktree_via_git: - Pre-restore: verify original_commit_hash exists via resolve_commit; abort with user-facing error if the git history is gone - Worktree-already-exists: check for .git file to detect if path is a real git worktree; if not, call repair_worktrees to adopt it - Resilient WIP resets: track success of mixed and soft resets independently; if either fails, fall back to mixed reset directly to original_commit_hash - Post-reset HEAD verification: confirm HEAD landed at original_commit_hash after all resets - Branch restoration: after switching, verify branch points at original_commit_hash; if it doesn't, reset and create a fresh branch
persist_worktree_state: - Read HEAD SHA before creating WIP commits as original_commit_hash - Pass it to create_archived_worktree restore_worktree_via_git: - Pre-restore: verify original_commit_hash exists via resolve_commit; abort with user-facing error if the git history is gone - Worktree-already-exists: check for .git file to detect if path is a real git worktree; if not, call repair_worktrees to adopt it - Resilient WIP resets: track success of mixed and soft resets independently; if either fails, fall back to mixed reset directly to original_commit_hash - Post-reset HEAD verification: confirm HEAD landed at original_commit_hash after all resets - Branch restoration: after switching, verify branch points at original_commit_hash; if it doesn't, reset and create a fresh branch
persist_worktree_state: - Read HEAD SHA before creating WIP commits as original_commit_hash - Pass it to create_archived_worktree restore_worktree_via_git: - Pre-restore: verify original_commit_hash exists via resolve_commit; abort with user-facing error if the git history is gone - Worktree-already-exists: check for .git file to detect if path is a real git worktree; if not, call repair_worktrees to adopt it - Resilient WIP resets: track success of mixed and soft resets independently; if either fails, fall back to mixed reset directly to original_commit_hash - Post-reset HEAD verification: confirm HEAD landed at original_commit_hash after all resets - Branch restoration: after switching, verify branch points at original_commit_hash; if it doesn't, reset and create a fresh branch
persist_worktree_state: - Read HEAD SHA before creating WIP commits as original_commit_hash - Pass it to create_archived_worktree restore_worktree_via_git: - Pre-restore: verify original_commit_hash exists via resolve_commit; abort with user-facing error if the git history is gone - Worktree-already-exists: check for .git file to detect if path is a real git worktree; if not, call repair_worktrees to adopt it - Resilient WIP resets: track success of mixed and soft resets independently; if either fails, fall back to mixed reset directly to original_commit_hash - Post-reset HEAD verification: confirm HEAD landed at original_commit_hash after all resets - Branch restoration: after switching, verify branch points at original_commit_hash; if it doesn't, reset and create a fresh branch
persist_worktree_state: - Read HEAD SHA before creating WIP commits as original_commit_hash - Pass it to create_archived_worktree restore_worktree_via_git: - Pre-restore: verify original_commit_hash exists via resolve_commit; abort with user-facing error if the git history is gone - Worktree-already-exists: check for .git file to detect if path is a real git worktree; if not, call repair_worktrees to adopt it - Resilient WIP resets: track success of mixed and soft resets independently; if either fails, fall back to mixed reset directly to original_commit_hash - Post-reset HEAD verification: confirm HEAD landed at original_commit_hash after all resets - Branch restoration: after switching, verify branch points at original_commit_hash; if it doesn't, reset and create a fresh branch
Track in-flight worktree restores in the Sidebar via a HashSet<SessionId>. While a restore is pending, the thread item shows a spinning 'Restoring worktree…' indicator with a cancel button that appears on hover. Clicking cancel clears the pending state. This is purely UI — the restore itself still runs to completion in the background; cancel just hides the spinner.
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
from
April 6, 2026 21:39
b9379b1 to
e9783e6
Compare
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
2 times, most recently
from
April 6, 2026 21:48
9f93a1a to
e3f89e1
Compare
- worktree_restore_tasks HashMap on Sidebar tracks in-flight restore operations keyed by SessionId - Restore task is now stored (not detached) so it can be tracked and the pending state cleaned up when it completes - cancel_worktree_restore drops the task from the map and notifies - ThreadItem wired up with pending_worktree_restore bool and on_cancel_restore callback from the Sidebar's render_thread - Action slot (archive/stop buttons) hidden while a restore is pending - Reconciled with existing PR4 restore spinner in worktree labels
rtfeldman
force-pushed
the
persist-worktree-4-cancel-restore
branch
from
April 6, 2026 21:55
e3f89e1 to
fa56504
Compare
rtfeldman
force-pushed
the
persist-worktree-3-wiring
branch
from
April 7, 2026 20:09
e9783e6 to
1860c47
Compare
Contributor
Author
|
Closing in favor of #53463 |
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.
Track in-flight worktree restores in the Sidebar via a
HashSet<SessionId>. While a restore is pending, the thread item shows a spinning "Restoring worktree…" indicator with a cancel button that appears on hover. Clicking cancel clears the pending state.This is purely UI — the restore itself still runs to completion in the background; cancel just hides the spinner.
Part 4 of 4 in the persist-worktree stack. Stacked on #53215.
Release Notes: