diff --git a/CHANGELOG.md b/CHANGELOG.md index fa9c8e2c6..589afc3e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). * In `jj config list` template, `value` is now typed as `ConfigValue`, not as `String` serialized in TOML syntax. +* `jj git remote add`/`set-url` now converts relative Git remote path to + absolute path. + * Upgraded `scm-record` from v0.4.0 to v0.5.0. See release notes at . diff --git a/cli/src/commands/git/clone.rs b/cli/src/commands/git/clone.rs index 396c3a50c..0f8c6aaf1 100644 --- a/cli/src/commands/git/clone.rs +++ b/cli/src/commands/git/clone.rs @@ -46,6 +46,8 @@ use crate::ui::Ui; #[derive(clap::Args, Clone, Debug)] pub struct GitCloneArgs { /// URL or path of the Git repo to clone + /// + /// Local path will be resolved to absolute form. #[arg(value_hint = clap::ValueHint::DirPath)] source: String, /// Specifies the target directory for the Jujutsu repository clone. diff --git a/cli/src/commands/git/remote/add.rs b/cli/src/commands/git/remote/add.rs index a66a7faac..d0868c3a9 100644 --- a/cli/src/commands/git/remote/add.rs +++ b/cli/src/commands/git/remote/add.rs @@ -17,6 +17,7 @@ use jj_lib::repo::Repo; use crate::cli_util::CommandHelper; use crate::command_error::CommandError; +use crate::git_util::absolute_git_url; use crate::git_util::get_git_repo; use crate::ui::Ui; @@ -25,7 +26,10 @@ use crate::ui::Ui; pub struct GitRemoteAddArgs { /// The remote's name remote: String, - /// The remote's URL + /// The remote's URL or path + /// + /// Local path will be resolved to absolute form. + #[arg(value_hint = clap::ValueHint::DirPath)] url: String, } @@ -37,6 +41,7 @@ pub fn cmd_git_remote_add( let workspace_command = command.workspace_helper(ui)?; let repo = workspace_command.repo(); let git_repo = get_git_repo(repo.store())?; - git::add_remote(&git_repo, &args.remote, &args.url)?; + let url = absolute_git_url(command.cwd(), &args.url)?; + git::add_remote(&git_repo, &args.remote, &url)?; Ok(()) } diff --git a/cli/src/commands/git/remote/set_url.rs b/cli/src/commands/git/remote/set_url.rs index 770efa7f5..d60435781 100644 --- a/cli/src/commands/git/remote/set_url.rs +++ b/cli/src/commands/git/remote/set_url.rs @@ -19,6 +19,7 @@ use jj_lib::repo::Repo; use crate::cli_util::CommandHelper; use crate::command_error::CommandError; use crate::complete; +use crate::git_util::absolute_git_url; use crate::git_util::get_git_repo; use crate::ui::Ui; @@ -28,7 +29,10 @@ pub struct GitRemoteSetUrlArgs { /// The remote's name #[arg(add = ArgValueCandidates::new(complete::git_remotes))] remote: String, - /// The desired url for `remote` + /// The desired URL or path for `remote` + /// + /// Local path will be resolved to absolute form. + #[arg(value_hint = clap::ValueHint::DirPath)] url: String, } @@ -40,6 +44,7 @@ pub fn cmd_git_remote_set_url( let workspace_command = command.workspace_helper(ui)?; let repo = workspace_command.repo(); let git_repo = get_git_repo(repo.store())?; - git::set_remote_url(&git_repo, &args.remote, &args.url)?; + let url = absolute_git_url(command.cwd(), &args.url)?; + git::set_remote_url(&git_repo, &args.remote, &url)?; Ok(()) } diff --git a/cli/tests/cli-reference@.md.snap b/cli/tests/cli-reference@.md.snap index 6df2b3d3f..7d22daa0e 100644 --- a/cli/tests/cli-reference@.md.snap +++ b/cli/tests/cli-reference@.md.snap @@ -1051,6 +1051,8 @@ The Git repo will be a bare git repo stored inside the `.jj/` directory. ###### **Arguments:** * `` — URL or path of the Git repo to clone + + Local path will be resolved to absolute form. * `` — Specifies the target directory for the Jujutsu repository clone. If not provided, defaults to a directory named after the last component of the source URL. The full directory path will be created if it doesn't exist ###### **Options:** @@ -1203,7 +1205,9 @@ Add a Git remote ###### **Arguments:** * `` — The remote's name -* `` — The remote's URL +* `` — The remote's URL or path + + Local path will be resolved to absolute form. @@ -1249,7 +1253,9 @@ Set the URL of a Git remote ###### **Arguments:** * `` — The remote's name -* `` — The desired url for `remote` +* `` — The desired URL or path for `remote` + + Local path will be resolved to absolute form. diff --git a/cli/tests/test_git_remotes.rs b/cli/tests/test_git_remotes.rs index 09ebf7899..b80f832b3 100644 --- a/cli/tests/test_git_remotes.rs +++ b/cli/tests/test_git_remotes.rs @@ -13,6 +13,7 @@ // limitations under the License. use std::fs; +use std::path::PathBuf; use crate::common::TestEnvironment; @@ -144,6 +145,30 @@ fn test_git_remote_set_url() { "###); } +#[test] +fn test_git_remote_relative_path() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); + let repo_path = test_env.env_root().join("repo"); + + // Relative path using OS-native separator + let path = PathBuf::from_iter(["..", "native", "sep"]); + test_env.jj_cmd_ok( + &repo_path, + &["git", "remote", "add", "foo", path.to_str().unwrap()], + ); + let stdout = test_env.jj_cmd_success(&repo_path, &["git", "remote", "list"]); + insta::assert_snapshot!(stdout, @"foo $TEST_ENV/native/sep"); + + // Relative path using UNIX separator + test_env.jj_cmd_ok( + test_env.env_root(), + &["-Rrepo", "git", "remote", "set-url", "foo", "unix/sep"], + ); + let stdout = test_env.jj_cmd_success(&repo_path, &["git", "remote", "list"]); + insta::assert_snapshot!(stdout, @"foo $TEST_ENV/unix/sep"); +} + #[test] fn test_git_remote_rename() { let test_env = TestEnvironment::default();