Skip to content

Replace legacy But API call for Project Not Found branches#13686

Merged
Byron merged 3 commits intogitbutlerapp:masterfrom
sebastianhuus:sh-branch-1
May 8, 2026
Merged

Replace legacy But API call for Project Not Found branches#13686
Byron merged 3 commits intogitbutlerapp:masterfrom
sebastianhuus:sh-branch-1

Conversation

@sebastianhuus
Copy link
Copy Markdown
Contributor

@sebastianhuus sebastianhuus commented May 7, 2026

🧢 Changes

crates/but-api/src/legacy/projects.rs:

  • Replace manual Context creation with direct get_raw call to reduce unnecessary intermediate variable allocation and improve code clarity in the legacy projects module.
  • Replace legacy_project with gitbutler_project::get_raw

crates/gitbutler-project/src/lib.rs and crates/gitbutler-project/src/lib.rs:

  • Adds new helper get_raw_with_path and new test that verifies get_raw can recover when a project is no longer present on disk.

☕️ Reasoning

This is a follow-up based on a discussion for #13613. I traced the error chain from the message posted in the picture below and found that it was a race condition in the legacy project API. This led to the Remove Project button not being displayed if you try to open a Git Butler project that was deleted from disk.

image

Notice that there is no button to remove the project – the project is effectively stuck in the Projects list

This PR covers two scenarios which I've tested:

  1. You delete the currently active project in the GUI and refresh the app. GitButler will now offer to remove the project if it wasn't found.
  2. You delete a GitButler project which is not the currently active project in the GUI. GitButler will now offer to remove the project if it wasn't found as well.

These changes restore existing backend and frontend logic that was never hit:

image

Remove Project button is now restored

refactor: replace legacy_project with gitbutler_project::get_raw
refactor: simplify project context creation

Replace manual Context creation with direct get_raw call
to reduce unnecessary intermediate variable allocation
and improve code clarity in the legacy projects module.
fix: skip unresolvable project handles in listing

Change project listing to gracefully skip handles that can no
longer be resolved instead of failing the entire operation. This
handles cases where projects are deleted from storage but the
frontend's opened_projects set hasn't caught up yet.

Replace the map().collect() pattern with filter_map() to skip
stale entries and log warnings for debugging. This mirrors the
warn-and-skip pattern used elsewhere for migration failures and
ensures the post-deletion refresh flow doesn't break.
@sebastianhuus sebastianhuus force-pushed the sh-branch-1 branch 2 times, most recently from 8f6a9a5 to 2e21580 Compare May 7, 2026 11:00
@sebastianhuus sebastianhuus marked this pull request as ready for review May 7, 2026 11:02
Copilot AI review requested due to automatic review settings May 7, 2026 11:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the “project not found / removed from disk” recovery path by ensuring legacy project API calls can still read project metadata from storage without eagerly opening the repository, allowing the frontend to show the “Remove Project” action again.

Changes:

  • Switched legacy but-api project endpoints to use gitbutler_project::get_raw instead of constructing a but_ctx::Context / using legacy_project.
  • Added gitbutler_project::get_raw_with_path to support isolated tests (explicit app_data_dir).
  • Added an integration test verifying raw project metadata can be loaded after the worktree directory is deleted from disk.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
crates/but-api/src/legacy/projects.rs Uses storage-only get_raw for get_project (no-validation path), list_projects opened-project detection, and delete_project to avoid repo-opening failures when the worktree is missing.
crates/gitbutler-project/src/lib.rs Adds get_raw_with_path(app_data_dir, id) helper for tests/diagnostics that must not rely on global app_data_dir.
crates/gitbutler-project/tests/project/main.rs Adds coverage to ensure raw project retrieval still succeeds after the project worktree is removed from disk.

Comment thread crates/but-api/src/legacy/projects.rs Outdated
#[instrument(err(Debug))]
pub fn delete_project(project_id: ProjectHandleOrLegacyProjectId) -> Result<()> {
let project = legacy_project(project_id)?;
let project = gitbutler_project::get_raw(project_id)?;
@sebastianhuus
Copy link
Copy Markdown
Contributor Author

Pushing with an extra fix to satisfy e2e test. will squash if good

Copilot AI review requested due to automatic review settings May 7, 2026 14:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread crates/but-api/src/legacy/projects.rs
Comment thread crates/but-api/src/legacy/projects.rs Outdated
Add a new testing function `get_raw_with_path` that allows
retrieving raw project metadata without validating the worktree
exists on disk. This enables testing the recovery flow used by
`ProjectNotFound`, `delete_project`, and `list_projects` which
rely on storage-only metadata.

Include a test case verifying `get_raw` succeeds when the worktree
is deleted from disk, ensuring the recovery flow remains functional.

Refactor formatting in legacy projects handler for consistency.
Copilot AI review requested due to automatic review settings May 8, 2026 02:13
Copy link
Copy Markdown
Collaborator

@Byron Byron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the follow-up.

I was able to validate that the project removal option is now present again and it works.

While the fix isn't great, it's all in legacy code and we will have to do this properly once it's moved to non-legacy.
So let's take the quick fix and keep the time spent with it as low as possible.

@Byron Byron enabled auto-merge May 8, 2026 02:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

Comment thread crates/but-api/src/legacy/projects.rs
Comment thread crates/but-api/src/legacy/projects.rs
@Byron Byron merged commit 29c3384 into gitbutlerapp:master May 8, 2026
44 of 45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants