summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/cat-file.c7
-rw-r--r--fetch-object-info.c38
-rw-r--r--fetch-object-info.h3
3 files changed, 45 insertions, 3 deletions
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 8dcad2f5eb..8502020083 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -842,6 +842,8 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
if (data->info.sizep)
results.wants_size = 1;
+ if (data->info.typep)
+ results.wants_type = 1;
if (get_remote_info(count, argv, &results, &object_info_oids))
die(_("failed to get object info from the remote: %s"), argv[0]);
@@ -850,6 +852,8 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
string_list_append(&data->remote_allowed_atoms, "objectname");
if (results.sizes)
string_list_append(&data->remote_allowed_atoms, "objectsize");
+ if (results.types)
+ string_list_append(&data->remote_allowed_atoms, "objecttype");
data->skip_object_info = 1;
for (size_t i = 0; i < results.nr; i++) {
@@ -868,6 +872,9 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
if (results.sizes)
data->size = results.sizes[i];
+ if (results.types)
+ data->type = results.types[i];
+
opt->batch_mode = BATCH_MODE_INFO;
data->is_remote = 1;
batch_object_write(argv[i + 1], output, opt, data, NULL, 0);
diff --git a/fetch-object-info.c b/fetch-object-info.c
index fe26bf4bbc..0a58308f9b 100644
--- a/fetch-object-info.c
+++ b/fetch-object-info.c
@@ -1,6 +1,7 @@
#include "git-compat-util.h"
#include "gettext.h"
#include "hex.h"
+#include "object.h"
#include "pkt-line.h"
#include "connect.h"
#include "oid-array.h"
@@ -12,7 +13,8 @@
static void send_object_info_request(const int fd_out,
const struct string_list *server_options,
const struct oid_array *oids,
- unsigned ask_size)
+ unsigned ask_size,
+ unsigned ask_type)
{
struct strbuf req_buf = STRBUF_INIT;
@@ -21,6 +23,9 @@ static void send_object_info_request(const int fd_out,
if (ask_size)
packet_buf_write(&req_buf, "size");
+ if (ask_type)
+ packet_buf_write(&req_buf, "type");
+
if (oids)
for (size_t i = 0; i < oids->nr; i++)
packet_buf_write(&req_buf, "oid %s",
@@ -56,7 +61,9 @@ void fetch_object_info(const enum protocol_version version,
const int fd_out)
{
unsigned ask_size = 0;
+ unsigned ask_type = 0;
int size_index = -1;
+ int type_index = -1;
size_t wanted;
results->nr = oids->nr;
@@ -71,11 +78,16 @@ void fetch_object_info(const enum protocol_version version,
server_supports_feature("object-info", "size", 0))
ask_size = 1;
+ if (results->wants_type &&
+ server_supports_feature("object-info", "type", 0))
+ ask_type = 1;
+
/*
* Even if no options are left, we still send the oid so we get
* at least an existence check.
*/
- send_object_info_request(fd_out, server_options, oids, ask_size);
+ send_object_info_request(fd_out, server_options, oids, ask_size,
+ ask_type);
break;
case protocol_v1:
case protocol_v0:
@@ -83,7 +95,7 @@ void fetch_object_info(const enum protocol_version version,
case protocol_unknown_version:
BUG("unknown protocol version");
}
- wanted = ask_size;
+ wanted = ask_size + ask_type;
for (size_t i = 0; i < wanted; i++) {
if (packet_reader_read(reader) != PACKET_READ_NORMAL) {
@@ -100,6 +112,13 @@ void fetch_object_info(const enum protocol_version version,
die(_("object-info: duplicate 'size' attribute"));
size_index = (int)i;
CALLOC_ARRAY(results->sizes, results->nr);
+ } else if (!strcmp(reader->line, "type")) {
+ if (!ask_type)
+ die(_("object-info: unrequested 'type' attribute"));
+ if (results->types)
+ die(_("object-info: duplicate 'type' attribute"));
+ type_index = (int)i;
+ CALLOC_ARRAY(results->types, results->nr);
} else {
die(_("object-info: unknown attribute '%s'"),
reader->line);
@@ -149,6 +168,18 @@ void fetch_object_info(const enum protocol_version version,
object_info_values.items[0].string,
object_info_values.items[size_index + 1].string);
+ if (results->types) {
+ const char *type_str =
+ object_info_values.items[type_index + 1].string;
+ int type = type_from_string_gently(type_str, -1, 1);
+
+ if (type < 0)
+ die(_("object-info: object %s has invalid type '%s'"),
+ object_info_values.items[0].string, type_str);
+
+ results->types[i] = type;
+ }
+
string_list_clear(&object_info_values, 0);
}
@@ -162,6 +193,7 @@ void fetch_object_info(const enum protocol_version version,
void free_fetch_object_info_results(struct fetch_object_info_results *results)
{
free(results->sizes);
+ free(results->types);
free(results->unrecognized);
memset(results, 0, sizeof(*results));
}
diff --git a/fetch-object-info.h b/fetch-object-info.h
index 10cf9f5f63..2fba96c6f7 100644
--- a/fetch-object-info.h
+++ b/fetch-object-info.h
@@ -1,14 +1,17 @@
#ifndef FETCH_OBJECT_INFO_H
#define FETCH_OBJECT_INFO_H
+#include "object.h"
#include "pkt-line.h"
#include "protocol.h"
struct fetch_object_info_results {
size_t *sizes;
+ enum object_type *types;
uint8_t *unrecognized;
size_t nr;
unsigned wants_size:1;
+ unsigned wants_type:1;
};
#define FETCH_OBJECT_INFO_RESULTS_INIT { 0 }