diff --git a/eden/mononoke/Cargo.toml b/eden/mononoke/Cargo.toml index 3cddaec42c..7502397bcb 100644 --- a/eden/mononoke/Cargo.toml +++ b/eden/mononoke/Cargo.toml @@ -210,6 +210,7 @@ members = [ "git/git_types", "git/git_types/if", "git/gitimport", + "git/import_tools", "gotham_ext", "hgcli", "hgproto", diff --git a/eden/mononoke/git/gitimport/Cargo.toml b/eden/mononoke/git/gitimport/Cargo.toml index f2c7cadfd0..f9e585b703 100644 --- a/eden/mononoke/git/gitimport/Cargo.toml +++ b/eden/mononoke/git/gitimport/Cargo.toml @@ -17,6 +17,7 @@ context = { path = "../../server/context" } derived_data = { path = "../../derived_data" } filestore = { path = "../../filestore" } git_types = { path = "../git_types" } +import_tools = { path = "../import_tools" } manifest = { path = "../../manifest" } mercurial_types = { path = "../../mercurial/types" } mononoke_types = { path = "../../mononoke_types" } diff --git a/eden/mononoke/git/gitimport/src/main.rs b/eden/mononoke/git/gitimport/src/main.rs index cc2710ff2f..c8da92e58c 100644 --- a/eden/mononoke/git/gitimport/src/main.rs +++ b/eden/mononoke/git/gitimport/src/main.rs @@ -36,17 +36,16 @@ use futures_old::{ future::IntoFuture, stream::{self as stream_old, Stream}, }; -use git2::{ObjectType, Oid, Repository, Revwalk, Sort}; +use git2::{ObjectType, Oid, Repository, Sort}; use git_types::{mode, TreeHandle}; +use import_tools::{GitimportPreferences, GitimportTarget}; use linked_hash_map::LinkedHashMap; use manifest::{bonsai_diff, BonsaiDiffFileChange, Entry, Manifest, StoreLoadable}; use mercurial_types::HgManifestId; use mononoke_types::{ - blob::BlobstoreValue, - hash::{GitSha1, RichGitSha1}, - typed_hash::MononokeId, - BonsaiChangeset, BonsaiChangesetMut, ChangesetId, ContentMetadata, DateTime, FileChange, - FileType, MPath, MPathElement, + blob::BlobstoreValue, hash::RichGitSha1, typed_hash::MononokeId, BonsaiChangeset, + BonsaiChangesetMut, ChangesetId, ContentMetadata, DateTime, FileChange, FileType, MPath, + MPathElement, }; use slog::info; use std::collections::{BTreeMap, HashMap, HashSet}; @@ -75,88 +74,6 @@ const ARG_GIT_TO: &str = "git-to"; const HGGIT_COMMIT_ID_EXTRA: &str = "convert_revision"; -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] -struct GitimportPreferences { - dry_run: bool, - derive_trees: bool, - derive_hg: bool, - hggit_compatibility: bool, -} - -impl GitimportPreferences { - fn enable_dry_run(&mut self) { - self.dry_run = true - } - - fn enable_derive_trees(&mut self) { - self.derive_trees = true - } - - fn enable_derive_hg(&mut self) { - self.derive_hg = true - } - - fn enable_hggit_compatibility(&mut self) { - self.hggit_compatibility = true - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -enum GitimportTarget { - FullRepo, - GitRange(Oid, Oid), -} - -impl GitimportTarget { - fn populate_walk(&self, repo: &Repository, walk: &mut Revwalk) -> Result<(), Error> { - match self { - Self::FullRepo => { - for reference in repo.references()? { - let reference = reference?; - if let Some(oid) = reference.target() { - walk.push(oid)?; - } - } - } - Self::GitRange(from, to) => { - walk.hide(*from)?; - walk.push(*to)?; - } - }; - - Ok(()) - } - - async fn populate_roots( - &self, - ctx: &CoreContext, - repo: &BlobRepo, - roots: &mut HashMap, - ) -> Result<(), Error> { - match self { - Self::FullRepo => { - // Noop - } - Self::GitRange(from, _to) => { - let root = repo - .bonsai_git_mapping() - .get_bonsai_from_git_sha1(&ctx, GitSha1::from_bytes(from)?) - .await? - .ok_or_else(|| { - format_err!( - "Cannot start import from {}: commit does not exist in Blobrepo", - from - ) - })?; - - roots.insert(*from, root); - } - }; - - Ok(()) - } -} - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] struct GitTree(Oid); diff --git a/eden/mononoke/git/import_tools/Cargo.toml b/eden/mononoke/git/import_tools/Cargo.toml new file mode 100644 index 0000000000..2f191446d2 --- /dev/null +++ b/eden/mononoke/git/import_tools/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "import_tools" +edition = "2018" +version = "0.1.0" +authors = ['Facebook'] +license = "GPLv2+" +include = ["src/**/*.rs"] + +[dependencies] +blobrepo = { path = "../../blobrepo" } +context = { path = "../../server/context" } +mononoke_types = { path = "../../mononoke_types" } +anyhow = "1.0" +git2 = "0.13" diff --git a/eden/mononoke/git/import_tools/src/lib.rs b/eden/mononoke/git/import_tools/src/lib.rs new file mode 100644 index 0000000000..e885016ef5 --- /dev/null +++ b/eden/mononoke/git/import_tools/src/lib.rs @@ -0,0 +1,10 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This software may be used and distributed according to the terms of the + * GNU General Public License version 2. + */ + +mod objects; + +pub use crate::objects::{GitimportPreferences, GitimportTarget}; diff --git a/eden/mononoke/git/import_tools/src/objects.rs b/eden/mononoke/git/import_tools/src/objects.rs new file mode 100644 index 0000000000..11eefedb32 --- /dev/null +++ b/eden/mononoke/git/import_tools/src/objects.rs @@ -0,0 +1,95 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This software may be used and distributed according to the terms of the + * GNU General Public License version 2. + */ + +use anyhow::{format_err, Error}; +use blobrepo::BlobRepo; +use context::CoreContext; +use git2::{Oid, Repository, Revwalk}; +use mononoke_types::{hash::GitSha1, typed_hash::ChangesetId}; +use std::collections::HashMap; + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Default)] +pub struct GitimportPreferences { + pub dry_run: bool, + pub derive_trees: bool, + pub derive_hg: bool, + pub hggit_compatibility: bool, +} + +impl GitimportPreferences { + pub fn enable_dry_run(&mut self) { + self.dry_run = true + } + + pub fn enable_derive_trees(&mut self) { + self.derive_trees = true + } + + pub fn enable_derive_hg(&mut self) { + self.derive_hg = true + } + + pub fn enable_hggit_compatibility(&mut self) { + self.hggit_compatibility = true + } +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +pub enum GitimportTarget { + FullRepo, + GitRange(Oid, Oid), +} + +impl GitimportTarget { + pub fn populate_walk(&self, repo: &Repository, walk: &mut Revwalk) -> Result<(), Error> { + match self { + Self::FullRepo => { + for reference in repo.references()? { + let reference = reference?; + if let Some(oid) = reference.target() { + walk.push(oid)?; + } + } + } + Self::GitRange(from, to) => { + walk.hide(*from)?; + walk.push(*to)?; + } + }; + + Ok(()) + } + + pub async fn populate_roots( + &self, + ctx: &CoreContext, + repo: &BlobRepo, + roots: &mut HashMap, + ) -> Result<(), Error> { + match self { + Self::FullRepo => { + // Noop + } + Self::GitRange(from, _to) => { + let root = repo + .bonsai_git_mapping() + .get_bonsai_from_git_sha1(&ctx, GitSha1::from_bytes(from)?) + .await? + .ok_or_else(|| { + format_err!( + "Cannot start import from {}: commit does not exist in Blobrepo", + from + ) + })?; + + roots.insert(*from, root); + } + }; + + Ok(()) + } +}