From ac25d05e27ae9b5649fb96f6b81c053f119d16a1 Mon Sep 17 00:00:00 2001 From: Paul Nameless Date: Sun, 13 Apr 2025 16:56:27 +0200 Subject: [PATCH] Add global and .git/info/exclude ignore files --- crates/worktree/src/worktree.rs | 49 ++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index 9af79e128a..cc6e0ef263 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -3147,12 +3147,53 @@ async fn build_gitignore(abs_path: &Path, fs: &dyn Fs) -> Result { let mut combined_builder = GitignoreBuilder::new(parent); let home = home_dir(); - if !home.as_os_str().is_empty() { - let global_ignore_path = home.join(".config/git/ignore"); + let repo_root = abs_path.parent().unwrap_or_else(|| Path::new("/")); + let repo_git_path = repo_root.join(".git"); + let repo_git_config_path = repo_git_path.join("config"); + + let mut global_ignore_path = None; + if let Ok(config_output) = std::process::Command::new("git") + .args(["config", "--file", &repo_git_config_path.to_string_lossy(), "core.excludesFile"]) + .output() + { + if config_output.status.success() { + let path_str = String::from_utf8_lossy(&config_output.stdout).trim().to_string(); + if !path_str.is_empty() { + let path = PathBuf::from(path_str); + global_ignore_path = Some(path); + } + } + } + + if global_ignore_path.is_none() { + if let Ok(config_output) = std::process::Command::new("git") + .args(["config", "--global", "core.excludesFile"]) + .output() + { + if config_output.status.success() { + let path_str = String::from_utf8_lossy(&config_output.stdout).trim().to_string(); + if !path_str.is_empty() { + let path = PathBuf::from(path_str); + global_ignore_path = Some(path); + } + } + } + } + + if global_ignore_path.is_none() && !home.as_os_str().is_empty() { + global_ignore_path = Some(home.join(".config/git/ignore")); + } + + let repo_git_exclude_path = repo_git_path.join("info/exclude"); + if let Ok(exclude_contents) = fs.load(&repo_git_exclude_path).await { + for line in exclude_contents.lines() { + let _ = combined_builder.add_line(Some(repo_git_exclude_path.clone()), line); + } + } + + if let Some(global_ignore_path) = global_ignore_path { if let Ok(global_contents) = fs.load(&global_ignore_path).await { for line in global_contents.lines() { - // Ignore errors for global gitignore entries, as we don't want to block - // local gitignore functionality if the global one has issues let _ = combined_builder.add_line(Some(global_ignore_path.clone()), line); } }