From 386f002f5a21736d3e2fb8e0501809f07cdab767 Mon Sep 17 00:00:00 2001 From: Vladimir Petrzhikovskii Date: Tue, 22 Aug 2023 12:21:02 +0200 Subject: [PATCH] git: add --all-remotes to git fetch --- CHANGELOG.md | 3 +++ cli/src/commands/git.rs | 15 ++++++++++++++- cli/tests/test_git_fetch.rs | 31 +++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f946917f3..9128643fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `jj diff --stat` has been implemented. It shows a histogram of the changes, same as `git diff --stat`. Fixes [#2066](https://github.com/martinvonz/jj/issues/2066) +* `jj git fetch --all-remotes` has been implemented. It fetches all remotes + instead of just the default remote + ### Breaking changes * The minimum supported Rust version (MSRV) is now 1.71.0. diff --git a/cli/src/commands/git.rs b/cli/src/commands/git.rs index 25a05ca9c..2632bb39a 100644 --- a/cli/src/commands/git.rs +++ b/cli/src/commands/git.rs @@ -102,6 +102,9 @@ pub struct GitFetchArgs { /// repeated) #[arg(long = "remote", value_name = "remote")] remotes: Vec, + /// Fetch from all remotes + #[arg(long, conflicts_with = "remotes")] + all_remotes: bool, } /// Create a new repo backed by a clone of a Git repo @@ -314,7 +317,9 @@ fn cmd_git_fetch( ) -> Result<(), CommandError> { let mut workspace_command = command.workspace_helper(ui)?; let git_repo = get_git_repo(workspace_command.repo().store())?; - let remotes = if args.remotes.is_empty() { + let remotes = if args.all_remotes { + get_all_remotes(&git_repo)? + } else if args.remotes.is_empty() { get_default_fetch_remotes(ui, command.settings(), &git_repo)? } else { args.remotes.clone() @@ -379,6 +384,14 @@ fn get_default_fetch_remotes( } } +fn get_all_remotes(git_repo: &git2::Repository) -> Result, CommandError> { + let git_remotes = git_repo.remotes()?; + Ok(git_remotes + .iter() + .filter_map(|x| x.map(ToOwned::to_owned)) + .collect()) +} + fn absolute_git_source(cwd: &Path, source: &str) -> String { // Git appears to turn URL-like source to absolute path if local git directory // exits, and fails because '$PWD/https' is unsupported protocol. Since it would diff --git a/cli/tests/test_git_fetch.rs b/cli/tests/test_git_fetch.rs index 876de30c8..ea0cf78b5 100644 --- a/cli/tests/test_git_fetch.rs +++ b/cli/tests/test_git_fetch.rs @@ -98,6 +98,22 @@ fn test_git_fetch_single_remote() { "###); } +#[test] +fn test_git_fetch_single_remote_all_remotes_flag() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); + let repo_path = test_env.env_root().join("repo"); + add_git_remote(&test_env, &repo_path, "rem1"); + + test_env + .jj_cmd(&repo_path, &["git", "fetch", "--all-remotes"]) + .assert() + .success(); + insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###" + rem1: qxosxrvv 6a211027 message + "###); +} + #[test] fn test_git_fetch_single_remote_from_arg() { let test_env = TestEnvironment::default(); @@ -143,6 +159,21 @@ fn test_git_fetch_multiple_remotes() { "###); } +#[test] +fn test_git_fetch_all_remotes() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); + let repo_path = test_env.env_root().join("repo"); + add_git_remote(&test_env, &repo_path, "rem1"); + add_git_remote(&test_env, &repo_path, "rem2"); + + test_env.jj_cmd_success(&repo_path, &["git", "fetch", "--all-remotes"]); + insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###" + rem1: qxosxrvv 6a211027 message + rem2: yszkquru 2497a8a0 message + "###); +} + #[test] fn test_git_fetch_multiple_remotes_from_config() { let test_env = TestEnvironment::default();