ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: do not allow jj init --git in existing Git repo

Allowing `jj init --git` in an existing Git repo creates a second Git
store in `.jj/repo/store/git`, totally disconnected from the existing
Git store. This will only produce extremely confusing bugs for users,
since any operations they make in Git will *not* be reflected in the
jj repo.
This commit is contained in:
Chris Krycho 2023-11-26 15:29:03 -07:00 committed by Austin Seipp
parent e7ae1f9c0b
commit b4caef7fe0
3 changed files with 19 additions and 16 deletions

View file

@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `jj branch set` no longer creates a new branch. Use `jj branch create`
instead.
* `jj init --git` in an existing Git repository now errors and exits rather than
creating a second Git store.
### New features

View file

@ -65,6 +65,8 @@ pub(crate) fn cmd_init(
let wc_path = wc_path
.canonicalize()
.map_err(|e| user_error(format!("Failed to create workspace: {e}")))?; // raced?
let cwd = command.cwd().canonicalize().unwrap();
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);
@ -101,6 +103,16 @@ pub(crate) fn cmd_init(
}
print_trackable_remote_branches(ui, workspace_command.repo().view())?;
} else if args.git {
if wc_path.join(".git").exists() {
return Err(user_error_with_hint(
"Did not create a jj repo because there is an existing Git repo in this directory.",
format!(
r#"To create a repo backed by the existing Git repo, run `jj init --git-repo={}` instead."#,
relative_wc_path.display()
),
));
}
Workspace::init_internal_git(command.settings(), &wc_path)?;
} else {
if !command.settings().allow_native_backend() {
@ -112,22 +124,12 @@ Set `ui.allow-init-native` to allow initializing a repo with the native backend.
}
Workspace::init_local(command.settings(), &wc_path)?;
};
let cwd = command.cwd().canonicalize().unwrap();
let relative_wc_path = file_util::relative_path(&cwd, &wc_path);
writeln!(
ui.stderr(),
"Initialized repo in \"{}\"",
relative_wc_path.display()
)?;
if args.git && wc_path.join(".git").exists() {
writeln!(ui.warning(), "Empty repo created.")?;
writeln!(
ui.hint(),
"Hint: To create a repo backed by the existing Git repo, run `jj init --git-repo={}` \
instead.",
relative_wc_path.display()
)?;
}
Ok(())
}

View file

@ -418,16 +418,14 @@ fn test_init_git_external_but_git_dir_exists() {
}
#[test]
fn test_init_git_internal_but_could_be_colocated() {
fn test_init_git_internal_must_be_colocated() {
let test_env = TestEnvironment::default();
let workspace_root = test_env.env_root().join("repo");
init_git_repo(&workspace_root, false);
let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["init", "--git"]);
insta::assert_snapshot!(stdout, @"");
let stderr = test_env.jj_cmd_failure(&workspace_root, &["init", "--git"]);
insta::assert_snapshot!(stderr, @r###"
Initialized repo in "."
Empty repo created.
Error: Did not create a jj repo because there is an existing Git repo in this directory.
Hint: To create a repo backed by the existing Git repo, run `jj init --git-repo=.` instead.
"###);
}