-
-
Notifications
You must be signed in to change notification settings - Fork 306
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
212 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
use crate::OutputFormat; | ||
|
||
pub struct Options { | ||
pub format: OutputFormat, | ||
pub execute: bool, | ||
pub ignored: bool, | ||
pub precious: bool, | ||
pub directories: bool, | ||
} | ||
pub(crate) mod function { | ||
use crate::repository::clean::Options; | ||
use crate::OutputFormat; | ||
use anyhow::bail; | ||
use gix::bstr::BString; | ||
use gix_dir::entry::{Kind, Status}; | ||
use gix_dir::walk::EmissionMode::{CollapseDirectory, Matching}; | ||
use std::path::Path; | ||
|
||
pub fn clean( | ||
repo: gix::Repository, | ||
out: &mut dyn std::io::Write, | ||
patterns: Vec<BString>, | ||
Options { | ||
format, | ||
execute, | ||
ignored, | ||
precious, | ||
directories, | ||
}: Options, | ||
) -> anyhow::Result<()> { | ||
if format != OutputFormat::Human { | ||
bail!("JSON output isn't implemented yet"); | ||
} | ||
let Some(workdir) = repo.work_dir() else { | ||
bail!("Need a worktree to clean, this is a bare repository"); | ||
}; | ||
|
||
let index = repo.index()?; | ||
let mut excludes = repo | ||
.excludes( | ||
&index, | ||
None, | ||
gix::worktree::stack::state::ignore::Source::WorktreeThenIdMappingIfNotSkipped, | ||
)? | ||
.detach(); | ||
let (mut pathspec, mut maybe_attributes) = repo | ||
.pathspec( | ||
patterns.iter(), | ||
repo.work_dir().is_some(), | ||
&index, | ||
gix::worktree::stack::state::attributes::Source::WorktreeThenIdMapping, | ||
)? | ||
.into_parts(); | ||
|
||
let prefix = repo.prefix()?.unwrap_or(Path::new("")); | ||
let git_dir_realpath = | ||
gix::path::realpath_opts(repo.git_dir(), repo.current_dir(), gix::path::realpath::MAX_SYMLINKS)?; | ||
let mut collect = gix_dir::walk::delegate::Collect::default(); | ||
let fs_caps = repo.filesystem_options()?; | ||
let emission_mode = if directories { CollapseDirectory } else { Matching }; | ||
let accelerate_lookup = fs_caps.ignore_case.then(|| index.prepare_icase_backing()); | ||
gix_dir::walk( | ||
&workdir.join(prefix), | ||
workdir, | ||
gix_dir::walk::Context { | ||
git_dir_realpath: git_dir_realpath.as_ref(), | ||
current_dir: repo.current_dir(), | ||
index: &index, | ||
ignore_case_index_lookup: accelerate_lookup.as_ref(), | ||
pathspec: &mut pathspec, | ||
pathspec_attributes: &mut |relative_path, case, is_dir, out| { | ||
let stack = maybe_attributes | ||
.as_mut() | ||
.expect("can only be called if attributes are used in patterns"); | ||
stack | ||
.set_case(case) | ||
.at_entry(relative_path, Some(is_dir), &repo.objects) | ||
.map_or(false, |platform| platform.matching_attributes(out)) | ||
}, | ||
excludes: Some(&mut excludes), | ||
objects: &repo.objects, | ||
}, | ||
gix_dir::walk::Options { | ||
precompose_unicode: fs_caps.precompose_unicode, | ||
ignore_case: fs_caps.ignore_case, | ||
recurse_repositories: false, | ||
emit_pruned: false, | ||
emit_ignored: (ignored || precious).then_some(emission_mode), | ||
for_deletion: true, | ||
emit_tracked: false, | ||
emit_untracked: emission_mode, | ||
emit_empty_directories: directories, | ||
}, | ||
&mut collect, | ||
)?; | ||
|
||
let entries = collect.into_entries_by_path(); | ||
for entry in entries | ||
.into_iter() | ||
.filter_map(|(entry, dir_status)| dir_status.is_none().then_some(entry)) | ||
.filter(|entry| match entry.disk_kind { | ||
Kind::File | Kind::Symlink => true, | ||
Kind::EmptyDirectory | Kind::Directory | Kind::Repository => directories, | ||
}) | ||
.filter(|e| match e.status { | ||
Status::DotGit | Status::Pruned | Status::TrackedExcluded => { | ||
unreachable!("Pruned aren't emitted") | ||
} | ||
Status::Tracked => { | ||
unreachable!("tracked aren't emitted") | ||
} | ||
Status::Ignored(gix::ignore::Kind::Expendable) => ignored, | ||
Status::Ignored(gix::ignore::Kind::Precious) => precious, | ||
Status::Untracked => true, | ||
}) | ||
{ | ||
if entry.disk_kind == gix_dir::entry::Kind::Repository { | ||
writeln!(out, "Would skip repository {}", entry.rela_path)?; | ||
continue; | ||
} | ||
writeln!( | ||
out, | ||
"{maybe} {}{} ({:?})", | ||
entry.rela_path, | ||
entry.disk_kind.is_dir().then_some("/").unwrap_or_default(), | ||
entry.status, | ||
maybe = if execute { "removing" } else { "WOULD remove" }, | ||
)?; | ||
} | ||
if !execute { | ||
writeln!( | ||
out, | ||
"\nWARNING: would removes repositories that are hidden inside of ignored directories" | ||
)?; | ||
} | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters