use std::{fs, io, io::Write, path::Path};
use bstr::BStr;
pub fn set_lock(git_dir: &Path, reason: Option<&BStr>) -> io::Result<()> {
let path = git_dir.join("locked");
match reason {
Some(reason) => {
match path.symlink_metadata() {
Ok(metadata) if !metadata.is_file() => {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"worktree lock is not a regular file",
));
}
Err(err) if err.kind() != io::ErrorKind::NotFound => return Err(err),
_ => {}
}
let mut file = gix_fs::open_options_no_follow().write(true).create(true).open(path)?;
if !file.metadata()?.is_file() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
"worktree lock is not a regular file",
));
}
file.set_len(0)?;
file.write_all(reason)?;
if !reason.ends_with(b"\n") {
file.write_all(b"\n")?;
}
Ok(())
}
None => match fs::remove_file(path) {
Ok(()) => Ok(()),
Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(()),
Err(err) => Err(err),
},
}
}