Skip to content

Commit

Permalink
Merge branch 'main' into new-http-impl
Browse files Browse the repository at this point in the history
 Conflicts:
	Cargo.lock
	git-transport/src/client/blocking_io/http/mod.rs
  • Loading branch information
Byron committed Oct 8, 2022
2 parents 0b0ba03 + cca2ad5 commit 702a161
Show file tree
Hide file tree
Showing 150 changed files with 4,258 additions and 1,683 deletions.
35 changes: 35 additions & 0 deletions Cargo.lock

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

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ env_logger = { version = "0.9.0", default-features = false }
crosstermion = { version = "0.10.1", optional = true, default-features = false }
futures-lite = { version = "1.12.0", optional = true, default-features = false, features = ["std"] }

# for progress
owo-colors = "3.5.0"
tabled = { version = "0.8.0", default-features = false }

document-features = { version = "0.2.0", optional = true }

[profile.dev.package]
Expand Down
15 changes: 15 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@
* We `thiserror` generally.
* Adhere to the [stability guide](https://github.com/Byron/gitoxide/blob/main/STABILITY.md)

## Configuration and overrides

As a general rule, respect and implement all applicable [git-config](https://git-scm.com/docs/git-config) by default, but allow the
caller to set overrides. How overrides work depends on the goals of the particular API so it can be done on the main call path,
forcing a choice, or more typically, as a side-lane where overrides can be done on demand.

Note that it should be possible to obtain the current configuration for modification by the user for selective overrides, either
by calling methods or by obtaining a data structure that can be set as a whole using a `get -> modify -> set` cycle.

Note that without any of that, one should document that with `config_snapshot_mut()` any of the relevant configuration can be
changed in memory before invoking a method in order to affect it.

Parameters which are not available in git or specific to `gitoxide` or the needs of the caller can be passed as parameters or via
`Options` or `Context` structures as needed.

## General

* **async**
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ Please see _'Development Status'_ for a listing of all crates and their capabili
* Based on the [git-hours] algorithm.
* See the [discussion][git-hours-discussion] for some performance data.
* **the `gix` program** _(plumbing)_ - lower level commands for use in automation
* **progress** - provide an overview of what works and what doesn't from the perspective of the git configuration.
This is likely to change a lot over time depending on actual needs, but maybe useful for you to see
if particular git-configuration is picked up and where it deviates.
* **config** - list the complete git configuration in human-readable form and optionally filter sections by name.
* **exclude**
* [x] **query** - check if path specs are excluded via gits exclusion rules like `.gitignore`.
Expand All @@ -49,6 +52,7 @@ Please see _'Development Status'_ for a listing of all crates and their capabili
* **remote**
* [x] **refs** - list all references available on the remote based on the current remote configuration.
* [x] **ref-map** - show how remote references relate to their local tracking branches as mapped by refspecs.
* **fetch** - fetch the current remote or the given one, optionally just as dry-run.
* **credential**
* [x] **fill/approve/reject** - The same as `git credential`, but implemented in Rust, calling helpers only when from trusted configuration.
* **free** - no git repository necessary
Expand Down
4 changes: 2 additions & 2 deletions etc/check-package-size.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ echo "in root: gitoxide CLI"
(enter git-chunk && indent cargo diet -n --package-size-limit 10KB)
(enter git-rebase && indent cargo diet -n --package-size-limit 5KB)
(enter git-sequencer && indent cargo diet -n --package-size-limit 5KB)
(enter git-features && indent cargo diet -n --package-size-limit 50KB)
(enter git-features && indent cargo diet -n --package-size-limit 55KB)
(enter git-ref && indent cargo diet -n --package-size-limit 50KB)
(enter git-diff && indent cargo diet -n --package-size-limit 10KB)
(enter git-traverse && indent cargo diet -n --package-size-limit 10KB)
Expand All @@ -57,6 +57,6 @@ echo "in root: gitoxide CLI"
(enter git-odb && indent cargo diet -n --package-size-limit 120KB)
(enter git-protocol && indent cargo diet -n --package-size-limit 50KB)
(enter git-packetline && indent cargo diet -n --package-size-limit 35KB)
(enter git-repository && indent cargo diet -n --package-size-limit 175KB)
(enter git-repository && indent cargo diet -n --package-size-limit 185KB)
(enter git-transport && indent cargo diet -n --package-size-limit 55KB)
(enter gitoxide-core && indent cargo diet -n --package-size-limit 90KB)
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ value = branch-override-by-include
deref: false,
}),
git_repository::lock::acquire::Fail::Immediately,
git_repository::lock::acquire::Fail::Immediately,
)?
.commit(repo.committer_or_default())?;

