From 7eacdd1e7a15ad3188b8615d94c2ea4091bf2898 Mon Sep 17 00:00:00 2001 From: Richard Feldman Date: Wed, 1 Apr 2026 13:24:45 -0400 Subject: [PATCH] Attempt to undo mixed reset when soft reset fails during restore When restoring a worktree, if the mixed reset succeeds but the soft reset fails, the worktree was left with HEAD pointing at the internal WIP staged commit. Now we attempt to undo the mixed reset by resetting back to the original WIP commit hash, returning the worktree to a coherent (if not fully unwound) state. --- crates/sidebar/src/sidebar.rs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index 61ad53ce78e57220cd666792be4e0068b6f8f84a..8925dc8508431c857bc20d3b87d495503b7ab76f 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -2413,7 +2413,7 @@ impl Sidebar { if !final_path_exists && !is_restored_and_valid { // Create the worktree in detached HEAD mode at the WIP commit. let create_receiver = main_repo.update(cx, |repo, _cx| { - repo.create_worktree_detached(final_worktree_path.clone(), commit_hash) + repo.create_worktree_detached(final_worktree_path.clone(), commit_hash.clone()) }); match create_receiver.await { Ok(Ok(())) => {} @@ -2506,10 +2506,36 @@ impl Sidebar { Ok(Ok(())) => {} Ok(Err(err)) => { log::warn!("Failed to soft-reset WIP staged commit: {err}"); + // Attempt to undo the mixed reset to return to the WIP commit. + let undo = worktree_repo.update(cx, |repo, cx| { + repo.reset(commit_hash.clone(), ResetMode::Mixed, cx) + }); + match undo.await { + Ok(Ok(())) => { + log::info!("Undid mixed reset after soft-reset failure") + } + Ok(Err(undo_err)) => { + log::warn!("Could not undo mixed reset: {undo_err}") + } + Err(_) => log::warn!("Undo of mixed reset was canceled"), + } break 'resets false; } Err(_) => { log::warn!("Soft reset was canceled"); + // Attempt to undo the mixed reset to return to the WIP commit. + let undo = worktree_repo.update(cx, |repo, cx| { + repo.reset(commit_hash.clone(), ResetMode::Mixed, cx) + }); + match undo.await { + Ok(Ok(())) => { + log::info!("Undid mixed reset after soft-reset cancellation") + } + Ok(Err(undo_err)) => { + log::warn!("Could not undo mixed reset: {undo_err}") + } + Err(_) => log::warn!("Undo of mixed reset was canceled"), + } break 'resets false; } }