git_policy_cli/
landing_objects.rs1use super::shadow_git::shadow_request;
16use super::transaction_journal::Base;
18use super::transaction_git::{GitContext, GitFailure, GitRequest, run_git_checked};
20use std::path::Path;
22
23pub fn migrate_shadow_objects(
36 context: &GitContext,
37 cwd: &Path,
38 shadow: &Path,
39 new_oid: &str,
40 old_base: &Base,
41 keep_message: Option<&str>,
42) -> Result<String, GitFailure> {
43 let mut revisions: String = format!("{new_oid}\n");
44 if let Base::Commit(oid) = old_base {
45 revisions.push_str(&format!("^{oid}\n"));
46 }
47 let mut pack_request = shadow_request(
48 shadow,
49 cwd,
50 &["pack-objects", "--revs", "--local", "--stdout", "--quiet"],
51 );
52 pack_request.input = Some(revisions.into_bytes());
53 let pack = run_git_checked(context, &pack_request)?;
54 let mut index_arguments: Vec<String> = vec!["index-pack".to_string(), "--stdin".to_string()];
55 if let Some(message) = keep_message {
56 index_arguments.push(format!("--keep={message}"));
57 }
58 let mut index_request = GitRequest::new(cwd, &index_arguments);
59 index_request.input = Some(pack.stdout);
60 let indexed = run_git_checked(context, &index_request)?;
61 let report: String = String::from_utf8(indexed.stdout)
62 .map_err(|error| { return GitFailure(format!("git index-pack printed non-UTF-8 text: {error}")); })?;
63 let trimmed: &str = report.trim();
64 let Some((_, name)) = trimmed.split_once('\t') else {
65 return Err(GitFailure(format!(
66 "git index-pack reported no pack: {}",
67 serde_json::to_string(trimmed).unwrap_or_default()
68 )));
69 };
70 return Ok(name.to_string());
71}
72
73#[cfg(test)]
75#[path = "landing_objects_tests.rs"]
76mod tests;