revset: allow checking out git-tracking (@git) branches

This commit is contained in:
Ilya Grigoriev 2023-06-10 22:54:10 -07:00
parent d5e8896d1b
commit a483252cf2
4 changed files with 61 additions and 2 deletions

View file

@ -102,8 +102,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
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`.
`jj branch list` as a remote called `git` (e.g. `main@git`). They can also be
referenced in revsets. Such branches exist in colocated repos or if you use
`jj git export`.
### Fixed bugs

View file

@ -70,6 +70,10 @@ pub fn git_tracking_branches(view: &View) -> impl Iterator<Item = (&str, &RefTar
})
}
pub fn get_git_tracking_branch<'a>(view: &'a View, branch: &str) -> Option<&'a RefTarget> {
view.git_refs().get(&local_branch_name_to_ref_name(branch))
}
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.

View file

@ -31,6 +31,7 @@ use thiserror::Error;
use crate::backend::{BackendError, BackendResult, ChangeId, CommitId, ObjectId};
use crate::commit::Commit;
use crate::git::get_git_tracking_branch;
use crate::hex_util::to_forward_hex;
use crate::index::{HexPrefix, PrefixResolution};
use crate::op_store::WorkspaceId;
@ -1640,6 +1641,12 @@ fn resolve_branch(repo: &dyn Repo, symbol: &str) -> Option<Vec<CommitId>> {
return Some(target.adds());
}
}
// A remote with name "git" will shadow local-git tracking branches
if remote_name == "git" {
if let Some(target) = get_git_tracking_branch(repo.view(), name) {
return Some(target.adds());
}
}
}
None
}

View file

@ -20,6 +20,53 @@ use crate::common::{get_stderr_string, TestEnvironment};
pub mod common;
#[test]
fn test_resolution_of_git_tracking_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");
test_env.jj_cmd_success(&repo_path, &["branch", "create", "main"]);
test_env.jj_cmd_success(&repo_path, &["describe", "-r", "main", "-m", "old_message"]);
// Create local-git tracking branch
let stdout = test_env.jj_cmd_success(&repo_path, &["git", "export"]);
insta::assert_snapshot!(stdout, @"");
// Move the local branch somewhere else
test_env.jj_cmd_success(&repo_path, &["describe", "-r", "main", "-m", "new_message"]);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
main: 3af370264cdc new_message
@git (ahead by 1 commits, behind by 1 commits): 16d541ca40f4 old_message
"###);
// Test that we can address both revisions
let stdout = test_env.jj_cmd_success(
&repo_path,
&[
"log",
"-r=main",
"-T",
r#"commit_id ++ " " ++ description"#,
"--no-graph",
],
);
insta::assert_snapshot!(stdout, @r###"
3af370264cdcbba791762f8ef6bc79b456dcbf3b new_message
"###);
let stdout = test_env.jj_cmd_success(
&repo_path,
&[
"log",
"-r=main@git",
"-T",
r#"commit_id ++ " " ++ description"#,
"--no-graph",
],
);
insta::assert_snapshot!(stdout, @r###"
16d541ca40f42baf2dea41aa61a0b5f1cbf1f91b old_message
"###);
}
#[test]
fn test_git_export_conflicting_git_refs() {
let test_env = TestEnvironment::default();