ok/jj
1
0
Fork 0
forked from mirrors/jj

git: add git.auto-local-branch

Add a new git.auto-local-branch config option. When set to false, a
remote-tracking branch imported from Git will not automatically create a
local branch target. This is implemented by a new GitSettings struct
that passes Git-related settings from UserSettings.

This behavior is particularly useful in a co-located jj and Git repo,
because a Git remote might have branches that are not of everyday
interest to the user, so it does not make sense to export them as local
branches in Git. E.g. https://github.com/gitster/git, the maintainer's
fork of Git, has 379 branches, most of which are topic branches kept
around for historical reasons, and Git developers wouldn't be expected
to have local branches for each remote-tracking branch.
This commit is contained in:
Glen Choo 2022-12-12 16:18:19 -08:00
parent 4716c1e9e2
commit 3418c8ff73
9 changed files with 186 additions and 28 deletions

View file

@ -268,6 +268,29 @@ the conflict is done, `jj` assumes that the conflict was only partially resolved
and parses the conflict markers to get the new state of the conflict. The
conflict is considered fully resolved when there are no conflict markers left.
## Git settings
### Automatic local branch creation
By default, when `jj` imports a remote-tracking branch from Git, it also
creates a local branch with the same name. In some repositories, this
may be undesirable, e.g.:
- There is a remote with a lot of historical branches that you don't
want to be exported to the co-located Git repo.
- There are multiple remotes with conflicting views of that branch,
resulting in an unhelpful conflicted state.
You can disable this behavior by setting `git.auto-local-branch` like
so,
git.auto-local-branch = false
Note that this setting may make it easier to accidentally delete remote
branches. Since the local branch isn't created, the remote branch will be
deleted if you push the branch with `jj git push --branch` or `jj git push
--all`.
# Alternative ways to specify configuration settings
Instead of `~/.jjconfig.toml`, the config settings can be located at

View file

