gitoxide_core/repository/index/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::{ffi::OsString, path::PathBuf};

use anyhow::bail;

pub fn from_tree(
    repo: gix::Repository,
    mut spec: OsString,
    index_path: Option<PathBuf>,
    force: bool,
    skip_hash: bool,
) -> anyhow::Result<()> {
    spec.push("^{tree}");
    let spec = gix::path::os_str_into_bstr(&spec)?;
    let tree = repo.rev_parse_single(spec)?;

    let mut index = repo.index_from_tree(&tree)?;
    let options = gix::index::write::Options {
        skip_hash,
        ..Default::default()
    };

    match index_path {
        Some(index_path) => {
            if index_path.is_file() && !force {
                anyhow::bail!(
                    "File at \"{}\" already exists, to overwrite use the '-f' flag",
                    index_path.display()
                );
            }
            index.set_path(index_path);
            index.write(options)?;
        }
        None => {
            let mut out = Vec::with_capacity(512 * 1024);
            index.write_to(&mut out, options)?;
        }
    }

    Ok(())
}

pub fn from_list(
    entries_file: PathBuf,
    index_path: Option<PathBuf>,
    force: bool,
    skip_hash: bool,
) -> anyhow::Result<()> {
    use std::io::BufRead;
    let object_hash = gix::hash::Kind::Sha1;

    let mut index = gix::index::State::new(object_hash);
    for path in std::io::BufReader::new(std::fs::File::open(entries_file)?).lines() {
        let path: PathBuf = path?.into();
        if !path.is_relative() {
            bail!("Input paths need to be relative, but {path:?} is not.")
        }
        let path = gix::path::into_bstr(path);
        index.dangerously_push_entry(
            gix::index::entry::Stat::default(),
            gix::hash::ObjectId::empty_blob(object_hash),
            gix::index::entry::Flags::empty(),
            gix::index::entry::Mode::FILE,
            gix::path::to_unix_separators_on_windows(path).as_ref(),
        );
    }
    index.sort_entries();

    let options = gix::index::write::Options {
        skip_hash,
        ..Default::default()
    };
    match index_path {
        Some(index_path) => {
            if index_path.is_file() && !force {
                anyhow::bail!(
                    "File at \"{}\" already exists, to overwrite use the '-f' flag",
                    index_path.display()
                );
            }
            let mut index = gix::index::File::from_state(index, index_path);
            index.write(options)?;
        }
        None => {
            let index = gix::index::File::from_state(index, std::path::PathBuf::new());
            let mut out = Vec::with_capacity(512 * 1024);
            index.write_to(&mut out, options)?;
        }
    }

    Ok(())
}

pub mod entries;
pub use entries::function::entries;