Skip to content

Commit

Permalink
Merge branch 'status'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Jun 20, 2024
2 parents 2856434 + acc1331 commit 2f9f0ac
Show file tree
Hide file tree
Showing 28 changed files with 140 additions and 111 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions gitoxide-core/src/repository/attributes/validate_baseline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,13 @@ pub(crate) mod function {
}

fn parse_exclude(line: &str) -> Option<(String, Baseline)> {
let (left, value) = line.split_at(line.find(|c| c == '\t')?);
let (left, value) = line.split_at(line.find('\t')?);
let value = &value[1..];

let location = if left == "::" {
None
} else {
let mut tokens = left.split(|b| b == ':');
let mut tokens = left.split(':');
let source = tokens.next()?;
let line_number: usize = tokens.next()?.parse().ok()?;
let pattern = tokens.next()?;
Expand Down Expand Up @@ -363,8 +363,8 @@ pub(crate) mod function {
"unspecified" => StateRef::Unspecified,
_ => StateRef::from_bytes(info.as_bytes()),
};
path = path.trim_end_matches(|b| b == ':');
let attr = attr.trim_end_matches(|b| b == ':');
path = path.trim_end_matches(':');
let attr = attr.trim_end_matches(':');
let assignment = gix::attrs::AssignmentRef {
name: gix::attrs::NameRef::try_from(attr.as_bytes().as_bstr()).ok()?,
state,
Expand Down
4 changes: 2 additions & 2 deletions gitoxide-core/src/repository/index/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ pub(crate) mod function {

#[cfg(feature = "serde")]
fn to_json(
mut out: &mut impl std::io::Write,
out: &mut impl std::io::Write,
index: &gix::index::File,
entry: &gix::index::Entry,
attrs: Option<Attrs>,
Expand All @@ -338,7 +338,7 @@ pub(crate) mod function {
}

serde_json::to_writer(
&mut out,
&mut *out,
&Entry {
stat: &entry.stat,
hex_id: entry.id.to_hex().to_string(),
Expand Down
2 changes: 1 addition & 1 deletion gix-config/src/file/section/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl<'a> Section<'a> {
/// Stream ourselves to the given `out`, in order to reproduce this section mostly losslessly
/// as it was parsed.
pub fn write_to(&self, mut out: &mut dyn std::io::Write) -> std::io::Result<()> {
self.header.write_to(&mut out)?;
self.header.write_to(&mut *out)?;

if self.body.0.is_empty() {
return Ok(());
Expand Down
5 changes: 3 additions & 2 deletions gix-config/src/file/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl File<'_> {
pub fn write_to_filter(
&self,
mut out: &mut dyn std::io::Write,
mut filter: &mut dyn FnMut(&Section<'_>) -> bool,
filter: &mut dyn FnMut(&Section<'_>) -> bool,
) -> std::io::Result<()> {
let nl = self.detect_newline_style();

Expand All @@ -27,7 +27,8 @@ impl File<'_> {
event.write_to(&mut out)?;
}

if !ends_with_newline(self.frontmatter_events.as_ref(), nl, true) && self.sections.values().any(&mut filter)
if !ends_with_newline(self.frontmatter_events.as_ref(), nl, true)
&& self.sections.values().any(&mut *filter)
{
out.write_all(nl)?;
}
Expand Down
6 changes: 3 additions & 3 deletions gix-config/src/parse/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Event<'_> {

/// Stream ourselves to the given `out`, in order to reproduce this event mostly losslessly
/// as it was parsed.
pub fn write_to(&self, mut out: &mut dyn std::io::Write) -> std::io::Result<()> {
pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
match self {
Self::ValueNotDone(e) => {
out.write_all(e.as_ref())?;
Expand All @@ -42,8 +42,8 @@ impl Event<'_> {
Self::Whitespace(e) | Self::Newline(e) | Self::Value(e) | Self::ValueDone(e) => out.write_all(e.as_ref()),
Self::KeyValueSeparator => out.write_all(b"="),
Self::SectionKey(k) => out.write_all(k.0.as_ref()),
Self::SectionHeader(h) => h.write_to(&mut out),
Self::Comment(c) => c.write_to(&mut out),
Self::SectionHeader(h) => h.write_to(out),
Self::Comment(c) => c.write_to(out),
}
}

Expand Down
30 changes: 15 additions & 15 deletions gix-config/src/parse/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,26 @@ pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>;
///
/// For concrete examples, some notable differences are:
/// - `git-config` sections permit subsections via either a quoted string
/// (`[some-section "subsection"]`) or via the deprecated dot notation
/// (`[some-section.subsection]`). Successful parsing these section names is not
/// well defined in typical `.ini` parsers. This parser will handle these cases
/// perfectly.
/// (`[some-section "subsection"]`) or via the deprecated dot notation
/// (`[some-section.subsection]`). Successful parsing these section names is not
/// well defined in typical `.ini` parsers. This parser will handle these cases
/// perfectly.
/// - Comment markers are not strictly defined either. This parser will always
/// and only handle a semicolon or octothorpe (also known as a hash or number
/// sign).
/// and only handle a semicolon or octothorpe (also known as a hash or number
/// sign).
/// - Global properties may be allowed in `.ini` parsers, but is strictly
/// disallowed by this parser.
/// disallowed by this parser.
/// - Only `\t`, `\n`, `\b` `\\` are valid escape characters.
/// - Quoted and semi-quoted values will be parsed (but quotes will be included
/// in event outputs). An example of a semi-quoted value is `5"hello world"`,
/// which should be interpreted as `5hello world` after
/// [normalization][crate::value::normalize()].
/// in event outputs). An example of a semi-quoted value is `5"hello world"`,
/// which should be interpreted as `5hello world` after
/// [normalization][crate::value::normalize()].
/// - Line continuations via a `\` character is supported (inside or outside of quotes)
/// - Whitespace handling similarly follows the `git-config` specification as
/// closely as possible, where excess whitespace after a non-quoted value are
/// trimmed, and line continuations onto a new line with excess spaces are kept.
/// closely as possible, where excess whitespace after a non-quoted value are
/// trimmed, and line continuations onto a new line with excess spaces are kept.
/// - Only equal signs (optionally padded by spaces) are valid name/value
/// delimiters.
/// delimiters.
///
/// Note that things such as case-sensitivity or duplicate sections are
/// _not_ handled. This parser is a low level _syntactic_ interpreter
Expand All @@ -62,8 +62,8 @@ pub type FrontMatterEvents<'a> = SmallVec<[Event<'a>; 8]>;
/// # Trait Implementations
///
/// - This struct does _not_ implement [`FromStr`] due to lifetime
/// constraints implied on the required `from_str` method. Instead, it provides
/// [`From<&'_ str>`].
/// constraints implied on the required `from_str` method. Instead, it provides
/// [`From<&'_ str>`].
///
/// # Idioms
///
Expand Down
12 changes: 6 additions & 6 deletions gix-fs/src/symlink.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use std::{io, io::ErrorKind::AlreadyExists, path::Path};

#[cfg(not(windows))]
/// Create a new symlink at `link` which points to `original`.
///
/// Note that `original` doesn't have to exist.
#[cfg(not(windows))]
pub fn create(original: &Path, link: &Path) -> io::Result<()> {
std::os::unix::fs::symlink(original, link)
}

#[cfg(not(windows))]
/// Remove a symlink.
///
/// Note that on only on windows this is special.
#[cfg(not(windows))]
pub fn remove(path: &Path) -> io::Result<()> {
std::fs::remove_file(path)
}
Expand All @@ -31,12 +31,12 @@ pub fn remove(path: &Path) -> io::Result<()> {
}
}

#[cfg(windows)]
/// Create a new symlink at `link` which points to `original`.
///
/// Note that if a symlink target (the `original`) isn't present on disk, it's assumed to be a
/// file, creating a dangling file symlink. This is similar to a dangling symlink on Unix,
/// which doesn't have to care about the target type though.
#[cfg(windows)]
pub fn create(original: &Path, link: &Path) -> io::Result<()> {
use std::os::windows::fs::{symlink_dir, symlink_file};
// TODO: figure out if links to links count as files or whatever they point at
Expand All @@ -53,20 +53,20 @@ pub fn create(original: &Path, link: &Path) -> io::Result<()> {
}
}

#[cfg(not(windows))]
/// Return true if `err` indicates that a file collision happened, i.e. a symlink couldn't be created as the `link`
/// already exists as filesystem object.
#[cfg(not(windows))]
pub fn is_collision_error(err: &std::io::Error) -> bool {
// TODO: use ::IsDirectory as well when stabilized instead of raw_os_error(), and ::FileSystemLoop respectively
err.kind() == AlreadyExists
|| err.raw_os_error() == Some(if cfg!(windows) { 5 } else { 21 })
|| err.raw_os_error() == Some(21)
|| err.raw_os_error() == Some(62) // no-follow on symlnk on mac-os
|| err.raw_os_error() == Some(40) // no-follow on symlnk on ubuntu
}

#[cfg(windows)]
/// Return true if `err` indicates that a file collision happened, i.e. a symlink couldn't be created as the `link`
/// already exists as filesystem object.
#[cfg(windows)]
pub fn is_collision_error(err: &std::io::Error) -> bool {
err.kind() == AlreadyExists || err.kind() == std::io::ErrorKind::PermissionDenied
}
2 changes: 1 addition & 1 deletion gix-ignore/src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl Search {
.transpose()?,
);
group.patterns.extend(pattern::List::<Ignore>::from_file(
&git_dir.join("info").join("exclude"),
git_dir.join("info").join("exclude"),
None,
follow_symlinks,
buf,
Expand Down
3 changes: 2 additions & 1 deletion gix-odb/tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ gix-date = { path = "../../gix-date" }
gix-object = { path = "../../gix-object" }
gix-pack = { path = "../../gix-pack" }

gix-testtools = { path = "../../tests/tools"}
gix-testtools = { path = "../../tests/tools" }
gix-actor = { path = "../../gix-actor" }
pretty_assertions = "1.0.0"
filetime = "0.2.15"
maplit = "1.0.2"
crossbeam-channel = "0.5.13"

Binary file not shown.
11 changes: 6 additions & 5 deletions gix-odb/tests/odb/regression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ mod repo_with_small_packs {
}

#[test]
#[cfg(feature = "internal-testing-gix-features-parallel")]
#[cfg(feature = "gix-features-parallel")]
fn multi_threaded_access_will_not_panic() -> crate::Result {
for arg in ["no", "without-multi-index"] {
let base = gix_testtools::scripted_fixture_read_only_with_args("make_repo_multi_index.sh", Some(arg))?
.join(".git")
.join("objects");
let base =
gix_testtools::scripted_fixture_read_only_with_args_standalone("make_repo_multi_index.sh", Some(arg))?
.join(".git")
.join("objects");
let store = gix_odb::at(base)?;
let (tx, barrier) = crossbeam_channel::unbounded::<()>();
let handles = (0..std::thread::available_parallelism()?.get()).map(|tid| {
Expand All @@ -36,7 +37,7 @@ mod repo_with_small_packs {
for id in store.iter()? {
let id = id?;
assert!(
store.try_find(id, &mut buf).is_ok(),
store.try_find(&id, &mut buf).is_ok(),
"Thread {} could not find {}",
tid,
id
Expand Down
58 changes: 32 additions & 26 deletions gix-pack/src/bundle/write/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ impl crate::Bundle {
/// * `progress` provides detailed progress information which can be discarded with [`gix_features::progress::Discard`].
/// * `should_interrupt` is checked regularly and when true, the whole operation will stop.
/// * `thin_pack_base_object_lookup` If set, we expect to see a thin-pack with objects that reference their base object by object id which is
/// expected to exist in the object database the bundle is contained within.
/// `options` further configure how the task is performed.
/// expected to exist in the object database the bundle is contained within.
/// `options` further configure how the task is performed.
///
/// # Note
///
Expand Down Expand Up @@ -300,31 +300,37 @@ impl crate::Bundle {
)?;
drop(pack_entries_iter);

let data_path = directory.join(format!("pack-{}.pack", outcome.data_hash.to_hex()));
let index_path = data_path.with_extension("idx");
let keep_path = data_path.with_extension("keep");
if outcome.num_objects == 0 {
WriteOutcome {
outcome,
data_path: None,
index_path: None,
keep_path: None,
}
} else {
let data_path = directory.join(format!("pack-{}.pack", outcome.data_hash.to_hex()));
let index_path = data_path.with_extension("idx");
let keep_path = data_path.with_extension("keep");

std::fs::write(&keep_path, b"")?;
Arc::try_unwrap(data_file)
.expect("only one handle left after pack was consumed")
.into_inner()
.into_inner()
.map_err(|err| Error::from(err.into_error()))?
.persist(&data_path)?;
index_file
.persist(&index_path)
.map_err(|err| {
progress.info(format!(
"pack file at {} is retained despite failing to move the index file into place. You can use plumbing to make it usable.",
data_path.display()
));
err
})?;
WriteOutcome {
outcome,
data_path: Some(data_path),
index_path: Some(index_path),
keep_path: Some(keep_path),
std::fs::write(&keep_path, b"")?;
Arc::try_unwrap(data_file)
.expect("only one handle left after pack was consumed")
.into_inner()
.into_inner()
.map_err(|err| Error::from(err.into_error()))?
.persist(&data_path)?;
index_file
.persist(&index_path)
.map_err(|err| {
gix_features::trace::warn!("pack file at \"{}\" is retained despite failing to move the index file into place. You can use plumbing to make it usable.",data_path.display());
err
})?;
WriteOutcome {
outcome,
data_path: Some(data_path),
index_path: Some(index_path),
keep_path: Some(keep_path),
}
}
}
None => WriteOutcome {
Expand Down
8 changes: 4 additions & 4 deletions gix-pack/src/cache/delta/from_offsets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ const PACK_HEADER_LEN: usize = 12;
impl<T> Tree<T> {
/// Create a new `Tree` from any data sorted by offset, ascending as returned by the `data_sorted_by_offsets` iterator.
/// * `get_pack_offset(item: &T) -> data::Offset` is a function returning the pack offset of the given item, which can be used
/// for obtaining the objects entry within the pack.
/// for obtaining the objects entry within the pack.
/// * `pack_path` is the path to the pack file itself and from which to read the entry data, which is a pack file matching the offsets
/// returned by `get_pack_offset(…)`.
/// returned by `get_pack_offset(…)`.
/// * `progress` is used to track progress when creating the tree.
/// * `resolve_in_pack_id(gix_hash::oid) -> Option<data::Offset>` takes an object ID and tries to resolve it to an object within this pack if
/// possible. Failing to do so aborts the operation, and this function is not expected to be called in usual packs. It's a theoretical
/// possibility though as old packs might have referred to their objects using the 20 bytes hash, instead of their encoded offset from the base.
/// possible. Failing to do so aborts the operation, and this function is not expected to be called in usual packs. It's a theoretical
/// possibility though as old packs might have referred to their objects using the 20 bytes hash, instead of their encoded offset from the base.
///
/// Note that the sort order is ascending. The given pack file path must match the provided offsets.
pub fn from_offsets_in_pack(
Expand Down
2 changes: 1 addition & 1 deletion gix-pack/src/data/output/entry/iter_from_counts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub(crate) mod function {
///
/// * ~~currently there is no way to easily write the pack index, even though the state here is uniquely positioned to do
/// so with minimal overhead (especially compared to `gix index-from-pack`)~~ Probably works now by chaining Iterators
/// or keeping enough state to write a pack and then generate an index with recorded data.
/// or keeping enough state to write a pack and then generate an index with recorded data.
///
pub fn iter_from_counts<Find>(
mut counts: Vec<output::Count>,
Expand Down
6 changes: 3 additions & 3 deletions gix-pack/src/index/write/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ impl crate::index::File {
///
/// * neither in-pack nor out-of-pack Ref Deltas are supported here, these must have been resolved beforehand.
/// * `make_resolver()` will only be called after the iterator stopped returning elements and produces a function that
/// provides all bytes belonging to a pack entry writing them to the given mutable output `Vec`.
/// It should return `None` if the entry cannot be resolved from the pack that produced the `entries` iterator, causing
/// the write operation to fail.
/// provides all bytes belonging to a pack entry writing them to the given mutable output `Vec`.
/// It should return `None` if the entry cannot be resolved from the pack that produced the `entries` iterator, causing
/// the write operation to fail.
#[allow(clippy::too_many_arguments)]
pub fn write_data_iter_to_stream<F, F2, R>(
version: crate::index::Version,
Expand Down
Loading

0 comments on commit 2f9f0ac

Please sign in to comment.