Expand Down
3 changes: 1 addition & 2 deletions git-diff/src/lines.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use git_object::bstr::BStr;
use similar::TextDiff;

/// The crate powering file diffs.
pub use similar;
pub use similar::Algorithm;
use similar::TextDiff;

/// Provide an iterator over the changes needed to turn `old` into `new` with `algorithm`.
///
Expand Down
33 changes: 26 additions & 7 deletions git-discover/tests/upwards/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,32 @@ fn from_dir_with_dot_dot() -> crate::Result {
let working_dir = repo_path()?;
let dir = working_dir.join("some/very/deeply/nested/subdir/../../../../../..");
let (path, trust) = git_discover::upwards(&dir)?;
assert_eq!(path.kind(), Kind::WorkTree { linked_git_dir: None });
assert_eq!(
path.as_ref(),
std::path::Path::new(".."),
"there is only the minimal amount of relative path components to see this worktree"
);
assert_ne!(
path.as_ref().canonicalize()?,
working_dir.canonicalize()?,
"a relative path that climbs above the test repo should yield the gitoxide repo"
"a relative path that climbs above the test repo should yield the parent-gitoxide repo"
);
// If the parent repo is actually a main worktree, we can make more assertions. If it is not,
// it will use an absolute paths and we have to bail.
if path.as_ref() == std::path::Path::new("..") {
assert_eq!(path.kind(), Kind::WorkTree { linked_git_dir: None });
assert_eq!(
path.as_ref(),
std::path::Path::new(".."),
"there is only the minimal amount of relative path components to see this worktree"
);
} else {
assert!(
path.as_ref().is_absolute(),
"worktree paths are absolute and the parent repo is one"
);
assert!(matches!(
path.kind(),
Kind::WorkTree {
linked_git_dir: Some(_)
}
));
}
assert_eq!(trust, expected_trust());
Ok(())
}
Expand Down Expand Up @@ -182,6 +197,10 @@ fn cross_fs() -> crate::Result {
use std::{os::unix::fs::symlink, process::Command};

use git_discover::upwards::Options;
if git_testtools::is_ci::cached() {
// Don't run on CI as it's too slow there, resource busy, it fails more often than it succeeds by now.
return Ok(());
}

let top_level_repo = git_testtools::scripted_fixture_repo_writable("make_basic_repo.sh")?;

Expand Down
46 changes: 34 additions & 12 deletions git-features/src/parallel/in_parallel.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};

use crate::parallel::{num_threads, Reduce};

