Skip to main content

PushFacts

Struct PushFacts 

Source
pub struct PushFacts<'a> {
    pub objects: &'a dyn GitServe,
    pub new_objects: Result<&'a [ObjectId], &'a str>,
    pub pack_bytes: Option<u64>,
    pub push_options: &'a [String],
}
Expand description

Everything receive-pack learned about the push, handed to every gate.

§Why this is a struct and not three arguments

The gate seam used to be (&RefCommand, &dyn ObjectStore) and nothing else, so a gate could not see which objects the push introduced or how many bytes the client sent. gunnar-policy’s size and quota gates (gunnar_policy::gates::limits) are the things standing between a forge and a client pushing until the disk fills, and neither could be enforced: the object set was recovered downstream by reading the written .idx back, which counts a thin pack’s resolved bases as if the client had sent them, and the byte count was never produced at all.

A struct rather than a wider tuple so the next fact does not re-break every implementation of PushGate.

Fields§

§objects: &'a dyn GitServe

The store, after the pack has been taken in.

GitServe: a gate reads objects, and reading means inflated and delta-resolved. gunnar-policy’s ancestry walk and its signature gate were two of the three errors that crate was blocked on, and they are the same missing capability the connectivity walk here needs.

§new_objects: Result<&'a [ObjectId], &'a str>

The objects this push genuinely introduced, or the reason they could not be enumerated.

Err is not “none”: a gate that cannot see what was pushed cannot decide, and an undecidable gate refuses. Handing an empty slice for “I do not know” is the shape that lets a configured limit be silently satisfied, which is what this type exists to prevent.

§pack_bytes: Option<u64>

Packfile bytes the client sent, counted off the wire by ReceivePack::serve rather than measured from what landed on disk.

Some(0) for a deletions-only push, which carries no pack: that is a measured zero, not an absent measurement, and a byte limit must not refuse it. None only if the count is genuinely unavailable.

§push_options: &'a [String]

The push-option lines the client sent, in wire order.

§Why this field exists

push-options was advertised by caps::receive_pack_capabilities, parsed by ReceivePack::serve and then thrown away: the only consumer in the whole tree was .len() in one log line. A client that sent -o ci.skip got the capability acknowledged on the wire and the option silently ignored, which is a wrong answer on the wire rather than a missing feature — the gate could not see them, so no policy could act on one even in principle.

Stock git hands push options to the pre-receive hook. gunnar has no hooks and no shell; PushGate is what replaces them, so this is where they have to arrive.

Empty means the client sent none, which is also what a client that never negotiated the capability produces. The two are not told apart here on purpose: a gate that requires an option must refuse both, and a gate that forbids unknown ones must accept both.

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for PushFacts<'a>

§

impl<'a> !UnwindSafe for PushFacts<'a>

§

impl<'a> Freeze for PushFacts<'a>

§

impl<'a> Send for PushFacts<'a>

§

impl<'a> Sync for PushFacts<'a>

§

impl<'a> Unpin for PushFacts<'a>

§

impl<'a> UnsafeUnpin for PushFacts<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more