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 if !path.is_relative() {
55 bail!("Input paths need to be relative, but {path:?} is not.")
56 }
57 let path = gix::path::into_bstr(path);
58 index.dangerously_push_entry(
59 gix::index::entry::Stat::default(),
60 gix::hash::ObjectId::empty_blob(object_hash),
61 gix::index::entry::Flags::empty(),
62 gix::index::entry::Mode::FILE,
63 gix::path::to_unix_separators_on_windows(path).as_ref(),
64 );
65 }
66 index.sort_entries();
67
68 let options = gix::index::write::Options {
69 skip_hash,
70 ..Default::default()
71 };
72 match index_path {
73 Some(index_path) => {
74 if index_path.is_file() && !force {
75 anyhow::bail!(
76 "File at \"{}\" already exists, to overwrite use the '-f' flag",
77 index_path.display()
78 );
79 }
80 let mut index = gix::index::File::from_state(index, index_path);
81 index.write(options)?;
82 }
83 None => {
84 let index = gix::index::File::from_state(index, std::path::PathBuf::new());
85 let mut out = Vec::with_capacity(512 * 1024);
86 index.write_to(&mut out, options)?;
87 }
88 }
89
90 Ok(())
91}
92
93pub mod entries;
94pub use entries::function::entries;