-
Notifications
You must be signed in to change notification settings - Fork 365
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
Colocated workspaces, minimal #4644
base: main
Are you sure you want to change the base?
Changes from all commits
92bbf56
7e34182
0d72f0b
6c62985
899ac30
64adf64
3e4b0c1
2923211
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,22 +73,72 @@ pub fn get_git_repo(store: &Store) -> Result<git2::Repository, CommandError> { | |
} | ||
} | ||
|
||
pub fn is_colocated_git_workspace(workspace: &Workspace, repo: &ReadonlyRepo) -> bool { | ||
pub fn is_colocated_git_workspace( | ||
ui: Option<&Ui>, | ||
workspace: &Workspace, | ||
repo: &ReadonlyRepo, | ||
) -> bool { | ||
let Some(git_backend) = repo.store().backend_impl().downcast_ref::<GitBackend>() else { | ||
return false; | ||
}; | ||
let Some(git_workdir) = git_backend.git_workdir() else { | ||
return false; // Bare repository | ||
}; | ||
if git_workdir == workspace.workspace_root() { | ||
|
||
if git_backend.is_colocated() { | ||
return true; | ||
} | ||
// Colocated workspace should have ".git" directory, file, or symlink. Compare | ||
// its parent as the git_workdir might be resolved from the real ".git" path. | ||
let Ok(dot_git_path) = workspace.workspace_root().join(".git").canonicalize() else { | ||
return false; | ||
}; | ||
git_workdir.canonicalize().ok().as_deref() == dot_git_path.parent() | ||
|
||
if let Some(ui) = ui { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to add a separate function to print warning instead of passing |
||
let workspace_dot_git = workspace.workspace_root().join(".git"); | ||
let Ok(meta) = workspace_dot_git.symlink_metadata() else { | ||
return git_backend.is_colocated(); | ||
}; | ||
// Check symlink first as is_dir follows symlinks | ||
if meta.is_symlink() { | ||
let target = std::fs::read_link(&workspace_dot_git) | ||
.unwrap_or_else(|_| Path::new("<could not read link>").to_path_buf()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
writeln!( | ||
ui.warning_default(), | ||
"Workspace has a .git symlink (pointing to {}), that isn't pointing to JJ's git \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
repo", | ||
target.display() | ||
) | ||
.ok(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: no need to suppress There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What would you do instead? If we can't write a warning to stderr, we aren't going to be able to print a panic message either. So I figured there was no point panicking. All other instances of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I meant was just make this function return |
||
} else if meta.is_dir() { | ||
writeln!( | ||
ui.warning_default(), | ||
"Workspace has a .git directory that is not managed by JJ" | ||
) | ||
.ok(); | ||
} else if let Ok(_worktree_repo) = gix::open(workspace.workspace_root()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, I had it like this because there are more details you can add to the warning if you don't have to make the tests work on windows with its myriad path formats, and I had to remove them. |
||
writeln!( | ||
ui.warning_default(), | ||
"Workspace is also a Git worktree that is not managed by JJ", | ||
) | ||
.ok(); | ||
} else { | ||
let gitfile_contents = std::fs::read_to_string(&workspace_dot_git) | ||
.unwrap_or_else(|_| "<could not read .git file>".to_string()); | ||
let gitdir = gitfile_contents | ||
.strip_prefix("gitdir: ") | ||
.unwrap_or(&gitfile_contents) | ||
.trim(); | ||
writeln!(ui.warning_default(), "Workspace is a broken Git worktree").ok(); | ||
writeln!(ui.warning_no_heading(), "The .git file points at: {gitdir}").ok(); | ||
// work_dir may return Some even if colocated = false, because we may be in some | ||
// secondary workspace, and we may have just opened the colocated primary | ||
// workspace with a .git directory. | ||
let git_repo = git_backend.git_repo(); | ||
let repair_dir = git_repo.work_dir().unwrap_or(git_repo.common_dir()); | ||
writeln!( | ||
ui.hint_default(), | ||
"If this is meant to be a colocated JJ workspace, you may like to try `git -C {} \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: s/JJ/jj/g, orient yourself on the previous uses in the project. |
||
worktree repair`", | ||
repair_dir.display() | ||
) | ||
.ok(); | ||
} | ||
} | ||
|
||
false | ||
} | ||
|
||
fn terminal_get_username(ui: &Ui, url: &str) -> Option<String> { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this warning could be very noisy, so we should probably move it behind the future config flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had the same thought. Want me to add a flag in this PR?
git.suppress-colocation-warning
or something?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it can be verbose, I would remove the warning at all. Maybe the warning can be inserted to initialization/debug commands?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I think landing it as is or with Yuya's suggestion is fine, but it should definitely move behind the auto-colocate workspace flag in the follow-up
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jj git init
in an existing Git repo. To accomplish that you have to manually move files around.git init
in an existing JJ repo is what this is most likely to warn about.git.sync-with-colocated
or similar. I think that flag should be separate fromgit.auto-colocate
because of the use case I just described.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we would want a flag to disable import/export in colocated workspace, but that's a separate issue, so let's not discuss here.
Regarding the warning, suppose we have some concerns, I would remove it at least from this PR. I personally don't think we'll need these warnings, and there are no bug report about that iirc.