git: import git refs as anonymous heads when creating Git-backed repo

The fact that no commits from the underlying Git repo were imported
when creating a new Jujube repo from it was quite surprising. This
commit finally fixes that.
This commit is contained in:
Martin von Zweigbergk 2020-12-29 23:19:39 -08:00
parent 4235ea975d
commit ff3b20c537
2 changed files with 24 additions and 3 deletions

View file

@ -105,7 +105,7 @@ fn test_import_refs_non_git() {
}
/// Create a Git repo with a single commit in the "main" branch.
fn create_source_repo(dir: &Path) -> CommitId {
fn create_git_repo(dir: &Path) -> CommitId {
let git_repo = git2::Repository::init_bare(dir).unwrap();
let signature = git2::Signature::now("Someone", "someone@example.com").unwrap();
let empty_tree_id = Oid::from_str("4b825dc642cb6eb9a060e54bf8d69288fbee4904").unwrap();
@ -123,6 +123,21 @@ fn create_source_repo(dir: &Path) -> CommitId {
CommitId(oid.as_bytes().to_vec())
}
#[test]
fn test_init() {
let settings = testutils::user_settings();
let temp_dir = tempfile::tempdir().unwrap();
let git_repo_dir = temp_dir.path().join("git");
let jj_repo_dir = temp_dir.path().join("jj");
let initial_commit_id = create_git_repo(&git_repo_dir);
std::fs::create_dir(&jj_repo_dir).unwrap();
let repo = ReadonlyRepo::init_external_git(&settings, jj_repo_dir.clone(), git_repo_dir);
let heads: HashSet<_> = repo.view().heads().cloned().collect();
// The refs were *not* imported -- it's the caller's responsibility to import
// any refs they care about.
assert!(!heads.contains(&initial_commit_id));
}
fn create_repo_clone(source: &Path, destination: &Path) {
git2::Repository::clone(&source.to_str().unwrap(), destination).unwrap();
}
@ -138,7 +153,7 @@ fn set_up_push_repos(settings: &UserSettings, temp_dir: &TempDir) -> PushTestSet
let source_repo_dir = temp_dir.path().join("source");
let clone_repo_dir = temp_dir.path().join("clone");
let jj_repo_dir = temp_dir.path().join("jj");
let initial_commit_id = create_source_repo(&source_repo_dir);
let initial_commit_id = create_git_repo(&source_repo_dir);
create_repo_clone(&source_repo_dir, &clone_repo_dir);
std::fs::create_dir(&jj_repo_dir).unwrap();
let mut jj_repo =

View file

@ -39,6 +39,7 @@ use jj_lib::evolution::evolve;
use jj_lib::evolution::EvolveListener;
use jj_lib::files;
use jj_lib::files::DiffLine;
use jj_lib::git;
use jj_lib::op_store::{OpStoreError, OperationId};
use jj_lib::repo::{ReadonlyRepo, Repo};
use jj_lib::repo_path::RepoPath;
@ -559,6 +560,11 @@ fn cmd_init(
if let Some(git_store_str) = sub_matches.value_of("git-store") {
let git_store_path = ui.cwd().join(git_store_str);
repo = ReadonlyRepo::init_external_git(ui.settings(), wc_path, git_store_path);
let mut tx = repo.start_transaction("import git refs");
git::import_refs(&mut tx).unwrap();
// TODO: Check out a recent commit. Maybe one with the highest generation
// number.
tx.commit();
} else if sub_matches.is_present("git") {
repo = ReadonlyRepo::init_internal_git(ui.settings(), wc_path);
} else {
@ -1960,7 +1966,7 @@ fn cmd_git_push(
let commit = resolve_revision_arg(ui, mut_repo, cmd_matches)?;
let remote_name = cmd_matches.value_of("remote").unwrap();
let branch_name = cmd_matches.value_of("branch").unwrap();
jj_lib::git::push_commit(&commit, remote_name, branch_name).map_err(|err| match err {
git::push_commit(&commit, remote_name, branch_name).map_err(|err| match err {
GitPushError::NotAGitRepo => CommandError::UserError(
"git push can only be used in repos backed by a git repo".to_string(),
),