mirror of
https://github.com/git-for-windows/git.git
synced 2026-06-11 08:30:32 -05:00
Add a new --negotiation-include option to 'git fetch', which ensures that certain ref tips are always sent as 'have' lines during fetch negotiation, regardless of what the negotiation algorithm selects. This is useful when the repository has a large number of references, so the normal negotiation algorithm truncates the list. This is especially important in repositories with long parallel commit histories. For example, a repo could have a 'dev' branch for development and a 'release' branch for released versions. If the 'dev' branch isn't selected for negotiation, then it's not a big deal because there are many in-progress development branches with a shared history. However, if 'release' is not selected for negotiation, then the server may think that this is the first time the client has asked for that reference, causing a full download of its parallel commit history (and any extra data that may be unique to that branch). This is based on a real example where certain fetches would grow to 60+ GB when a release branch updated. This option is a complement to --negotiation-restrict, which reduces the negotiation ref set to a specific list. In the earlier example, using --negotiation-restrict to focus the negotiation to 'dev' and 'release' would avoid those problematic downloads, but would still not allow advertising potentially-relevant user branches. In this way, the 'include' version solves the problem I mention while allowing negotiation to pick other references opportunistically. The two options can also be combined to allow the best of both worlds. The argument may be an exact ref name or a glob pattern. Non-existent refs are silently ignored. This behavior is also updated in the ref matching logic for the related --negotiation-restrict option to match. The implementation outputs the requested objects as haves before the negotiator performs its own algorithm to choose the next haves. Use the new have_sent() interface to signal these have commits were sent before engaging with the negotiator's next() iterator. Also add --negotiation-include to 'git pull' passthrough options. Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com> Signed-off-by: Derrick Stolee <stolee@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
123 lines
3.8 KiB
C
123 lines
3.8 KiB
C
#ifndef FETCH_PACK_H
|
|
#define FETCH_PACK_H
|
|
|
|
#include "string-list.h"
|
|
#include "protocol.h"
|
|
#include "list-objects-filter-options.h"
|
|
#include "oidset.h"
|
|
|
|
struct oid_array;
|
|
|
|
struct fetch_pack_args {
|
|
const char *uploadpack;
|
|
int unpacklimit;
|
|
int depth;
|
|
const char *deepen_since;
|
|
const struct string_list *deepen_not;
|
|
struct list_objects_filter_options filter_options;
|
|
const struct string_list *server_options;
|
|
|
|
/*
|
|
* If not NULL, during packfile negotiation, fetch-pack will send "have"
|
|
* lines for all _include_ tips and then a subset of the _restrict_ tips.
|
|
*/
|
|
const struct oid_array *negotiation_restrict_tips;
|
|
const struct oid_array *negotiation_include_tips;
|
|
|
|
unsigned deepen_relative:1;
|
|
unsigned quiet:1;
|
|
unsigned keep_pack:1;
|
|
unsigned lock_pack:1;
|
|
unsigned use_thin_pack:1;
|
|
unsigned fetch_all:1;
|
|
unsigned stdin_refs:1;
|
|
unsigned diag_url:1;
|
|
unsigned verbose:1;
|
|
unsigned no_progress:1;
|
|
unsigned include_tag:1;
|
|
unsigned stateless_rpc:1;
|
|
unsigned check_self_contained_and_connected:1;
|
|
unsigned self_contained_and_connected:1;
|
|
unsigned cloning:1;
|
|
unsigned update_shallow:1;
|
|
unsigned reject_shallow_remote:1;
|
|
unsigned deepen:1;
|
|
unsigned refetch:1;
|
|
|
|
/*
|
|
* Indicate that the remote of this request is a promisor remote. The
|
|
* pack received does not need all referred-to objects to be present in
|
|
* the local object store, and fetch-pack will store the pack received
|
|
* together with a ".promisor" file indicating that the aforementioned
|
|
* pack is a promisor pack.
|
|
*/
|
|
unsigned from_promisor:1;
|
|
|
|
/*
|
|
* Because fetch_pack() overwrites the shallow file upon a
|
|
* successful deepening non-clone fetch, if this struct
|
|
* specifies such a fetch, fetch_pack() needs to perform a
|
|
* connectivity check before deciding if a fetch is successful
|
|
* (and overwriting the shallow file). fetch_pack() sets this
|
|
* field to 1 if such a connectivity check was performed.
|
|
*
|
|
* This is different from check_self_contained_and_connected
|
|
* in that the former allows existing objects in the
|
|
* repository to satisfy connectivity needs, whereas the
|
|
* latter doesn't.
|
|
*/
|
|
unsigned connectivity_checked:1;
|
|
};
|
|
|
|
/*
|
|
* sought represents remote references that should be updated from.
|
|
* On return, the names that were found on the remote will have been
|
|
* marked as such.
|
|
*/
|
|
struct ref *fetch_pack(struct fetch_pack_args *args,
|
|
int fd[],
|
|
const struct ref *ref,
|
|
struct ref **sought,
|
|
int nr_sought,
|
|
struct oid_array *shallow,
|
|
struct string_list *pack_lockfiles,
|
|
enum protocol_version version);
|
|
|
|
/*
|
|
* Execute the --negotiate-only mode of "git fetch", adding all known common
|
|
* commits to acked_commits.
|
|
*
|
|
* In the capability advertisement that has happened prior to invoking this
|
|
* function, the "wait-for-done" capability must be present.
|
|
*/
|
|
void negotiate_using_fetch(const struct oid_array *negotiation_restrict_tips,
|
|
const struct string_list *server_options,
|
|
int stateless_rpc,
|
|
int fd[],
|
|
struct oidset *acked_commits,
|
|
const struct oid_array *negotiation_include_tips);
|
|
|
|
/*
|
|
* Print an appropriate error message for each sought ref that wasn't
|
|
* matched. Return 0 if all sought refs were matched, otherwise 1.
|
|
*/
|
|
int report_unmatched_refs(struct ref **sought, int nr_sought);
|
|
|
|
/*
|
|
* Return true if checks for broken objects in received pack are required.
|
|
*/
|
|
int fetch_pack_fsck_objects(void);
|
|
|
|
/*
|
|
* Check if the provided config variable pertains to fetch fsck and if so append
|
|
* the configuration to the provided strbuf.
|
|
*
|
|
* When a fetch fsck config option is successfully processed the function
|
|
* returns 0. If the provided config option is unrelated to fetch fsck, 1 is
|
|
* returned. Errors return -1.
|
|
*/
|
|
int fetch_pack_fsck_config(const char *var, const char *value,
|
|
struct strbuf *msg_types);
|
|
|
|
#endif
|