summaryrefslogtreecommitdiff
path: root/upload-pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'upload-pack.c')
-rw-r--r--upload-pack.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/upload-pack.c b/upload-pack.c
index 551f22ffa5..d3312006a3 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -1,10 +1,14 @@
-#include "cache.h"
+#include "git-compat-util.h"
#include "config.h"
+#include "environment.h"
+#include "gettext.h"
+#include "hex.h"
#include "refs.h"
#include "pkt-line.h"
#include "sideband.h"
#include "repository.h"
#include "object-store.h"
+#include "oid-array.h"
#include "tag.h"
#include "object.h"
#include "commit.h"
@@ -19,6 +23,7 @@
#include "version.h"
#include "string-list.h"
#include "strvec.h"
+#include "trace2.h"
#include "prio-queue.h"
#include "protocol.h"
#include "quote.h"
@@ -27,6 +32,8 @@
#include "commit-graph.h"
#include "commit-reach.h"
#include "shallow.h"
+#include "wrapper.h"
+#include "write-or-die.h"
/* Remember to update object flag allocation in object.h */
#define THEY_HAVE (1u << 11)
@@ -113,6 +120,7 @@ struct upload_pack_data {
unsigned allow_ref_in_want : 1; /* v2 only */
unsigned allow_sideband_all : 1; /* v2 only */
unsigned advertise_sid : 1;
+ unsigned sent_capabilities : 1;
};
static void upload_pack_data_init(struct upload_pack_data *data)
@@ -499,8 +507,8 @@ static int got_oid(struct upload_pack_data *data,
{
if (get_oid_hex(hex, oid))
die("git upload-pack: expected SHA1 object, got '%s'", hex);
- if (!has_object_file_with_flags(oid,
- OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT))
+ if (!repo_has_object_file_with_flags(the_repository, oid,
+ OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT))
return -1;
return do_got_oid(data, oid);
}
@@ -1063,7 +1071,7 @@ static void receive_needs(struct upload_pack_data *data,
const char *features;
struct object_id oid_buf;
const char *arg;
- int feature_len;
+ size_t feature_len;
reset_timeout(data->timeout);
if (packet_reader_read(reader) != PACKET_READ_NORMAL)
@@ -1199,18 +1207,17 @@ static void format_session_id(struct strbuf *buf, struct upload_pack_data *d) {
strbuf_addf(buf, " session-id=%s", trace2_session_id());
}
-static int send_ref(const char *refname, const struct object_id *oid,
- int flag UNUSED, void *cb_data)
+static void write_v0_ref(struct upload_pack_data *data,
+ const char *refname, const char *refname_nons,
+ const struct object_id *oid)
{
static const char *capabilities = "multi_ack thin-pack side-band"
" side-band-64k ofs-delta shallow deepen-since deepen-not"
" deepen-relative no-progress include-tag multi_ack_detailed";
- const char *refname_nons = strip_namespace(refname);
struct object_id peeled;
- struct upload_pack_data *data = cb_data;
if (mark_our_ref(refname_nons, refname, oid, &data->hidden_refs))
- return 0;
+ return;
if (capabilities) {
struct strbuf symref_info = STRBUF_INIT;
@@ -1233,12 +1240,20 @@ static int send_ref(const char *refname, const struct object_id *oid,
git_user_agent_sanitized());
strbuf_release(&symref_info);
strbuf_release(&session_id);
+ data->sent_capabilities = 1;
} else {
packet_fwrite_fmt(stdout, "%s %s\n", oid_to_hex(oid), refname_nons);
}
capabilities = NULL;
if (!peel_iterated_oid(oid, &peeled))
packet_fwrite_fmt(stdout, "%s %s^{}\n", oid_to_hex(&peeled), refname_nons);
+ return;
+}
+
+static int send_ref(const char *refname, const struct object_id *oid,
+ int flag UNUSED, void *cb_data)
+{
+ write_v0_ref(cb_data, refname, strip_namespace(refname), oid);
return 0;
}
@@ -1372,6 +1387,10 @@ void upload_pack(const int advertise_refs, const int stateless_rpc,
data.no_done = 1;
head_ref_namespaced(send_ref, &data);
for_each_namespaced_ref(send_ref, &data);
+ if (!data.sent_capabilities) {
+ const char *refname = "capabilities^{}";
+ write_v0_ref(&data, refname, refname, null_oid());
+ }
/*
* fflush stdout before calling advertise_shallow_grafts because send_ref
* uses stdio.
@@ -1600,8 +1619,8 @@ static int process_haves(struct upload_pack_data *data, struct oid_array *common
for (i = 0; i < data->haves.nr; i++) {
const struct object_id *oid = &data->haves.oid[i];
- if (!has_object_file_with_flags(oid,
- OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT))
+ if (!repo_has_object_file_with_flags(the_repository, oid,
+ OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT))
continue;
oid_array_append(common, oid);
@@ -1699,7 +1718,7 @@ enum fetch_state {
FETCH_DONE,
};
-int upload_pack_v2(struct repository *r, struct packet_reader *request)
+int upload_pack_v2(struct repository *r UNUSED, struct packet_reader *request)
{
enum fetch_state state = FETCH_PROCESS_ARGS;
struct upload_pack_data data;
@@ -1775,26 +1794,26 @@ int upload_pack_advertise(struct repository *r,
strbuf_addstr(value, "shallow wait-for-done");
- if (!repo_config_get_bool(the_repository,
+ if (!repo_config_get_bool(r,
"uploadpack.allowfilter",
&allow_filter_value) &&
allow_filter_value)
strbuf_addstr(value, " filter");
- if (!repo_config_get_bool(the_repository,
+ if (!repo_config_get_bool(r,
"uploadpack.allowrefinwant",
&allow_ref_in_want) &&
allow_ref_in_want)
strbuf_addstr(value, " ref-in-want");
if (git_env_bool("GIT_TEST_SIDEBAND_ALL", 0) ||
- (!repo_config_get_bool(the_repository,
+ (!repo_config_get_bool(r,
"uploadpack.allowsidebandall",
&allow_sideband_all_value) &&
allow_sideband_all_value))
strbuf_addstr(value, " sideband-all");
- if (!repo_config_get_string(the_repository,
+ if (!repo_config_get_string(r,
"uploadpack.blobpackfileuri",
&str) &&
str) {