Skip to content

integrate gix-status #1285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 43 additions & 45 deletions gitoxide-core/src/repository/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,44 +103,24 @@ pub(crate) mod function {
continue;
}

pruned_entries += usize::from(entry.pathspec_match.is_none());
if entry.status.is_pruned() || entry.pathspec_match.is_none() {
continue;
}
let mut disk_kind = entry.disk_kind.expect("present if not pruned");
match disk_kind {
Kind::File | Kind::Symlink => {}
Kind::EmptyDirectory | Kind::Directory | Kind::Repository => {
let keep = directories
|| entry
.pathspec_match
.map_or(false, |m| m != gix::dir::entry::PathspecMatch::Always);
if !keep {
skipped_directories += 1;
if debug {
writeln!(err, "DBG: prune '{}' as -d is missing", entry.rela_path).ok();
}
continue;
}
}
};

let keep = entry
let pathspec_includes_entry = entry
.pathspec_match
.map_or(true, |m| m != gix::dir::entry::PathspecMatch::Excluded);
if !keep {
if debug {
writeln!(err, "DBG: prune '{}' as it is excluded by pathspec", entry.rela_path).ok();
}
.map_or(false, |m| m != gix::dir::entry::PathspecMatch::Excluded);
pruned_entries += usize::from(!pathspec_includes_entry);
if !pathspec_includes_entry && debug {
writeln!(err, "DBG: prune '{}' as it is excluded by pathspec", entry.rela_path).ok();
}
if entry.status.is_pruned() || !pathspec_includes_entry {
continue;
}

let mut disk_kind = entry.disk_kind.expect("present if not pruned");
let keep = match entry.status {
Status::DotGit | Status::Pruned | Status::TrackedExcluded => {
unreachable!("Pruned aren't emitted")
unreachable!("BUG: Pruned are skipped already as their pathspec is always None")
}
Status::Tracked => {
unreachable!("tracked aren't emitted")
unreachable!("BUG: tracked aren't emitted")
}
Status::Ignored(gix::ignore::Kind::Expendable) => {
skipped_ignored += usize::from(!ignored);
Expand Down Expand Up @@ -168,18 +148,30 @@ pub(crate) mod function {
disk_kind = gix::dir::entry::Kind::Repository;
}

let is_ignored = matches!(entry.status, gix::dir::entry::Status::Ignored(_));
let display_path = entry.rela_path[prefix_len..].as_bstr();
if (!repositories || is_ignored) && disk_kind == gix::dir::entry::Kind::Repository {
if !is_ignored {
skipped_repositories += 1;
match disk_kind {
Kind::File | Kind::Symlink => {}
Kind::EmptyDirectory | Kind::Directory => {
if !directories {
skipped_directories += 1;
if debug {
writeln!(err, "DBG: prune '{}' as -d is missing", entry.rela_path).ok();
}
continue;
}
}
if debug {
writeln!(err, "DBG: skipped repository at '{display_path}'")?;
Kind::Repository => {
if !repositories {
skipped_repositories += 1;
if debug {
writeln!(err, "DBG: skipped repository at '{}'", entry.rela_path)?;
}
continue;
}
}
continue;
}
};

let is_ignored = matches!(entry.status, gix::dir::entry::Status::Ignored(_));
let display_path = entry.rela_path[prefix_len..].as_bstr();
if disk_kind == gix::dir::entry::Kind::Directory {
saw_ignored_directory |= is_ignored;
saw_untracked_directory |= entry.status == gix::dir::entry::Status::Untracked;
Expand All @@ -194,8 +186,8 @@ pub(crate) mod function {
Cow::Owned(format!(
"({})",
match kind {
gix::ignore::Kind::Precious => "$",
gix::ignore::Kind::Expendable => "",
gix::ignore::Kind::Precious => "💲",
gix::ignore::Kind::Expendable => "🗑️",
}
))
}
Expand All @@ -210,10 +202,16 @@ pub(crate) mod function {
},
},
maybe = if execute { "removing" } else { "WOULD remove" },
suffix = if disk_kind == gix::dir::entry::Kind::Repository {
" repository"
} else {
""
suffix = match disk_kind {
Kind::File | Kind::Symlink | Kind::Directory => {
""
}
Kind::EmptyDirectory => {
" empty"
}
Kind::Repository => {
" repository"
}
},
)?;

Expand Down
2 changes: 1 addition & 1 deletion gitoxide-core/src/repository/index/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ pub(crate) mod function {
buf.push_str(" ➡ ");
}
if a.is_excluded {
buf.push_str(" ");
buf.push_str(" 🗑️");
}
if !a.attributes.is_empty() {
buf.push_str(" (");
Expand Down
32 changes: 15 additions & 17 deletions gix-dir/src/walk/readdir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub(super) fn recursive(
if can_recurse(current_bstr.as_bstr(), info, opts.for_deletion, delegate) {
let (action, subdir_prevent_collapse) =
recursive(false, current, current_bstr, info, ctx, opts, delegate, out, state)?;
prevent_collapse = subdir_prevent_collapse;
prevent_collapse |= subdir_prevent_collapse;
if action != Action::Continue {
break;
}
Expand Down Expand Up @@ -158,6 +158,7 @@ impl Mark {
} else {
dir_info.disk_kind
},
pathspec_match: filter_dir_pathspec(dir_info.pathspec_match),
..dir_info
};
if opts.should_hold(empty_info.status) {
Expand All @@ -174,18 +175,10 @@ impl Mark {
}
} else if *prevent_collapse {
self.emit_all_held(state, opts, out, delegate)
} else if let Some(action) = self.try_collapse(
dir_rela_path,
dir_info,
state,
prevent_collapse,
out,
opts,
ctx,
delegate,
) {
} else if let Some(action) = self.try_collapse(dir_rela_path, dir_info, state, out, opts, ctx, delegate) {
action
} else {
*prevent_collapse = true;
self.emit_all_held(state, opts, out, delegate)
}
}
Expand Down Expand Up @@ -213,7 +206,6 @@ impl Mark {
dir_rela_path: &BStr,
dir_info: classify::Outcome,
state: &mut State,
prevent_collapse: &mut bool,
out: &mut walk::Outcome,
opts: Options,
ctx: &mut Context<'_>,
Expand All @@ -229,7 +221,6 @@ impl Mark {
{
entries += 1;
if kind == Some(entry::Kind::Repository) {
*prevent_collapse = true;
return None;
}
if pathspec_match.map_or(false, |m| {
Expand Down Expand Up @@ -287,12 +278,10 @@ impl Mark {
.filter_map(|e| e.pathspec_match)
.max()
.or_else(|| {
// Only take directory matches for value if they are above the 'guessed' ones.
// Only take directory matches as value if they are above the 'guessed' ones.
// Otherwise we end up with seemingly matched entries in the parent directory which
// affects proper folding.
dir_info
.pathspec_match
.filter(|m| matches!(m, PathspecMatch::WildcardMatch | PathspecMatch::Verbatim))
filter_dir_pathspec(dir_info.pathspec_match)
});
let mut removed_without_emitting = 0;
let mut action = Action::Continue;
Expand All @@ -317,6 +306,15 @@ impl Mark {
}
}

fn filter_dir_pathspec(current: Option<PathspecMatch>) -> Option<PathspecMatch> {
current.filter(|m| {
matches!(
m,
PathspecMatch::Always | PathspecMatch::WildcardMatch | PathspecMatch::Verbatim
)
})
}

impl Options {
fn should_hold(&self, status: entry::Status) -> bool {
if status.is_pruned() {
Expand Down
21 changes: 21 additions & 0 deletions gix-dir/tests/fixtures/many.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ cp -R ignored-dir ignored-dir-with-nested-bare-repository
git init --bare bare
)

cp -R ignored-dir-with-nested-bare-repository ignored-dir-nested-minimal
(cd ignored-dir-nested-minimal
(cd bare
rm -Rf hooks config description
)
(cd dir/subdir/nested-bare
rm -Rf refs hooks config description
)
)

mkdir untracked-hidden-bare
(cd untracked-hidden-bare
mkdir subdir
Expand Down Expand Up @@ -245,6 +255,17 @@ git init expendable-and-precious
git commit -m "init"
)

git init expendable-and-precious-nested-in-ignored-dir
(cd expendable-and-precious-nested-in-ignored-dir
echo 'ignored/' > .gitignore
git add .gitignore && git commit -m "init"
mkdir -p ignored/other
cp -Rv ../expendable-and-precious ignored/d
rm -Rf ignored/d/*-by-filematch ignored/d/some-*
mkdir -p other/ignored && >other/ignored/a
)


mkdir empty-and-untracked-dir
(cd empty-and-untracked-dir
mkdir empty untracked
Expand Down
Loading