Skip to content

Add ArchivedGitWorktree data model and DB operations#53214

Merged
rtfeldman merged 19 commits intomainfrom
persist-worktree-2-archived-model
Apr 7, 2026
Merged

Add ArchivedGitWorktree data model and DB operations#53214
rtfeldman merged 19 commits intomainfrom
persist-worktree-2-archived-model

Conversation

@rtfeldman
Copy link
Copy Markdown
Contributor

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, mark as restored
  • Column impl for deserializing ArchivedGitWorktree from DB rows
  • Tests for two-SHA round-trip, create/retrieve, delete, restore flag, multi-thread linking, and multiple worktrees per thread

Part 2 of 3 in the persist-worktree stack. Stacked on #53213. This is pure data model — nothing is wired up yet.

Release Notes:

  • N/A

…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 rtfeldman self-assigned this Apr 6, 2026
@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Apr 6, 2026
@zed-community-bot zed-community-bot bot added the staff Pull requests authored by a current member of Zed staff label Apr 6, 2026
@rtfeldman rtfeldman force-pushed the persist-worktree-2-archived-model branch from 7f05a6c to 33b4871 Compare April 6, 2026 14:51
Anthony-Eid and others added 8 commits April 6, 2026 14:52
This argument already gets added when calling git_binary.run()
Now creating a worktree from a detached head also has remote support
This goes against what git does internally and could cause testing bugs
in the future
GitStore::stage_all already does everything this method does and updates
pending_ops as well. So I'm removing this method to avoid a potential
foot gun in our codebase
- resolve_commit on Repository entity: wraps revparse_batch to check
  if a commit SHA exists in the repo. Used during restore to verify
  original_commit_hash is present before attempting recovery.
- repair_worktrees on GitRepository trait + RealGitRepository (runs
  git worktree repair) and FakeGitRepository (no-op). Used during
  restore when a worktree directory exists on disk but may not be in
  git's worktree metadata.
- repair_worktrees wrapper on Repository entity.
@rtfeldman rtfeldman force-pushed the persist-worktree-2-archived-model branch from 33b4871 to c2284f4 Compare April 6, 2026 20:34
@rtfeldman rtfeldman force-pushed the persist-worktree-1-git-api branch from bd78423 to 3061d32 Compare April 6, 2026 20:34
Anthony-Eid and others added 2 commits April 6, 2026 16:44
- resolve_commit on Repository entity: wraps revparse_batch to check
  if a commit SHA exists in the repo. Used during restore to verify
  original_commit_hash is present before attempting recovery.
- repair_worktrees on GitRepository trait + RealGitRepository (runs
  git worktree repair) and FakeGitRepository (no-op). Used during
  restore when a worktree directory exists on disk but may not be in
  git's worktree metadata.
- repair_worktrees wrapper on Repository entity.
@rtfeldman rtfeldman force-pushed the persist-worktree-2-archived-model branch from c2284f4 to 94d3f4f Compare April 6, 2026 20:52
@rtfeldman rtfeldman force-pushed the persist-worktree-1-git-api branch from 13b51f6 to 8edcdbd Compare April 6, 2026 20:52
@rtfeldman rtfeldman marked this pull request as ready for review April 6, 2026 21:12
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.
@rtfeldman rtfeldman force-pushed the persist-worktree-2-archived-model branch from 94d3f4f to e2f2e38 Compare April 6, 2026 21:30
Base automatically changed from persist-worktree-1-git-api to main April 6, 2026 21:32
Remove the old commit_hash and restored columns that were never shipped,
and fold the staged_commit_hash, unstaged_commit_hash, and
original_commit_hash columns directly into the CREATE TABLE statement
instead of adding them via ALTER TABLE migrations.

Also fix a bug in the INSERT where unstaged_commit_hash was bound twice
(once where commit_hash used to go).
@rtfeldman rtfeldman enabled auto-merge (squash) April 7, 2026 20:07
@rtfeldman rtfeldman merged commit f2ef434 into main Apr 7, 2026
29 checks passed
@rtfeldman rtfeldman deleted the persist-worktree-2-archived-model branch April 7, 2026 20:18
MasoudAlali pushed a commit to MasoudAlali/zed-ide that referenced this pull request Apr 7, 2026
…53214)

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, mark
as restored
- `Column` impl for deserializing `ArchivedGitWorktree` from DB rows
- Tests for two-SHA round-trip, create/retrieve, delete, restore flag,
multi-thread linking, and multiple worktrees per thread

Part 2 of 3 in the persist-worktree stack. Stacked on zed-industries#53213. This is
pure data model — nothing is wired up yet.

Release Notes:

- N/A

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
rtfeldman added a commit that referenced this pull request Apr 8, 2026
…ive (#53215)

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
- Add pending worktree restore UI state with spinner and cancel button
- Show toast on restore failure instead of silent log
- Switch to surviving workspace when archiving active thread whose
workspace will be deleted
- Deserialize persisted `project_group_keys` on window restore
- Guard `cleanup_empty_workspaces` against dropped entities
- Await rollback DB operations instead of fire-and-forget

Part 3 of 3 in the persist-worktree stack. Stacked on #53214. This wires
up parts 1 and 2.

Release Notes:

- Added worktree state preservation when archiving agent threads,
automatically restoring staged and unstaged changes when the thread is
unarchived

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
rtfeldman added a commit that referenced this pull request Apr 10, 2026
…ive (#53215)

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
- Add pending worktree restore UI state with spinner and cancel button
- Show toast on restore failure instead of silent log
- Switch to surviving workspace when archiving active thread whose
workspace will be deleted
- Deserialize persisted `project_group_keys` on window restore
- Guard `cleanup_empty_workspaces` against dropped entities
- Await rollback DB operations instead of fire-and-forget

Part 3 of 3 in the persist-worktree stack. Stacked on #53214. This wires
up parts 1 and 2.

Release Notes:

- Added worktree state preservation when archiving agent threads,
automatically restoring staged and unstaged changes when the thread is
unarchived

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement staff Pull requests authored by a current member of Zed staff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants