mirror of
https://github.com/jj-vcs/jj.git
synced 2025-12-23 06:01:01 +00:00
git init: prefer upstream over origin for trunk() alias
When both `origin` and `upstream` are present, prefer `upstream` over `origin` as the default remote for the `trunk()` alias. This allows developers working on forks to have `trunk()` automatically point to the `main` branch of the upstream repository rather than their fork's origin. This is common when using the `gh` CLI to set up repositories. Resolves #7228
This commit is contained in:
parent
b89cce9162
commit
5fedd36fd0
3 changed files with 109 additions and 15 deletions
|
|
@ -48,6 +48,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|||
* `jj log`, `jj evolog` and `jj op log` output can now be anonymized with the
|
||||
`builtin_log_redacted` and `builtin_op_log_redacted` templates.
|
||||
|
||||
* `jj git init` now checks for an `upstream` remote in addition to `origin` when
|
||||
setting the repository-level `trunk()` alias. The `upstream` remote takes
|
||||
precedence over `origin` if both exist.
|
||||
|
||||
* Add the `jj touch` command, which modifies a revision's metadata. This can be
|
||||
used to generate a new change-id, which may help resolve some divergences.
|
||||
|
||||
|
|
|
|||
|
|
@ -240,27 +240,39 @@ fn init_git_refs(
|
|||
Ok(repo)
|
||||
}
|
||||
|
||||
// Set repository level `trunk()` alias to the default branch for "origin".
|
||||
// Set repository level `trunk()` alias to the default branch.
|
||||
// Checks "upstream" first, then "origin" as fallback.
|
||||
pub fn maybe_set_repository_level_trunk_alias(
|
||||
ui: &Ui,
|
||||
workspace_command: &WorkspaceCommandHelper,
|
||||
) -> Result<(), CommandError> {
|
||||
let git_repo = git::get_git_repo(workspace_command.repo().store())?;
|
||||
if let Some(reference) = git_repo
|
||||
.try_find_reference("refs/remotes/origin/HEAD")
|
||||
.map_err(internal_error)?
|
||||
{
|
||||
if let Some(reference_name) = reference.target().try_name() {
|
||||
if let Some((GitRefKind::Bookmark, symbol)) = str::from_utf8(reference_name.as_bstr())
|
||||
.ok()
|
||||
.and_then(|name| parse_git_ref(name.as_ref()))
|
||||
{
|
||||
// TODO: Can we assume the symbolic target points to the same remote?
|
||||
let symbol = symbol.name.to_remote_symbol("origin".as_ref());
|
||||
write_repository_level_trunk_alias(ui, workspace_command.repo_path(), symbol)?;
|
||||
|
||||
// Try "upstream" first, then fall back to "origin"
|
||||
for remote in ["upstream", "origin"] {
|
||||
let ref_name = format!("refs/remotes/{remote}/HEAD");
|
||||
if let Some(reference) = git_repo
|
||||
.try_find_reference(&ref_name)
|
||||
.map_err(internal_error)?
|
||||
{
|
||||
// Found a HEAD reference for this remote. Even if we can't parse it,
|
||||
// we should stop here and not try other remotes because it doesn't
|
||||
// really make sense if "origin" were to be set as the default if we
|
||||
// know "upstream" exists.
|
||||
if let Some(reference_name) = reference.target().try_name() {
|
||||
if let Some((GitRefKind::Bookmark, symbol)) =
|
||||
str::from_utf8(reference_name.as_bstr())
|
||||
.ok()
|
||||
.and_then(|name| parse_git_ref(name.as_ref()))
|
||||
{
|
||||
// TODO: Can we assume the symbolic target points to the same remote?
|
||||
let symbol = symbol.name.to_remote_symbol(remote.as_ref());
|
||||
write_repository_level_trunk_alias(ui, workspace_command.repo_path(), symbol)?;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,6 +234,84 @@ fn test_git_init_external_import_trunk(bare: bool) {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_init_external_import_trunk_upstream_takes_precedence() {
|
||||
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, false);
|
||||
|
||||
let oid = git_repo
|
||||
.find_reference("refs/heads/my-bookmark")
|
||||
.unwrap()
|
||||
.id();
|
||||
|
||||
// Add both upstream and origin remotes with different default branches
|
||||
// upstream has "develop" as default
|
||||
git_repo
|
||||
.reference(
|
||||
"refs/remotes/upstream/develop",
|
||||
oid.detach(),
|
||||
gix::refs::transaction::PreviousValue::MustNotExist,
|
||||
"create upstream remote ref",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
git::set_symbolic_reference(
|
||||
&git_repo,
|
||||
"refs/remotes/upstream/HEAD",
|
||||
"refs/remotes/upstream/develop",
|
||||
);
|
||||
|
||||
// origin has "trunk" as default
|
||||
git_repo
|
||||
.reference(
|
||||
"refs/remotes/origin/trunk",
|
||||
oid.detach(),
|
||||
gix::refs::transaction::PreviousValue::MustNotExist,
|
||||
"create origin remote ref",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
git::set_symbolic_reference(
|
||||
&git_repo,
|
||||
"refs/remotes/origin/HEAD",
|
||||
"refs/remotes/origin/trunk",
|
||||
);
|
||||
|
||||
let output = test_env.run_jj_in(
|
||||
".",
|
||||
[
|
||||
"git",
|
||||
"init",
|
||||
"repo",
|
||||
"--git-repo",
|
||||
git_repo_path.to_str().unwrap(),
|
||||
],
|
||||
);
|
||||
insta::allow_duplicates! {
|
||||
insta::assert_snapshot!(output, @r#"
|
||||
------- stderr -------
|
||||
Done importing changes from the underlying Git repo.
|
||||
Setting the revset alias `trunk()` to `develop@upstream`
|
||||
Working copy (@) now at: sqpuoqvx ed6b5138 (empty) (no description set)
|
||||
Parent commit (@-) : nntyzxmz e80a42cc develop@upstream my-bookmark trunk@origin | My commit message
|
||||
Added 1 files, modified 0 files, removed 0 files
|
||||
Initialized repo in "repo"
|
||||
[EOF]
|
||||
"#);
|
||||
}
|
||||
|
||||
// "trunk()" alias should be set to "upstream"'s default, not "origin"'s
|
||||
let work_dir = test_env.work_dir("repo");
|
||||
let output = work_dir.run_jj(["config", "list", "--repo", "revset-aliases.\"trunk()\""]);
|
||||
insta::allow_duplicates! {
|
||||
insta::assert_snapshot!(output, @r#"
|
||||
revset-aliases."trunk()" = "develop@upstream"
|
||||
[EOF]
|
||||
"#);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_git_init_external_ignore_working_copy() {
|
||||
let test_env = TestEnvironment::default();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue