simplify logic and mock out global gitignore location
This commit is contained in:
parent
f0da50bcb7
commit
8792bf839b
4 changed files with 39 additions and 64 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -5678,6 +5678,7 @@ dependencies = [
|
|||
"async-trait",
|
||||
"cocoa 0.26.0",
|
||||
"collections",
|
||||
"dirs 4.0.0",
|
||||
"fsevent",
|
||||
"futures 0.3.31",
|
||||
"git",
|
||||
|
|
|
@ -16,6 +16,7 @@ anyhow.workspace = true
|
|||
async-tar.workspace = true
|
||||
async-trait.workspace = true
|
||||
collections.workspace = true
|
||||
dirs.workspace = true
|
||||
futures.workspace = true
|
||||
git.workspace = true
|
||||
gpui.workspace = true
|
||||
|
|
|
@ -134,6 +134,7 @@ pub trait Fs: Send + Sync {
|
|||
fn home_dir(&self) -> Option<PathBuf>;
|
||||
fn open_repo(&self, abs_dot_git: &Path) -> Option<Arc<dyn GitRepository>>;
|
||||
fn git_init(&self, abs_work_directory: &Path, fallback_branch_name: String) -> Result<()>;
|
||||
fn global_git_ignore_path(&self, abs_work_directory: &Path) -> Option<PathBuf>;
|
||||
fn is_fake(&self) -> bool;
|
||||
async fn is_case_sensitive(&self) -> Result<bool>;
|
||||
|
||||
|
@ -821,6 +822,19 @@ impl Fs for RealFs {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn global_git_ignore_path(&self, abs_work_directory_path: &Path) -> Option<PathBuf> {
|
||||
new_std_command("git")
|
||||
.current_dir(abs_work_directory_path)
|
||||
.args(&["config", "--get", "core.excludesFile"])
|
||||
.output()
|
||||
.ok()
|
||||
.filter(|output| output.status.success())
|
||||
.and_then(|output| String::from_utf8(output.stdout).ok())
|
||||
.filter(|output| !output.is_empty())
|
||||
.map(|path| PathBuf::from(path))
|
||||
.or_else(|| Some(dirs::config_dir()?.join("git").join("ignore")))
|
||||
}
|
||||
|
||||
fn is_fake(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
@ -2319,6 +2333,10 @@ impl Fs for FakeFs {
|
|||
smol::block_on(self.create_dir(&abs_work_directory_path.join(".git")))
|
||||
}
|
||||
|
||||
fn global_git_ignore_path(&self, _abs_work_directory: &Path) -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
|
||||
fn is_fake(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
|
|
@ -3222,76 +3222,31 @@ async fn is_git_dir(path: &Path, fs: &dyn Fs) -> bool {
|
|||
}
|
||||
|
||||
async fn build_gitignore(abs_path: &Path, fs: &dyn Fs) -> Result<Gitignore> {
|
||||
let contents = fs.load(abs_path).await?;
|
||||
let parent = abs_path.parent().unwrap_or_else(|| Path::new("/"));
|
||||
|
||||
let mut builder = GitignoreBuilder::new(parent);
|
||||
|
||||
if let Some(path) = fs.global_git_ignore_path(parent) {
|
||||
if let Ok(contents) = fs.load(&path).await {
|
||||
for line in contents.lines() {
|
||||
let _ = builder.add_line(Some(path.clone()), line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let repo_git_exclude_path = parent.join(".git").join("info").join("exclude");
|
||||
if let Ok(contents) = fs.load(&repo_git_exclude_path).await {
|
||||
for line in contents.lines() {
|
||||
let _ = builder.add_line(Some(repo_git_exclude_path.clone()), line);
|
||||
}
|
||||
}
|
||||
|
||||
let contents = fs.load(abs_path).await?;
|
||||
for line in contents.lines() {
|
||||
builder.add_line(Some(abs_path.into()), line)?;
|
||||
}
|
||||
|
||||
builder.build()?;
|
||||
|
||||
let mut combined_builder = GitignoreBuilder::new(parent);
|
||||
|
||||
let home = home_dir();
|
||||
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() {
|
||||
let _ = combined_builder.add_line(Some(global_ignore_path.clone()), line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for line in contents.lines() {
|
||||
combined_builder.add_line(Some(abs_path.into()), line)?;
|
||||
}
|
||||
|
||||
Ok(combined_builder.build()?)
|
||||
let gitignore = builder.build()?;
|
||||
Ok(gitignore)
|
||||
}
|
||||
|
||||
impl Deref for Worktree {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue