gitoxide_core/repository/index/
mod.rs1use std::{ffi::OsString, path::PathBuf};
2
3use anyhow::bail;
4
5pub fn from_tree(
6 repo: gix::Repository,
7 mut spec: OsString,
8 index_path: Option<PathBuf>,
9 force: bool,
10 skip_hash: bool,
11) -> anyhow::Result<()> {
12 spec.push("^{tree}");
13 let spec = gix::path::os_str_into_bstr(&spec)?;
14 let tree = repo.rev_parse_single(spec)?;
15
16 let mut index = repo.index_from_tree(&tree)?;
17 let options = gix::index::write::Options {
18 skip_hash,
19 ..Default::default()
20 };
21
22 match index_path {
23 Some(index_path) => {
24 if index_path.is_file() && !force {
25 anyhow::bail!(
26 "File at \"{}\" already exists, to overwrite use the '-f' flag",
27 index_path.display()
28 );
29 }
30 index.set_path(index_path);
31 index.write(options)?;
32 }
33 None => {
34 let mut out = Vec::with_capacity(512 * 1024);
35 index.write_to(&mut out, options)?;
36 }
37 }
38
39 Ok(())
40}
41
42pub fn from_list(
43 entries_file: PathBuf,
44 index_path: Option<PathBuf>,
45 force: bool,
46 skip_hash: bool,
47) -> anyhow::Result<()> {
48 use std::io::BufRead;
49 let object_hash = gix::hash::Kind::Sha1;
50
51 let mut index = gix::index::State::new(object_hash);
52 for path in std::io::BufReader::new(std::fs::File::open(entries_file)?).lines() {
53 let path: PathBuf = path?.into();
54 #[allow(clippy::unnecessary_debug_formatting)]
55 if !path.is_relative() {
56 bail!("Input paths need to be relative, but {path:?} is not.")
57 }
58 let path = gix::path::into_bstr(path);
59 index.dangerously_push_entry(
60 gix::index::entry::Stat::default(),
61 gix::hash::ObjectId::empty_blob(object_hash),
62 gix::index::entry::Flags::empty(),
63 gix::index::entry::Mode::FILE,
64 gix::path::to_unix_separators_on_windows(path).as_ref(),
65 );
66 }
67 index.sort_entries();
68
69 let options = gix::index::write::Options {
70 skip_hash,
71 ..Default::default()
72 };
73 match index_path {
74 Some(index_path) => {
75 if index_path.is_file() && !force {
76 anyhow::bail!(
77 "File at \"{}\" already exists, to overwrite use the '-f' flag",
78 index_path.display()
79 );
80 }
81 let mut index = gix::index::File::from_state(index, index_path);
82 index.write(options)?;
83 }
84 None => {
85 let index = gix::index::File::from_state(index, std::path::PathBuf::new());
86 let mut out = Vec::with_capacity(512 * 1024);
87 index.write_to(&mut out, options)?;
88 }
89 }
90
91 Ok(())
92}
93
94pub mod entries;
95pub use entries::function::entries;