use crate::diagnostic_log::debug;
use crate::private_storage::remove_tree;
use crate::recovery_error::{RecoveryError, io_failure};
use crate::transaction_git::GitRequest;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
pub const REPOSITORY_REDIRECT_VARIABLES: [&str; 5] = [
"GIT_DIR",
"GIT_WORK_TREE",
"GIT_COMMON_DIR",
"GIT_OBJECT_DIRECTORY",
"GIT_INDEX_FILE",
];
pub const SHADOW_NO_HOOKS_NAME: &str = "no-hooks";
pub const SHADOW_ROOT_NAME: &str = "shadow";
pub fn shadow_repository_path(common_dir: &Path, transaction_id: &str) -> PathBuf {
return common_dir
.join("cli-git")
.join(SHADOW_ROOT_NAME)
.join(transaction_id);
}
pub fn shadow_request<S: AsRef<std::ffi::OsStr>>(
shadow: &Path,
cwd: &Path,
arguments: &[S],
) -> GitRequest {
let mut git_dir: OsString = OsString::from("--git-dir=");
git_dir.push(shadow.as_os_str());
let mut hooks: OsString = OsString::from("core.hooksPath=");
hooks.push(shadow.join(SHADOW_NO_HOOKS_NAME).as_os_str());
let mut full: Vec<OsString> = vec![git_dir, OsString::from("-c"), hooks];
for argument in arguments {
full.push(argument.as_ref().to_os_string());
}
let mut request: GitRequest = GitRequest::new(cwd, full.as_slice());
request.without_prefix = true;
for name in REPOSITORY_REDIRECT_VARIABLES {
request.unset.push(OsString::from(name));
}
return request;
}
pub fn remove_shadow_repository(shadow: &Path) -> Result<(), RecoveryError> {
if let Err(error) = remove_tree(shadow) {
return Err(io_failure("removing the shadow repository", shadow, &error));
}
debug(
"removeShadowRepository",
format!("removed shadow repository {}", shadow.display()).as_str(),
);
return Ok(());
}
#[cfg(test)]
#[path = "shadow_git_tests.rs"]
mod tests;