diff options
Diffstat (limited to 'upload-pack.c')
-rw-r--r-- | upload-pack.c | 51 |
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) { |