Merge branch 'jt/lazy-fetch'

Updates to on-demand fetching code in lazily cloned repositories.

* jt/lazy-fetch:
  fetch: no FETCH_HEAD display if --no-write-fetch-head
  fetch-pack: remove no_dependents code
  promisor-remote: lazy-fetch objects in subprocess
  fetch-pack: do not lazy-fetch during ref iteration
  fetch: only populate existing_refs if needed
  fetch: avoid reading submodule config until needed
  fetch: allow refspecs specified through stdin
  negotiator/noop: add noop fetch negotiator
This commit is contained in:
Junio C Hamano
2020-09-03 12:37:04 -07:00
25 changed files with 277 additions and 214 deletions

View File

@ -80,6 +80,7 @@ static struct list_objects_filter_options filter_options;
static struct string_list server_options = STRING_LIST_INIT_DUP;
static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
static int fetch_write_commit_graph = -1;
static int stdin_refspecs = 0;
static int git_fetch_config(const char *k, const char *v, void *cb)
{
@ -205,6 +206,8 @@ static struct option builtin_fetch_options[] = {
N_("check for forced-updates on all updated branches")),
OPT_BOOL(0, "write-commit-graph", &fetch_write_commit_graph,
N_("write the commit-graph after fetching")),
OPT_BOOL(0, "stdin", &stdin_refspecs,
N_("accept refspecs from stdin")),
OPT_END()
};
@ -442,6 +445,7 @@ static struct ref *get_ref_map(struct remote *remote,
struct ref *orefs = NULL, **oref_tail = &orefs;
struct hashmap existing_refs;
int existing_refs_populated = 0;
if (rs->nr) {
struct refspec *fetch_refspec;
@ -535,15 +539,18 @@ static struct ref *get_ref_map(struct remote *remote,
ref_map = ref_remove_duplicates(ref_map);
refname_hash_init(&existing_refs);
for_each_ref(add_one_refname, &existing_refs);
for (rm = ref_map; rm; rm = rm->next) {
if (rm->peer_ref) {
const char *refname = rm->peer_ref->name;
struct refname_hash_entry *peer_item;
unsigned int hash = strhash(refname);
if (!existing_refs_populated) {
refname_hash_init(&existing_refs);
for_each_ref(add_one_refname, &existing_refs);
existing_refs_populated = 1;
}
peer_item = hashmap_get_entry_from_hash(&existing_refs,
hash, refname,
struct refname_hash_entry, ent);
@ -553,7 +560,8 @@ static struct ref *get_ref_map(struct remote *remote,
}
}
}
hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent);
if (existing_refs_populated)
hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent);
return ref_map;
}
@ -1015,11 +1023,17 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
rc |= update_local_ref(ref, what, rm, &note,
summary_width);
free(ref);
} else
} else if (write_fetch_head || dry_run) {
/*
* Display fetches written to FETCH_HEAD (or
* would be written to FETCH_HEAD, if --dry-run
* is set).
*/
format_display(&note, '*',
*kind ? kind : "branch", NULL,
*what ? what : "HEAD",
"FETCH_HEAD", summary_width);
}
if (note.len) {
if (verbosity >= 0 && !shown_url) {
fprintf(stderr, _("From %.*s\n"),
@ -1680,7 +1694,8 @@ static inline void fetch_one_setup_partial(struct remote *remote)
return;
}
static int fetch_one(struct remote *remote, int argc, const char **argv, int prune_tags_ok)
static int fetch_one(struct remote *remote, int argc, const char **argv,
int prune_tags_ok, int use_stdin_refspecs)
{
struct refspec rs = REFSPEC_INIT_FETCH;
int i;
@ -1737,6 +1752,13 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
}
}
if (use_stdin_refspecs) {
struct strbuf line = STRBUF_INIT;
while (strbuf_getline_lf(&line, stdin) != EOF)
refspec_append(&rs, line.buf);
strbuf_release(&line);
}
if (server_options.nr)
gtransport->server_options = &server_options;
@ -1771,12 +1793,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
free(anon);
}
fetch_config_from_gitmodules(&submodule_fetch_jobs_config,
&recurse_submodules);
git_config(git_fetch_config, NULL);
argc = parse_options(argc, argv, prefix,
builtin_fetch_options, builtin_fetch_usage, 0);
if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
int *sfjc = submodule_fetch_jobs_config == -1
? &submodule_fetch_jobs_config : NULL;
int *rs = recurse_submodules == RECURSE_SUBMODULES_DEFAULT
? &recurse_submodules : NULL;
fetch_config_from_gitmodules(sfjc, rs);
}
if (deepen_relative) {
if (deepen_relative < 0)
@ -1837,7 +1865,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
if (remote) {
if (filter_options.choice || has_promisor_remote())
fetch_one_setup_partial(remote);
result = fetch_one(remote, argc, argv, prune_tags_ok);
result = fetch_one(remote, argc, argv, prune_tags_ok, stdin_refspecs);
} else {
int max_children = max_jobs;
@ -1845,6 +1873,10 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
die(_("--filter can only be used with the remote "
"configured in extensions.partialclone"));
if (stdin_refspecs)
die(_("--stdin can only be used when fetching "
"from one remote"));
if (max_children < 0)
max_children = fetch_parallel_config;