summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Tan <jonathantanmy@google.com>2017-09-29 13:11:42 -0700
committerJunio C Hamano <gitster@pobox.com>2017-10-02 10:15:19 +0900
commit4a22d786671d71522629955e6fdfcda3f4c4b332 (patch)
treeae2efc6ae446520ddb6dfcb30cd3451ecf36d98d
parent9dcda6e1ee5c49c0fc477c4e6679c468df1418e5 (diff)
downloadgit-4a22d786671d71522629955e6fdfcda3f4c4b332.tar.gz
introduce fetch-object: fetch one promisor object
Introduce fetch-object, providing the ability to fetch one object from a promisor remote. This uses fetch-pack. To do this, the transport mechanism has been updated with 2 flags, "from-promisor" to indicate that the resulting pack comes from a promisor remote (and thus should be annotated as such by index-pack), and "no-haves" to suppress the sending of "have" lines. This will be tested in a subsequent commit. NEEDSWORK: update this when we have more information about protocol v2, which should allow a way to suppress the ref advertisement and officially allow any object type to be "want"-ed. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Makefile1
-rw-r--r--builtin/fetch-pack.c8
-rw-r--r--builtin/index-pack.c16
-rw-r--r--fetch-object.c23
-rw-r--r--fetch-object.h6
-rw-r--r--fetch-pack.c8
-rw-r--r--fetch-pack.h2
-rw-r--r--remote-curl.c14
-rw-r--r--transport.c8
-rw-r--r--transport.h8
10 files changed, 88 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index ed5960e6b3..4303ef6f89 100644
--- a/Makefile
+++ b/Makefile
@@ -789,6 +789,7 @@ LIB_OBJS += ewah/ewah_bitmap.o
LIB_OBJS += ewah/ewah_io.o
LIB_OBJS += ewah/ewah_rlw.o
LIB_OBJS += exec_cmd.o
+LIB_OBJS += fetch-object.o
LIB_OBJS += fetch-pack.o
LIB_OBJS += fsck.o
LIB_OBJS += gettext.o
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 366b9d13f9..9f303cf986 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -143,6 +143,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
args.update_shallow = 1;
continue;
}
+ if (!strcmp("--from-promisor", arg)) {
+ args.from_promisor = 1;
+ continue;
+ }
+ if (!strcmp("--no-haves", arg)) {
+ args.no_haves = 1;
+ continue;
+ }
usage(fetch_pack_usage);
}
if (deepen_not.nr)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 7ad1705906..14ebb2f173 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1429,14 +1429,16 @@ static void write_special_file(const char *suffix, const char *msg,
if (close(fd) != 0)
die_errno(_("cannot close written %s file '%s'"),
suffix, filename);
- *report = suffix;
+ if (report)
+ *report = suffix;
}
strbuf_release(&name_buf);
}
static void final(const char *final_pack_name, const char *curr_pack_name,
const char *final_index_name, const char *curr_index_name,
- const char *keep_msg, unsigned char *sha1)
+ const char *keep_msg, const char *promisor_msg,
+ unsigned char *sha1)
{
const char *report = "pack";
struct strbuf pack_name = STRBUF_INIT;
@@ -1455,6 +1457,9 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
if (keep_msg)
write_special_file("keep", keep_msg, final_pack_name, sha1,
&report);
+ if (promisor_msg)
+ write_special_file("promisor", promisor_msg, final_pack_name,
+ sha1, NULL);
if (final_pack_name != curr_pack_name) {
if (!final_pack_name)
@@ -1644,6 +1649,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
const char *curr_index;
const char *index_name = NULL, *pack_name = NULL;
const char *keep_msg = NULL;
+ const char *promisor_msg = NULL;
struct strbuf index_name_buf = STRBUF_INIT;
struct pack_idx_entry **idx_objects;
struct pack_idx_option opts;
@@ -1693,6 +1699,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
keep_msg = "";
} else if (starts_with(arg, "--keep=")) {
keep_msg = arg + 7;
+ } else if (!strcmp(arg, "--promisor")) {
+ promisor_msg = "";
+ } else if (starts_with(arg, "--promisor=")) {
+ promisor_msg = arg + strlen("--promisor=");
} else if (starts_with(arg, "--threads=")) {
char *end;
nr_threads = strtoul(arg+10, &end, 0);
@@ -1803,7 +1813,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
if (!verify)
final(pack_name, curr_pack,
index_name, curr_index,
- keep_msg,
+ keep_msg, promisor_msg,
pack_sha1);
else
close(input_fd);
diff --git a/fetch-object.c b/fetch-object.c
new file mode 100644
index 0000000000..f89dbba75c
--- /dev/null
+++ b/fetch-object.c
@@ -0,0 +1,23 @@
+#include "cache.h"
+#include "packfile.h"
+#include "pkt-line.h"
+#include "strbuf.h"
+#include "transport.h"
+
+void fetch_object(const char *remote_name, const unsigned char *sha1)
+{
+ struct remote *remote;
+ struct transport *transport;
+ struct ref *ref;
+
+ remote = remote_get(remote_name);
+ if (!remote->url[0])
+ die(_("Remote with no URL"));
+ transport = transport_get(remote, remote->url[0]);
+
+ ref = alloc_ref(sha1_to_hex(sha1));
+ hashcpy(ref->old_oid.hash, sha1);
+ transport_set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
+ transport_set_option(transport, TRANS_OPT_NO_HAVES, "1");
+ transport_fetch_refs(transport, ref);
+}
diff --git a/fetch-object.h b/fetch-object.h
new file mode 100644
index 0000000000..f371300c88
--- /dev/null
+++ b/fetch-object.h
@@ -0,0 +1,6 @@
+#ifndef FETCH_OBJECT_H
+#define FETCH_OBJECT_H
+
+extern void fetch_object(const char *remote_name, const unsigned char *sha1);
+
+#endif
diff --git a/fetch-pack.c b/fetch-pack.c
index 105506e9aa..d376c4ef16 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -450,6 +450,8 @@ static int find_common(struct fetch_pack_args *args,
flushes = 0;
retval = -1;
+ if (args->no_haves)
+ goto done;
while ((oid = get_rev())) {
packet_buf_write(&req_buf, "have %s\n", oid_to_hex(oid));
print_verbose(args, "have %s", oid_to_hex(oid));
@@ -832,7 +834,7 @@ static int get_pack(struct fetch_pack_args *args,
argv_array_push(&cmd.args, alternate_shallow_file);
}
- if (do_keep) {
+ if (do_keep || args->from_promisor) {
if (pack_lockfile)
cmd.out = -1;
cmd_name = "index-pack";
@@ -842,7 +844,7 @@ static int get_pack(struct fetch_pack_args *args,
argv_array_push(&cmd.args, "-v");
if (args->use_thin_pack)
argv_array_push(&cmd.args, "--fix-thin");
- if (args->lock_pack || unpack_limit) {
+ if (do_keep && (args->lock_pack || unpack_limit)) {
char hostname[HOST_NAME_MAX + 1];
if (xgethostname(hostname, sizeof(hostname)))
xsnprintf(hostname, sizeof(hostname), "localhost");
@@ -852,6 +854,8 @@ static int get_pack(struct fetch_pack_args *args,
}
if (args->check_self_contained_and_connected)
argv_array_push(&cmd.args, "--check-self-contained-and-connected");
+ if (args->from_promisor)
+ argv_array_push(&cmd.args, "--promisor");
}
else {
cmd_name = "unpack-objects";
diff --git a/fetch-pack.h b/fetch-pack.h
index b6aeb43a8e..84904c3480 100644
--- a/fetch-pack.h
+++ b/fetch-pack.h
@@ -29,6 +29,8 @@ struct fetch_pack_args {
unsigned cloning:1;
unsigned update_shallow:1;
unsigned deepen:1;
+ unsigned from_promisor:1;
+ unsigned no_haves:1;
};
/*
diff --git a/remote-curl.c b/remote-curl.c
index 0053b09549..34a81b8d3f 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -33,7 +33,9 @@ struct options {
thin : 1,
/* One of the SEND_PACK_PUSH_CERT_* constants. */
push_cert : 2,
- deepen_relative : 1;
+ deepen_relative : 1,
+ from_promisor : 1,
+ no_haves : 1;
};
static struct options options;
static struct string_list cas_options = STRING_LIST_INIT_DUP;
@@ -157,6 +159,12 @@ static int set_option(const char *name, const char *value)
return -1;
return 0;
#endif /* LIBCURL_VERSION_NUM >= 0x070a08 */
+ } else if (!strcmp(name, "from-promisor")) {
+ options.from_promisor = 1;
+ return 0;
+ } else if (!strcmp(name, "no-haves")) {
+ options.no_haves = 1;
+ return 0;
} else {
return 1 /* unsupported */;
}
@@ -822,6 +830,10 @@ static int fetch_git(struct discovery *heads,
options.deepen_not.items[i].string);
if (options.deepen_relative && options.depth)
argv_array_push(&args, "--deepen-relative");
+ if (options.from_promisor)
+ argv_array_push(&args, "--from-promisor");
+ if (options.no_haves)
+ argv_array_push(&args, "--no-haves");
argv_array_push(&args, url.buf);
for (i = 0; i < nr_heads; i++) {
diff --git a/transport.c b/transport.c
index d75ff0514d..fb46e33bf1 100644
--- a/transport.c
+++ b/transport.c
@@ -161,6 +161,12 @@ static int set_git_option(struct git_transport_options *opts,
} else if (!strcmp(name, TRANS_OPT_DEEPEN_RELATIVE)) {
opts->deepen_relative = !!value;
return 0;
+ } else if (!strcmp(name, TRANS_OPT_FROM_PROMISOR)) {
+ opts->from_promisor = !!value;
+ return 0;
+ } else if (!strcmp(name, TRANS_OPT_NO_HAVES)) {
+ opts->no_haves = !!value;
+ return 0;
}
return 1;
}
@@ -229,6 +235,8 @@ static int fetch_refs_via_pack(struct transport *transport,
data->options.check_self_contained_and_connected;
args.cloning = transport->cloning;
args.update_shallow = data->options.update_shallow;
+ args.from_promisor = data->options.from_promisor;
+ args.no_haves = data->options.no_haves;
if (!data->got_remote_heads) {
connect_setup(transport, 0);
diff --git a/transport.h b/transport.h
index bc5571574b..67428f6df6 100644
--- a/transport.h
+++ b/transport.h
@@ -15,6 +15,8 @@ struct git_transport_options {
unsigned self_contained_and_connected : 1;
unsigned update_shallow : 1;
unsigned deepen_relative : 1;
+ unsigned from_promisor : 1;
+ unsigned no_haves : 1;
int depth;
const char *deepen_since;
const struct string_list *deepen_not;
@@ -210,6 +212,12 @@ void transport_check_allowed(const char *type);
/* Send push certificates */
#define TRANS_OPT_PUSH_CERT "pushcert"
+/* Indicate that these objects are being fetched by a promisor */
+#define TRANS_OPT_FROM_PROMISOR "from-promisor"
+
+/* Do not send "have" lines */
+#define TRANS_OPT_NO_HAVES "no-haves"
+
/**
* Returns 0 if the option was used, non-zero otherwise. Prints a
* message to stderr if the option is not used.