summaryrefslogtreecommitdiff
path: root/promisor-remote.c
diff options
context:
space:
mode:
authorJonathan Tan <jonathantanmy@google.com>2020-08-18 04:01:36 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-08-18 23:46:53 (GMT)
commit7ca3c0ac37bfb803f11db14b7223f6d8f0cd142e (patch)
tree398fb7d6f2379542cfeae4db21a7e75046c3306a /promisor-remote.c
parent5c3b801dab9d29c63c6c929405f808f064c11b77 (diff)
downloadgit-7ca3c0ac37bfb803f11db14b7223f6d8f0cd142e.zip
git-7ca3c0ac37bfb803f11db14b7223f6d8f0cd142e.tar.gz
git-7ca3c0ac37bfb803f11db14b7223f6d8f0cd142e.tar.bz2
promisor-remote: lazy-fetch objects in subprocess
Teach Git to lazy-fetch missing objects in a subprocess instead of doing it in-process. This allows any fatal errors that occur during the fetch to be isolated and converted into an error return value, instead of causing the current command being run to terminate. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'promisor-remote.c')
-rw-r--r--promisor-remote.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/promisor-remote.c b/promisor-remote.c
index baaea12..6530e26 100644
--- a/promisor-remote.c
+++ b/promisor-remote.c
@@ -3,6 +3,7 @@
#include "promisor-remote.h"
#include "config.h"
#include "transport.h"
+#include "strvec.h"
static char *repository_format_partial_clone;
static const char *core_partial_clone_filter_default;
@@ -12,39 +13,34 @@ void set_repository_format_partial_clone(char *partial_clone)
repository_format_partial_clone = xstrdup_or_null(partial_clone);
}
-static int fetch_refs(const char *remote_name, struct ref *ref)
-{
- struct remote *remote;
- struct transport *transport;
- int res;
-
- remote = remote_get(remote_name);
- if (!remote->url[0])
- die(_("Remote with no URL"));
- transport = transport_get(remote, remote->url[0]);
-
- transport_set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
- transport_set_option(transport, TRANS_OPT_NO_DEPENDENTS, "1");
- res = transport_fetch_refs(transport, ref);
-
- return res;
-}
-
static int fetch_objects(const char *remote_name,
const struct object_id *oids,
int oid_nr)
{
- struct ref *ref = NULL;
+ struct child_process child = CHILD_PROCESS_INIT;
int i;
+ FILE *child_in;
+
+ child.git_cmd = 1;
+ child.in = -1;
+ strvec_pushl(&child.args, "-c", "fetch.negotiationAlgorithm=noop",
+ "fetch", remote_name, "--no-tags",
+ "--no-write-fetch-head", "--recurse-submodules=no",
+ "--filter=blob:none", "--stdin", NULL);
+ if (start_command(&child))
+ die(_("promisor-remote: unable to fork off fetch subprocess"));
+ child_in = xfdopen(child.in, "w");
for (i = 0; i < oid_nr; i++) {
- struct ref *new_ref = alloc_ref(oid_to_hex(&oids[i]));
- oidcpy(&new_ref->old_oid, &oids[i]);
- new_ref->exact_oid = 1;
- new_ref->next = ref;
- ref = new_ref;
+ if (fputs(oid_to_hex(&oids[i]), child_in) < 0)
+ die_errno(_("promisor-remote: could not write to fetch subprocess"));
+ if (fputc('\n', child_in) < 0)
+ die_errno(_("promisor-remote: could not write to fetch subprocess"));
}
- return fetch_refs(remote_name, ref);
+
+ if (fclose(child_in) < 0)
+ die_errno(_("promisor-remote: could not close stdin to fetch subprocess"));
+ return finish_command(&child) ? -1 : 0;
}
static struct promisor_remote *promisors;