Skip to content

Commit b4100f3

Browse files
committed
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
2 parents 3f02c0a + db3c293 commit b4100f3

25 files changed

+278
-215
lines changed

Documentation/config/fetch.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ fetch.negotiationAlgorithm::
6060
sent when negotiating the contents of the packfile to be sent by the
6161
server. Set to "skipping" to use an algorithm that skips commits in an
6262
effort to converge faster, but may result in a larger-than-necessary
63-
packfile; The default is "default" which instructs Git to use the default algorithm
63+
packfile; or set to "noop" to not send any information at all, which
64+
will almost certainly result in a larger-than-necessary packfile, but
65+
will skip the negotiation step.
66+
The default is "default" which instructs Git to use the default algorithm
6467
that never skips commits (unless the server has acknowledged it or one
6568
of its descendants). If `feature.experimental` is enabled, then this
6669
setting defaults to "skipping".

Documentation/git-fetch.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ include::fetch-options.txt[]
4848

4949
include::pull-fetch-param.txt[]
5050

51+
--stdin::
52+
Read refspecs, one per line, from stdin in addition to those provided
53+
as arguments. The "tag <name>" format is not supported.
54+
5155
include::urls-remotes.txt[]
5256

5357

Documentation/technical/partial-clone.txt

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -171,20 +171,13 @@ additional flag.
171171
Fetching Missing Objects
172172
------------------------
173173

174-
- Fetching of objects is done using the existing transport mechanism using
175-
transport_fetch_refs(), setting a new transport option
176-
TRANS_OPT_NO_DEPENDENTS to indicate that only the objects themselves are
177-
desired, not any object that they refer to.
178-
+
179-
Because some transports invoke fetch_pack() in the same process, fetch_pack()
180-
has been updated to not use any object flags when the corresponding argument
181-
(no_dependents) is set.
174+
- Fetching of objects is done by invoking a "git fetch" subprocess.
182175

183176
- The local repository sends a request with the hashes of all requested
184-
objects as "want" lines, and does not perform any packfile negotiation.
177+
objects, and does not perform any packfile negotiation.
185178
It then receives a packfile.
186179

187-
- Because we are reusing the existing fetch-pack mechanism, fetching
180+
- Because we are reusing the existing fetch mechanism, fetching
188181
currently fetches all objects referred to by the requested objects, even
189182
though they are not necessary.
190183

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,7 @@ LIB_OBJS += mergesort.o
908908
LIB_OBJS += midx.o
909909
LIB_OBJS += name-hash.o
910910
LIB_OBJS += negotiator/default.o
911+
LIB_OBJS += negotiator/noop.o
911912
LIB_OBJS += negotiator/skipping.o
912913
LIB_OBJS += notes-cache.o
913914
LIB_OBJS += notes-merge.o

