use std::path::Path;
use std::{io, ops::Sub, thread::sleep, time::Duration};
use anyhow::Result;
use log::warn;
use remove_dir_all::remove_dir_all;
pub use utils::clone_git_template_into_temp;
pub mod gitconfig;
pub mod utils;
pub use utils::{tmp_dir, try_get_branch_from_path};
pub fn init(project_dir: &Path, branch: Option<&str>, force: bool) -> Result<()> {
match (gix::discover(project_dir).ok(), force) {
(Some(_), false) => Ok(()),
(Some(_), true) if gix::open(project_dir).is_ok() => Ok(()),
_ => just_init(project_dir, branch),
}
}
fn just_init(project_dir: &Path, branch: Option<&str>) -> Result<()> {
let repo = gix::init(project_dir)?;
if let Some(branch) = branch {
std::fs::write(
repo.git_dir().join("HEAD"),
format!("ref: refs/heads/{branch}\n"),
)?;
}
Ok(())
}
pub fn remove_history(project_dir: &Path) -> io::Result<()> {
let git_dir = project_dir.join(".git");
if git_dir.exists() && git_dir.is_dir() {
let mut attempt = 0_u8;
loop {
attempt += 1;
if let Err(e) = remove_dir_all(&git_dir) {
if attempt == 5 {
return Err(e);
}
if e.to_string().contains("The process cannot access the file because it is being used by another process.") {
let wait_for = Duration::from_secs(2_u64.pow(attempt.sub(1).into()));
warn!("Git history cleanup failed with a windows process blocking error. [Retry in {wait_for:?}]");
sleep(wait_for);
} else {
return Err(e);
}
} else {
return Ok(());
}
}
} else {
Ok(())
}
}