forked from mirrors/jj
cmd: --branch
option for git fetch
.
Thanks to @samueltardieu for noticing a subtle bug in the refspecs, providing the fix, as well as the two `conflicting_branches` tests.
This commit is contained in:
parent
cd8a18daf8
commit
30d03a66e6
5 changed files with 519 additions and 2 deletions
|
@ -23,6 +23,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
* `jj rebase` now accepts multiple `-s` and `-b` arguments. Revsets with
|
||||
multiple commits are allowed with `--allow-large-revsets`.
|
||||
|
||||
* `jj git fetch` now supports a `--branch` argument to fetch some of the
|
||||
branches only.
|
||||
|
||||
### Fixed bugs
|
||||
|
||||
* Modify/delete conflicts now include context lines
|
||||
|
|
|
@ -330,6 +330,8 @@ pub fn export_refs(
|
|||
pub enum GitFetchError {
|
||||
#[error("No git remote named '{0}'")]
|
||||
NoSuchRemote(String),
|
||||
#[error("Invalid glob provided. Globs may not contain the characters `:` or `^`.")]
|
||||
InvalidGlob,
|
||||
// TODO: I'm sure there are other errors possible, such as transport-level errors.
|
||||
#[error("Unexpected git error when fetching: {0}")]
|
||||
InternalGitError(#[from] git2::Error),
|
||||
|
@ -340,6 +342,7 @@ pub fn fetch(
|
|||
mut_repo: &mut MutableRepo,
|
||||
git_repo: &git2::Repository,
|
||||
remote_name: &str,
|
||||
globs: &[String],
|
||||
callbacks: RemoteCallbacks<'_>,
|
||||
git_settings: &GitSettings,
|
||||
) -> Result<Option<String>, GitFetchError> {
|
||||
|
@ -361,9 +364,17 @@ pub fn fetch(
|
|||
fetch_options.proxy_options(proxy_options);
|
||||
let callbacks = callbacks.into_git();
|
||||
fetch_options.remote_callbacks(callbacks);
|
||||
let refspec: &[&str] = &[];
|
||||
if globs.iter().any(|g| g.contains(|c| ":^".contains(c))) {
|
||||
return Err(GitFetchError::InvalidGlob);
|
||||
}
|
||||
// At this point, we are only updating Git's remote tracking branches, not the
|
||||
// local branches.
|
||||
let refspecs = globs
|
||||
.iter()
|
||||
.map(|glob| format!("+refs/heads/{glob}:refs/remotes/{remote_name}/{glob}"))
|
||||
.collect_vec();
|
||||
tracing::debug!("remote.download");
|
||||
remote.download(refspec, Some(&mut fetch_options))?;
|
||||
remote.download(&refspecs, Some(&mut fetch_options))?;
|
||||
tracing::debug!("remote.prune");
|
||||
remote.prune(None)?;
|
||||
tracing::debug!("remote.update_tips");
|
||||
|
|
|
@ -957,6 +957,7 @@ fn test_fetch_empty_repo() {
|
|||
tx.mut_repo(),
|
||||
&test_data.git_repo,
|
||||
"origin",
|
||||
&[],
|
||||
git::RemoteCallbacks::default(),
|
||||
&git_settings,
|
||||
)
|
||||
|
@ -980,6 +981,7 @@ fn test_fetch_initial_commit() {
|
|||
tx.mut_repo(),
|
||||
&test_data.git_repo,
|
||||
"origin",
|
||||
&[],
|
||||
git::RemoteCallbacks::default(),
|
||||
&git_settings,
|
||||
)
|
||||
|
@ -1021,6 +1023,7 @@ fn test_fetch_success() {
|
|||
tx.mut_repo(),
|
||||
&test_data.git_repo,
|
||||
"origin",
|
||||
&[],
|
||||
git::RemoteCallbacks::default(),
|
||||
&git_settings,
|
||||
)
|
||||
|
@ -1041,6 +1044,7 @@ fn test_fetch_success() {
|
|||
tx.mut_repo(),
|
||||
&test_data.git_repo,
|
||||
"origin",
|
||||
&[],
|
||||
git::RemoteCallbacks::default(),
|
||||
&git_settings,
|
||||
)
|
||||
|
@ -1082,6 +1086,7 @@ fn test_fetch_prune_deleted_ref() {
|
|||
tx.mut_repo(),
|
||||
&test_data.git_repo,
|
||||
"origin",
|
||||
&[],
|
||||
git::RemoteCallbacks::default(),
|
||||
&git_settings,
|
||||
)
|
||||
|
@ -1100,6 +1105,7 @@ fn test_fetch_prune_deleted_ref() {
|
|||
tx.mut_repo(),
|
||||
&test_data.git_repo,
|
||||
"origin",
|
||||
&[],
|
||||
git::RemoteCallbacks::default(),
|
||||
&git_settings,
|
||||
)
|
||||
|
@ -1120,6 +1126,7 @@ fn test_fetch_no_default_branch() {
|
|||
tx.mut_repo(),
|
||||
&test_data.git_repo,
|
||||
"origin",
|
||||
&[],
|
||||
git::RemoteCallbacks::default(),
|
||||
&git_settings,
|
||||
)
|
||||
|
@ -1142,6 +1149,7 @@ fn test_fetch_no_default_branch() {
|
|||
tx.mut_repo(),
|
||||
&test_data.git_repo,
|
||||
"origin",
|
||||
&[],
|
||||
git::RemoteCallbacks::default(),
|
||||
&git_settings,
|
||||
)
|
||||
|
@ -1161,6 +1169,7 @@ fn test_fetch_no_such_remote() {
|
|||
tx.mut_repo(),
|
||||
&test_data.git_repo,
|
||||
"invalid-remote",
|
||||
&[],
|
||||
git::RemoteCallbacks::default(),
|
||||
&git_settings,
|
||||
);
|
||||
|
|
|
@ -85,6 +85,12 @@ pub struct GitRemoteListArgs {}
|
|||
/// Fetch from a Git remote
|
||||
#[derive(clap::Args, Clone, Debug)]
|
||||
pub struct GitFetchArgs {
|
||||
/// Fetch only some of the branches (caution: known bugs)
|
||||
///
|
||||
/// Any `*` in the argument is expanded as a glob. So, one `--branch` can
|
||||
/// match several branches.
|
||||
#[arg(long)]
|
||||
branch: Vec<String>,
|
||||
/// The remote to fetch from (only named remotes are supported, can be
|
||||
/// repeated)
|
||||
#[arg(long = "remote", value_name = "remote")]
|
||||
|
@ -263,6 +269,7 @@ fn cmd_git_fetch(
|
|||
tx.mut_repo(),
|
||||
&git_repo,
|
||||
&remote,
|
||||
&args.branch,
|
||||
cb,
|
||||
&command.settings().git_settings(),
|
||||
)
|
||||
|
@ -390,6 +397,7 @@ fn do_git_clone(
|
|||
fetch_tx.mut_repo(),
|
||||
&git_repo,
|
||||
remote_name,
|
||||
&[],
|
||||
cb,
|
||||
&command.settings().git_settings(),
|
||||
)
|
||||
|
@ -399,6 +407,9 @@ fn do_git_clone(
|
|||
panic!("shouldn't happen as we just created the git remote")
|
||||
}
|
||||
GitFetchError::InternalGitError(err) => user_error(format!("Fetch failed: {err}")),
|
||||
GitFetchError::InvalidGlob => {
|
||||
unreachable!("we didn't provide any globs")
|
||||
}
|
||||
})?;
|
||||
fetch_tx.finish(ui)?;
|
||||
Ok((workspace_command, maybe_default_branch))
|
||||
|
|
|
@ -50,6 +50,32 @@ fn get_branch_output(test_env: &TestEnvironment, repo_path: &Path) -> String {
|
|||
test_env.jj_cmd_success(repo_path, &["branch", "list"])
|
||||
}
|
||||
|
||||
fn create_commit(test_env: &TestEnvironment, repo_path: &Path, name: &str, parents: &[&str]) {
|
||||
let descr = format!("descr_for_{name}");
|
||||
if parents.is_empty() {
|
||||
test_env.jj_cmd_success(repo_path, &["new", "root", "-m", &descr]);
|
||||
} else {
|
||||
let mut args = vec!["new", "-m", &descr];
|
||||
args.extend(parents);
|
||||
test_env.jj_cmd_success(repo_path, &args);
|
||||
}
|
||||
std::fs::write(repo_path.join(name), format!("{name}\n")).unwrap();
|
||||
test_env.jj_cmd_success(repo_path, &["branch", "create", name]);
|
||||
}
|
||||
|
||||
fn get_log_output(test_env: &TestEnvironment, workspace_root: &Path) -> String {
|
||||
test_env.jj_cmd_success(
|
||||
workspace_root,
|
||||
&[
|
||||
"log",
|
||||
"-T",
|
||||
r#"commit_id.short() " " description.first_line() " " branches"#,
|
||||
"-r",
|
||||
"all()",
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_fetch_default_remote() {
|
||||
let test_env = TestEnvironment::default();
|
||||
|
@ -182,3 +208,460 @@ fn test_git_fetch_prune_before_updating_tips() {
|
|||
origin/subname: 9f01a0e04879 message
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_fetch_conflicting_branches() {
|
||||
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");
|
||||
|
||||
// Create a rem1 branch locally
|
||||
test_env.jj_cmd_success(&repo_path, &["new", "root"]);
|
||||
test_env.jj_cmd_success(&repo_path, &["branch", "create", "rem1"]);
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
|
||||
rem1: fcdbbd731496 (no description set)
|
||||
"###);
|
||||
|
||||
test_env.jj_cmd_success(
|
||||
&repo_path,
|
||||
&["git", "fetch", "--remote", "rem1", "--branch", "*"],
|
||||
);
|
||||
// This should result in a CONFLICTED branch
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
|
||||
rem1 (conflicted):
|
||||
+ fcdbbd731496 (no description set)
|
||||
+ 9f01a0e04879 message
|
||||
@rem1 (behind by 1 commits): 9f01a0e04879 message
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_fetch_conflicting_branches_colocated() {
|
||||
let test_env = TestEnvironment::default();
|
||||
let repo_path = test_env.env_root().join("repo");
|
||||
let _git_repo = git2::Repository::init(&repo_path).unwrap();
|
||||
// create_colocated_repo_and_branches_from_trunk1(&test_env, &repo_path);
|
||||
test_env.jj_cmd_success(&repo_path, &["init", "--git-repo", "."]);
|
||||
add_git_remote(&test_env, &repo_path, "rem1");
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @"");
|
||||
|
||||
// Create a rem1 branch locally
|
||||
test_env.jj_cmd_success(&repo_path, &["new", "root"]);
|
||||
test_env.jj_cmd_success(&repo_path, &["branch", "create", "rem1"]);
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
|
||||
rem1: f652c32197cf (no description set)
|
||||
"###);
|
||||
|
||||
test_env.jj_cmd_success(
|
||||
&repo_path,
|
||||
&["git", "fetch", "--remote", "rem1", "--branch", "rem1"],
|
||||
);
|
||||
// This should result in a CONFLICTED branch
|
||||
// See https://github.com/martinvonz/jj/pull/1146#discussion_r1112372340 for the bug this tests for.
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
|
||||
rem1 (conflicted):
|
||||
+ f652c32197cf (no description set)
|
||||
+ 9f01a0e04879 message
|
||||
@rem1 (behind by 1 commits): 9f01a0e04879 message
|
||||
"###);
|
||||
}
|
||||
|
||||
// Helper functions to test obtaining multiple branches at once and changed
|
||||
// branches
|
||||
fn create_colocated_repo_and_branches_from_trunk1(
|
||||
test_env: &TestEnvironment,
|
||||
repo_path: &Path,
|
||||
) -> String {
|
||||
// Create a colocated repo in `source` to populate it more easily
|
||||
test_env.jj_cmd_success(repo_path, &["init", "--git-repo", "."]);
|
||||
create_commit(test_env, repo_path, "trunk1", &[]);
|
||||
create_commit(test_env, repo_path, "a1", &["trunk1"]);
|
||||
create_commit(test_env, repo_path, "a2", &["trunk1"]);
|
||||
create_commit(test_env, repo_path, "b", &["trunk1"]);
|
||||
format!(
|
||||
" ===== Source git repo contents =====\n{}",
|
||||
get_log_output(test_env, repo_path)
|
||||
)
|
||||
}
|
||||
|
||||
fn create_trunk2_and_rebase_branches(test_env: &TestEnvironment, repo_path: &Path) -> String {
|
||||
create_commit(test_env, repo_path, "trunk2", &["trunk1"]);
|
||||
for br in ["a1", "a2", "b"] {
|
||||
test_env.jj_cmd_success(repo_path, &["rebase", "-b", br, "-d", "trunk2"]);
|
||||
}
|
||||
format!(
|
||||
" ===== Source git repo contents =====\n{}",
|
||||
get_log_output(test_env, repo_path)
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_fetch_all() {
|
||||
let test_env = TestEnvironment::default();
|
||||
let source_git_repo_path = test_env.env_root().join("source");
|
||||
let _git_repo = git2::Repository::init(source_git_repo_path.clone()).unwrap();
|
||||
|
||||
// Clone an empty repo. The target repo is a normal `jj` repo, *not* colocated
|
||||
let stdout =
|
||||
test_env.jj_cmd_success(test_env.env_root(), &["git", "clone", "source", "target"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
Fetching into new repo in "$TEST_ENV/target"
|
||||
Nothing changed.
|
||||
"###);
|
||||
let target_jj_repo_path = test_env.env_root().join("target");
|
||||
|
||||
let source_log =
|
||||
create_colocated_repo_and_branches_from_trunk1(&test_env, &source_git_repo_path);
|
||||
insta::assert_snapshot!(source_log, @r###"
|
||||
===== Source git repo contents =====
|
||||
@ c7d4bdcbc215 descr_for_b b
|
||||
│ o decaa3966c83 descr_for_a2 a2
|
||||
├─╯
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1 master trunk1
|
||||
o 000000000000
|
||||
"###);
|
||||
|
||||
// Nothing in our repo before the fetch
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
@ 230dd059e1b0
|
||||
o 000000000000
|
||||
"###);
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &target_jj_repo_path), @"");
|
||||
insta::assert_snapshot!(test_env.jj_cmd_success(&target_jj_repo_path, &["git", "fetch"]), @"");
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &target_jj_repo_path), @r###"
|
||||
a1: 359a9a02457d descr_for_a1
|
||||
a2: decaa3966c83 descr_for_a2
|
||||
b: c7d4bdcbc215 descr_for_b
|
||||
master: ff36dc55760e descr_for_trunk1
|
||||
trunk1: ff36dc55760e descr_for_trunk1
|
||||
"###);
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o c7d4bdcbc215 descr_for_b b
|
||||
│ o decaa3966c83 descr_for_a2 a2
|
||||
├─╯
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1 master trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
|
||||
// ==== Change both repos ====
|
||||
// First, change the target repo:
|
||||
let source_log = create_trunk2_and_rebase_branches(&test_env, &source_git_repo_path);
|
||||
insta::assert_snapshot!(source_log, @r###"
|
||||
===== Source git repo contents =====
|
||||
o babc49226c14 descr_for_b b
|
||||
│ o 91e46b4b2653 descr_for_a2 a2
|
||||
├─╯
|
||||
│ o 0424f6dfc1ff descr_for_a1 a1
|
||||
├─╯
|
||||
@ 8f1f14fbbf42 descr_for_trunk2 trunk2
|
||||
o ff36dc55760e descr_for_trunk1 master trunk1
|
||||
o 000000000000
|
||||
"###);
|
||||
// Change a branch in the source repo as well, so that it becomes conflicted.
|
||||
test_env.jj_cmd_success(
|
||||
&target_jj_repo_path,
|
||||
&["describe", "b", "-m=new_descr_for_b_to_create_conflict"],
|
||||
);
|
||||
|
||||
// Our repo before and after fetch
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o 061eddbb43ab new_descr_for_b_to_create_conflict b*
|
||||
│ o decaa3966c83 descr_for_a2 a2
|
||||
├─╯
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1 master trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &target_jj_repo_path), @r###"
|
||||
a1: 359a9a02457d descr_for_a1
|
||||
a2: decaa3966c83 descr_for_a2
|
||||
b: 061eddbb43ab new_descr_for_b_to_create_conflict
|
||||
@origin (ahead by 1 commits, behind by 1 commits): c7d4bdcbc215 descr_for_b
|
||||
master: ff36dc55760e descr_for_trunk1
|
||||
trunk1: ff36dc55760e descr_for_trunk1
|
||||
"###);
|
||||
insta::assert_snapshot!(test_env.jj_cmd_success(&target_jj_repo_path, &["git", "fetch"]), @"");
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &target_jj_repo_path), @r###"
|
||||
a1: 0424f6dfc1ff descr_for_a1
|
||||
a2: 91e46b4b2653 descr_for_a2
|
||||
b (conflicted):
|
||||
- c7d4bdcbc215 descr_for_b
|
||||
+ 061eddbb43ab new_descr_for_b_to_create_conflict
|
||||
+ babc49226c14 descr_for_b
|
||||
@origin (behind by 1 commits): babc49226c14 descr_for_b
|
||||
master: ff36dc55760e descr_for_trunk1
|
||||
trunk1: ff36dc55760e descr_for_trunk1
|
||||
trunk2: 8f1f14fbbf42 descr_for_trunk2
|
||||
"###);
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o babc49226c14 descr_for_b b?? b@origin
|
||||
│ o 91e46b4b2653 descr_for_a2 a2
|
||||
├─╯
|
||||
│ o 0424f6dfc1ff descr_for_a1 a1
|
||||
├─╯
|
||||
o 8f1f14fbbf42 descr_for_trunk2 trunk2
|
||||
│ o 061eddbb43ab new_descr_for_b_to_create_conflict b??
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1 master trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_fetch_some_of_many_branches() {
|
||||
let test_env = TestEnvironment::default();
|
||||
let source_git_repo_path = test_env.env_root().join("source");
|
||||
let _git_repo = git2::Repository::init(source_git_repo_path.clone()).unwrap();
|
||||
|
||||
// Clone an empty repo. The target repo is a normal `jj` repo, *not* colocated
|
||||
let stdout =
|
||||
test_env.jj_cmd_success(test_env.env_root(), &["git", "clone", "source", "target"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
Fetching into new repo in "$TEST_ENV/target"
|
||||
Nothing changed.
|
||||
"###);
|
||||
let target_jj_repo_path = test_env.env_root().join("target");
|
||||
|
||||
let source_log =
|
||||
create_colocated_repo_and_branches_from_trunk1(&test_env, &source_git_repo_path);
|
||||
insta::assert_snapshot!(source_log, @r###"
|
||||
===== Source git repo contents =====
|
||||
@ c7d4bdcbc215 descr_for_b b
|
||||
│ o decaa3966c83 descr_for_a2 a2
|
||||
├─╯
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1 master trunk1
|
||||
o 000000000000
|
||||
"###);
|
||||
|
||||
// Test an error message
|
||||
let stderr =
|
||||
test_env.jj_cmd_failure(&target_jj_repo_path, &["git", "fetch", "--branch", "^:a*"]);
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Error: Invalid glob provided. Globs may not contain the characters `:` or `^`.
|
||||
"###);
|
||||
|
||||
// Nothing in our repo before the fetch
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
@ 230dd059e1b0
|
||||
o 000000000000
|
||||
"###);
|
||||
// Fetch one branch...
|
||||
let stdout = test_env.jj_cmd_success(&target_jj_repo_path, &["git", "fetch", "--branch", "b"]);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o c7d4bdcbc215 descr_for_b b
|
||||
o ff36dc55760e descr_for_trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
// ...check what the intermediate state looks like...
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &target_jj_repo_path), @r###"
|
||||
b: c7d4bdcbc215 descr_for_b
|
||||
"###);
|
||||
// ...then fetch two others with a glob.
|
||||
let stdout = test_env.jj_cmd_success(&target_jj_repo_path, &["git", "fetch", "--branch", "a*"]);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o decaa3966c83 descr_for_a2 a2
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
│ o c7d4bdcbc215 descr_for_b b
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
// Fetching the same branch again
|
||||
let stdout = test_env.jj_cmd_success(&target_jj_repo_path, &["git", "fetch", "--branch", "a1"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
Nothing changed.
|
||||
"###);
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o decaa3966c83 descr_for_a2 a2
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
│ o c7d4bdcbc215 descr_for_b b
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
|
||||
// ==== Change both repos ====
|
||||
// First, change the target repo:
|
||||
let source_log = create_trunk2_and_rebase_branches(&test_env, &source_git_repo_path);
|
||||
insta::assert_snapshot!(source_log, @r###"
|
||||
===== Source git repo contents =====
|
||||
o 13ac032802f1 descr_for_b b
|
||||
│ o 010977d69c5b descr_for_a2 a2
|
||||
├─╯
|
||||
│ o 6f4e1c4dfe29 descr_for_a1 a1
|
||||
├─╯
|
||||
@ 09430ba04a82 descr_for_trunk2 trunk2
|
||||
o ff36dc55760e descr_for_trunk1 master trunk1
|
||||
o 000000000000
|
||||
"###);
|
||||
// Change a branch in the source repo as well, so that it becomes conflicted.
|
||||
test_env.jj_cmd_success(
|
||||
&target_jj_repo_path,
|
||||
&["describe", "b", "-m=new_descr_for_b_to_create_conflict"],
|
||||
);
|
||||
|
||||
// Our repo before and after fetch of two branches
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o 2be688d8c664 new_descr_for_b_to_create_conflict b*
|
||||
│ o decaa3966c83 descr_for_a2 a2
|
||||
├─╯
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
let stdout = test_env.jj_cmd_success(
|
||||
&target_jj_repo_path,
|
||||
&["git", "fetch", "--branch", "b", "--branch", "a1"],
|
||||
);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o 13ac032802f1 descr_for_b b?? b@origin
|
||||
│ o 6f4e1c4dfe29 descr_for_a1 a1
|
||||
├─╯
|
||||
o 09430ba04a82 descr_for_trunk2
|
||||
│ o 2be688d8c664 new_descr_for_b_to_create_conflict b??
|
||||
├─╯
|
||||
│ o decaa3966c83 descr_for_a2 a2
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
|
||||
// We left a2 where it was before, let's see how `jj branch list` sees this.
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &target_jj_repo_path), @r###"
|
||||
a1: 6f4e1c4dfe29 descr_for_a1
|
||||
a2: decaa3966c83 descr_for_a2
|
||||
b (conflicted):
|
||||
- c7d4bdcbc215 descr_for_b
|
||||
+ 2be688d8c664 new_descr_for_b_to_create_conflict
|
||||
+ 13ac032802f1 descr_for_b
|
||||
@origin (behind by 1 commits): 13ac032802f1 descr_for_b
|
||||
"###);
|
||||
// Now, let's fetch a2 and double-check that fetching a1 and b again doesn't do
|
||||
// anything.
|
||||
let stdout = test_env.jj_cmd_success(
|
||||
&target_jj_repo_path,
|
||||
&["git", "fetch", "--branch", "b", "--branch", "a*"],
|
||||
);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o 010977d69c5b descr_for_a2 a2
|
||||
│ o 13ac032802f1 descr_for_b b?? b@origin
|
||||
├─╯
|
||||
│ o 6f4e1c4dfe29 descr_for_a1 a1
|
||||
├─╯
|
||||
o 09430ba04a82 descr_for_trunk2
|
||||
│ o 2be688d8c664 new_descr_for_b_to_create_conflict b??
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &target_jj_repo_path), @r###"
|
||||
a1: 6f4e1c4dfe29 descr_for_a1
|
||||
a2: 010977d69c5b descr_for_a2
|
||||
b (conflicted):
|
||||
- c7d4bdcbc215 descr_for_b
|
||||
+ 2be688d8c664 new_descr_for_b_to_create_conflict
|
||||
+ 13ac032802f1 descr_for_b
|
||||
@origin (behind by 1 commits): 13ac032802f1 descr_for_b
|
||||
"###);
|
||||
}
|
||||
|
||||
// TODO: Fix the bug this test demonstrates. (https://github.com/martinvonz/jj/issues/1300)
|
||||
// The issue likely stems from the fact that `jj undo` does not undo the fetch
|
||||
// inside the git repo backing the `target` repo. It is unclear whether it
|
||||
// should.
|
||||
#[test]
|
||||
fn test_git_fetch_undo() {
|
||||
let test_env = TestEnvironment::default();
|
||||
let source_git_repo_path = test_env.env_root().join("source");
|
||||
let _git_repo = git2::Repository::init(source_git_repo_path.clone()).unwrap();
|
||||
|
||||
// Clone an empty repo. The target repo is a normal `jj` repo, *not* colocated
|
||||
let stdout =
|
||||
test_env.jj_cmd_success(test_env.env_root(), &["git", "clone", "source", "target"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
Fetching into new repo in "$TEST_ENV/target"
|
||||
Nothing changed.
|
||||
"###);
|
||||
let target_jj_repo_path = test_env.env_root().join("target");
|
||||
|
||||
let source_log =
|
||||
create_colocated_repo_and_branches_from_trunk1(&test_env, &source_git_repo_path);
|
||||
insta::assert_snapshot!(source_log, @r###"
|
||||
===== Source git repo contents =====
|
||||
@ c7d4bdcbc215 descr_for_b b
|
||||
│ o decaa3966c83 descr_for_a2 a2
|
||||
├─╯
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1 master trunk1
|
||||
o 000000000000
|
||||
"###);
|
||||
|
||||
// Fetch 2 branches
|
||||
let stdout = test_env.jj_cmd_success(
|
||||
&target_jj_repo_path,
|
||||
&["git", "fetch", "--branch", "b", "--branch", "a1"],
|
||||
);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o c7d4bdcbc215 descr_for_b b
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
insta::assert_snapshot!(test_env.jj_cmd_success(&target_jj_repo_path, &["undo"]), @"");
|
||||
// The undo works as expected
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
@ 230dd059e1b0
|
||||
o 000000000000
|
||||
"###);
|
||||
// Now try to fetch just one branch
|
||||
let stdout = test_env.jj_cmd_success(&target_jj_repo_path, &["git", "fetch", "--branch", "b"]);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
// BUG: Both branches got fetched.
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &target_jj_repo_path), @r###"
|
||||
o c7d4bdcbc215 descr_for_b b
|
||||
│ o 359a9a02457d descr_for_a1 a1
|
||||
├─╯
|
||||
o ff36dc55760e descr_for_trunk1
|
||||
│ @ 230dd059e1b0
|
||||
├─╯
|
||||
o 000000000000
|
||||
"###);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue