Skip to content

Commit

Permalink
feat: no-repo index from-list to create an index with empty files f…
Browse files Browse the repository at this point in the history
…rom the given list.

The list could be created with `find . -type f` for example.
  • Loading branch information
Byron committed May 4, 2023
1 parent edeb4de commit b8db207
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
44 changes: 44 additions & 0 deletions gitoxide-core/src/repository/index/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::bail;
use std::{ffi::OsString, path::PathBuf};

use gix::prelude::FindExt;
Expand Down Expand Up @@ -35,5 +36,48 @@ pub fn from_tree(
Ok(())
}

pub fn from_list(entries_file: PathBuf, index_path: Option<PathBuf>, force: 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::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;
14 changes: 13 additions & 1 deletion src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,26 @@ pub fn main() -> Result<()> {
index_path,
cmd,
}) => match cmd {
free::index::Subcommands::FromList {
force,
index_output_path,
file,
} => prepare_and_run(
"index-from-list",
verbose,
progress,
progress_keep_open,
None,
move |_progress, _out, _err| core::repository::index::from_list(file, index_output_path, force),
),
free::index::Subcommands::CheckoutExclusive {
directory,
empty_files,
repository,
keep_going,
} => prepare_and_run(
"index-checkout",
verbose,
auto_verbose,
progress,
progress_keep_open,
None,
Expand Down
13 changes: 13 additions & 0 deletions src/plumbing/options/free.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ pub mod index {

#[derive(Debug, clap::Subcommand)]
pub enum Subcommands {
/// Create an index from a list of empty files, one per line of the input.
FromList {
/// Overwrite the specified index file if it already exists.
#[clap(long, short = 'f')]
force: bool,
/// Path to the index file to be written.
/// If none is given it will be kept in memory only as a way to measure performance. One day we will probably write the index
/// back by default, but that requires us to write more of the index to work.
#[clap(long, short = 'i')]
index_output_path: Option<PathBuf>,
/// The file to read the index entries from, one path per line.
file: PathBuf,
},
/// Validate constraints and assumptions of an index along with its integrity.
Verify,
/// Print information about the index structure
Expand Down

0 comments on commit b8db207

Please sign in to comment.