2 #include "object-store.h"
3 #include "promisor-remote.h"
8 static char *repository_format_partial_clone
;
10 void set_repository_format_partial_clone(char *partial_clone
)
12 repository_format_partial_clone
= xstrdup_or_null(partial_clone
);
15 static int fetch_objects(const char *remote_name
,
16 const struct object_id
*oids
,
19 struct child_process child
= CHILD_PROCESS_INIT
;
25 strvec_pushl(&child
.args
, "-c", "fetch.negotiationAlgorithm=noop",
26 "fetch", remote_name
, "--no-tags",
27 "--no-write-fetch-head", "--recurse-submodules=no",
28 "--filter=blob:none", "--stdin", NULL
);
29 if (start_command(&child
))
30 die(_("promisor-remote: unable to fork off fetch subprocess"));
31 child_in
= xfdopen(child
.in
, "w");
33 for (i
= 0; i
< oid_nr
; i
++) {
34 if (fputs(oid_to_hex(&oids
[i
]), child_in
) < 0)
35 die_errno(_("promisor-remote: could not write to fetch subprocess"));
36 if (fputc('\n', child_in
) < 0)
37 die_errno(_("promisor-remote: could not write to fetch subprocess"));
40 if (fclose(child_in
) < 0)
41 die_errno(_("promisor-remote: could not close stdin to fetch subprocess"));
42 return finish_command(&child
) ? -1 : 0;
45 static struct promisor_remote
*promisors
;
46 static struct promisor_remote
**promisors_tail
= &promisors
;
48 static struct promisor_remote
*promisor_remote_new(const char *remote_name
)
50 struct promisor_remote
*r
;
52 if (*remote_name
== '/') {
53 warning(_("promisor remote name cannot begin with '/': %s"),
58 FLEX_ALLOC_STR(r
, name
, remote_name
);
61 promisors_tail
= &r
->next
;
66 static struct promisor_remote
*promisor_remote_lookup(const char *remote_name
,
67 struct promisor_remote
**previous
)
69 struct promisor_remote
*r
, *p
;
71 for (p
= NULL
, r
= promisors
; r
; p
= r
, r
= r
->next
)
72 if (!strcmp(r
->name
, remote_name
)) {
81 static void promisor_remote_move_to_tail(struct promisor_remote
*r
,
82 struct promisor_remote
*previous
)
88 previous
->next
= r
->next
;
90 promisors
= r
->next
? r
->next
: r
;
93 promisors_tail
= &r
->next
;
96 static int promisor_remote_config(const char *var
, const char *value
, void *data
)
102 if (parse_config_key(var
, "remote", &name
, &namelen
, &subkey
) < 0)
105 if (!strcmp(subkey
, "promisor")) {
108 if (!git_config_bool(var
, value
))
111 remote_name
= xmemdupz(name
, namelen
);
113 if (!promisor_remote_lookup(remote_name
, NULL
))
114 promisor_remote_new(remote_name
);
119 if (!strcmp(subkey
, "partialclonefilter")) {
120 struct promisor_remote
*r
;
121 char *remote_name
= xmemdupz(name
, namelen
);
123 r
= promisor_remote_lookup(remote_name
, NULL
);
125 r
= promisor_remote_new(remote_name
);
132 return git_config_string(&r
->partial_clone_filter
, var
, value
);
138 static int initialized
;
140 static void promisor_remote_init(void)
146 git_config(promisor_remote_config
, NULL
);
148 if (repository_format_partial_clone
) {
149 struct promisor_remote
*o
, *previous
;
151 o
= promisor_remote_lookup(repository_format_partial_clone
,
154 promisor_remote_move_to_tail(o
, previous
);
156 promisor_remote_new(repository_format_partial_clone
);
160 static void promisor_remote_clear(void)
163 struct promisor_remote
*r
= promisors
;
164 promisors
= promisors
->next
;
168 promisors_tail
= &promisors
;
171 void promisor_remote_reinit(void)
174 promisor_remote_clear();
175 promisor_remote_init();
178 struct promisor_remote
*promisor_remote_find(const char *remote_name
)
180 promisor_remote_init();
185 return promisor_remote_lookup(remote_name
, NULL
);
188 int has_promisor_remote(void)
190 return !!promisor_remote_find(NULL
);
193 static int remove_fetched_oids(struct repository
*repo
,
194 struct object_id
**oids
,
195 int oid_nr
, int to_free
)
197 int i
, remaining_nr
= 0;
198 int *remaining
= xcalloc(oid_nr
, sizeof(*remaining
));
199 struct object_id
*old_oids
= *oids
;
200 struct object_id
*new_oids
;
202 for (i
= 0; i
< oid_nr
; i
++)
203 if (oid_object_info_extended(repo
, &old_oids
[i
], NULL
,
204 OBJECT_INFO_SKIP_FETCH_OBJECT
)) {
211 CALLOC_ARRAY(new_oids
, remaining_nr
);
212 for (i
= 0; i
< oid_nr
; i
++)
214 oidcpy(&new_oids
[j
++], &old_oids
[i
]);
225 int promisor_remote_get_direct(struct repository
*repo
,
226 const struct object_id
*oids
,
229 struct promisor_remote
*r
;
230 struct object_id
*remaining_oids
= (struct object_id
*)oids
;
231 int remaining_nr
= oid_nr
;
238 promisor_remote_init();
240 for (r
= promisors
; r
; r
= r
->next
) {
241 if (fetch_objects(r
->name
, remaining_oids
, remaining_nr
) < 0) {
242 if (remaining_nr
== 1)
244 remaining_nr
= remove_fetched_oids(repo
, &remaining_oids
,
245 remaining_nr
, to_free
);
256 free(remaining_oids
);