Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 20 additions & 17 deletions apps/staged/src-tauri/src/branches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ pub(crate) fn validate_workspace_subpath(subpath: &str) -> Result<String, String
///
/// The name is sanitised so it is safe to use as a directory name on the
/// workspace filesystem.
fn repo_name_from_github_repo(github_repo: &str) -> String {
pub(crate) fn repo_name_from_github_repo(github_repo: &str) -> String {
let raw = github_repo.rsplit('/').next().unwrap_or(github_repo);
let collapsed = raw
.chars()
Expand Down Expand Up @@ -272,7 +272,12 @@ pub(crate) fn resolve_workspace_repo_path(
///
/// Returns a `home:<dir>` string suitable for `resolve_workspace_repo_path`,
/// or `None` when the branch has no associated project repo.
pub(crate) fn resolve_branch_workspace_subpath(
/// Return just the repo-root clone directory as `home:<clone_dir>`.
///
/// This is the base path on the workspace filesystem where the repo is
/// cloned. Use this when you need commands to run from the repo root
/// (e.g. `git diff` in `diff_commands`).
pub(crate) fn resolve_branch_clone_dir(
store: &Arc<Store>,
branch: &store::Branch,
) -> Result<Option<String>, String> {
Expand All @@ -282,23 +287,21 @@ pub(crate) fn resolve_branch_workspace_subpath(
let Some(repo) = store.get_project_repo(repo_id).map_err(|e| e.to_string())? else {
return Ok(None);
};
let clone_dir = repo_name_from_github_repo(&repo.github_repo);
Ok(Some(format!("home:{clone_dir}")))
}

// Backward compatibility: existing DB rows may still have the old
// `repo:` prefix or `repos/` path format.
if let Some(ref subpath) = repo.subpath {
let trimmed = subpath.trim().trim_matches('/');
if let Some(repo_dir) = trimmed.strip_prefix("repo:") {
let dir = validate_workspace_subpath(repo_dir)?;
return Ok(Some(format!("home:{dir}")));
}
if trimmed.starts_with("repos/") {
return Ok(Some(trimmed.to_string()));
}
}
pub(crate) fn resolve_branch_workspace_subpath(
store: &Arc<Store>,
branch: &store::Branch,
) -> Result<Option<String>, String> {
let Some(repo_id) = branch.project_repo_id.as_deref() else {
return Ok(None);
};
let Some(repo) = store.get_project_repo(repo_id).map_err(|e| e.to_string())? else {
return Ok(None);
};

// Current format: repo.subpath is None or a plain path relative to the
// repo root (e.g. "apps/staged"). Derive the workspace clone directory
// from github_repo.
let clone_dir = repo_name_from_github_repo(&repo.github_repo);
let workspace_path = match &repo.subpath {
Some(subpath) => {
Comment on lines 306 to 307

Choose a reason for hiding this comment

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

P1 Badge Preserve legacy subpath formats when resolving workspace paths

resolve_branch_workspace_subpath now always builds home:{clone_dir}/{subpath} and no longer recognizes legacy stored subpath formats (repo:<dir> / repos/...) that older project rows can still contain. For upgraded users with those rows, this returns a different directory than before (for example home:g2/repo:legacy), so downstream callers that execute git with -C against this path (e.g. workspace startup and remote branch operations) will fail to find the repository. Please keep the backward-compat parsing or migrate existing records before this path construction.

Useful? React with 👍 / 👎.

Expand Down
6 changes: 5 additions & 1 deletion apps/staged/src-tauri/src/diff_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ pub(crate) fn resolve_branch_context(
.workspace_name
.clone()
.ok_or_else(|| format!("Branch has no workspace name: {branch_id}"))?;
let repo_subpath = branches::resolve_branch_workspace_subpath(store, &branch)?;

// Use the repo root (clone dir only) so all paths are consistently
// repo-root-relative — git diff pathspecs, git show tree paths, etc.
let repo_subpath = branches::resolve_branch_clone_dir(store, &branch)?;

return Ok(BranchDiffContext {
base_branch: branch.base_branch,
worktree_path: None,
Expand Down