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 25, 2024
1 parent 1a26732 commit 9863d75
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 6 deletions.
40 changes: 34 additions & 6 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 pathspec_matches_result: 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,
pathspec_matches_result,
}: Options,
) -> anyhow::Result<()> {
if format != OutputFormat::Human {
Expand All @@ -56,6 +58,7 @@ pub(crate) mod function {
};

let index = repo.index_or_empty()?;
let pathspec_for_dirwalk = !pathspec_matches_result;
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 pathspec_for_dirwalk {
patterns.clone()
} else {
Vec::new()
},
options,
&mut collect,
)?;

let mut pathspec = pathspec_matches_result
.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 All @@ -114,7 +142,7 @@ pub(crate) mod function {

let keep = match entry.status {
Status::Pruned => {
unreachable!("BUG: assumption that pruned entries have no pathspec match, but probably not")
unreachable!("BUG: we skipped these above")
}
Status::Tracked => {
unreachable!("BUG: tracked aren't emitted")
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,
pathspec_matches_result,
skip_hidden_repositories,
find_untracked_repositories,
}) => prepare_and_run(
Expand All @@ -178,6 +179,7 @@ pub fn main() -> Result<()> {
precious,
directories,
repositories,
pathspec_matches_result,
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,
/// Pathspec patterns are used to match the result of the dirwalk, not 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 pathspec_matches_result: bool,
/// Enter ignored directories to skip repositories contained within.
#[arg(long)]
pub skip_hidden_repositories: Option<FindRepository>,
Expand Down

0 comments on commit 9863d75

Please sign in to comment.