Skip to content

Commit 37c2852

Browse files
committedJul 25, 2024··
adapt to changes in gix-dir
This includes an improvement on how `gix` initiates a dirwalk with the purpose of deletion so that worktrees are protected should the fall into the parent-repository working directory.
1 parent c9cd2d2 commit 37c2852

File tree

5 files changed

+35
-5
lines changed

5 files changed

+35
-5
lines changed
 

‎gix-status/src/index_as_worktree_with_renames/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub(super) mod function {
4949
objects: Find,
5050
progress: &mut dyn gix_features::progress::Progress,
5151
mut ctx: Context<'_>,
52-
options: Options,
52+
options: Options<'_>,
5353
) -> Result<Outcome, Error>
5454
where
5555
T: Send + Clone,

‎gix-status/src/index_as_worktree_with_renames/types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl<ContentChange, SubmoduleStatus> Entry<'_, ContentChange, SubmoduleStatus> {
274274

275275
/// Options for use in [index_as_worktree_with_renames()](crate::index_as_worktree_with_renames()).
276276
#[derive(Clone, Default)]
277-
pub struct Options {
277+
pub struct Options<'a> {
278278
/// The way all output should be sorted.
279279
///
280280
/// If `None`, and depending on the `rewrites` field, output will be immediate but the output order
@@ -299,7 +299,7 @@ pub struct Options {
299299
///
300300
/// If `None`, the directory walk portion will not run at all, yielding data similar
301301
/// to a bare [index_as_worktree()](crate::index_as_worktree()) call.
302-
pub dirwalk: Option<gix_dir::walk::Options>,
302+
pub dirwalk: Option<gix_dir::walk::Options<'a>>,
303303
/// The configuration for the rewrite tracking. Note that if set, the [`dirwalk`](Self::dirwalk) should be configured
304304
/// to *not* collapse untracked and ignored entries, as rewrite tracking is on a file-by-file basis.
305305
/// Also note that when `Some(_)`, it will collect certain changes depending on the exact configuration, which typically increases

‎gix/src/dirwalk/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ pub enum Error {
5454
Prefix(#[from] gix_path::realpath::Error),
5555
#[error(transparent)]
5656
FilesystemOptions(#[from] config::boolean::Error),
57+
#[error("Could not list worktrees to assure they are no candidates for deletion")]
58+
ListWorktrees(#[from] std::io::Error),
5759
}
5860

5961
/// The outcome of the [dirwalk()](crate::Repository::dirwalk).

‎gix/src/dirwalk/options.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl Options {
2222
}
2323
}
2424

25-
impl From<Options> for gix_dir::walk::Options {
25+
impl From<Options> for gix_dir::walk::Options<'static> {
2626
fn from(v: Options) -> Self {
2727
gix_dir::walk::Options {
2828
precompose_unicode: v.precompose_unicode,
@@ -38,6 +38,7 @@ impl From<Options> for gix_dir::walk::Options {
3838
emit_collapsed: v.emit_collapsed,
3939
symlinks_to_directories_are_ignored_like_directories: v
4040
.symlinks_to_directories_are_ignored_like_directories,
41+
worktree_relative_worktree_dirs: None,
4142
}
4243
}
4344
}

‎gix/src/repository/dirwalk.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ impl Repository {
2020
/// lookup. Note that items will only count as tracked if they have the [`gix_index::entry::Flags::UPTODATE`]
2121
/// flag set.
2222
///
23+
/// Note that dirwalks for the purpose of deletion will be initialized with the worktrees of this repository
24+
/// if they fall into the working directory of this repository as well to mark them as `tracked`. That way
25+
/// it's hard to accidentally flag them for deletion.
26+
/// This is intentionally not the case when deletion is not intended so they look like
27+
/// untracked repositories instead.
28+
///
2329
/// See [`gix_dir::walk::delegate::Collect`] for a delegate that collects all seen entries.
2430
pub fn dirwalk(
2531
&self,
@@ -48,6 +54,27 @@ impl Repository {
4854
crate::path::realpath_opts(self.git_dir(), self.current_dir(), crate::path::realpath::MAX_SYMLINKS)?;
4955
let fs_caps = self.filesystem_options()?;
5056
let accelerate_lookup = fs_caps.ignore_case.then(|| index.prepare_icase_backing());
57+
let mut opts = gix_dir::walk::Options::from(options);
58+
let worktree_relative_worktree_dirs_storage;
59+
if let Some(workdir) = self.work_dir().filter(|_| opts.for_deletion.is_some()) {
60+
let linked_worktrees = self.worktrees()?;
61+
if !linked_worktrees.is_empty() {
62+
let real_workdir = gix_path::realpath_opts(
63+
workdir,
64+
self.options.current_dir_or_empty(),
65+
gix_path::realpath::MAX_SYMLINKS,
66+
)?;
67+
worktree_relative_worktree_dirs_storage = linked_worktrees
68+
.into_iter()
69+
.filter_map(|proxy| proxy.base().ok())
70+
.filter_map(|base| base.strip_prefix(&real_workdir).map(ToOwned::to_owned).ok())
71+
.map(|rela_path| {
72+
gix_path::to_unix_separators_on_windows(gix_path::into_bstr(rela_path)).into_owned()
73+
})
74+
.collect();
75+
opts.worktree_relative_worktree_dirs = Some(&worktree_relative_worktree_dirs_storage);
76+
}
77+
}
5178
let (outcome, traversal_root) = gix_dir::walk(
5279
workdir,
5380
gix_dir::walk::Context {
@@ -71,7 +98,7 @@ impl Repository {
7198
objects: &self.objects,
7299
explicit_traversal_root: (!options.empty_patterns_match_prefix).then_some(workdir),
73100
},
74-
options.into(),
101+
opts,
75102
delegate,
76103
)?;
77104

0 commit comments

Comments
 (0)
Please sign in to comment.