Skip to content

Commit

Permalink
cli: list new remote branches during git fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
0xdeafbeef committed Feb 14, 2024
1 parent 3500cd8 commit 6589310
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#1252](https://github.com/martinvonz/jj/issues/1252),
[#2971](https://github.com/martinvonz/jj/issues/2971)). This may become the
default depending on feedback.
* `jj git fetch` now automatically prints new remote branches and tags by default.

### Fixed bugs

Expand Down
2 changes: 1 addition & 1 deletion cli/src/cli_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ impl WorkspaceCommandHelper {
return Ok(());
}

print_git_import_stats(ui, &stats)?;
print_git_import_stats(ui, &stats, false)?;
let mut tx = tx.into_inner();
// Rebase here to show slightly different status message.
let num_rebased = tx.mut_repo().rebase_descendants(&self.settings)?;
Expand Down
8 changes: 4 additions & 4 deletions cli/src/commands/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ fn init_git_refs(
if !tx.mut_repo().has_changes() {
return Ok(repo);
}
print_git_import_stats(ui, &stats)?;
print_git_import_stats(ui, &stats, false)?;
if colocated {
// If git.auto-local-branch = true, local branches could be created for
// the imported remote branches.
Expand Down Expand Up @@ -537,7 +537,7 @@ fn cmd_git_fetch(
GitFetchError::InternalGitError(err) => map_git_error(err),
_ => user_error(err),
})?;
print_git_import_stats(ui, &stats.import_stats)?;
print_git_import_stats(ui, &stats.import_stats, true)?;
}
tx.finish(
ui,
Expand Down Expand Up @@ -751,7 +751,7 @@ fn do_git_clone(
unreachable!("we didn't provide any globs")
}
})?;
print_git_import_stats(ui, &stats.import_stats)?;
print_git_import_stats(ui, &stats.import_stats, false)?;
fetch_tx.finish(ui, "fetch from git remote into empty repo")?;
Ok((workspace_command, stats))
}
Expand Down Expand Up @@ -1190,7 +1190,7 @@ fn cmd_git_import(
// That's why cmd_git_export() doesn't export the HEAD ref.
git::import_head(tx.mut_repo())?;
let stats = git::import_refs(tx.mut_repo(), &command.settings().git_settings())?;
print_git_import_stats(ui, &stats)?;
print_git_import_stats(ui, &stats, false)?;
tx.finish(ui, "import git refs")?;
Ok(())
}
Expand Down
42 changes: 40 additions & 2 deletions cli/src/git_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use std::sync::Mutex;
use std::time::Instant;
use std::{error, iter};

use jj_lib::git::{self, FailedRefExport, FailedRefExportReason, GitImportStats};
use jj_lib::git::{self, FailedRefExport, FailedRefExportReason, GitImportStats, RefName};
use jj_lib::git_backend::GitBackend;
use jj_lib::repo::{ReadonlyRepo, Repo as _};
use jj_lib::store::Store;
Expand Down Expand Up @@ -172,7 +172,45 @@ pub fn with_remote_git_callbacks<T>(
f(callbacks)
}