@ -25,6 +25,7 @@ use crate::commit::Commit;
use crate::git_backend::NO_GC_REF_NAMESPACE;
use crate::op_store::RefTarget;
use crate::repo::MutableRepo;
use crate::settings::GitSettings;
use crate::view::RefName;
#[derive(Error, Debug, PartialEq)]
@ -65,6 +66,7 @@ fn prevent_gc(git_repo: &git2::Repository, id: &CommitId) {
pub fn import_refs(
mut_repo: &mut MutableRepo,
git_repo: &git2::Repository,
git_settings: &GitSettings,
) -> Result<(), GitImportError> {
let store = mut_repo.store().clone();
let mut existing_git_refs = mut_repo.view().git_refs().clone();
@ -141,6 +143,9 @@ pub fn import_refs(
mut_repo.merge_single_ref(&ref_name, old_git_target.as_ref(), new_git_target.as_ref());
// If a git remote-tracking branch changed, apply the change to the local branch
// as well
if !git_settings.auto_local_branch {
continue;
}
if let RefName::RemoteBranch { branch, remote: _ } = ref_name {
mut_repo.merge_single_ref(
&RefName::LocalBranch(branch),
@ -336,6 +341,7 @@ pub fn fetch(
git_repo: &git2::Repository,
remote_name: &str,
callbacks: RemoteCallbacks<'_>,
git_settings: &GitSettings,
) -> Result<Option<String>, GitFetchError> {
let mut remote =
git_repo
@ -378,7 +384,7 @@ pub fn fetch(
tracing::debug!("remote.disconnect");
remote.disconnect()?;
tracing::debug!("import_refs");
import_refs(mut_repo, git_repo).map_err(|err| match err {
import_refs(mut_repo, git_repo, git_settings).map_err(|err| match err {
GitImportError::InternalGitError(source) => GitFetchError::InternalGitError(source),
})?;
Ok(default_branch)

View file

@ -33,6 +33,27 @@ pub struct RepoSettings {
_config: config::Config,
}
#[derive(Debug, Clone)]
pub struct GitSettings {
pub auto_local_branch: bool,
}
impl GitSettings {
pub fn from_config(config: &config::Config) -> Self {
GitSettings {
auto_local_branch: config.get_bool("git.auto-local-branch").unwrap_or(true),
}
}
}
impl Default for GitSettings {
fn default() -> Self {
GitSettings {
auto_local_branch: true,
}
}
}
fn get_timestamp_config(config: &config::Config, key: &str) -> Option<Timestamp> {
match config.get_string(key) {
Ok(timestamp_str) => match DateTime::parse_from_rfc3339(&timestamp_str) {
@ -153,6 +174,10 @@ impl UserSettings {
&self.config
}
pub fn git_settings(&self) -> GitSettings {
GitSettings::from_config(&self.config)
}
pub fn graph_style(&self) -> String {
self.config
.get_string("ui.graph.style")

View file

@ -24,7 +24,7 @@ use jujutsu_lib::git::{GitFetchError, GitPushError, GitRefUpdate};
use jujutsu_lib::git_backend::GitBackend;
use jujutsu_lib::op_store::{BranchTarget, RefTarget};
use jujutsu_lib::repo::ReadonlyRepo;
use jujutsu_lib::settings::UserSettings;
use jujutsu_lib::settings::{GitSettings, UserSettings};
use maplit::{btreemap, hashset};
use tempfile::TempDir;
use testutils::{create_random_commit, write_random_commit, TestRepo};
@ -61,6 +61,7 @@ fn git_id(commit: &Commit) -> Oid {
#[test]
fn test_import_refs() {
let settings = testutils::user_settings();
let git_settings = GitSettings::default();
let test_repo = TestRepo::init(true);
let repo = &test_repo.repo;
let git_repo = repo.store().git_repo().unwrap();
@ -80,7 +81,7 @@ fn test_import_refs() {
let git_repo = repo.store().git_repo().unwrap();
let mut tx = repo.start_transaction(&settings, "test");
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
let repo = tx.commit();
let view = repo.view();
@ -166,6 +167,7 @@ fn test_import_refs() {
#[test]
fn test_import_refs_reimport() {
let settings = testutils::user_settings();
let git_settings = GitSettings::default();
let test_workspace = TestRepo::init(true);
let repo = &test_workspace.repo;
let git_repo = repo.store().git_repo().unwrap();
@ -181,7 +183,7 @@ fn test_import_refs_reimport() {
.unwrap();
let mut tx = repo.start_transaction(&settings, "test");
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
let repo = tx.commit();
@ -203,7 +205,7 @@ fn test_import_refs_reimport() {
let repo = tx.commit();
let mut tx = repo.start_transaction(&settings, "test");
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
let repo = tx.commit();
@ -261,13 +263,14 @@ fn test_import_refs_reimport() {
fn test_import_refs_reimport_head_removed() {
// Test that re-importing refs doesn't cause a deleted head to come back
let settings = testutils::user_settings();
let git_settings = GitSettings::default();
let test_repo = TestRepo::init(true);
let repo = &test_repo.repo;
let git_repo = repo.store().git_repo().unwrap();
let commit = empty_git_commit(&git_repo, "refs/heads/main", &[]);
let mut tx = repo.start_transaction(&settings, "test");
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
let commit_id = jj_id(&commit);
// Test the setup
@ -275,7 +278,7 @@ fn test_import_refs_reimport_head_removed() {
// Remove the head and re-import
tx.mut_repo().remove_head(&commit_id);
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
assert!(!tx.mut_repo().view().heads().contains(&commit_id));
}
@ -285,6 +288,7 @@ fn test_import_refs_reimport_git_head_counts() {
// Test that if a branch is removed but the Git HEAD points to the commit (or a
// descendant of it), we still keep it alive.
let settings = testutils::user_settings();
let git_settings = GitSettings::default();
let test_repo = TestRepo::init(true);
let repo = &test_repo.repo;
let git_repo = repo.store().git_repo().unwrap();
@ -293,7 +297,7 @@ fn test_import_refs_reimport_git_head_counts() {
git_repo.set_head_detached(commit.id()).unwrap();
let mut tx = repo.start_transaction(&settings, "test");
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
// Delete the branch and re-import. The commit should still be there since HEAD
@ -303,7 +307,7 @@ fn test_import_refs_reimport_git_head_counts() {
.unwrap()
.delete()
.unwrap();
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
assert!(tx.mut_repo().view().heads().contains(&jj_id(&commit)));
}
@ -313,13 +317,14 @@ fn test_import_refs_reimport_all_from_root_removed() {
// Test that if a chain of commits all the way from the root gets unreferenced,
// we abandon the whole stack, but not including the root commit.
let settings = testutils::user_settings();
let git_settings = GitSettings::default();
let test_repo = TestRepo::init(true);
let repo = &test_repo.repo;
let git_repo = repo.store().git_repo().unwrap();
let commit = empty_git_commit(&git_repo, "refs/heads/main", &[]);
let mut tx = repo.start_transaction(&settings, "test");
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
// Test the setup
assert!(tx.mut_repo().view().heads().contains(&jj_id(&commit)));
@ -330,7 +335,7 @@ fn test_import_refs_reimport_all_from_root_removed() {
.unwrap()
.delete()
.unwrap();
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
tx.mut_repo().rebase_descendants(&settings).unwrap();
assert!(!tx.mut_repo().view().heads().contains(&jj_id(&commit)));
}
@ -383,11 +388,12 @@ impl GitRepoData {
#[test]
fn test_import_refs_empty_git_repo() {
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let heads_before = test_data.repo.view().heads().clone();
let mut tx = test_data
.repo
.start_transaction(&test_data.settings, "test");
git::import_refs(tx.mut_repo(), &test_data.git_repo).unwrap();
git::import_refs(tx.mut_repo(), &test_data.git_repo, &git_settings).unwrap();
tx.mut_repo()
.rebase_descendants(&test_data.settings)
.unwrap();
@ -402,6 +408,7 @@ fn test_import_refs_empty_git_repo() {
#[test]
fn test_import_refs_detached_head() {
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let commit1 = empty_git_commit(&test_data.git_repo, "refs/heads/main", &[]);
// Delete the reference. Check that the detached HEAD commit still gets added to
// the set of heads
@ -416,7 +423,7 @@ fn test_import_refs_detached_head() {
let mut tx = test_data
.repo
.start_transaction(&test_data.settings, "test");
git::import_refs(tx.mut_repo(), &test_data.git_repo).unwrap();
git::import_refs(tx.mut_repo(), &test_data.git_repo, &git_settings).unwrap();
tx.mut_repo()
.rebase_descendants(&test_data.settings)
.unwrap();
@ -433,6 +440,7 @@ fn test_export_refs_no_detach() {
// When exporting the branch that's current checked out, don't detach HEAD if
// the target already matches
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let git_repo = test_data.git_repo;
let commit1 = empty_git_commit(&git_repo, "refs/heads/main", &[]);
git_repo.set_head("refs/heads/main").unwrap();
@ -440,7 +448,7 @@ fn test_export_refs_no_detach() {
.repo
.start_transaction(&test_data.settings, "test");
let mut_repo = tx.mut_repo();
git::import_refs(mut_repo, &git_repo).unwrap();
git::import_refs(mut_repo, &git_repo, &git_settings).unwrap();
mut_repo.rebase_descendants(&test_data.settings).unwrap();
// Do an initial export to make sure `main` is considered
@ -460,6 +468,7 @@ fn test_export_refs_no_detach() {
fn test_export_refs_branch_changed() {
// We can export a change to a branch
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let git_repo = test_data.git_repo;
let commit = empty_git_commit(&git_repo, "refs/heads/main", &[]);
git_repo
@ -471,7 +480,7 @@ fn test_export_refs_branch_changed() {
.repo
.start_transaction(&test_data.settings, "test");
let mut_repo = tx.mut_repo();
git::import_refs(mut_repo, &git_repo).unwrap();
git::import_refs(mut_repo, &git_repo, &git_settings).unwrap();
mut_repo.rebase_descendants(&test_data.settings).unwrap();
assert_eq!(git::export_refs(mut_repo, &git_repo), Ok(vec![]));
@ -505,6 +514,7 @@ fn test_export_refs_branch_changed() {
fn test_export_refs_current_branch_changed() {
// If we update a branch that is checked out in the git repo, HEAD gets detached
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let git_repo = test_data.git_repo;
let commit1 = empty_git_commit(&git_repo, "refs/heads/main", &[]);
git_repo.set_head("refs/heads/main").unwrap();
@ -512,7 +522,7 @@ fn test_export_refs_current_branch_changed() {
.repo
.start_transaction(&test_data.settings, "test");
let mut_repo = tx.mut_repo();
git::import_refs(mut_repo, &git_repo).unwrap();
git::import_refs(mut_repo, &git_repo, &git_settings).unwrap();
mut_repo.rebase_descendants(&test_data.settings).unwrap();
assert_eq!(git::export_refs(mut_repo, &git_repo), Ok(vec![]));
@ -545,13 +555,14 @@ fn test_export_refs_current_branch_changed() {
fn test_export_refs_unborn_git_branch() {
// Can export to an empty Git repo (we can handle Git's "unborn branch" state)
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let git_repo = test_data.git_repo;
git_repo.set_head("refs/heads/main").unwrap();
let mut tx = test_data
.repo
.start_transaction(&test_data.settings, "test");
let mut_repo = tx.mut_repo();
git::import_refs(mut_repo, &git_repo).unwrap();
git::import_refs(mut_repo, &git_repo, &git_settings).unwrap();
mut_repo.rebase_descendants(&test_data.settings).unwrap();
assert_eq!(git::export_refs(mut_repo, &git_repo), Ok(vec![]));
@ -586,6 +597,7 @@ fn test_export_import_sequence() {
// modify it in git to point to C, then import it again. There should be no
// conflict.
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let git_repo = test_data.git_repo;
let mut tx = test_data
.repo
@ -599,7 +611,7 @@ fn test_export_import_sequence() {
git_repo
.reference("refs/heads/main", git_id(&commit_a), true, "test")
.unwrap();
git::import_refs(mut_repo, &git_repo).unwrap();
git::import_refs(mut_repo, &git_repo, &git_settings).unwrap();
assert_eq!(
mut_repo.get_git_ref("refs/heads/main"),
Some(RefTarget::Normal(commit_a.id().clone()))
@ -621,7 +633,7 @@ fn test_export_import_sequence() {
.unwrap();
// Import from git
git::import_refs(mut_repo, &git_repo).unwrap();
git::import_refs(mut_repo, &git_repo, &git_settings).unwrap();
assert_eq!(
mut_repo.get_git_ref("refs/heads/main"),
Some(RefTarget::Normal(commit_c.id().clone()))
@ -632,6 +644,44 @@ fn test_export_import_sequence() {
);
}
#[test]
fn test_import_export_no_auto_local_branch() {
// Import a remote tracking branch and export it. We should not create a git
// branch.
let test_data = GitRepoData::create();
let git_settings = GitSettings {
auto_local_branch: false,
};
let git_repo = test_data.git_repo;
let git_commit = empty_git_commit(&git_repo, "refs/remotes/origin/main", &[]);
let mut tx = test_data
.repo
.start_transaction(&test_data.settings, "test");
let mut_repo = tx.mut_repo();
git::import_refs(mut_repo, &git_repo, &git_settings).unwrap();
let expected_branch = BranchTarget {
local_target: None,
remote_targets: btreemap! {
"origin".to_string() => RefTarget::Normal(jj_id(&git_commit))
},
};
assert_eq!(
mut_repo.view().branches().get("main"),
Some(expected_branch).as_ref()
);
assert_eq!(
mut_repo.get_git_ref("refs/remotes/origin/main"),
Some(RefTarget::Normal(jj_id(&git_commit)))
);
// Export the branch to git
assert_eq!(git::export_refs(mut_repo, &git_repo), Ok(vec![]));
assert_eq!(mut_repo.get_git_ref("refs/heads/main"), None);
}
#[test]
fn test_export_conflicts() {
// We skip export of conflicted branches
@ -895,6 +945,7 @@ fn test_init() {
#[test]
fn test_fetch_empty_repo() {
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let mut tx = test_data
.repo
@ -904,6 +955,7 @@ fn test_fetch_empty_repo() {
&test_data.git_repo,
"origin",
git::RemoteCallbacks::default(),
&git_settings,
)
.unwrap();
// No default branch and no refs
@ -915,6 +967,7 @@ fn test_fetch_empty_repo() {
#[test]
fn test_fetch_initial_commit() {
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let initial_git_commit = empty_git_commit(&test_data.origin_repo, "refs/heads/main", &[]);
let mut tx = test_data
@ -925,6 +978,7 @@ fn test_fetch_initial_commit() {
&test_data.git_repo,
"origin",
git::RemoteCallbacks::default(),
&git_settings,
)
.unwrap();
// No default branch because the origin repo's HEAD wasn't set
@ -954,6 +1008,7 @@ fn test_fetch_initial_commit() {
#[test]
fn test_fetch_success() {
let mut test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let initial_git_commit = empty_git_commit(&test_data.origin_repo, "refs/heads/main", &[]);
let mut tx = test_data
@ -964,6 +1019,7 @@ fn test_fetch_success() {
&test_data.git_repo,
"origin",
git::RemoteCallbacks::default(),
&git_settings,
)
.unwrap();
test_data.repo = tx.commit();
@ -983,6 +1039,7 @@ fn test_fetch_success() {
&test_data.git_repo,
"origin",
git::RemoteCallbacks::default(),
&git_settings,
)
.unwrap();
// The default branch is "main"
@ -1012,6 +1069,7 @@ fn test_fetch_success() {
#[test]
fn test_fetch_prune_deleted_ref() {
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
empty_git_commit(&test_data.git_repo, "refs/heads/main", &[]);
let mut tx = test_data
@ -1022,6 +1080,7 @@ fn test_fetch_prune_deleted_ref() {
&test_data.git_repo,
"origin",
git::RemoteCallbacks::default(),
&git_settings,
)
.unwrap();
// Test the setup
@ -1039,6 +1098,7 @@ fn test_fetch_prune_deleted_ref() {
&test_data.git_repo,
"origin",
git::RemoteCallbacks::default(),
&git_settings,
)
.unwrap();
assert!(tx.mut_repo().get_branch("main").is_none());
@ -1047,6 +1107,7 @@ fn test_fetch_prune_deleted_ref() {
#[test]
fn test_fetch_no_default_branch() {
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let initial_git_commit = empty_git_commit(&test_data.origin_repo, "refs/heads/main", &[]);
let mut tx = test_data
@ -1057,6 +1118,7 @@ fn test_fetch_no_default_branch() {
&test_data.git_repo,
"origin",
git::RemoteCallbacks::default(),
&git_settings,
)
.unwrap();
@ -1078,6 +1140,7 @@ fn test_fetch_no_default_branch() {
&test_data.git_repo,
"origin",
git::RemoteCallbacks::default(),
&git_settings,
)
.unwrap();
// There is no default branch
@ -1087,7 +1150,7 @@ fn test_fetch_no_default_branch() {
#[test]
fn test_fetch_no_such_remote() {
let test_data = GitRepoData::create();
let git_settings = GitSettings::default();
let mut tx = test_data
.repo
.start_transaction(&test_data.settings, "test");
@ -1096,6 +1159,7 @@ fn test_fetch_no_such_remote() {
&test_data.git_repo,
"invalid-remote",
git::RemoteCallbacks::default(),
&git_settings,
);
assert!(matches!(result, Err(GitFetchError::NoSuchRemote(_))));
}

View file

@ -25,6 +25,7 @@ use jujutsu_lib::revset::{
self, optimize, parse, resolve_symbol, RevsetAliasesMap, RevsetError, RevsetExpression,
RevsetWorkspaceContext,
};
use jujutsu_lib::settings::GitSettings;
use jujutsu_lib::workspace::Workspace;
use test_case::test_case;
use testutils::{
@ -160,6 +161,7 @@ fn test_resolve_symbol_commit_id() {
#[test_case(true ; "readonly")]
fn test_resolve_symbol_change_id(readonly: bool) {
let settings = testutils::user_settings();
let git_settings = GitSettings::default();
// Test only with git so we can get predictable change ids
let test_repo = TestRepo::init(true);
let repo = &test_repo.repo;
@ -196,7 +198,7 @@ fn test_resolve_symbol_change_id(readonly: bool) {
}
let mut tx = repo.start_transaction(&settings, "test");
git::import_refs(tx.mut_repo(), &git_repo).unwrap();
git::import_refs(tx.mut_repo(), &git_repo, &git_settings).unwrap();
// Test the test setup
assert_eq!(

View file

@ -505,7 +505,7 @@ impl WorkspaceCommandHelper {
git_repo: &Repository,
) -> Result<(), CommandError> {
let mut tx = self.start_transaction("import git refs").into_inner();
git::import_refs(tx.mut_repo(), git_repo)?;
git::import_refs(tx.mut_repo(), git_repo, &self.settings.git_settings())?;
if tx.mut_repo().has_changes() {
let old_git_head = self.repo.view().git_head();
let new_git_head = tx.mut_repo().view().git_head();

View file

@ -246,8 +246,16 @@ fn cmd_git_fetch(
let repo = workspace_command.repo();
let git_repo = get_git_repo(repo.store())?;
let mut tx = workspace_command.start_transaction(&format!("fetch from git remote {}", &remote));
with_remote_callbacks(ui, |cb| git::fetch(tx.mut_repo(), &git_repo, &remote, cb))
.map_err(|err| user_error(err.to_string()))?;
with_remote_callbacks(ui, |cb| {
git::fetch(
tx.mut_repo(),
&git_repo,
&remote,
cb,
&command.settings().git_settings(),
)
})
.map_err(|err| user_error(err.to_string()))?;
tx.finish(ui)?;
Ok(())
}
@ -365,7 +373,13 @@ fn do_git_clone(
let mut fetch_tx = workspace_command.start_transaction("fetch from git remote into empty repo");
let maybe_default_branch = with_remote_callbacks(ui, |cb| {
git::fetch(fetch_tx.mut_repo(), &git_repo, remote_name, cb)
git::fetch(
fetch_tx.mut_repo(),
&git_repo,
remote_name,
cb,
&command.settings().git_settings(),
)
})
.map_err(|err| match err {
GitFetchError::NoSuchRemote(_) => {
@ -792,7 +806,7 @@ fn cmd_git_push(
git::push_updates(&git_repo, &remote, &ref_updates, cb)
})
.map_err(|err| user_error(err.to_string()))?;
git::import_refs(tx.mut_repo(), &git_repo)?;
git::import_refs(tx.mut_repo(), &git_repo, &command.settings().git_settings())?;
tx.finish(ui)?;
Ok(())
}
@ -828,7 +842,7 @@ fn cmd_git_import(
let repo = workspace_command.repo();
let git_repo = get_git_repo(repo.store())?;
let mut tx = workspace_command.start_transaction("import git refs");
git::import_refs(tx.mut_repo(), &git_repo)?;
git::import_refs(tx.mut_repo(), &git_repo, &command.settings().git_settings())?;
tx.finish(ui)?;
Ok(())
}

View file

@ -980,7 +980,11 @@ fn cmd_init(ui: &mut Ui, command: &CommandHelper, args: &InitArgs) -> Result<(),
add_to_git_exclude(ui, &git_repo)?;
} else {
let mut tx = workspace_command.start_transaction("import git refs");
jujutsu_lib::git::import_refs(tx.mut_repo(), &git_repo)?;
jujutsu_lib::git::import_refs(
tx.mut_repo(),
&git_repo,
&command.settings().git_settings(),
)?;
if let Some(git_head_id) = tx.mut_repo().view().git_head() {
let git_head_commit = tx.mut_repo().store().get_commit(&git_head_id)?;
tx.check_out(&git_head_commit)?;

View file

@ -62,6 +62,7 @@ fn test_git_import_remote_only_branch() {
&["git", "remote", "add", "origin", "../git-repo"],
);
// Import using default config
git_repo
.commit(
Some("refs/heads/feature1"),
@ -76,6 +77,25 @@ fn test_git_import_remote_only_branch() {
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
feature1: 9f01a0e04879 message
"###);
// Import using git.auto_local_branch = false
git_repo
.commit(
Some("refs/heads/feature2"),
&signature,
&signature,
"message",
&tree,
&[],
)
.unwrap();
test_env.add_config("git.auto-local-branch = false");
test_env.jj_cmd_success(&repo_path, &["git", "fetch", "--remote=origin"]);
insta::assert_snapshot!(get_branch_output(&test_env, &repo_path), @r###"
feature1: 9f01a0e04879 message
feature2 (deleted)
@origin: 9f01a0e04879 message
"###);
}
fn get_branch_output(test_env: &TestEnvironment, repo_path: &Path) -> String {