forked from mirrors/jj
git init: add revset alias for trunk()
when intializing with existing git repository
This commit is contained in:
parent
d8899e1ae7
commit
0c0e001262
5 changed files with 100 additions and 7 deletions
|
@ -20,8 +20,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||
individually instead of being passed a directory by setting
|
||||
`merge-tools.$TOOL.diff-invocation-mode="file-by-file"` in config.toml.
|
||||
|
||||
* `jj git clone` adds the default branch of the remote as repository
|
||||
settings for `revset-aliases."trunk()"`.`
|
||||
* `jj git clone` and `jj git init` with an existing git repository adds the
|
||||
default branch of the remote as repository settings for
|
||||
`revset-aliases."trunk()"`.`
|
||||
|
||||
### Fixed bugs
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ use std::io::Write;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
|
||||
use jj_lib::git::{parse_git_ref, RefName};
|
||||
use jj_lib::repo::{ReadonlyRepo, Repo};
|
||||
use jj_lib::workspace::Workspace;
|
||||
use jj_lib::{file_util, git};
|
||||
|
@ -23,8 +24,9 @@ use jj_lib::{file_util, git};
|
|||
use crate::cli_util::{print_trackable_remote_branches, start_repo_transaction, CommandHelper};
|
||||
use crate::command_error::{user_error_with_hint, user_error_with_message, CommandError};
|
||||
use crate::commands::git::maybe_add_gitignore;
|
||||
use crate::config::{write_config_value_to_file, ConfigNamePathBuf};
|
||||
use crate::git_util::{
|
||||
is_colocated_git_workspace, print_failed_git_export, print_git_import_stats,
|
||||
get_git_repo, is_colocated_git_workspace, print_failed_git_export, print_git_import_stats,
|
||||
};
|
||||
use crate::ui::Ui;
|
||||
|
||||
|
@ -152,6 +154,7 @@ pub fn do_init(
|
|||
let mut workspace_command = command.for_loaded_repo(ui, workspace, repo)?;
|
||||
maybe_add_gitignore(&workspace_command)?;
|
||||
workspace_command.maybe_snapshot(ui)?;
|
||||
maybe_set_repository_level_trunk_alias(ui, workspace_command.repo())?;
|
||||
if !workspace_command.working_copy_shared_with_git() {
|
||||
let mut tx = workspace_command.start_transaction();
|
||||
jj_lib::git::import_head(tx.mut_repo())?;
|
||||
|
@ -210,3 +213,33 @@ fn init_git_refs(
|
|||
)?;
|
||||
Ok(repo)
|
||||
}
|
||||
|
||||
// Set repository level `trunk()` alias to the default branch for "origin".
|
||||
pub fn maybe_set_repository_level_trunk_alias(
|
||||
ui: &Ui,
|
||||
repo: &Arc<ReadonlyRepo>,
|
||||
) -> Result<(), CommandError> {
|
||||
let git_repo = get_git_repo(repo.store())?;
|
||||
if let Ok(reference) = git_repo.find_reference("refs/remotes/origin/HEAD") {
|
||||
if let Some(reference_name) = reference.symbolic_target() {
|
||||
if let Some(RefName::RemoteBranch {
|
||||
branch: default_branch,
|
||||
..
|
||||
}) = parse_git_ref(reference_name)
|
||||
{
|
||||
let config_path = repo.repo_path().join("config.toml");
|
||||
write_config_value_to_file(
|
||||
&ConfigNamePathBuf::from_iter(["revset-aliases", "trunk()"]),
|
||||
&format!("{default_branch}@origin"),
|
||||
&config_path,
|
||||
)?;
|
||||
writeln!(
|
||||
ui.status(),
|
||||
"Setting the revset alias \"trunk()\" to \"{default_branch}@origin\"",
|
||||
)?;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -148,6 +148,65 @@ fn test_git_init_external(bare: bool) {
|
|||
}
|
||||
}
|
||||
|
||||
#[test_case(false; "full")]
|
||||
#[test_case(true; "bare")]
|
||||
fn test_git_init_external_import_trunk(bare: bool) {
|
||||
let test_env = TestEnvironment::default();
|
||||
let git_repo_path = test_env.env_root().join("git-repo");
|
||||
let git_repo = init_git_repo(&git_repo_path, bare);
|
||||
|
||||
// Add remote branch "trunk" for remote "origin", and set it as "origin/HEAD"
|
||||
let oid = git_repo
|
||||
.find_reference("refs/heads/my-branch")
|
||||
.unwrap()
|
||||
.target()
|
||||
.unwrap();
|
||||
git_repo
|
||||
.reference("refs/remotes/origin/trunk", oid, false, "")
|
||||
.unwrap();
|
||||
git_repo
|
||||
.reference_symbolic(
|
||||
"refs/remotes/origin/HEAD",
|
||||
"refs/remotes/origin/trunk",
|
||||
false,
|
||||
"",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let (stdout, stderr) = test_env.jj_cmd_ok(
|
||||
test_env.env_root(),
|
||||
&[
|
||||
"git",
|
||||
"init",
|
||||
"repo",
|
||||
"--git-repo",
|
||||
git_repo_path.to_str().unwrap(),
|
||||
],
|
||||
);
|
||||
insta::allow_duplicates! {
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Done importing changes from the underlying Git repo.
|
||||
Setting the revset alias "trunk()" to "trunk@origin"
|
||||
Working copy now at: sqpuoqvx f6950fc1 (empty) (no description set)
|
||||
Parent commit : mwrttmos 8d698d4a my-branch trunk@origin | My commit message
|
||||
Added 1 files, modified 0 files, removed 0 files
|
||||
Initialized repo in "repo"
|
||||
"###);
|
||||
}
|
||||
|
||||
// "trunk()" alias should be set to remote "origin"'s default branch "trunk"
|
||||
let stdout = test_env.jj_cmd_success(
|
||||
&test_env.env_root().join("repo"),
|
||||
&["config", "list", "--repo", "revset-aliases.\"trunk()\""],
|
||||
);
|
||||
insta::allow_duplicates! {
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
revset-aliases."trunk()" = "trunk@origin"
|
||||
"###);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_init_external_non_existent_directory() {
|
||||
let test_env = TestEnvironment::default();
|
||||
|
|
|
@ -362,9 +362,9 @@ for a comprehensive list.
|
|||
tried. If more than one potential trunk commit exists, the newest one is
|
||||
chosen. If none of the branches exist, the revset evaluates to `root()`.
|
||||
|
||||
When working with an existing Git repository (via `jj git clone`),
|
||||
`trunk()` will be overridden at the repository level to the default branch of
|
||||
the remote.
|
||||
When working with an existing Git repository (via `jj git clone` or
|
||||
`jj git init`), `trunk()` will be overridden at the repository level
|
||||
to the default branch of the remote `origin`.
|
||||
|
||||
You can [override](./config.md) this as appropriate. If you do, make sure it
|
||||
always resolves to exactly one commit. For example:
|
||||
|
|
|
@ -62,7 +62,7 @@ impl fmt::Display for RefName {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_git_ref(ref_name: &str) -> Option<RefName> {
|
||||
pub fn parse_git_ref(ref_name: &str) -> Option<RefName> {
|
||||
if let Some(branch_name) = ref_name.strip_prefix("refs/heads/") {
|
||||
// Git CLI says 'HEAD' is not a valid branch name
|
||||
(branch_name != "HEAD").then(|| RefName::LocalBranch(branch_name.to_string()))
|
||||
|
|
Loading…
Reference in a new issue