diff --git a/lib/src/workspace.rs b/lib/src/workspace.rs index fd0707cbc..7b275550a 100644 --- a/lib/src/workspace.rs +++ b/lib/src/workspace.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::fs::File; +use std::io::Read; use std::path::{Path, PathBuf}; use std::sync::Arc; @@ -30,6 +32,8 @@ pub enum WorkspaceInitError { #[derive(Error, Debug, PartialEq)] pub enum WorkspaceLoadError { + #[error("The repo appears to no longer be at {0}")] + RepoDoesNotExist(PathBuf), #[error("There is no Jujutsu repo in {0}")] NoWorkspaceHere(PathBuf), } @@ -149,7 +153,7 @@ impl Workspace { let jj_dir = find_jj_dir(&workspace_path) .ok_or(WorkspaceLoadError::NoWorkspaceHere(workspace_path))?; let workspace_root = jj_dir.parent().unwrap().to_owned(); - let repo_dir = jj_dir.join("repo"); + let mut repo_dir = jj_dir.join("repo"); if !repo_dir.exists() { // TODO: Delete this in mid 2022 or so println!("The repo format has changed. Moving repo into .jj/repo/"); @@ -158,6 +162,18 @@ impl Workspace { std::fs::rename(jj_dir.join(dir), repo_dir.join(dir)).unwrap(); } } + // If .jj/repo is a file, then we interpret its contents as a relative path to + // the actual repo directory (typically in another workspace). + if repo_dir.is_file() { + let mut repo_file = File::open(repo_dir).unwrap(); + let mut buf = Vec::new(); + repo_file.read_to_end(&mut buf).unwrap(); + let repo_path_str = String::from_utf8(buf).unwrap(); + repo_dir = std::fs::canonicalize(jj_dir.join(repo_path_str)).unwrap(); + if !repo_dir.is_dir() { + return Err(WorkspaceLoadError::RepoDoesNotExist(repo_dir)); + } + } let repo_loader = RepoLoader::init(user_settings, repo_dir); let working_copy_state_path = jj_dir.join("working_copy"); let working_copy = WorkingCopy::load( diff --git a/src/commands.rs b/src/commands.rs index ce36eadd7..49f287c63 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -197,6 +197,12 @@ jj init --git-repo=."; } return Err(CommandError::UserError(message)); } + Err(WorkspaceLoadError::RepoDoesNotExist(repo_dir)) => { + return Err(CommandError::UserError(format!( + "The repository directory at {} is missing. Was it moved?", + repo_dir.to_str().unwrap() + ))); + } }; let repo_loader = workspace.repo_loader(); let op_str = self.root_args.value_of("at_op").unwrap();