use crate::constants::HASH_FILE;
use crate::core::index::CommitEntryReader;
use crate::error::OxenError;
use crate::model::{Commit, CommitEntry, ContentHashable, LocalRepository, NewCommit};
use crate::util;
#[derive(Debug)]
struct SimpleHash {
hash: String,
}
impl ContentHashable for SimpleHash {
fn content_hash(&self) -> String {
self.hash.clone()
}
}
pub fn compute_commit_content_hash(
repository: &LocalRepository,
commit: &Commit,
) -> Result<String, OxenError> {
let commit_entry_reader = CommitEntryReader::new(repository, commit)?;
let entries = commit_entry_reader.list_entries()?;
let n_commit = NewCommit::from_commit(commit); let content_hash = compute_versions_hash(repository, &n_commit, &entries)?;
Ok(content_hash)
}
fn compute_versions_hash(
repository: &LocalRepository,
commit: &NewCommit,
entries: &[CommitEntry],
) -> Result<String, OxenError> {
let mut hashes: Vec<SimpleHash> = vec![];
for (_, entry) in entries.iter().enumerate() {
let version_path = util::fs::version_path(repository, entry);
let maybe_hash_file = version_path.parent().unwrap().join(HASH_FILE);
if maybe_hash_file.exists() {
let hash = util::fs::read_from_path(&maybe_hash_file)?;
hashes.push(SimpleHash { hash });
continue;
}
let hash = util::hasher::hash_file_contents_with_retry(&version_path)?;
hashes.push(SimpleHash { hash })
}
let content_id = util::hasher::compute_commit_hash(commit, &hashes);
Ok(content_id)
}