pub fn print_git_import_stats(ui: &mut Ui, stats: &GitImportStats) -> Result<(), CommandError> {
pub fn print_git_import_stats(
ui: &mut Ui,
stats: &GitImportStats,
show_ref_stats: bool,
) -> Result<(), CommandError> {
use std::collections::BTreeMap;

if show_ref_stats && !stats.new_remote_refs.is_empty() {
let mut new_remote_branches: BTreeMap<_, Vec<_>> = BTreeMap::new();
let mut tags = Vec::new();
let mut local_branches = Vec::new();
for refname in &stats.new_remote_refs {
match refname {
RefName::RemoteBranch { branch, remote } => {
new_remote_branches.entry(remote).or_default().push(branch);
}
RefName::Tag(tag) => tags.push(tag),
RefName::LocalBranch(b) => local_branches.push(b),
}
}
local_branches.sort_unstable();
for branch in local_branches {
writeln!(ui.stderr(), "* [imported local branch] {branch}")?;
}
for (remote, branches) in new_remote_branches.iter_mut() {
writeln!(ui.stderr(), "From {remote}")?;
branches.sort_unstable();
for branch in branches {
writeln!(ui.stderr(), "* [new untracked branch] {branch}")?;
}
}
if !tags.is_empty() {
writeln!(ui.stderr(), "Tags:")?;
tags.sort_unstable();
for tag in tags {
writeln!(ui.stderr(), "* [new tag] {tag}")?;
}
}
}
if !stats.abandoned_commits.is_empty() {
writeln!(
ui.stderr(),
Expand Down
40 changes: 34 additions & 6 deletions cli/tests/test_branch_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,10 @@ fn test_branch_forget_fetched_branch() {
// We can fetch feature1 again.
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["git", "fetch", "--remote=origin"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(stderr, @r###"
From origin
* [new untracked branch] feature1
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
feature1: mzyxwzks 9f01a0e0 message
@origin: mzyxwzks 9f01a0e0 message
Expand All @@ -548,7 +551,10 @@ fn test_branch_forget_fetched_branch() {
// Fetch works even without the export-import
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["git", "fetch", "--remote=origin"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(stderr, @r###"
From origin
* [new untracked branch] feature1
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
feature1: mzyxwzks 9f01a0e0 message
@origin: mzyxwzks 9f01a0e0 message
Expand All @@ -574,7 +580,10 @@ fn test_branch_forget_fetched_branch() {
// Fetching a moved branch does not create a conflict
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["git", "fetch", "--remote=origin"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(stderr, @r###"
From origin
* [new untracked branch] feature1
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
feature1: ooosovrs 38aefb17 (empty) another message
@origin: ooosovrs 38aefb17 (empty) another message
Expand Down Expand Up @@ -687,7 +696,12 @@ fn test_branch_track_untrack() {
);
test_env.add_config("git.auto-local-branch = false");
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["git", "fetch"]);
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(stderr, @r###"
From origin
* [new untracked branch] feature1
* [new untracked branch] feature2
* [new untracked branch] main
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
feature1@origin: sptzoqmo 7b33f629 commit 1
feature2@origin: sptzoqmo 7b33f629 commit 1
Expand Down Expand Up @@ -759,7 +773,12 @@ fn test_branch_track_untrack() {
],
);
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["git", "fetch"]);
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(stderr, @r###"
From origin
* [new untracked branch] feature1
* [new untracked branch] feature2
* [new untracked branch] main
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
feature1: sptzoqmo 7b33f629 commit 1
feature1@origin: mmqqkyyt 40dabdaf commit 2
Expand Down Expand Up @@ -791,6 +810,11 @@ fn test_branch_track_untrack() {
test_env.add_config("git.auto-local-branch = true");
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["git", "fetch"]);
insta::assert_snapshot!(stderr, @r###"
From origin
* [new untracked branch] feature1
* [new untracked branch] feature2
* [new untracked branch] feature3
* [new untracked branch] main
Abandoned 1 commits that are no longer reachable.
"###);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
Expand Down Expand Up @@ -847,7 +871,11 @@ fn test_branch_track_untrack_patterns() {
// Fetch new commit without auto tracking
test_env.add_config("git.auto-local-branch = false");
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["git", "fetch"]);
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(stderr, @r###"
From origin
* [new untracked branch] feature1
* [new untracked branch] feature2
"###);

// Track local branch
test_env.jj_cmd_ok(&repo_path, &["branch", "create", "main"]);
Expand Down
3 changes: 3 additions & 0 deletions cli/tests/test_git_colocated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,9 @@ fn test_git_colocated_fetch_deleted_or_moved_branch() {
let (stdout, stderr) = test_env.jj_cmd_ok(&clone_path, &["git", "fetch"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
From origin
* [new untracked branch] B_to_delete
* [new untracked branch] C_to_move
Abandoned 2 commits that are no longer reachable.
"###);
// "original C" and "B_to_delete" are abandoned, as the corresponding branches
Expand Down
Loading

0 comments on commit 6589310

Please sign in to comment.