builtin/fetch-pack.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,6 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
153153
args.from_promisor = 1;
154154
continue;
155155
}
156-
if (!strcmp("--no-dependents", arg)) {
157-
args.no_dependents = 1;
158-
continue;
159-
}
160156
if (skip_prefix(arg, ("--" CL_ARG__FILTER "="), &arg)) {
161157
parse_list_objects_filter(&args.filter_options, arg);
162158
continue;

builtin/fetch.c

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ static struct list_objects_filter_options filter_options;
8080
static struct string_list server_options = STRING_LIST_INIT_DUP;
8181
static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
8282
static int fetch_write_commit_graph = -1;
83+
static int stdin_refspecs = 0;
8384

8485
static int git_fetch_config(const char *k, const char *v, void *cb)
8586
{
@@ -205,6 +206,8 @@ static struct option builtin_fetch_options[] = {
205206
N_("check for forced-updates on all updated branches")),
206207
OPT_BOOL(0, "write-commit-graph", &fetch_write_commit_graph,
207208
N_("write the commit-graph after fetching")),
209+
OPT_BOOL(0, "stdin", &stdin_refspecs,
210+
N_("accept refspecs from stdin")),
208211
OPT_END()
209212
};
210213

@@ -442,6 +445,7 @@ static struct ref *get_ref_map(struct remote *remote,
442445
struct ref *orefs = NULL, **oref_tail = &orefs;
443446

444447
struct hashmap existing_refs;
448+
int existing_refs_populated = 0;
445449

446450
if (rs->nr) {
447451
struct refspec *fetch_refspec;
@@ -535,15 +539,18 @@ static struct ref *get_ref_map(struct remote *remote,
535539

536540
ref_map = ref_remove_duplicates(ref_map);
537541

538-
refname_hash_init(&existing_refs);
539-
for_each_ref(add_one_refname, &existing_refs);
540-
541542
for (rm = ref_map; rm; rm = rm->next) {
542543
if (rm->peer_ref) {
543544
const char *refname = rm->peer_ref->name;
544545
struct refname_hash_entry *peer_item;
545546
unsigned int hash = strhash(refname);
546547

548+
if (!existing_refs_populated) {
549+
refname_hash_init(&existing_refs);
550+
for_each_ref(add_one_refname, &existing_refs);
551+
existing_refs_populated = 1;
552+
}
553+
547554
peer_item = hashmap_get_entry_from_hash(&existing_refs,
548555
hash, refname,
549556
struct refname_hash_entry, ent);
@@ -553,7 +560,8 @@ static struct ref *get_ref_map(struct remote *remote,
553560
}
554561
}
555562
}
556-
hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent);
563+
if (existing_refs_populated)
564+
hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent);
557565

558566
return ref_map;
559567
}
@@ -1015,11 +1023,17 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
10151023
rc |= update_local_ref(ref, what, rm, &note,
10161024
summary_width);
10171025
free(ref);
1018-
} else
1026+
} else if (write_fetch_head || dry_run) {
1027+
/*
1028+
* Display fetches written to FETCH_HEAD (or
1029+
* would be written to FETCH_HEAD, if --dry-run
1030+
* is set).
1031+
*/
10191032
format_display(&note, '*',
10201033
*kind ? kind : "branch", NULL,
10211034
*what ? what : "HEAD",
10221035
"FETCH_HEAD", summary_width);
1036+
}
10231037
if (note.len) {
10241038
if (verbosity >= 0 && !shown_url) {
10251039
fprintf(stderr, _("From %.*s\n"),
@@ -1680,7 +1694,8 @@ static inline void fetch_one_setup_partial(struct remote *remote)
16801694
return;
16811695
}
16821696

1683-
static int fetch_one(struct remote *remote, int argc, const char **argv, int prune_tags_ok)
1697+
static int fetch_one(struct remote *remote, int argc, const char **argv,
1698+
int prune_tags_ok, int use_stdin_refspecs)
16841699
{
16851700
struct refspec rs = REFSPEC_INIT_FETCH;
16861701
int i;
@@ -1737,6 +1752,13 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
17371752
}
17381753
}
17391754

1755+
if (use_stdin_refspecs) {
1756+
struct strbuf line = STRBUF_INIT;
1757+
while (strbuf_getline_lf(&line, stdin) != EOF)
1758+
refspec_append(&rs, line.buf);
1759+
strbuf_release(&line);
1760+
}
1761+
17401762
if (server_options.nr)
17411763
gtransport->server_options = &server_options;
17421764

@@ -1771,12 +1793,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
17711793
free(anon);
17721794
}
17731795

1774-
fetch_config_from_gitmodules(&submodule_fetch_jobs_config,
1775-
&recurse_submodules);
17761796
git_config(git_fetch_config, NULL);
17771797

17781798
argc = parse_options(argc, argv, prefix,
17791799
builtin_fetch_options, builtin_fetch_usage, 0);
1800+
if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
1801+
int *sfjc = submodule_fetch_jobs_config == -1
1802+
? &submodule_fetch_jobs_config : NULL;
1803+
int *rs = recurse_submodules == RECURSE_SUBMODULES_DEFAULT
1804+
? &recurse_submodules : NULL;
1805+
1806+
fetch_config_from_gitmodules(sfjc, rs);
1807+
}
17801808

17811809
if (deepen_relative) {
17821810
if (deepen_relative < 0)
@@ -1837,14 +1865,18 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
18371865
if (remote) {
18381866
if (filter_options.choice || has_promisor_remote())
18391867
fetch_one_setup_partial(remote);
1840-
result = fetch_one(remote, argc, argv, prune_tags_ok);
1868+
result = fetch_one(remote, argc, argv, prune_tags_ok, stdin_refspecs);
18411869
} else {
18421870
int max_children = max_jobs;
18431871

18441872
if (filter_options.choice)
18451873
die(_("--filter can only be used with the remote "
18461874
"configured in extensions.partialclone"));
18471875

1876+
if (stdin_refspecs)
1877+
die(_("--stdin can only be used when fetching "
1878+
"from one remote"));
1879+
18481880
if (max_children < 0)
18491881
max_children = fetch_parallel_config;
18501882

fetch-negotiator.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "fetch-negotiator.h"
33
#include "negotiator/default.h"
44
#include "negotiator/skipping.h"
5+
#include "negotiator/noop.h"
56
#include "repository.h"
67

78
void fetch_negotiator_init(struct repository *r,
@@ -13,6 +14,10 @@ void fetch_negotiator_init(struct repository *r,
1314
skipping_negotiator_init(negotiator);
1415
return;
1516

17+
case FETCH_NEGOTIATION_NOOP:
18+
noop_negotiator_init(negotiator);
19+
return;
20+
1621
case FETCH_NEGOTIATION_DEFAULT:
1722
default:
1823
default_negotiator_init(negotiator);

0 commit comments

Comments
 (0)