differential_engine/
tree.rs1use crate::EngineError;
12use crate::apply::apply_hunks;
13use crate::model::{DiffView, Hunk};
14use crate::plan;
15use crate::ports::{IndexEntry, IndexSession, ObjectReader, ObjectWriter, TreeBuilder};
16
17pub fn build_tree<G>(git: &G, base: &str, view: &DiffView) -> Result<String, EngineError>
19where
20 G: ObjectReader + ObjectWriter + TreeBuilder,
21{
22 let mut session = git.begin_from_tree(base)?;
23 let mut entries = Vec::with_capacity(view.files.len());
25 for f in &view.files {
26 entries.push(staging_entry(git, base, view, f)?);
27 }
28 session.stage(&entries)?;
29 session.write_tree()
30}
31
32fn staging_entry<G>(
35 git: &G,
36 base: &str,
37 view: &DiffView,
38 f: &crate::model::FileChange,
39) -> Result<IndexEntry, EngineError>
40where
41 G: ObjectReader + ObjectWriter,
42{
43 IndexEntry::from_staged(plan::final_state(f)?, f.path.clone(), || {
44 let hunks: Vec<&Hunk> = f.hunks.iter().map(|&i| &view.hunks[i]).collect();
45 let base_content = git.blob(base, &f.path)?;
46 let content = apply_hunks(base_content.as_deref(), &hunks);
47 git.write_blob(&content)
48 })
49}