Skip to content
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

Various fixes #1374

Merged
merged 51 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f3d5a69
mark safety-related core-flags as planned
Byron May 14, 2024
0d78db2
add validation for path components and tree-names
Byron May 14, 2024
eff4c00
feat: add validation for path components
Byron May 15, 2024
874cfd6
fix!: validate all components pushed onto the stack when creating lea…
Byron May 16, 2024
595fe87
feat!: `Stack::at_path()` replaces `is_dir` parameter with `mode`.
Byron May 17, 2024
9564699
feat: add `From<gix_object::tree::Mode> for gix_index::entry::Mode`.
Byron May 17, 2024
1ca6a3c
adapt to changes in `gix-worktree`
Byron May 17, 2024
886d6b5
feat: checkout respects options for `core.protectHFS` and `core.prote…
Byron May 17, 2024
b6a67d7
doc: make clear that indices can contain invalid or dangerous paths.
Byron May 18, 2024
a67d82d
feat: defend against `CON` device names and more if `gitoxide.core.pr…
Byron May 18, 2024
1076375
thanks clippy
Byron May 19, 2024
7fa0185
Start on demo script making repo with .. trees, deploying above repo
EliahKagan Apr 20, 2024
bf49d73
Hard-code target to fix remaining replacement bugs
EliahKagan Apr 20, 2024
4e3b77d
Add missing executable bit to payloads
EliahKagan Apr 20, 2024
474bf0d
Make the script more robust, and don't require `ex`
EliahKagan Apr 20, 2024
9180dde
Set LC_ALL=C when using sed on a binary file
EliahKagan Apr 21, 2024
0d15e5c
No need to actually create the directories
EliahKagan Apr 23, 2024
845c6bc
Don't bother running `git show --stat`
EliahKagan Apr 23, 2024
0581966
Don't require the filesystem that makes the repo to support +x
EliahKagan Apr 23, 2024
a59c05a
Stage and set mode in one step instead of two
EliahKagan Apr 23, 2024
49eb14c
Start on demo script making repo with NTFS stream
EliahKagan Apr 28, 2024
7041e73
Use .git::$INDEX_ALLOCATION instead of .git:$I30
EliahKagan May 1, 2024
7daca49
Start on demo script making repo with .git/… filename
EliahKagan May 1, 2024
981cf5b
Show the new commit, once made and on the branch
EliahKagan May 1, 2024
9436f3f
Split into commented sections
EliahKagan May 1, 2024
89ee180
Reword to be more portable and self-documenting
EliahKagan May 1, 2024
6846c90
Pass --literally to hash-object when making tree
EliahKagan May 1, 2024
4c684ca
Start on demo script making repo with ../… filename
EliahKagan May 1, 2024
bad9a79
Apply suggestions from code review
Byron May 20, 2024
fcc3b69
address review comments
Byron May 19, 2024
ccbc119
Apply suggestions from code review
Byron May 21, 2024
fe8c2c9
Adjust make_traverse_dotdot_slashes.sh for environment
EliahKagan May 21, 2024
7e9c769
Combine "slashes" scripts and make it a fixture
EliahKagan May 21, 2024
6f44aca
Combine non-"slashes" (i.e. trees) scripts and make it a fixture
EliahKagan May 21, 2024
f3edaa3
Make more test repos with traversal-attempting blob names
EliahKagan May 21, 2024
4791e31
further testing of `.git` path variants
Byron May 21, 2024
00a1c47
better detection of pre-requisites for symlink test (#1373)
Byron May 21, 2024
bec648d
fix: multi-process safe parallel filesystem capabilities probing (#1373)
Byron May 21, 2024
a6710c5
add tests for actual worktree checkouts to assure validations kick in
Byron May 21, 2024
f961687
fix compile warnings
Byron May 21, 2024
2683235
fix: assure high-speed SHA1 assembly is only used in not on Windows (…
Byron May 21, 2024
2ea87f0
fix!: `State::from_tree()` now performs name validation.
Byron May 21, 2024
5f86e6b
adapt to changes in `gix-index`
Byron May 21, 2024
f1f0ba5
feat: add `path::component_is_windows_device()`
Byron May 21, 2024
9555efe
fix!: assure that special device names on Windows aren't allowed.
Byron May 21, 2024
d2ae9d5
adapt to changes in `gix-ref`
Byron May 21, 2024
1242151
Apply suggestions from code review
Byron May 22, 2024
79dce79
Merge pull request from GHSA-7w47-3wg8-547c
Byron May 22, 2024
6f55f2a
fix-CI
Byron May 22, 2024
cd4de83
update dependencies
Byron May 22, 2024
e955770
fix: symlink support for `zip` archives
Byron May 22, 2024
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
213 changes: 153 additions & 60 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 6 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,22 @@ max = ["max-control", "fast", "gitoxide-core-blocking-client", "http-client-curl
## transports as it uses Rust's HTTP implementation.
##
## As fast as possible, with TUI progress, progress line rendering with auto-configuration, all transports available but less mature pure Rust HTTP implementation, all `ein` tools, CLI colors and local-time support, JSON output, regex support for rev-specs.
max-pure = ["max-control", "gix-features/rustsha1", "gix-features/zlib-rust-backend", "http-client-reqwest", "gitoxide-core-blocking-client" ]
max-pure = ["max-control", "gix-features/rustsha1", "gix-features/zlib-rust-backend", "http-client-reqwest", "gitoxide-core-blocking-client"]

## Like `max`, but with more control for configuration. See the *Package Maintainers* headline for more information.
max-control = ["tracing", "fast-safe", "pretty-cli", "gitoxide-core-tools-query", "gitoxide-core-tools-corpus", "gitoxide-core-tools", "prodash-render-line", "prodash-render-tui", "prodash/render-line-autoconfigure", "gix/revparse-regex" ]
max-control = ["tracing", "fast-safe", "pretty-cli", "gitoxide-core-tools-query", "gitoxide-core-tools-corpus", "gitoxide-core-tools", "prodash-render-line", "prodash-render-tui", "prodash/render-line-autoconfigure", "gix/revparse-regex"]

## All of the good stuff, with less fanciness for smaller binaries.
##
## As fast as possible, progress line rendering, all transports based on their most mature implementation (HTTP), all `ein` tools, CLI colors and local-time support, JSON output.
lean = ["fast", "tracing", "pretty-cli", "http-client-curl", "gitoxide-core-tools-query", "gitoxide-core-tools-corpus", "gitoxide-core-tools", "gitoxide-core-blocking-client", "prodash-render-line" ]
lean = ["fast", "tracing", "pretty-cli", "http-client-curl", "gitoxide-core-tools-query", "gitoxide-core-tools-corpus", "gitoxide-core-tools", "gitoxide-core-blocking-client", "prodash-render-line"]

## The smallest possible build, best suitable for small single-core machines.
##
## This build is essentially limited to local operations without any fanciness.
##
## Optimized for size, no parallelism thus much slower, progress line rendering.
small = ["pretty-cli", "gix-features/rustsha1", "gix-features/zlib-rust-backend", "prodash-render-line", "is-terminal" ]
small = ["pretty-cli", "gix-features/rustsha1", "gix-features/zlib-rust-backend", "prodash-render-line", "is-terminal"]

## Like lean, but uses Rusts async implementations for networking.
##
Expand Down Expand Up @@ -107,12 +107,12 @@ fast = ["gix/max-performance", "gix/comfort"]
fast-safe = ["gix/max-performance-safe", "gix/comfort"]

## Enable tracing in `gitoxide-core`.
tracing = ["dep:tracing-forest", "dep:tracing-subscriber", "dep:tracing", "gix-features/tracing", "gix-features/tracing-detail" ]
tracing = ["dep:tracing-forest", "dep:tracing-subscriber", "dep:tracing", "gix-features/tracing", "gix-features/tracing-detail"]

## Use `clap` 3.0 to build the prettiest, best documented and most user-friendly CLI at the expense of binary size.
## Provides a terminal user interface for detailed and exhaustive progress.
## Provides a line renderer for leaner progress display, without the need for a full-blown TUI.
pretty-cli = [ "gitoxide-core/serde", "prodash/progress-tree", "prodash/progress-tree-log", "prodash/local-time", "env_logger/humantime", "env_logger/color", "env_logger/auto-color" ]
pretty-cli = ["gitoxide-core/serde", "prodash/progress-tree", "prodash/progress-tree-log", "prodash/local-time", "env_logger/humantime", "env_logger/color", "env_logger/auto-color"]

## The `--verbose` flag will be powered by an interactive progress mechanism that doubles as log as well as interactive progress
## that appears after a short duration.
Expand Down Expand Up @@ -285,9 +285,7 @@ members = [
"gix-worktree-stream",
"gix-revwalk",
"gix-fsck",

"tests/tools",

"gix-diff/tests",
"gix-pack/tests",
"gix-odb/tests",
Expand Down
24 changes: 1 addition & 23 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,6 @@
# More documentation for the advisories section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html
[advisories]
# The path where the advisory database is cloned/fetched into
db-path = "~/.cargo/advisory-db"
# The url(s) of the advisory databases to use
db-urls = ["https:/rustsec/advisory-db"]
# The lint level for security vulnerabilities
vulnerability = "deny"
# The lint level for unmaintained crates
unmaintained = "warn"
# The lint level for crates that have been yanked from their source registry
yanked = "warn"
# The lint level for crates with security notices. Note that as of
# 2019-12-17 there are no security notice advisories in
# https:/rustsec/advisory-db
notice = "warn"
ignore = [
# this is `[email protected]` coming in with `curl`, which doesn't have an update yet. It's only active optionally, not by default.
"RUSTSEC-2024-0336",
Expand All @@ -33,28 +19,20 @@ ignore = [
# More documentation for the licenses section can be found here:
# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html
[licenses]
# The lint level for crates which do not have a detectable license
unlicensed = "deny"
# List of explicitly allowed licenses
# See https://spdx.org/licenses/ for list of possible licenses
# [possible values: any SPDX 3.11 short identifier (+ optional exception)].
allow = [
"Apache-2.0",
"BSD-3-Clause",
"BSL-1.0",
"MIT",
"MIT-0",
"ISC",
"Unicode-DFS-2016",
"LicenseRef-ring",
"Zlib"
]
# Lint level for licenses considered copyleft
copyleft = "allow"
# Lint level used when no other predicates are matched
# 1. License isn't in the allow or deny lists
# 2. License isn't copyleft
# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither"
default = "deny"
# The confidence threshold for detecting a license from license text.
# The higher the value, the more closely the license text must be to the
# canonical license text of a valid SPDX license file.
Expand Down
4 changes: 2 additions & 2 deletions gitoxide-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ estimate-hours = ["dep:fs-err", "dep:crossbeam-channel", "dep:smallvec"]
query = ["dep:rusqlite"]
## Run algorithms on a corpus of repositories and store their results for later comparison and intelligence gathering.
## *Note that* `organize` we need for finding git repositories fast.
corpus = [ "dep:rusqlite", "dep:sysinfo", "organize", "dep:crossbeam-channel", "dep:serde_json", "dep:tracing-forest", "dep:tracing-subscriber", "tracing", "dep:parking_lot" ]
corpus = ["dep:rusqlite", "dep:sysinfo", "organize", "dep:crossbeam-channel", "dep:serde_json", "dep:tracing-forest", "dep:tracing-subscriber", "tracing", "dep:parking_lot"]

## The ability to create archives from virtual worktrees, similar to `git archive`.
archive = ["dep:gix-archive-for-configuration-only", "gix/worktree-archive"]
Expand Down Expand Up @@ -77,7 +77,7 @@ crossbeam-channel = { version = "0.5.6", optional = true }
smallvec = { version = "1.10.0", optional = true }

# for 'query' and 'corpus'
rusqlite = { version = "0.30.0", optional = true, features = ["bundled"] }
rusqlite = { version = "0.31.0", optional = true, features = ["bundled"] }

# for 'corpus'
parking_lot = { version = "0.12.1", optional = true }
Expand Down
8 changes: 8 additions & 0 deletions gitoxide-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,11 @@ pub use discover::discover;

#[cfg(all(feature = "async-client", feature = "blocking-client"))]
compile_error!("Cannot set both 'blocking-client' and 'async-client' features as they are mutually exclusive");

fn is_dir_to_mode(is_dir: bool) -> gix::index::entry::Mode {
if is_dir {
gix::index::entry::Mode::DIR
} else {
gix::index::entry::Mode::FILE
}
}
15 changes: 8 additions & 7 deletions gitoxide-core/src/repository/attributes/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub(crate) mod function {
use gix::bstr::BStr;

use crate::{
is_dir_to_mode,
repository::{
attributes::query::{attributes_cache, Options},
PathsOrPatterns,
Expand All @@ -38,12 +39,12 @@ pub(crate) mod function {
match input {
PathsOrPatterns::Paths(paths) => {
for path in paths {
let is_dir = gix::path::from_bstr(Cow::Borrowed(path.as_ref()))
let mode = gix::path::from_bstr(Cow::Borrowed(path.as_ref()))
.metadata()
.ok()
.map(|m| m.is_dir());
.map(|m| is_dir_to_mode(m.is_dir()));

let entry = cache.at_entry(path.as_slice(), is_dir)?;
let entry = cache.at_entry(path.as_slice(), mode)?;
if !entry.matching_attributes(&mut matches) {
continue;
}
Expand All @@ -61,9 +62,9 @@ pub(crate) mod function {
)?;
let mut pathspec_matched_entry = false;
if let Some(it) = pathspec.index_entries_with_paths(&index) {
for (path, _entry) in it {
for (path, entry) in it {
pathspec_matched_entry = true;
let entry = cache.at_entry(path, Some(false))?;
let entry = cache.at_entry(path, entry.mode.into())?;
if !entry.matching_attributes(&mut matches) {
continue;
}
Expand All @@ -87,10 +88,10 @@ pub(crate) mod function {
let path = pattern.path();
let entry = cache.at_entry(
path,
Some(
Some(is_dir_to_mode(
workdir.map_or(false, |wd| wd.join(gix::path::from_bstr(path)).is_dir())
|| pattern.signature.contains(gix::pathspec::MagicSignature::MUST_BE_DIR),
),
)),
)?;
if !entry.matching_attributes(&mut matches) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ pub(crate) mod function {
);

for (rela_path, baseline) in rx_base {
let entry = cache.at_entry(rela_path.as_str(), Some(false))?;
let entry = cache.at_entry(rela_path.as_str(), None)?;
match baseline {
Baseline::Attribute { assignments: expected } => {
entry.matching_attributes(&mut matches);
Expand Down
16 changes: 8 additions & 8 deletions gitoxide-core/src/repository/exclude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{borrow::Cow, io};
use anyhow::bail;
use gix::bstr::BStr;

use crate::{repository::PathsOrPatterns, OutputFormat};
use crate::{is_dir_to_mode, repository::PathsOrPatterns, OutputFormat};

pub mod query {
use std::ffi::OsString;
Expand Down Expand Up @@ -44,11 +44,11 @@ pub fn query(
match input {
PathsOrPatterns::Paths(paths) => {
for path in paths {
let is_dir = gix::path::from_bstr(Cow::Borrowed(path.as_ref()))
let mode = gix::path::from_bstr(Cow::Borrowed(path.as_ref()))
.metadata()
.ok()
.map(|m| m.is_dir());
let entry = cache.at_entry(path.as_slice(), is_dir)?;
.map(|m| is_dir_to_mode(m.is_dir()));
let entry = cache.at_entry(path.as_slice(), mode)?;
let match_ = entry
.matching_exclude_pattern()
.and_then(|m| (show_ignore_patterns || !m.pattern.is_negative()).then_some(m));
Expand All @@ -66,9 +66,9 @@ pub fn query(
)?;

if let Some(it) = pathspec.index_entries_with_paths(&index) {
for (path, _entry) in it {
for (path, entry) in it {
pathspec_matched_something = true;
let entry = cache.at_entry(path, Some(false))?;
let entry = cache.at_entry(path, entry.mode.into())?;
let match_ = entry
.matching_exclude_pattern()
.and_then(|m| (show_ignore_patterns || !m.pattern.is_negative()).then_some(m));
Expand All @@ -92,10 +92,10 @@ pub fn query(
let path = pattern.path();
let entry = cache.at_entry(
path,
Some(
Some(is_dir_to_mode(
workdir.map_or(false, |wd| wd.join(gix::path::from_bstr(path)).is_dir())
|| pattern.signature.contains(gix::pathspec::MagicSignature::MUST_BE_DIR),
),
)),
)?;
let match_ = entry
.matching_exclude_pattern()
Expand Down
3 changes: 2 additions & 1 deletion gitoxide-core/src/repository/index/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub(crate) mod function {
};

use crate::{
is_dir_to_mode,
repository::index::entries::{Attributes, Options},
OutputFormat,
};
Expand Down Expand Up @@ -174,7 +175,7 @@ pub(crate) mod function {
}
// The user doesn't want attributes, so we set the cache position on demand only
None => cache
.at_entry(rela_path, Some(is_dir))
.at_entry(rela_path, Some(is_dir_to_mode(is_dir)))
.ok()
.map(|platform| platform.matching_attributes(out))
.unwrap_or_default(),
Expand Down
3 changes: 1 addition & 2 deletions gitoxide-core/src/repository/revision/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,10 @@ pub(crate) mod function {
}
gix::object::Kind::Blob if cache.is_some() && spec.path_and_mode().is_some() => {
let (path, mode) = spec.path_and_mode().expect("is present");
let is_dir = Some(mode.is_tree());
match cache.expect("is some") {
(BlobFormat::Git, _) => unreachable!("no need for a cache when querying object db"),
(BlobFormat::Worktree, cache) => {
let platform = cache.attr_stack.at_entry(path, is_dir, &repo.objects)?;
let platform = cache.attr_stack.at_entry(path, Some(mode.into()), &repo.objects)?;
let object = id.object()?;
let mut converted = cache.filter.worktree_filter.convert_to_worktree(
&object.data,
Expand Down
16 changes: 8 additions & 8 deletions gix-archive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ gix-path = { version = "^0.10.7", path = "../gix-path", optional = true }
gix-date = { version = "^0.8.6", path = "../gix-date" }

flate2 = { version = "1.0.26", optional = true }
zip = { version = "0.6.6", optional = true, default-features = false, features = ["deflate", "time"] }
zip = { version = "1.3.1", optional = true, default-features = false, features = ["deflate", "time"] }
time = { version = "0.3.23", optional = true, default-features = false, features = ["std"] }

thiserror = "1.0.26"
Expand All @@ -42,13 +42,13 @@ tar = { version = "0.4.38", optional = true }
document-features = { version = "0.2.0", optional = true }

[dev-dependencies]
gix-testtools = { path = "../tests/tools"}
gix-odb = { path = "../gix-odb"}
gix-worktree = { path = "../gix-worktree", default-features = false, features = ["attributes"]}
gix-hash = { path = "../gix-hash"}
gix-attributes = { path = "../gix-attributes"}
gix-object = { path = "../gix-object"}
gix-filter = { path = "../gix-filter"}
gix-testtools = { path = "../tests/tools" }
gix-odb = { path = "../gix-odb" }
gix-worktree = { path = "../gix-worktree", default-features = false, features = ["attributes"] }
gix-hash = { path = "../gix-hash" }
gix-attributes = { path = "../gix-attributes" }
gix-object = { path = "../gix-object" }
gix-filter = { path = "../gix-filter" }

[package.metadata.docs.rs]
all-features = true
Expand Down
6 changes: 3 additions & 3 deletions gix-archive/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ where
NextFn: FnMut(&mut Stream) -> Result<Option<Entry<'_>>, gix_worktree_stream::entry::Error>,
{
let compression_level = match opts.format {
Format::Zip { compression_level } => compression_level.map(|lvl| lvl as i32),
Format::Zip { compression_level } => compression_level.map(|lvl| lvl as i64),
_other => return write_stream(stream, next_entry, out, opts),
};

Expand Down Expand Up @@ -161,10 +161,10 @@ fn append_zip_entry<W: std::io::Write + std::io::Seek>(
mut entry: gix_worktree_stream::Entry<'_>,
buf: &mut Vec<u8>,
mtime: zip::DateTime,
compression_level: Option<i32>,
compression_level: Option<i64>,
tree_prefix: Option<&bstr::BString>,
) -> Result<(), Error> {
let file_opts = zip::write::FileOptions::default()
let file_opts = zip::write::FileOptions::<'_, ()>::default()
.compression_method(zip::CompressionMethod::Deflated)
.compression_level(compression_level)
.large_file(entry.bytes_remaining().map_or(true, |len| len > u32::MAX as usize))
Expand Down
8 changes: 6 additions & 2 deletions gix-archive/tests/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,11 @@ mod from_tree {
);
let mut link = ar.by_name("prefix/symlink-to-a")?;
assert!(!link.is_dir());
assert!(link.is_file(), "no symlink differentiation");
assert_eq!(
link.is_symlink(),
cfg!(not(windows)),
"symlinks are supported as well, but only on Unix"
);
assert_eq!(
link.unix_mode(),
Some(if cfg!(windows) { 0o100644 } else { 0o120644 }),
Expand All @@ -233,7 +237,7 @@ mod from_tree {
noop_pipeline(),
move |rela_path, mode, attrs| {
cache
.at_entry(rela_path, mode.is_tree().into(), &odb)
.at_entry(rela_path, Some(mode.into()), &odb)
.map(|entry| entry.matching_attributes(attrs))
.map(|_| ())
},
Expand Down
6 changes: 3 additions & 3 deletions gix-config/tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ name = "mem"
path = "mem.rs"

[dev-dependencies]
gix-config = { path = ".."}
gix-testtools = { path = "../../tests/tools"}
gix-config = { path = ".." }
gix-testtools = { path = "../../tests/tools" }
gix = { path = "../../gix", default-features = false }
gix-ref = { path = "../../gix-ref" }
gix-path = { path = "../../gix-path" }
gix-sec = { path = "../../gix-sec" }
serial_test = { version = "2.0.0", default-features = false }
serial_test = { version = "3.1.0", default-features = false }
bstr = { version = "1.3.0", default-features = false, features = ["std"] }

bytesize = "1.3.0"
Expand Down
16 changes: 8 additions & 8 deletions gix-diff/src/blob/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,14 +583,14 @@ impl Platform {
if self.diff_cache.contains_key(storage) {
return Ok(());
}
let entry = self
.attr_stack
.at_entry(rela_path, Some(false), objects)
.map_err(|err| set_resource::Error::Attributes {
source: err,
kind,
rela_path: rela_path.to_owned(),
})?;
let entry =
self.attr_stack
.at_entry(rela_path, None, objects)
.map_err(|err| set_resource::Error::Attributes {
source: err,
kind,
rela_path: rela_path.to_owned(),
})?;
let mut buf = Vec::new();
let out = self.filter.convert_to_diffable(
&id,
Expand Down
Loading
Loading