forked from mirrors/jj
cmd: have jj branch list
report git-tracking (@git
) branches
This doesn't change the way @git branches are stored in `git_refs` as opposed to inside `BranchTarget` like normal remote-tracking branches. There are subtle differences in behavior with e.g. `jj branch forget` and I'm not sure how easy it is to rewrite `jj git import/export` to support a different way of storage. I've decided to call these "local-git tracking branches" since they track branches in the local git repository. "local git-tracking" branches sounds a bit more natural, but these could be confused with there are no remote git-tracking branches. If one had the idea these might exist, they would be confused with remote-tracking branches in the local git repo. This addresses a portion of #1666
This commit is contained in:
parent
9963879d15
commit
8df945b71d
6 changed files with 45 additions and 7 deletions
|
@ -101,6 +101,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
now shorter within the default log revset. You can override the default by
|
||||
setting the `revsets.short-prefixes` config to a different revset.
|
||||
|
||||
* The last seen state of branches in the underlying git repo is now presented by
|
||||
`jj branch list` as a remote called `git` (e.g. `main@git`). Such branches
|
||||
exist in colocated repos or if you use `jj git export`.
|
||||
|
||||
### Fixed bugs
|
||||
|
||||
* Modify/delete conflicts now include context lines
|
||||
|
|
|
@ -27,7 +27,7 @@ use crate::op_store::RefTarget;
|
|||
use crate::repo::{MutableRepo, Repo};
|
||||
use crate::revset;
|
||||
use crate::settings::GitSettings;
|
||||
use crate::view::RefName;
|
||||
use crate::view::{RefName, View};
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub enum GitImportError {
|
||||
|
@ -60,6 +60,16 @@ fn local_branch_name_to_ref_name(branch: &str) -> String {
|
|||
format!("refs/heads/{branch}")
|
||||
}
|
||||
|
||||
// TODO: Eventually, git-tracking branches should no longer be stored in
|
||||
// git_refs but with the other remote-tracking branches in BranchTarget. Note
|
||||
// that there are important but subtle differences in behavior for, e.g. `jj
|
||||
// branch forget`.
|
||||
pub fn git_tracking_branches(view: &View) -> impl Iterator<Item = (&str, &RefTarget)> {
|
||||
view.git_refs().iter().filter_map(|(ref_name, target)| {
|
||||
ref_name_to_local_branch_name(ref_name).map(|branch_name| (branch_name, target))
|
||||
})
|
||||
}
|
||||
|
||||
fn prevent_gc(git_repo: &git2::Repository, id: &CommitId) -> Result<(), git2::Error> {
|
||||
// If multiple processes do git::import_refs() in parallel, this can fail to
|
||||
// acquire a lock file even with force=true.
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::collections::BTreeSet;
|
|||
use clap::builder::NonEmptyStringValueParser;
|
||||
use itertools::Itertools;
|
||||
use jujutsu_lib::backend::{CommitId, ObjectId};
|
||||
use jujutsu_lib::git::git_tracking_branches;
|
||||
use jujutsu_lib::op_store::RefTarget;
|
||||
use jujutsu_lib::repo::Repo;
|
||||
use jujutsu_lib::revset;
|
||||
|
@ -258,6 +259,28 @@ fn cmd_branch_list(
|
|||
let workspace_command = command.workspace_helper(ui)?;
|
||||
let repo = workspace_command.repo();
|
||||
|
||||
let mut all_branches = repo.view().branches().clone();
|
||||
for (branch_name, git_tracking_target) in git_tracking_branches(repo.view()) {
|
||||
let branch_target = all_branches.entry(branch_name.to_owned()).or_default();
|
||||
if branch_target.remote_targets.contains_key("git") {
|
||||
// TODO(#1690): There should be a mechanism to prevent importing a
|
||||
// remote named "git" in `jj git import`.
|
||||
// TODO: This is not currently tested
|
||||
writeln!(
|
||||
ui.warning(),
|
||||
"WARNING: Branch {branch_name} has a remote-tracking branch for a remote named \
|
||||
`git`. Local-git tracking branches for it will not be shown.\nIt is recommended \
|
||||
to rename that remote, as jj normally reserves the `@git` suffix to denote \
|
||||
local-git tracking branches."
|
||||
)?;
|
||||
} else {
|
||||
// TODO: `BTreeMap::try_insert` could be used here once that's stabilized.
|
||||
branch_target
|
||||
.remote_targets
|
||||
.insert("git".to_string(), git_tracking_target.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let print_branch_target =
|
||||
|formatter: &mut dyn Formatter, target: Option<&RefTarget>| -> Result<(), CommandError> {
|
||||
match target {
|
||||
|
@ -293,15 +316,12 @@ fn cmd_branch_list(
|
|||
|
||||
let mut formatter = ui.stdout_formatter();
|
||||
let formatter = formatter.as_mut();
|
||||
for (name, branch_target) in repo.view().branches() {
|
||||
|
||||
for (name, branch_target) in all_branches {
|
||||
write!(formatter.labeled("branch"), "{name}")?;
|
||||
print_branch_target(formatter, branch_target.local_target.as_ref())?;
|
||||
|
||||
for (remote, remote_target) in branch_target
|
||||
.remote_targets
|
||||
.iter()
|
||||
.sorted_by_key(|(name, _target)| name.to_owned())
|
||||
{
|
||||
for (remote, remote_target) in branch_target.remote_targets.iter() {
|
||||
if Some(remote_target) == branch_target.local_target.as_ref() {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -113,6 +113,8 @@ fn test_branch_forget_glob() {
|
|||
"###);
|
||||
}
|
||||
|
||||
// TODO: Test `jj branch list` with a remote named `git`
|
||||
|
||||
fn get_log_output(test_env: &TestEnvironment, cwd: &Path) -> String {
|
||||
let template = r#"branches ++ " " ++ commit_id.short()"#;
|
||||
test_env.jj_cmd_success(cwd, &["log", "-T", template])
|
||||
|
|
|
@ -272,6 +272,7 @@ fn test_git_fetch_conflicting_branches_colocated() {
|
|||
rem1 (conflicted):
|
||||
+ f652c32197cf (no description set)
|
||||
+ 6a21102783e8 message
|
||||
@git (behind by 1 commits): f652c32197cf (no description set)
|
||||
@rem1 (behind by 1 commits): 6a21102783e8 message
|
||||
"###);
|
||||
}
|
||||
|
|
|
@ -197,6 +197,7 @@ fn test_git_import_move_export_undo() {
|
|||
test_env.jj_cmd_success(&repo_path, &["branch", "set", "a"]);
|
||||
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
|
||||
a: 096dc80da670 (no description set)
|
||||
@git (behind by 1 commits): 230dd059e1b0 (no description set)
|
||||
"###);
|
||||
insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["git", "export"]), @"");
|
||||
|
||||
|
|
Loading…
Reference in a new issue