Skip to content

Commit

Permalink
cli: do not allow jj init --git in existing Git repo
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
chriskrycho authored and thoughtpolice committed Nov 28, 2023
1 parent e7ae1f9 commit b4caef7
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 16 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
24 changes: 13 additions & 11 deletions cli/src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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() {
Expand All @@ -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(())
}

Expand Down
8 changes: 3 additions & 5 deletions cli/tests/test_init_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"###);
}
Expand Down

0 comments on commit b4caef7

Please sign in to comment.