Skip to content

Commit

Permalink
git: Remove git worktrees when forgetting workspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
cormacrelf committed Oct 5, 2024
1 parent 95c501c commit 4919138
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 14 deletions.
30 changes: 28 additions & 2 deletions cli/src/commands/workspace/forget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,33 @@ pub fn cmd_workspace_forget(
}
}

let git_repo_path = workspace_command
.git_backend()
.map(|git_backend| git_backend.git_repo_path().to_owned());

// bundle every workspace forget into a single transaction, so that e.g.
// undo correctly restores all of them at once.
let mut tx = workspace_command.start_transaction();

let mut worktrees_to_remove = vec![];
wss.iter().try_for_each(|ws| {
tx.repo_mut().remove_git_head_target(ws);
tx.repo_mut().remove_wc_commit(ws)
if let Some(git_repo_path) = git_repo_path.as_deref() {
tx.repo_mut().remove_git_head_target(ws);
match jj_lib::git::git_worktree_validate(git_repo_path, ws.as_str()) {
Ok(stat) => worktrees_to_remove.push(stat),
Err(jj_lib::git::WorktreeValidationError::NonexistentWorktree(_named)) => {
tracing::debug!("No git worktree found named {_named}");
}
Err(e) => {
return Err(user_error(format!(
"Invalid worktree for workspace {ws}: {e}"
)))
}
}
}
tx.repo_mut()
.remove_wc_commit(ws)
.map_err(CommandError::from)
})?;

let description = if let [ws] = wss.as_slice() {
Expand All @@ -104,5 +125,10 @@ pub fn cmd_workspace_forget(
};

tx.finish(ui, description)?;

for validated in worktrees_to_remove {
jj_lib::git::git_worktree_remove(validated).map_err(user_error)?;
}

Ok(())
}
8 changes: 0 additions & 8 deletions cli/tests/test_git_colocated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1106,13 +1106,5 @@ fn test_colocated_workspace_add_forget_add() {

std::fs::remove_dir_all(&second_path).unwrap();

// HACK: prune the git worktree manually. We should probably implement `git worktree remove`
// and do that when forgetting workspaces.
Command::new("git")
.args(["worktree", "prune"])
.current_dir(&repo_path)
.assert()
.success();

let _ = test_env.jj_cmd_ok(&repo_path, &["workspace", "add", "--colocate", "../second"]);
}
5 changes: 3 additions & 2 deletions lib/src/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1346,8 +1346,9 @@ impl MutableRepo {
Ok(())
}

pub fn remove_git_head_target(&mut self, workspace_id: &WorkspaceId) {
self.view_mut().remove_git_head_target(workspace_id);
/// Returns true if did remove the HEAD
pub fn remove_git_head_target(&mut self, workspace_id: &WorkspaceId) -> bool {
self.view_mut().remove_git_head_target(workspace_id)
}

pub fn remove_wc_commit(&mut self, workspace_id: &WorkspaceId) -> Result<(), EditCommitError> {
Expand Down
5 changes: 3 additions & 2 deletions lib/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,9 @@ impl View {
self.data.git_heads = git_heads;
}

pub(crate) fn remove_git_head_target(&mut self, workspace_id: &WorkspaceId) {
self.data.git_heads.remove(workspace_id);
/// Returns true if did remove the HEAD
pub(crate) fn remove_git_head_target(&mut self, workspace_id: &WorkspaceId) -> bool {
self.data.git_heads.remove(workspace_id).is_some()
}

/// Iterates all commit ids referenced by this view.
Expand Down

0 comments on commit 4919138

Please sign in to comment.