Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: Move external git repo canonicalization into Workspace::init_g… #2830

Merged
merged 1 commit into from
Jan 16, 2024
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
3 changes: 3 additions & 0 deletions cli/src/cli_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ impl From<WorkspaceInitError> for CommandError {
WorkspaceInitError::Path(err) => {
CommandError::InternalError(format!("Failed to access the repository: {err}"))
}
WorkspaceInitError::PathNotFound(path) => {
user_error(format!("{} doesn't exist", path.display()))
}
WorkspaceInitError::Backend(err) => {
user_error(format!("Failed to access the repository: {err}"))
}
Expand Down
12 changes: 1 addition & 11 deletions cli/src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,7 @@ pub(crate) fn cmd_init(
let relative_wc_path = file_util::relative_path(&cwd, &wc_path);

if let Some(git_store_str) = &args.git_repo {
let mut git_store_path = command.cwd().join(git_store_str);
git_store_path = git_store_path
.canonicalize()
.map_err(|_| user_error(format!("{} doesn't exist", git_store_path.display())))?;
if !git_store_path.ends_with(".git") {
git_store_path.push(".git");
// Undo if .git doesn't exist - likely a bare repo.
if !git_store_path.exists() {
git_store_path.pop();
}
}
let git_store_path = cwd.join(git_store_str);
let (workspace, repo) =
Workspace::init_external_git(command.settings(), &wc_path, &git_store_path)?;
let mut workspace_command = command.for_loaded_repo(ui, workspace, repo)?;
Expand Down
15 changes: 14 additions & 1 deletion lib/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pub enum WorkspaceInitError {
DestinationExists(PathBuf),
#[error("Repo path could not be interpreted as Unicode text")]
NonUnicodePath,
#[error("Path {0} does not exist")]
PathNotFound(PathBuf),
#[error(transparent)]
CheckOutCommit(#[from] CheckOutCommitError),
#[error(transparent)]
Expand Down Expand Up @@ -194,6 +196,17 @@ impl Workspace {
workspace_root: &Path,
git_repo_path: &Path,
) -> Result<(Self, Arc<ReadonlyRepo>), WorkspaceInitError> {
let mut git_repo_path = git_repo_path
.canonicalize()
.map_err(|_| WorkspaceInitError::PathNotFound(git_repo_path.to_path_buf()))?;
if !git_repo_path.ends_with(".git") {
git_repo_path.push(".git");

if !git_repo_path.exists() {
git_repo_path.pop();
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not strongly against this change, but I think ".git" should be appended by CLI code. git_repo_path here should point to the git repository, not the workspace.

Copy link
Member

Choose a reason for hiding this comment

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

I think you're right. I saw the canonicalization below and figured it was consistent to normalize the git_repo_path here too, but I missed the TODO saying that we planned to move the canonicalization below out of this function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Circling back to clean things up.

I think I've managed to get myself confused by the terms. Help check my understanding:

Workspace path - This is the directory the user works in. It contains the 'jj' repo and may also contain a 'git' repo.

Repo path - This holds the "special" folder for git/jj, so for jj, this is the path to the .jj directory, but for git, it's the path to the .git directory.

Is that correct?

What should git_repo_path point to then?

I guess, technically, we want it to point to the '.git' directory, but for the user, it's a bit annoying UI wise, so we can accept the parent directory and normalize it ourselves.

Am I understanding this correctly?

Thanks! :-D

Copy link
Collaborator

Choose a reason for hiding this comment

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

Workspace path - This is the directory the user works in. It contains the 'jj' repo and may also contain a 'git' repo.

Repo path - This holds the "special" folder for git/jj, so for jj, this is the path to the .jj directory, but for git, it's the path to the .git directory.

Basically yes, that's my understanding. For jj, the repo path is probably .jj/repo. For "bare" git repo, the path might not end with ".git".

What should git_repo_path point to then?

I guess, technically, we want it to point to the '.git' directory, but for the user, it's a bit annoying UI wise, so we can accept the parent directory and normalize it ourselves.

Yes. That's why I insist that it's CLI/UI business to append ".git".

FWIW, we call -R/--repostiroy a repository path in CLI, but it's actually a workspace path.

let backend_initializer =
|settings: &UserSettings, store_path: &Path| -> Result<Box<dyn Backend>, _> {
// If the git repo is inside the workspace, use a relative path to it so the
Expand All @@ -203,7 +216,7 @@ impl Workspace {
// Workspace::new(), but it's not yet here.
let store_relative_git_repo_path = match (
workspace_root.canonicalize(),
canonicalize_git_repo_path(git_repo_path),
canonicalize_git_repo_path(&git_repo_path),
) {
(Ok(workspace_root), Ok(git_repo_path))
if git_repo_path.starts_with(&workspace_root) =>
Expand Down