const char *branch_top,
const char *msg,
struct transport *transport,
- int check_connectivity)
+ int check_connectivity,
+ int check_refs_only)
{
const struct ref *rm = mapped_refs;
opt.transport = transport;
opt.progress = transport->progress;
+ opt.check_refs_only = !!check_refs_only;
if (check_connected(iterate_ref_map, &rm, &opt))
die(_("remote did not send all necessary objects"));
update_remote_refs(refs, mapped_refs, remote_head_points_at,
branch_top.buf, reflog_msg.buf, transport,
- !is_local);
+ !is_local, filter_options.choice);
update_head(our_head_points_at, remote_head, reflog_msg.buf);
#include "cache.h"
+#include "object-store.h"
#include "run-command.h"
#include "sigchain.h"
#include "connected.h"
strbuf_release(&idx_file);
}
+ if (opt->check_refs_only) {
+ /*
+ * For partial clones, we don't want to have to do a regular
+ * connectivity check because we have to enumerate and exclude
+ * all promisor objects (slow), and then the connectivity check
+ * itself becomes a no-op because in a partial clone every
+ * object is a promisor object. Instead, just make sure we
+ * received the objects pointed to by each wanted ref.
+ */
+ do {
+ if (!repo_has_object_file(the_repository, &oid))
+ return 1;
+ } while (!fn(cb_data, &oid));
+ return 0;
+ }
+
if (opt->shallow_file) {
argv_array_push(&rev_list.args, "--shallow-file");
argv_array_push(&rev_list.args, opt->shallow_file);
* during a fetch.
*/
unsigned is_deepening_fetch : 1;
+
+ /*
+ * If non-zero, only check the top-level objects referenced by the
+ * wanted refs (passed in as cb_data). This is useful for partial
+ * clones, where enumerating and excluding all promisor objects is very
+ * slow and the commit-walk itself becomes a no-op.
+ */
+ unsigned check_refs_only : 1;
};
#define CHECK_CONNECTED_INIT { 0 }
--- /dev/null
+#!/bin/sh
+
+test_description='performance of partial clones'
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+test_expect_success 'enable server-side config' '
+ git config uploadpack.allowFilter true &&
+ git config uploadpack.allowAnySHA1InWant true
+'
+
+test_perf 'clone without blobs' '
+ rm -rf bare.git &&
+ git clone --no-local --bare --filter=blob:none . bare.git
+'
+
+test_perf 'checkout of result' '
+ rm -rf worktree &&
+ mkdir -p worktree/.git &&
+ tar -C bare.git -cf - . | tar -C worktree/.git -xf - &&
+ git -C worktree config core.bare false &&
+ git -C worktree checkout -f
+'
+
+test_done