diff --git a/CHANGELOG.md b/CHANGELOG.md index 50438c5db7..ec34db1d23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,6 +125,12 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). * `jj squash` now accepts a `--keep-emptied` option to keep the source commit. +* The new configuration option `git.colocate=boolean` controls whether or not + Git repositories are colocated by default. + +* Both `jj git clone` and `jj git init` now take a `--no-colocate` flag to + disable colocation (in case `git.colocate` is set to `true`.) + ### Fixed bugs * `jj git push` now ignores immutable commits when checking whether a diff --git a/cli/src/commands/git/clone.rs b/cli/src/commands/git/clone.rs index 0d450e8afd..1f11580e5a 100644 --- a/cli/src/commands/git/clone.rs +++ b/cli/src/commands/git/clone.rs @@ -45,6 +45,9 @@ pub struct GitCloneArgs { /// Whether or not to colocate the Jujutsu repo with the git repo #[arg(long)] colocate: bool, + /// Disable colocation of the Jujutsu repo with the git repo + #[arg(long, conflicts_with = "colocate")] + no_colocate: bool, } fn absolute_git_source(cwd: &Path, source: &str) -> String { @@ -105,6 +108,12 @@ pub fn cmd_git_clone( fs::create_dir_all(&wc_path) .map_err(|err| user_error_with_message(format!("Failed to create {wc_path_str}"), err))?; + let colocate = if command.settings().git_settings().colocate { + !args.no_colocate + } else { + args.colocate + }; + // Canonicalize because fs::remove_dir_all() doesn't seem to like e.g. // `/some/path/.` let canonical_wc_path: PathBuf = wc_path @@ -113,7 +122,7 @@ pub fn cmd_git_clone( let clone_result = do_git_clone( ui, command, - args.colocate, + colocate, remote_name, &source, &canonical_wc_path, @@ -121,7 +130,7 @@ pub fn cmd_git_clone( if clone_result.is_err() { let clean_up_dirs = || -> io::Result<()> { fs::remove_dir_all(canonical_wc_path.join(".jj"))?; - if args.colocate { + if colocate { fs::remove_dir_all(canonical_wc_path.join(".git"))?; } if !wc_path_existed { diff --git a/cli/src/commands/git/init.rs b/cli/src/commands/git/init.rs index 45c71ea06d..9438c48165 100644 --- a/cli/src/commands/git/init.rs +++ b/cli/src/commands/git/init.rs @@ -53,6 +53,10 @@ pub struct GitInitArgs { #[arg(long, conflicts_with = "git_repo")] colocate: bool, + /// Disable colocation of the Jujutsu repo with the git repo + #[arg(long, conflicts_with = "colocate")] + no_colocate: bool, + /// Specifies a path to an **existing** git repository to be /// used as the backing git repo for the newly created `jj` repo. /// @@ -77,13 +81,13 @@ pub fn cmd_git_init( .and_then(|_| wc_path.canonicalize()) .map_err(|e| user_error_with_message("Failed to create workspace", e))?; - do_init( - ui, - command, - &wc_path, - args.colocate, - args.git_repo.as_deref(), - )?; + let colocate = if command.settings().git_settings().colocate { + !args.no_colocate + } else { + args.colocate + }; + + do_init(ui, command, &wc_path, colocate, args.git_repo.as_deref())?; let relative_wc_path = file_util::relative_path(cwd, &wc_path); writeln!( diff --git a/cli/src/config-schema.json b/cli/src/config-schema.json index 5fbfdba40d..e9eb5df6a6 100644 --- a/cli/src/config-schema.json +++ b/cli/src/config-schema.json @@ -314,6 +314,11 @@ "type": "string", "description": "The remote to which commits are pushed", "default": "origin" + }, + "colocate": { + "type": "boolean", + "description": "Whether to colocate the working copy with the git repository", + "default": false } } }, diff --git a/cli/tests/cli-reference@.md.snap b/cli/tests/cli-reference@.md.snap index 66ab5779ae..cbde168d7c 100644 --- a/cli/tests/cli-reference@.md.snap +++ b/cli/tests/cli-reference@.md.snap @@ -845,6 +845,7 @@ The Git repo will be a bare git repo stored inside the `.jj/` directory. ###### **Options:** * `--colocate` — Whether or not to colocate the Jujutsu repo with the git repo +* `--no-colocate` — Disable colocation of the Jujutsu repo with the git repo @@ -907,6 +908,7 @@ Create a new Git backed repo This is done by placing the backing git repo into a `.git` directory in the root of the `jj` repo along with the `.jj` directory. If the `.git` directory already exists, all the existing commits will be imported. This option is mutually exclusive with `--git-repo`. +* `--no-colocate` — Disable colocation of the Jujutsu repo with the git repo * `--git-repo ` — Specifies a path to an **existing** git repository to be used as the backing git repo for the newly created `jj` repo. If the specified `--git-repo` path happens to be the same as the `jj` repo path (both .jj and .git directories are in the same working directory), then both `jj` and `git` commands will work on the same repo. This is called a co-located repo. diff --git a/docs/config.md b/docs/config.md index b2460af354..d5466b82f5 100644 --- a/docs/config.md +++ b/docs/config.md @@ -732,6 +732,19 @@ signing.backends.ssh.allowed-signers = "/path/to/allowed-signers" ## Git settings +### Default colocation + +When creating a git-backed Jujutsu repository, you can enable "colocation" which +places the `.git` directory next to the `.jj` directory, allowing some amount of +two-way interoperability. + +The setting `git.colocate` is a boolean option that controls whether or not the +`jj git init` and `jj git clone` commands should create colocated repositories +by default. By default, `git.colocate` is set to `false`. + +See [Co-located Jujutsu/Git repos](./ +git-compatibility.md#co-located-jujutsugit-repos) for more information. + ### Default remotes for `jj git fetch` and `jj git push` By default, if a single remote exists it is used for `jj git fetch` and `jj git diff --git a/lib/src/settings.rs b/lib/src/settings.rs index c0a17ef3b2..3d70cefbf5 100644 --- a/lib/src/settings.rs +++ b/lib/src/settings.rs @@ -42,6 +42,7 @@ pub struct RepoSettings { pub struct GitSettings { pub auto_local_branch: bool, pub abandon_unreachable_commits: bool, + pub colocate: bool, } impl GitSettings { @@ -51,6 +52,7 @@ impl GitSettings { abandon_unreachable_commits: config .get_bool("git.abandon-unreachable-commits") .unwrap_or(true), + colocate: config.get_bool("git.colocate").unwrap_or(false), } } } @@ -60,6 +62,7 @@ impl Default for GitSettings { GitSettings { auto_local_branch: false, abandon_unreachable_commits: true, + colocate: false, } } }