Skip to content

Commit

Permalink
feat: add gix clean --patterns-for-entries|-m to help with wildcards.
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Feb 24, 2024
1 parent 1a26732 commit 7b8619d
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 5 deletions.
38 changes: 33 additions & 5 deletions gitoxide-core/src/repository/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct Options {
pub precious: bool,
pub directories: bool,
pub repositories: bool,
pub patterns_for_entries: bool,
pub skip_hidden_repositories: Option<FindRepository>,
pub find_untracked_repositories: FindRepository,
}
Expand Down Expand Up @@ -46,6 +47,7 @@ pub(crate) mod function {
repositories,
skip_hidden_repositories,
find_untracked_repositories,
patterns_for_entries,
}: Options,
) -> anyhow::Result<()> {
if format != OutputFormat::Human {
Expand All @@ -56,6 +58,7 @@ pub(crate) mod function {
};

let index = repo.index_or_empty()?;
let patterns_for_dirwalk = !patterns_for_entries;
let has_patterns = !patterns.is_empty();
let mut collect = InterruptableCollect::default();
let collapse_directories = CollapseDirectory;
Expand All @@ -76,9 +79,29 @@ pub(crate) mod function {
.emit_ignored(Some(collapse_directories))
.empty_patterns_match_prefix(true)
.emit_empty_directories(true);
repo.dirwalk(&index, patterns, options, &mut collect)?;
let prefix = repo.prefix()?.unwrap_or(Path::new(""));
repo.dirwalk(
&index,
if patterns_for_dirwalk {
patterns.clone()
} else {
Vec::new()
},
options,
&mut collect,
)?;

let mut pathspec = patterns_for_entries
.then(|| {
repo.pathspec(
true,
patterns,
true,
&index,
gix::worktree::stack::state::attributes::Source::WorktreeThenIdMapping,
)
})
.transpose()?;
let prefix = repo.prefix()?.unwrap_or(Path::new(""));
let entries = collect.inner.into_entries_by_path();
let mut entries_to_clean = 0;
let mut skipped_directories = 0;
Expand All @@ -101,9 +124,14 @@ pub(crate) mod function {
continue;
}

let pathspec_includes_entry = entry
.pathspec_match
.map_or(false, |m| m != gix::dir::entry::PathspecMatch::Excluded);
let pathspec_includes_entry = match pathspec.as_mut() {
None => entry
.pathspec_match
.map_or(false, |m| m != gix::dir::entry::PathspecMatch::Excluded),
Some(pathspec) => pathspec
.pattern_matching_relative_path(entry.rela_path.as_bstr(), entry.disk_kind.map(|k| k.is_dir()))
.map_or(false, |m| !m.is_excluded()),
};
pruned_entries += usize::from(!pathspec_includes_entry);
if !pathspec_includes_entry && debug {
writeln!(err, "DBG: prune '{}'", entry.rela_path).ok();
Expand Down
2 changes: 2 additions & 0 deletions src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ pub fn main() -> Result<()> {
directories,
pathspec,
repositories,
patterns_for_entries,
skip_hidden_repositories,
find_untracked_repositories,
}) => prepare_and_run(
Expand All @@ -178,6 +179,7 @@ pub fn main() -> Result<()> {
precious,
directories,
repositories,
patterns_for_entries,
skip_hidden_repositories: skip_hidden_repositories.map(Into::into),
find_untracked_repositories: find_untracked_repositories.into(),
},
Expand Down
6 changes: 6 additions & 0 deletions src/plumbing/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@ pub mod clean {
/// Remove nested repositories.
#[arg(long, short = 'r')]
pub repositories: bool,
/// Patterns are used to match the result of the dirwalk, not for the dirwalk itself.
///
/// Use this if there is trouble using wildcard pathspecs, which affect the directory walk
/// in reasonable, but often unexpected ways.
#[arg(long, short = 'm')]
pub patterns_for_entries: bool,
/// Enter ignored directories to skip repositories contained within.
#[arg(long)]
pub skip_hidden_repositories: Option<FindRepository>,
Expand Down

0 comments on commit 7b8619d

Please sign in to comment.