gix_protocol::fetch::negotiate

Function mark_complete_and_common_ref

Source
pub fn mark_complete_and_common_ref<Out, F, E>(
    objects: &(impl Find + FindHeader + Exists),
    refs: &Store,
    alternates: impl FnOnce() -> Result<Out, E>,
    negotiator: &mut dyn Negotiator,
    graph: &mut Graph<'_, '_>,
    ref_map: &RefMap,
    shallow: &Shallow,
    mapping_is_ignored: impl Fn(&Mapping) -> bool,
) -> Result<Action, Error>
where E: Into<Box<dyn Error + Send + Sync + 'static>>, Out: Iterator<Item = (Store, F)>, F: Find,
Available on crate feature fetch only.
Expand description

This function is modeled after the similarly named one in the git codebase to mark known refs in a commit-graph.

It to do the following:

  • figure out all advertised refs on the remote that we already have and keep track of the oldest one as cutoff date.
  • mark all of our own refs as tips for a traversal.
  • mark all their parents, recursively, up to (and including) the cutoff date up to which we have seen the servers commit that we have.
  • pass all known-to-be-common-with-remote commits to the negotiator as common commits.

This is done so that we already find the most recent common commits, even if we are ahead, which is potentially better than what we would get if we would rely on tracking refs alone, particularly if one wouldn’t trust the tracking refs for some reason.

Note that git doesn’t trust its own tracking refs as the server might have changed completely, for instance by force-pushing, so marking our local tracking refs as known is something that’s actually not proven to be correct so it’s not done.

Additionally, it does what’s done in transport.c and we check if a fetch is actually needed as at least one advertised ref changed.

Finally, we also mark tips in the negotiator in one go to avoid traversing all refs twice, since we naturally encounter all tips during our own walk.

Return whether we should negotiate, along with a queue for later use.

§Parameters

  • objects
    • Access to the object database. Note that the exists() calls must not trigger a refresh of the ODB packs as plenty of them might fail, i.e. find on object.
  • refs
    • Access to the git references database.
  • alternates
    • A function that returns an iterator over (refs, objects) for each alternate repository, to assure all known objects are added also according to their tips.
  • negotiator
    • The implementation that performs the negotiation later, i.e. prepare wants and haves.
  • graph
    • The commit-graph for use by the negotiator - we populate it with tips to initialize the graph traversal.
  • ref_map
    • The references known on the remote, as previously obtained with RefMap::new().
  • shallow
    • How to deal with shallow repositories. It does affect how negotiations are performed.
  • mapping_is_ignored
    • f(mapping) -> bool returns true if the given mapping should not participate in change tracking.
    • make_refmapping_ignore_predicate() is a typical implementation for this.