Skip to content

Commit

Permalink
input id can now be a commit or tree as prefix or full object id
Browse files Browse the repository at this point in the history
  • Loading branch information
Sidney Douw committed Sep 27, 2022
1 parent 2fbd3df commit 8ef3fcb
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 21 deletions.
51 changes: 36 additions & 15 deletions gitoxide-core/src/index/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use git::odb::FindExt;
use git::{odb::FindExt, prelude::ObjectIdExt};
use git_repository as git;
use std::path::{Path, PathBuf};

Expand Down Expand Up @@ -88,27 +88,48 @@ pub fn information(
}

pub fn from_tree(
id: git::hash::ObjectId,
path: PathBuf,
id: String,
index: Option<PathBuf>,
force: bool,
repo: git::Repository,
mut out: impl std::io::Write,
mut err: impl std::io::Write,
) -> anyhow::Result<()> {
let state = git::index::State::from_tree(&id, |oid, buf| repo.objects.find_tree_iter(oid, buf).ok())?;

if path.is_file() {
writeln!(err, "File {:?} already exists", path).ok();
if force {
writeln!(err, "overwriting").ok();
} else {
anyhow::bail!("exiting");
// TODO: consider HashKind
let id = match id.len() {
40 => git::hash::ObjectId::from_hex(id.as_bytes())?,
_ => {
let prefix = git::hash::Prefix::from_hex(&id)?;
match repo.objects.lookup_prefix(prefix, None) {
Ok(Some(Ok(id))) => id,
Ok(Some(Err(_))) => anyhow::bail!("multiple objects found while trying to disambiguate id: {:?}", id),
Ok(None) => anyhow::bail!("no objects found while trying to disambiguate id: {:?}", id),
Err(e) => anyhow::bail!(e),
}
}
}
};

let mut file = std::fs::File::create(&path)?;
state.write_to(&mut file, git::index::write::Options::default())?;
let tree = id.attach(&repo).object()?.peel_to_kind(git::objs::Kind::Tree)?.id();
let state = git::index::State::from_tree(&tree, |oid, buf| repo.objects.find_tree_iter(oid, buf).ok())?;

writeln!(err, "Successfully wrote file {:?}", path).ok();
match index {
Some(index) => {
if index.is_file() {
writeln!(err, "File {:?} already exists", index).ok();
if force {
writeln!(err, "overwriting").ok();
} else {
anyhow::bail!("exiting, to overwrite use the '-f' flag");
}
}
let mut file = std::fs::File::create(&index)?;
state.write_to(&mut file, git::index::write::Options::default())?;
writeln!(err, "Successfully wrote file {:?}", index).ok();
}
None => {
state.write_to(&mut out, git::index::write::Options::default())?;
}
}

Ok(())
}
6 changes: 4 additions & 2 deletions src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,13 +756,15 @@ pub fn main() -> Result<()> {
),
},
Subcommands::Index(cmd) => match cmd {
index::Subcommands::FromTree { force, id, path } => prepare_and_run(
index::Subcommands::FromTree { force, id, index } => prepare_and_run(
"index-read-tree",
verbose,
progress,
progress_keep_open,
None,
move |_progress, _out, err| core::index::from_tree(id, path, force, repository(Mode::Strict)?, err),
move |_progress, out, err| {
core::index::from_tree(id, index, force, repository(Mode::Strict)?, out, err)
},
),
},
}?;
Expand Down
10 changes: 6 additions & 4 deletions src/plumbing/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,10 +678,12 @@ pub mod index {
/// Overwrite the specified file if it already exists
#[clap(long, short = 'f')]
force: bool,
/// Hash of the tree object to generate the index from
id: git_repository::hash::ObjectId,
/// Path to the index file to be written
path: PathBuf,
/// Treeish Id to generate the index from
id: String,
/// Path to the index file to be written.
/// If none is given output will be written to stdout.
#[clap(long, short = 'i')]
index: Option<PathBuf>,
},
}
}

0 comments on commit 8ef3fcb

Please sign in to comment.