Skip to content

Commit a2c120b

Browse files
committed
Prepare for a world with bare repositories
This simply makes a method that we shouldn't have a in the first place fallible.
1 parent f02ac37 commit a2c120b

File tree

51 files changed

+223
-195
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+223
-195
lines changed

crates/but-api/src/commands/claude.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ pub async fn claude_get_session_details(
7272
let session_id = uuid::Uuid::parse_str(&session_id).map_err(anyhow::Error::from)?;
7373
let session = but_claude::db::get_session_by_id(&mut ctx, session_id)?
7474
.context("Could not find session")?;
75-
let current_id =
76-
Transcript::current_valid_session_id(&project.worktree_dir(), &session).await?;
75+
let worktree_dir = project.worktree_dir()?;
76+
let current_id = Transcript::current_valid_session_id(worktree_dir, &session).await?;
7777
if let Some(current_id) = current_id {
7878
let transcript_path =
79-
but_claude::Transcript::get_transcript_path(&project.worktree_dir(), current_id)?;
79+
but_claude::Transcript::get_transcript_path(worktree_dir, current_id)?;
8080
let transcript = but_claude::Transcript::from_file(&transcript_path)?;
8181
Ok(but_claude::ClaudeSessionDetails {
8282
summary: transcript.summary(),
@@ -205,8 +205,9 @@ pub fn claude_maybe_create_prompt_dir(project_id: ProjectId, path: String) -> Re
205205
#[instrument(err(Debug))]
206206
pub async fn claude_get_mcp_config(project_id: ProjectId) -> Result<McpConfig, Error> {
207207
let project = gitbutler_project::get(project_id)?;
208-
let settings = ClaudeSettings::open(&project.worktree_dir()).await;
209-
let mcp_config = ClaudeMcpConfig::open(&settings, &project.worktree_dir()).await;
208+
let worktree_dir = project.worktree_dir()?;
209+
let settings = ClaudeSettings::open(worktree_dir).await;
210+
let mcp_config = ClaudeMcpConfig::open(&settings, worktree_dir).await;
210211
Ok(mcp_config.mcp_servers())
211212
}
212213

@@ -217,7 +218,7 @@ pub async fn claude_get_sub_agents(
217218
) -> Result<Vec<but_claude::SubAgent>, Error> {
218219
let project = gitbutler_project::get(project_id)?;
219220
let sub_agents =
220-
but_claude::claude_sub_agents::read_claude_sub_agents(&project.worktree_dir()).await;
221+
but_claude::claude_sub_agents::read_claude_sub_agents(project.worktree_dir()?).await;
221222
Ok(sub_agents)
222223
}
223224

@@ -231,7 +232,7 @@ pub async fn claude_verify_path(project_id: ProjectId, path: String) -> Result<b
231232
std::path::PathBuf::from(&path)
232233
} else {
233234
// If relative, make it relative to project path
234-
project.worktree_dir().join(&path)
235+
project.worktree_dir()?.join(&path)
235236
};
236237

237238
// Check if the path exists and is a directory

crates/but-api/src/commands/config.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use crate::error::Error;
1212
#[cfg_attr(feature = "tauri", tauri::command(async))]
1313
#[instrument(err(Debug))]
1414
pub fn get_gb_config(project_id: ProjectId) -> Result<GitConfigSettings, Error> {
15-
but_core::open_repo(gitbutler_project::get(project_id)?.worktree_dir())?
15+
gitbutler_project::get(project_id)?
16+
.open()?
1617
.git_settings()
1718
.map(Into::into)
1819
.map_err(Into::into)
@@ -22,7 +23,8 @@ pub fn get_gb_config(project_id: ProjectId) -> Result<GitConfigSettings, Error>
2223
#[cfg_attr(feature = "tauri", tauri::command(async))]
2324
#[instrument(err(Debug))]
2425
pub fn set_gb_config(project_id: ProjectId, config: GitConfigSettings) -> Result<(), Error> {
25-
but_core::open_repo(gitbutler_project::get(project_id)?.worktree_dir())?
26+
gitbutler_project::get(project_id)?
27+
.open()?
2628
.set_git_settings(&config.into())
2729
.map_err(Into::into)
2830
}
@@ -35,7 +37,7 @@ pub fn store_author_globally_if_unset(
3537
name: String,
3638
email: String,
3739
) -> Result<(), Error> {
38-
let repo = but_core::open_repo(gitbutler_project::get(project_id)?.worktree_dir())?;
40+
let repo = gitbutler_project::get(project_id)?.open()?;
3941
but_rebase::commit::save_author_if_unset_in_repo(
4042
&repo,
4143
gix::config::Source::User,
@@ -61,7 +63,7 @@ pub struct AuthorInfo {
6163
#[instrument(err(Debug))]
6264
/// Return the Git author information as the project repository would see it.
6365
pub fn get_author_info(project_id: ProjectId) -> Result<AuthorInfo, Error> {
64-
let repo = but_core::open_repo(gitbutler_project::get(project_id)?.worktree_dir())?;
66+
let repo = gitbutler_project::get(project_id)?.open()?;
6567
let (name, email) = repo
6668
.author()
6769
.transpose()

crates/but-api/src/commands/diff.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn tree_change_diffs(
3232
let change: but_core::TreeChange = change.into();
3333
let project = gitbutler_project::get(project_id)?;
3434
let app_settings = AppSettings::load_from_default_path_creating()?;
35-
let repo = gix::open(project.worktree_dir()).map_err(anyhow::Error::from)?;
35+
let repo = project.open()?;
3636
Ok(change.unified_diff(&repo, app_settings.context_lines)?)
3737
}
3838

@@ -53,11 +53,11 @@ pub fn commit_details(
5353
commit_id: HexHash,
5454
) -> anyhow::Result<CommitDetails, Error> {
5555
let project = gitbutler_project::get(project_id)?;
56-
let repo = &gix::open(project.worktree_dir()).context("Failed to open repo")?;
56+
let repo = project.open()?;
5757
let commit = repo
5858
.find_commit(commit_id)
5959
.context("Failed for find commit")?;
60-
let changes = but_core::diff::ui::commit_changes_by_worktree_dir(repo, commit_id.into())?;
60+
let changes = but_core::diff::ui::commit_changes_by_worktree_dir(&repo, commit_id.into())?;
6161
let conflict_entries = Commit::from_id(commit.id())?.conflict_entries()?;
6262
Ok(CommitDetails {
6363
commit: commit.try_into()?,
@@ -121,7 +121,7 @@ pub fn changes_in_worktree(project_id: ProjectId) -> anyhow::Result<WorktreeChan
121121

122122
let dependencies = hunk_dependencies_for_workspace_changes_by_worktree_dir(
123123
ctx,
124-
&ctx.project().worktree_dir(),
124+
ctx.project().worktree_dir()?,
125125
&ctx.project().gb_dir(),
126126
Some(changes.changes.clone()),
127127
);

crates/but-api/src/commands/forge.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
//! In place of commands.rs
2-
use std::path::Path;
3-
42
use anyhow::Context;
53
use but_api_macros::api_cmd;
64
use gitbutler_forge::{
@@ -18,7 +16,7 @@ use crate::error::Error;
1816
#[instrument(err(Debug))]
1917
pub fn pr_templates(project_id: ProjectId, forge: ForgeName) -> Result<Vec<String>, Error> {
2018
let project = gitbutler_project::get_validated(project_id)?;
21-
Ok(available_review_templates(&project.worktree_dir(), &forge))
19+
Ok(available_review_templates(project.worktree_dir()?, &forge))
2220
}
2321

2422
#[api_cmd]
@@ -39,7 +37,7 @@ pub fn pr_template(
3937
if !is_valid_review_template_path(&relative_path) {
4038
return Err(anyhow::format_err!(
4139
"Invalid review template path: {:?}",
42-
Path::join(&project.worktree_dir(), &relative_path)
40+
project.worktree_dir()?.join(relative_path),
4341
)
4442
.into());
4543
}

crates/but-api/src/commands/git.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ pub fn git_index_size(project_id: ProjectId) -> Result<usize, Error> {
6969
#[cfg_attr(feature = "tauri", tauri::command(async))]
7070
#[instrument(err(Debug))]
7171
pub fn delete_all_data() -> Result<(), Error> {
72-
for project in gitbutler_project::list().context("failed to list projects")? {
72+
for project in gitbutler_project::dangerously_list_without_migration()
73+
.context("failed to list projects")?
74+
{
7375
gitbutler_project::delete(project.id)
7476
.map_err(|err| err.context("failed to delete project"))?;
7577
}

crates/but-api/src/commands/virtual_branches.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,10 @@ pub fn unapply_stack(project_id: ProjectId, stack_id: StackId) -> Result<(), Err
257257
let (assignments, _) = but_hunk_assignment::assignments_with_fallback(
258258
ctx,
259259
false,
260-
Some(but_core::diff::ui::worktree_changes_by_worktree_dir(project.worktree_dir())?.changes),
260+
Some(
261+
but_core::diff::ui::worktree_changes_by_worktree_dir(project.worktree_dir()?.into())?
262+
.changes,
263+
),
261264
None,
262265
)?;
263266
let assigned_diffspec = but_workspace::flatten_diff_specs(

crates/but-api/src/commands/workspace.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ pub fn amend_commit_from_worktree_changes(
329329
) -> Result<commit_engine::ui::CreateCommitOutcome, Error> {
330330
let project = gitbutler_project::get(project_id)?;
331331
let mut guard = project.exclusive_worktree_access();
332-
let repo = but_core::open_repo_for_merging(project.worktree_dir())?;
332+
let repo = project.open_for_merging()?;
333333
let app_settings = AppSettings::load_from_default_path_creating()?;
334334
let outcome = commit_engine::create_commit_and_update_refs_with_project(
335335
&repo,
@@ -364,7 +364,7 @@ pub fn discard_worktree_changes(
364364
worktree_changes: Vec<but_workspace::DiffSpec>,
365365
) -> Result<Vec<but_workspace::DiffSpec>, Error> {
366366
let project = gitbutler_project::get(project_id)?;
367-
let repo = but_core::open_repo(project.worktree_dir())?;
367+
let repo = project.open()?;
368368
let ctx = CommandContext::open(&project, AppSettings::load_from_default_path_creating()?)?;
369369
let mut guard = project.exclusive_worktree_access();
370370

crates/but-claude/src/bridge.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ impl Claudes {
253253
writer,
254254
write_stderr,
255255
session,
256-
project.worktree_dir(),
256+
project.worktree_dir()?.to_owned(),
257257
ctx.clone(),
258258
user_params,
259259
summary_to_resume,

crates/but-claude/src/compact.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ pub async fn generate_summary(
234234
let app_settings = ctx.lock().await.app_settings().clone();
235235
let claude_executable = app_settings.claude.executable.clone();
236236
let session_id =
237-
Transcript::current_valid_session_id(&ctx.lock().await.project().worktree_dir(), session)
237+
Transcript::current_valid_session_id(ctx.lock().await.project().worktree_dir()?, session)
238238
.await?
239239
.context("Cant find current session id")?;
240240

@@ -248,7 +248,7 @@ pub async fn generate_summary(
248248
command.creation_flags(CREATE_NO_WINDOW);
249249
}
250250

251-
command.current_dir(ctx.lock().await.project().worktree_dir());
251+
command.current_dir(ctx.lock().await.project().worktree_dir()?);
252252
command.args(["--resume", &format!("{session_id}")]);
253253
command.arg("-p");
254254
command.arg(SUMMARY_PROMPT);

crates/but-claude/src/hooks/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,10 @@ pub async fn handle_stop() -> anyhow::Result<ClaudeHookOutput> {
103103
.ok_or(anyhow!("No worktree found for repo"))?,
104104
)?;
105105

106-
let changes =
107-
but_core::diff::ui::worktree_changes_by_worktree_dir(project.clone().worktree_dir())?
108-
.changes;
106+
let changes = but_core::diff::ui::worktree_changes_by_worktree_dir(
107+
project.clone().worktree_dir()?.into(),
108+
)?
109+
.changes;
109110

110111
// This is a naive way of handling this case.
111112
// If the user simply asks a question and there are no changes, we don't need to create a stack
@@ -329,7 +330,7 @@ pub fn handle_pre_tool_call() -> anyhow::Result<ClaudeHookOutput> {
329330
.ok_or(anyhow!("No worktree found for repo"))?,
330331
)?;
331332
let relative_file_path = std::path::PathBuf::from(&input.tool_input.file_path)
332-
.strip_prefix(project.worktree_dir())?
333+
.strip_prefix(project.worktree_dir()?)?
333334
.to_string_lossy()
334335
.to_string();
335336
input.tool_input.file_path = relative_file_path;
@@ -375,7 +376,7 @@ pub fn handle_post_tool_call() -> anyhow::Result<ClaudeHookOutput> {
375376
)?;
376377

377378
let relative_file_path = std::path::PathBuf::from(&input.tool_response.file_path)
378-
.strip_prefix(project.worktree_dir())?
379+
.strip_prefix(project.worktree_dir()?)?
379380
.to_string_lossy()
380381
.to_string();
381382
input.tool_response.file_path = relative_file_path.clone();
@@ -405,7 +406,8 @@ pub fn handle_post_tool_call() -> anyhow::Result<ClaudeHookOutput> {
405406
let stack_id = get_or_create_session(defer.ctx, &session_id, stacks, vb_state)?;
406407

407408
let changes =
408-
but_core::diff::ui::worktree_changes_by_worktree_dir(project.worktree_dir())?.changes;
409+
but_core::diff::ui::worktree_changes_by_worktree_dir(project.worktree_dir()?.into())?
410+
.changes;
409411
let (assignments, _assignments_error) = but_hunk_assignment::assignments_with_fallback(
410412
defer.ctx,
411413
true,

0 commit comments

Comments
 (0)