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/lib: add git.colocate to colocate repositories by default #2512

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
thoughtpolice marked this conversation as resolved.
Show resolved Hide resolved

* 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
Expand Down
13 changes: 11 additions & 2 deletions cli/src/commands/git/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand All @@ -113,15 +122,15 @@ pub fn cmd_git_clone(
let clone_result = do_git_clone(
ui,
command,
args.colocate,
colocate,
remote_name,
&source,
&canonical_wc_path,
);
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 {
Expand Down
18 changes: 11 additions & 7 deletions cli/src/commands/git/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand All @@ -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
};
thoughtpolice marked this conversation as resolved.
Show resolved Hide resolved

do_init(ui, command, &wc_path, colocate, args.git_repo.as_deref())?;

let relative_wc_path = file_util::relative_path(cwd, &wc_path);
writeln!(
Expand Down
5 changes: 5 additions & 0 deletions cli/src/config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
},
Expand Down
2 changes: 2 additions & 0 deletions cli/tests/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -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



Expand Down Expand Up @@ -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 <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.
Expand Down
13 changes: 13 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions lib/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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),
}
}
}
Expand All @@ -60,6 +62,7 @@ impl Default for GitSettings {
GitSettings {
auto_local_branch: false,
abandon_unreachable_commits: true,
colocate: false,
}
}
}
Expand Down