From 6e72b1cfb02b994e738a16f7e965f1d0ebfe7224 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Thu, 12 Sep 2024 21:20:46 +0200 Subject: [PATCH] git: add --remote option to clone command This makes it easier to work with multiple remotes at once while tracking the default branch of the remote used to create the local repository: ```shell $ jj git clone --remote upstream https://github.com/upstream-org/repo $ cd repo $ jj git remote add origin git@github.com:your-org/repo $ jj config set --repo git.fetch upstream ``` In the example above, `upstream` is the repository containing the reference source code that you might want to patch, while `origin` is your fork where pull-request will be pushed. The branch `main@upstream` will be tracked. --- CHANGELOG.md | 4 ++++ cli/src/commands/git/clone.rs | 5 ++++- cli/tests/cli-reference@.md.snap | 3 +++ cli/tests/test_git_clone.rs | 24 ++++++++++++++++++++++++ docs/git-comparison.md | 4 ++-- docs/git-compatibility.md | 3 +++ docs/github.md | 29 +++++++++++++++++++++++++---- 7 files changed, 65 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 243cd589a..1ef195237 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). * `jj op log` gained an option to include operation diffs. +* `jj git clone` now accepts a `--remote ` option, which + allows to set a name for the remote instead of using the default + `origin`. + ### Fixed bugs * Fixed panic when parsing invalid conflict markers of a particular form. diff --git a/cli/src/commands/git/clone.rs b/cli/src/commands/git/clone.rs index 311f62bdc..4c3e1cc13 100644 --- a/cli/src/commands/git/clone.rs +++ b/cli/src/commands/git/clone.rs @@ -54,6 +54,9 @@ pub struct GitCloneArgs { /// doesn't exist. #[arg(value_hint = clap::ValueHint::DirPath)] destination: Option, + /// Name of the newly created remote + #[arg(long = "remote", default_value = "origin")] + remote_name: String, /// Whether or not to colocate the Jujutsu repo with the git repo #[arg(long)] colocate: bool, @@ -97,10 +100,10 @@ pub fn cmd_git_clone( command: &CommandHelper, args: &GitCloneArgs, ) -> Result<(), CommandError> { + let remote_name = &args.remote_name; if command.global_args().at_operation.is_some() { return Err(cli_error("--at-op is not respected")); } - let remote_name = "origin"; let source = absolute_git_source(command.cwd(), &args.source); let wc_path_str = args .destination diff --git a/cli/tests/cli-reference@.md.snap b/cli/tests/cli-reference@.md.snap index f8ef40f15..8d255d7af 100644 --- a/cli/tests/cli-reference@.md.snap +++ b/cli/tests/cli-reference@.md.snap @@ -957,6 +957,9 @@ The Git repo will be a bare git repo stored inside the `.jj/` directory. ###### **Options:** +* `--remote ` — Name of the newly created remote + + Default value: `origin` * `--colocate` — Whether or not to colocate the Jujutsu repo with the git repo diff --git a/cli/tests/test_git_clone.rs b/cli/tests/test_git_clone.rs index 462b18a83..d8b611fa9 100644 --- a/cli/tests/test_git_clone.rs +++ b/cli/tests/test_git_clone.rs @@ -498,6 +498,30 @@ fn test_git_clone_at_operation() { "###); } +#[test] +fn test_git_clone_with_remote_name() { + let test_env = TestEnvironment::default(); + test_env.add_config("git.auto-local-branch = true"); + let git_repo_path = test_env.env_root().join("source"); + let git_repo = git2::Repository::init(git_repo_path).unwrap(); + set_up_non_empty_git_repo(&git_repo); + + // Clone with relative source path and a non-default remote name + let (stdout, stderr) = test_env.jj_cmd_ok( + test_env.env_root(), + &["git", "clone", "source", "clone", "--remote", "upstream"], + ); + insta::assert_snapshot!(stdout, @""); + insta::assert_snapshot!(stderr, @r#" + Fetching into new repo in "$TEST_ENV/clone" + bookmark: main@upstream [new] tracked + Setting the revset alias "trunk()" to "main@upstream" + Working copy now at: sqpuoqvx cad212e1 (empty) (no description set) + Parent commit : mzyxwzks 9f01a0e0 main | message + Added 1 files, modified 0 files, removed 0 files + "#); +} + fn get_bookmark_output(test_env: &TestEnvironment, repo_path: &Path) -> String { test_env.jj_cmd_success(repo_path, &["bookmark", "list", "--all-remotes"]) } diff --git a/docs/git-comparison.md b/docs/git-comparison.md index eab88a84e..2d779317a 100644 --- a/docs/git-comparison.md +++ b/docs/git-comparison.md @@ -105,9 +105,9 @@ parent. Clone an existing repo - jj git clone <source> <destination> (there is no support + jj git clone <source> <destination> [--remote <remote name>] (there is no support for cloning non-Git repos yet) - git clone <source> <destination> + git clone <source> <destination> [--origin <remote name>] Update the local repo with all bookmarks from a remote diff --git a/docs/git-compatibility.md b/docs/git-compatibility.md index 9afa34a43..36eb957b6 100644 --- a/docs/git-compatibility.md +++ b/docs/git-compatibility.md @@ -94,6 +94,9 @@ To create a Jujutsu repo from a remote Git URL, use `jj git clone https://github.com/octocat/Hello-World` will clone GitHub's "Hello-World" repo into a directory by the same name. +By default, the remote repository will be named `origin`. You can use +a name of your choice by adding `--remote ` to the `jj +git clone` command. ## Co-located Jujutsu/Git repos diff --git a/docs/github.md b/docs/github.md index e007222df..5a1bc67f1 100644 --- a/docs/github.md +++ b/docs/github.md @@ -253,11 +253,22 @@ the [tutorial][tut]. It is common to use several remotes when contributing to a shared repository. For example, "upstream" can designate the remote where the changes will be merged through a pull-request while "origin" is your private fork of the -project. In this case, you might want to `jj git fetch` from "upstream" and to -`jj git push` to "origin". +project. -You can configure the default remotes to fetch from and push to in your -configuration file (for example `.jj/repo/config.toml`): +```shell +$ jj git clone --remote upstream https://github.com/upstream-org/repo +$ cd repo +$ jj git remote add origin git@github.com:your-org/your-repo-fork +``` + +This will automatically setup your repository to track the main +bookmark from the upstream repository, typically `main@upstream` +or `master@upstream`. + +You might want to `jj git fetch` from "upstream" and to `jj git push` +to "origin". You can configure the default remotes to fetch from and +push to in your configuration file (for example, +`.jj/repo/config.toml`): ```toml [git] @@ -266,3 +277,13 @@ push = "origin" ``` The default for both `git.fetch` and `git.push` is "origin". + +If you usually work on a project from several computers, you may +configure `jj` to fetch from both repositories by default, in order to +keep your own bookmarks synchronized through your `origin` repository: + +```toml +[git] +fetch = ["upstream", "origin"] +push = "origin" +```