forked from mirrors/jj
cli: git: add jj git remote set-url
command
This commit is contained in:
parent
3c80e3453d
commit
f8e106a194
6 changed files with 143 additions and 0 deletions
|
@ -70,6 +70,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
* `jj prev` and `jj next` have gained a `--conflict` flag which moves you
|
||||
to the next conflict in a child commit.
|
||||
|
||||
* New command `jj git remote set-url` that sets the url of a git remote.
|
||||
|
||||
### Fixed bugs
|
||||
|
||||
## [0.18.0] - 2024-06-05
|
||||
|
|
|
@ -16,6 +16,7 @@ pub mod add;
|
|||
pub mod list;
|
||||
pub mod remove;
|
||||
pub mod rename;
|
||||
pub mod set_url;
|
||||
|
||||
use clap::Subcommand;
|
||||
|
||||
|
@ -23,6 +24,7 @@ use self::add::{cmd_remote_add, AddArgs};
|
|||
use self::list::{cmd_remote_list, ListArgs};
|
||||
use self::remove::{cmd_remote_remove, RemoveArgs};
|
||||
use self::rename::{cmd_remote_rename, RenameArgs};
|
||||
use self::set_url::{cmd_remote_set_url, SetUrlArgs};
|
||||
use crate::cli_util::CommandHelper;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::ui::Ui;
|
||||
|
@ -36,6 +38,7 @@ pub enum RemoteCommand {
|
|||
List(ListArgs),
|
||||
Remove(RemoveArgs),
|
||||
Rename(RenameArgs),
|
||||
SetUrl(SetUrlArgs),
|
||||
}
|
||||
|
||||
pub fn cmd_git_remote(
|
||||
|
@ -48,5 +51,6 @@ pub fn cmd_git_remote(
|
|||
RemoteCommand::List(args) => cmd_remote_list(ui, command, args),
|
||||
RemoteCommand::Remove(args) => cmd_remote_remove(ui, command, args),
|
||||
RemoteCommand::Rename(args) => cmd_remote_rename(ui, command, args),
|
||||
RemoteCommand::SetUrl(args) => cmd_remote_set_url(ui, command, args),
|
||||
}
|
||||
}
|
||||
|
|
42
cli/src/commands/git/remote/set_url.rs
Normal file
42
cli/src/commands/git/remote/set_url.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2024 The Jujutsu Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use jj_lib::git;
|
||||
use jj_lib::repo::Repo;
|
||||
|
||||
use crate::cli_util::CommandHelper;
|
||||
use crate::command_error::CommandError;
|
||||
use crate::git_util::get_git_repo;
|
||||
use crate::ui::Ui;
|
||||
|
||||
/// Set the URL of a Git remote
|
||||
#[derive(clap::Args, Clone, Debug)]
|
||||
pub struct SetUrlArgs {
|
||||
/// The remote's name
|
||||
remote: String,
|
||||
/// The desired url for `remote`
|
||||
url: String,
|
||||
}
|
||||
|
||||
pub fn cmd_remote_set_url(
|
||||
ui: &mut Ui,
|
||||
command: &CommandHelper,
|
||||
args: &SetUrlArgs,
|
||||
) -> Result<(), CommandError> {
|
||||
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)?;
|
||||
Ok(())
|
||||
}
|
|
@ -52,6 +52,7 @@ This document contains the help content for the `jj` command-line program.
|
|||
* [`jj git remote list`↴](#jj-git-remote-list)
|
||||
* [`jj git remote remove`↴](#jj-git-remote-remove)
|
||||
* [`jj git remote rename`↴](#jj-git-remote-rename)
|
||||
* [`jj git remote set-url`↴](#jj-git-remote-set-url)
|
||||
* [`jj init`↴](#jj-init)
|
||||
* [`jj interdiff`↴](#jj-interdiff)
|
||||
* [`jj log`↴](#jj-log)
|
||||
|
@ -955,6 +956,7 @@ The Git repo will be a bare git repo stored inside the `.jj/` directory.
|
|||
* `list` — List Git remotes
|
||||
* `remove` — Remove a Git remote and forget its branches
|
||||
* `rename` — Rename a Git remote
|
||||
* `set-url` — Set the URL of a Git remote
|
||||
|
||||
|
||||
|
||||
|
@ -1004,6 +1006,19 @@ Rename a Git remote
|
|||
|
||||
|
||||
|
||||
## `jj git remote set-url`
|
||||
|
||||
Set the URL of a Git remote
|
||||
|
||||
**Usage:** `jj git remote set-url <REMOTE> <URL>`
|
||||
|
||||
###### **Arguments:**
|
||||
|
||||
* `<REMOTE>` — The remote's name
|
||||
* `<URL>` — The desired url for `remote`
|
||||
|
||||
|
||||
|
||||
## `jj init`
|
||||
|
||||
Create a new repo in the given directory
|
||||
|
|
|
@ -90,6 +90,60 @@ fn test_git_remote_add() {
|
|||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_remote_set_url() {
|
||||
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");
|
||||
test_env.jj_cmd_ok(
|
||||
&repo_path,
|
||||
&["git", "remote", "add", "foo", "http://example.com/repo/foo"],
|
||||
);
|
||||
let stderr = test_env.jj_cmd_failure(
|
||||
&repo_path,
|
||||
&[
|
||||
"git",
|
||||
"remote",
|
||||
"set-url",
|
||||
"bar",
|
||||
"http://example.com/repo/bar",
|
||||
],
|
||||
);
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Error: No git remote named 'bar'
|
||||
"###);
|
||||
let stderr = test_env.jj_cmd_failure(
|
||||
&repo_path,
|
||||
&[
|
||||
"git",
|
||||
"remote",
|
||||
"set-url",
|
||||
"git",
|
||||
"http://example.com/repo/git",
|
||||
],
|
||||
);
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Error: Git remote named 'git' is reserved for local Git repository
|
||||
"###);
|
||||
let (stdout, stderr) = test_env.jj_cmd_ok(
|
||||
&repo_path,
|
||||
&[
|
||||
"git",
|
||||
"remote",
|
||||
"set-url",
|
||||
"foo",
|
||||
"http://example.com/repo/bar",
|
||||
],
|
||||
);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(stderr, @"");
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["git", "remote", "list"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
foo http://example.com/repo/bar
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_remote_rename() {
|
||||
let test_env = TestEnvironment::default();
|
||||
|
|
|
@ -1144,6 +1144,32 @@ pub fn rename_remote(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_remote_url(
|
||||
git_repo: &git2::Repository,
|
||||
remote_name: &str,
|
||||
new_remote_url: &str,
|
||||
) -> Result<(), GitRemoteManagementError> {
|
||||
if remote_name == REMOTE_NAME_FOR_LOCAL_GIT_REPO {
|
||||
return Err(GitRemoteManagementError::RemoteReservedForLocalGitRepo);
|
||||
}
|
||||
|
||||
// Repository::remote_set_url() doesn't ensure the remote exists, it just
|
||||
// creates it if it's missing.
|
||||
// Therefore ensure it exists first
|
||||
git_repo.find_remote(remote_name).map_err(|err| {
|
||||
if is_remote_not_found_err(&err) {
|
||||
GitRemoteManagementError::NoSuchRemote(remote_name.to_owned())
|
||||
} else {
|
||||
GitRemoteManagementError::InternalGitError(err)
|
||||
}
|
||||
})?;
|
||||
|
||||
git_repo
|
||||
.remote_set_url(remote_name, new_remote_url)
|
||||
.map_err(GitRemoteManagementError::InternalGitError)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn rename_remote_refs(mut_repo: &mut MutableRepo, old_remote_name: &str, new_remote_name: &str) {
|
||||
mut_repo.rename_remote(old_remote_name, new_remote_name);
|
||||
let prefix = format!("refs/remotes/{old_remote_name}/");
|
||||
|
|
Loading…
Reference in a new issue