agent: Clean up git exclusions after emergency (#38775)
In some rare cases, the auto-generated block gets stuck in `.git/info/exclude`. We now auto-clean it. Closes #38374 Release Notes: - Remove auto-generated block from git excludes if it gets stuck there.
This commit is contained in:
@@ -242,8 +242,20 @@ pub struct GitExcludeOverride {
|
||||
}
|
||||
|
||||
impl GitExcludeOverride {
|
||||
const START_BLOCK_MARKER: &str = "\n\n# ====== Auto-added by Zed: =======\n";
|
||||
const END_BLOCK_MARKER: &str = "\n# ====== End of auto-added by Zed =======\n";
|
||||
|
||||
pub async fn new(git_exclude_path: PathBuf) -> Result<Self> {
|
||||
let original_excludes = smol::fs::read_to_string(&git_exclude_path).await.ok();
|
||||
let original_excludes =
|
||||
smol::fs::read_to_string(&git_exclude_path)
|
||||
.await
|
||||
.ok()
|
||||
.map(|content| {
|
||||
// Auto-generated lines are normally cleaned up in
|
||||
// `restore_original()` or `drop()`, but may stuck in rare cases.
|
||||
// Make sure to remove them.
|
||||
Self::remove_auto_generated_block(&content)
|
||||
});
|
||||
|
||||
Ok(GitExcludeOverride {
|
||||
git_exclude_path,
|
||||
@@ -260,9 +272,10 @@ impl GitExcludeOverride {
|
||||
});
|
||||
|
||||
let mut content = self.original_excludes.clone().unwrap_or_default();
|
||||
content.push_str("\n\n# ====== Auto-added by Zed: =======\n");
|
||||
|
||||
content.push_str(Self::START_BLOCK_MARKER);
|
||||
content.push_str(self.added_excludes.as_ref().unwrap());
|
||||
content.push('\n');
|
||||
content.push_str(Self::END_BLOCK_MARKER);
|
||||
|
||||
smol::fs::write(&self.git_exclude_path, content).await?;
|
||||
Ok(())
|
||||
@@ -279,6 +292,33 @@ impl GitExcludeOverride {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn remove_auto_generated_block(content: &str) -> String {
|
||||
let start_marker = Self::START_BLOCK_MARKER;
|
||||
let end_marker = Self::END_BLOCK_MARKER;
|
||||
let mut content = content.to_string();
|
||||
|
||||
let start_index = content.find(start_marker);
|
||||
let end_index = content.rfind(end_marker);
|
||||
|
||||
if let (Some(start), Some(end)) = (start_index, end_index) {
|
||||
if end > start {
|
||||
content.replace_range(start..end + end_marker.len(), "");
|
||||
}
|
||||
}
|
||||
|
||||
// Older versions of Zed didn't have end-of-block markers,
|
||||
// so it's impossible to determine auto-generated lines.
|
||||
// Conservatively remove the standard list of excludes
|
||||
let standard_excludes = format!(
|
||||
"{}{}",
|
||||
Self::START_BLOCK_MARKER,
|
||||
include_str!("./checkpoint.gitignore")
|
||||
);
|
||||
content = content.replace(&standard_excludes, "");
|
||||
|
||||
content
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for GitExcludeOverride {
|
||||
|
||||
Reference in New Issue
Block a user