Expand Down Expand Up @@ -89,23 +89,25 @@ where
/// for file-io as it won't make use of sorted inputs well.
/// Note that `periodic` is not guaranteed to be called in case other threads come up first and finish too fast.
// TODO: better docs
pub fn in_parallel_with_slice<I, S, E>(
input: &[I],
pub fn in_parallel_with_slice<I, S, R, E>(
input: &mut [I],
thread_limit: Option<usize>,
new_thread_state: impl FnMut(usize) -> S + Send + Clone,
consume: impl FnMut(&I, &mut S) -> Result<(), E> + Send + Clone,
consume: impl FnMut(&mut I, &mut S) -> Result<(), E> + Send + Clone,
mut periodic: impl FnMut() -> Option<std::time::Duration> + Send,
) -> Result<Vec<S>, E>
state_to_rval: impl FnOnce(S) -> R + Send + Clone,
) -> Result<Vec<R>, E>
where
I: Send + Sync,
E: Send + Sync,
S: Send,
I: Send,
E: Send,
R: Send,
{
let num_threads = num_threads(thread_limit);
let num_items = input.len();
let mut results = Vec::with_capacity(num_threads);
let stop_everything = &AtomicBool::default();
let index = &AtomicUsize::default();

// TODO: use std::thread::scope() once Rust 1.63 is available.
crossbeam_utils::thread::scope({
move |s| {
s.spawn({
Expand All @@ -124,24 +126,44 @@ where
}
});

let input_len = input.len();
struct Input<I>(*mut [I])
where
I: Send;

// SAFETY: I is Send + Sync, so is a *mut [I]
#[allow(unsafe_code)]
unsafe impl<I> Send for Input<I> where I: Send {}

let threads: Vec<_> = (0..num_threads)
.map(|thread_id| {
s.spawn({
let mut new_thread_state = new_thread_state.clone();
let state_to_rval = state_to_rval.clone();
let mut consume = consume.clone();
let input = Input(input as *mut [I]);
move |_| {
let mut state = new_thread_state(thread_id);
for input_index in (thread_id..num_items).step_by(num_threads) {
while let Ok(input_index) = index
.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| (x < input_len).then(|| x + 1))
{
if stop_everything.load(Ordering::Relaxed) {
break;
}
let item = &input[input_index];
// SAFETY: our atomic counter for `input_index` is only ever incremented, yielding
// each item exactly once.
let item = {
#[allow(unsafe_code)]
unsafe {
&mut (&mut *input.0)[input_index]
}
};
if let Err(err) = consume(item, &mut state) {
stop_everything.store(true, Ordering::Relaxed);
return Err(err);
}
}
Ok(state)
Ok(state_to_rval(state))
}
})
})
Expand Down
20 changes: 8 additions & 12 deletions git-features/src/parallel/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,26 +60,22 @@ mod not_parallel {
/// This is only good for operations where near-random access isn't detrimental, so it's not usually great
/// for file-io as it won't make use of sorted inputs well.
// TODO: better docs
pub fn in_parallel_with_slice<I, S, E>(
input: &[I],
pub fn in_parallel_with_slice<I, S, R, E>(
input: &mut [I],
_thread_limit: Option<usize>,
mut new_thread_state: impl FnMut(usize) -> S + Send + Clone,
mut consume: impl FnMut(&I, &mut S) -> Result<(), E> + Send + Clone,
mut periodic: impl FnMut() -> Option<std::time::Duration> + Send,
) -> Result<Vec<S>, E>
where
I: Send + Sync,
S: Send,
E: Send,
{
mut new_thread_state: impl FnMut(usize) -> S + Clone,
mut consume: impl FnMut(&mut I, &mut S) -> Result<(), E> + Clone,
mut periodic: impl FnMut() -> Option<std::time::Duration>,
state_to_rval: impl FnOnce(S) -> R + Clone,
) -> Result<Vec<R>, E> {
let mut state = new_thread_state(0);
for item in input {
consume(item, &mut state)?;
if periodic().is_none() {
break;
}
}
Ok(vec![state])
Ok(vec![state_to_rval(state)])
}
}

Expand Down
2 changes: 1 addition & 1 deletion git-features/src/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io;

pub use prodash::{
messages::MessageLevel,
progress::{Discard, DoOrDiscard, Either, ThroughputOnDrop},
progress::{Discard, DoOrDiscard, Either, Step, StepShared, ThroughputOnDrop},
unit, Progress, Unit,
};

Expand Down
13 changes: 7 additions & 6 deletions git-features/tests/parallel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,23 @@ fn in_parallel() {
#[test]
fn in_parallel_with_mut_slice_in_chunks() {
let num_items = 33;
let input: Vec<_> = std::iter::repeat(1).take(num_items).collect();
let mut input: Vec<_> = std::iter::repeat(1).take(num_items).collect();
let counts = parallel::in_parallel_with_slice(
&input,
&mut input,
None,
|_| 0usize,
|item, acc| {
*acc += *item;
*item += 1;
Ok::<_, ()>(())
},
|| Some(std::time::Duration::from_millis(10)),
std::convert::identity,
)
.unwrap();
assert_eq!(
counts.iter().sum::<usize>(),
std::iter::repeat(1).take(num_items).sum::<usize>()
);
let expected = std::iter::repeat(1).take(num_items).sum::<usize>();
assert_eq!(counts.iter().sum::<usize>(), expected);
assert_eq!(input.iter().sum::<usize>(), expected * 2, "we increment each entry");
}

#[test]
Expand Down
3 changes: 2 additions & 1 deletion git-mailmap/src/snapshot/entry.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::snapshot::util::{EncodedString, EncodedStringRef};
use bstr::BString;

use crate::snapshot::util::{EncodedString, EncodedStringRef};

#[derive(Clone)]
pub(crate) struct NameEntry {
pub(crate) new_name: Option<BString>,
Expand Down
3 changes: 2 additions & 1 deletion git-mailmap/src/snapshot/signature.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use bstr::{BStr, BString, ByteSlice};
use std::borrow::Cow;

use bstr::{BStr, BString, ByteSlice};

/// A signature like [`git_actor::Signature`], but with all string fields being a `Cow`.
#[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)]
#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
Expand Down
4 changes: 2 additions & 2 deletions git-mailmap/src/snapshot/util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{cmp::Ordering, ops::Deref};

use bstr::{BStr, BString, ByteSlice};
use std::cmp::Ordering;
use std::ops::Deref;

#[cfg_attr(test, derive(Debug))]
#[derive(Clone)]
Expand Down

0 comments on commit 702a161

Please sign in to comment.