diff --git a/eden/mononoke/tools/admin/src/commands/git_objects/fetch.rs b/eden/mononoke/tools/admin/src/commands/git_objects/fetch.rs index 12dcf11d2009d..5d6fc92656ac9 100644 --- a/eden/mononoke/tools/admin/src/commands/git_objects/fetch.rs +++ b/eden/mononoke/tools/admin/src/commands/git_objects/fetch.rs @@ -5,13 +5,19 @@ * GNU General Public License version 2. */ +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + use anyhow::Context; use anyhow::Result; use clap::Args; use context::CoreContext; use git_types::fetch_git_object; +use git_types::fetch_git_object_bytes; use git_types::fetch_non_blob_git_object; use git_types::GitIdentifier; +use git_types::HeaderState; use gix_object::Object::Blob; use gix_object::Object::Commit; use gix_object::Object::Tag; @@ -26,6 +32,9 @@ pub struct FetchArgs { /// The Git SHA1 object id (in hex form) of the object that is to be fetched #[clap(long)] id: GitSha1, + /// Store the raw bytes of the git object in the specified file instead of printing the parsed object + #[clap(long)] + raw_bytes_file: Option, /// The type of the git object to be fetched. Required if the object can be git blob #[clap(long, requires = "size")] ty: Option, @@ -34,7 +43,16 @@ pub struct FetchArgs { size: Option, } -pub async fn fetch(repo: &Repo, ctx: &CoreContext, mut fetch_args: FetchArgs) -> Result<()> { +pub async fn fetch(repo: &Repo, ctx: &CoreContext, fetch_args: FetchArgs) -> Result<()> { + if fetch_args.raw_bytes_file.is_some() { + fetch_bytes(repo, ctx, fetch_args).await?; + } else { + fetch_object(repo, ctx, fetch_args).await?; + } + Ok(()) +} + +async fn fetch_object(repo: &Repo, ctx: &CoreContext, mut fetch_args: FetchArgs) -> Result<()> { let ty = fetch_args.ty.take(); let size = fetch_args.size.take(); let git_object = match (ty, size) { @@ -62,3 +80,20 @@ pub async fn fetch(repo: &Repo, ctx: &CoreContext, mut fetch_args: FetchArgs) -> }; Ok(()) } + +async fn fetch_bytes(repo: &Repo, ctx: &CoreContext, fetch_args: FetchArgs) -> Result<()> { + let git_object_bytes = fetch_git_object_bytes( + ctx, + repo.repo_blobstore.clone(), + &GitIdentifier::Basic(fetch_args.id), + HeaderState::Included, + ) + .await?; + let mut file = File::create( + fetch_args + .raw_bytes_file + .ok_or_else(|| anyhow::anyhow!("Path is required for writing raw output bytes"))?, + )?; + file.write_all(&git_object_bytes)?; + Ok(()) +}