Merge branch 'ps/cat-file-remote-object-info-type' into seen
The 'remote-object-info' command for 'git cat-file --batch-command' has been extended to support the '%(objecttype)' placeholder. * ps/cat-file-remote-object-info-type: cat-file: unify default format serve: advertise type capability fetch-object-info: request all supported options dynamically fetch-object-info: parse type from server response protocol-caps: add type support to object-infoseen
commit
2eedebac73
|
|
@ -348,15 +348,12 @@ newline. The available atoms are:
|
|||
after that first run of whitespace (i.e., the "rest" of the
|
||||
line) are output in place of the `%(rest)` atom.
|
||||
|
||||
The command `remote-object-info` only supports the `%(objectname)` and
|
||||
`%(objectsize)` placeholders. See `CAVEATS` below for more information.
|
||||
The command `remote-object-info` only supports the `%(objectname)`,
|
||||
`%(objectsize)` and `%(objecttype)` placeholders. See `CAVEATS` below for more
|
||||
information.
|
||||
|
||||
If no format is specified, the default format is `%(objectname)
|
||||
%(objecttype) %(objectsize)`, except for `remote-object-info` commands which
|
||||
use `%(objectname) %(objectsize)` because `%(objecttype)` is not supported yet.
|
||||
|
||||
WARNING: When "%(objecttype)" is supported, the default format WILL be unified,
|
||||
so DO NOT RELY on the current default format to stay the same!!!
|
||||
%(objecttype) %(objectsize)`.
|
||||
|
||||
If `--batch` is specified, or if `--batch-command` is used with the `contents`
|
||||
command, the object information is followed by the object contents (consisting
|
||||
|
|
@ -453,9 +450,9 @@ scripting purposes.
|
|||
CAVEATS
|
||||
-------
|
||||
|
||||
Note that only `%(objectname)` and `%(objectsize)` are currently
|
||||
supported by the `remote-object-info` command. Using any other placeholder in
|
||||
the format string will return an empty string in its position.
|
||||
Note that only `%(objectname)`, `%(objectsize)` and `%(objecttype)` are
|
||||
currently supported by the `remote-object-info` command. Using any other
|
||||
placeholder in the format string will return an empty string in its position.
|
||||
|
||||
Note that the sizes of objects on disk are reported accurately, but care
|
||||
should be taken in drawing conclusions about which refs or objects are
|
||||
|
|
|
|||
|
|
@ -558,14 +558,17 @@ object-info
|
|||
|
||||
`object-info` is the command to retrieve information about one or more objects.
|
||||
Its main purpose is to allow a client to make decisions based on this
|
||||
information without having to fully fetch objects. Object size is the only
|
||||
information that is currently supported.
|
||||
information without having to fully fetch objects. Object size and type are the
|
||||
only information that is currently supported.
|
||||
|
||||
An `object-info` request takes the following arguments:
|
||||
|
||||
size
|
||||
Requests size information to be returned for each listed object id.
|
||||
|
||||
type
|
||||
Requests type information to be returned for each listed object id.
|
||||
|
||||
oid <oid>
|
||||
Indicates to the server an object which the client wants to obtain
|
||||
information for. They must be full OIDs.
|
||||
|
|
@ -580,11 +583,15 @@ space.
|
|||
info = *PKT-LINE(attr LF)
|
||||
*PKT-LINE(obj-info LF)
|
||||
|
||||
attr = "size"
|
||||
attr = "size" | "type"
|
||||
|
||||
obj-size = 1*DIGIT
|
||||
|
||||
obj-info = obj-id [SP [obj-size]]
|
||||
obj-type = "blob" | "tree" | "commit" | "tag"
|
||||
|
||||
obj-val = obj-size | obj-type
|
||||
|
||||
obj-info = obj-id [SP [obj-val *(SP obj-val)]]
|
||||
|
||||
If the server does not recognize the OID, the response will be `<oid> SP`
|
||||
regardless of the number of attributes requested.
|
||||
|
|
|
|||
|
|
@ -841,15 +841,9 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
|
|||
struct object_info *remote_object_info = NULL;
|
||||
struct oid_array object_info_oids = OID_ARRAY_INIT;
|
||||
struct string_list object_info_options = STRING_LIST_INIT_NODUP;
|
||||
const char *saved_format = opt->format;
|
||||
|
||||
if (strlen(line) >= MAX_REMOTE_OBJ_INFO_LINE)
|
||||
die(_("remote-object-info command too long"));
|
||||
/*
|
||||
* TODO: Use the default format once %(objecttype) is supported.
|
||||
*/
|
||||
if (!opt->format)
|
||||
opt->format = "%(objectname) %(objectsize)";
|
||||
|
||||
line_to_split = xstrdup(line);
|
||||
count = split_cmdline(line_to_split, &argv);
|
||||
|
|
@ -904,7 +898,6 @@ static void parse_cmd_remote_object_info(struct batch_options *opt,
|
|||
data->is_remote = 0;
|
||||
}
|
||||
data->skip_object_info = 0;
|
||||
opt->format = saved_format;
|
||||
|
||||
for (size_t i = 0; i < object_info_oids.nr; i++)
|
||||
free_object_info_contents(&remote_object_info[i]);
|
||||
|
|
|
|||
|
|
@ -15,10 +15,13 @@ static void send_object_info_request(const int fd_out, struct object_info_args *
|
|||
|
||||
write_command_and_capabilities(&req_buf, "object-info", args->server_options);
|
||||
|
||||
if (unsorted_string_list_has_string(args->object_info_options, "size"))
|
||||
packet_buf_write(&req_buf, "size");
|
||||
else if (args->object_info_options->nr)
|
||||
BUG("only size should be in object_info_options");
|
||||
/*
|
||||
* The list is already checked to only request valid and supported fields
|
||||
* no need to check, just request everything left on the list
|
||||
*/
|
||||
for (size_t i = 0; i < args->object_info_options->nr; i++)
|
||||
packet_buf_write(&req_buf, "%s",
|
||||
args->object_info_options->items[i].string);
|
||||
|
||||
if (args->oids)
|
||||
for (size_t i = 0; i < args->oids->nr; i++)
|
||||
|
|
@ -50,6 +53,7 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
|
|||
const int stateless_rpc, const int fd_out)
|
||||
{
|
||||
int size_index = -1;
|
||||
int type_index = -1;
|
||||
|
||||
switch (version) {
|
||||
case protocol_v2:
|
||||
|
|
@ -101,8 +105,13 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
|
|||
for (size_t j = 0; j < args->oids->nr; j++)
|
||||
object_info_data[j].sizep =
|
||||
xcalloc(1, sizeof(*object_info_data[j].sizep));
|
||||
} else if (!strcmp(reader->line, "type")) {
|
||||
type_index = (int)i;
|
||||
for (size_t j = 0; j < args->oids->nr; j++)
|
||||
object_info_data[j].typep =
|
||||
xcalloc(1, sizeof(*object_info_data[j].typep));
|
||||
} else {
|
||||
BUG("only size is supported");
|
||||
BUG("unexpected object-info option: %s", reader->line);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -148,6 +157,10 @@ int fetch_object_info(const enum protocol_version version, struct object_info_ar
|
|||
object_info_values.items[0].string,
|
||||
object_info_values.items[size_index + 1].string);
|
||||
|
||||
if (type_index >= 0)
|
||||
*object_info_data[i].typep =
|
||||
type_from_string(object_info_values.items[type_index + 1].string);
|
||||
|
||||
string_list_clear(&object_info_values, 0);
|
||||
}
|
||||
check_stateless_delimiter(stateless_rpc, reader, "stateless delimiter expected");
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@
|
|||
#include "strbuf.h"
|
||||
|
||||
struct requested_info {
|
||||
unsigned size : 1;
|
||||
unsigned size:1;
|
||||
unsigned type:1;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -73,15 +74,20 @@ static void send_info(struct repository *r, struct packet_writer *writer,
|
|||
if (info->size)
|
||||
packet_writer_write(writer, "size");
|
||||
|
||||
if (info->type)
|
||||
packet_writer_write(writer, "type");
|
||||
|
||||
for_each_string_list_item (item, oid_str_list) {
|
||||
const char *oid_str = item->string;
|
||||
struct object_id oid;
|
||||
size_t object_size;
|
||||
enum object_type object_type;
|
||||
|
||||
if (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {
|
||||
packet_writer_error(
|
||||
writer,
|
||||
"object-info: protocol error, expected to get oid, not '%s'",
|
||||
"object-info: protocol error, expected to get "
|
||||
"oid, not '%s'",
|
||||
oid_str);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -93,7 +99,8 @@ static void send_info(struct repository *r, struct packet_writer *writer,
|
|||
* If an object is not recognized by the server append SP to
|
||||
* the response.
|
||||
*/
|
||||
if (get_object_info(r->objects, &oid, &object_size) <= OBJ_NONE) {
|
||||
object_type = get_object_info(r->objects, &oid, &object_size);
|
||||
if (object_type <= OBJ_NONE) {
|
||||
strbuf_addstr(&send_buffer, " ");
|
||||
goto write;
|
||||
}
|
||||
|
|
@ -103,6 +110,9 @@ static void send_info(struct repository *r, struct packet_writer *writer,
|
|||
(uintmax_t)object_size);
|
||||
}
|
||||
|
||||
if (info->type)
|
||||
strbuf_addf(&send_buffer, " %s", type_name(object_type));
|
||||
|
||||
write:
|
||||
packet_writer_write(writer, "%s", send_buffer.buf);
|
||||
strbuf_reset(&send_buffer);
|
||||
|
|
@ -124,6 +134,11 @@ int cap_object_info(struct repository *r, struct packet_reader *request)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp("type", request->line)) {
|
||||
info.type = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parse_oid(request->line, &oid_str_list))
|
||||
continue;
|
||||
|
||||
|
|
|
|||
4
serve.c
4
serve.c
|
|
@ -97,9 +97,9 @@ static int object_info_advertise(struct repository *r, struct strbuf *value)
|
|||
/* disabled by default */
|
||||
advertise_object_info = 0;
|
||||
}
|
||||
/* Currently only size is supported */
|
||||
/* Currently only size and type are supported */
|
||||
if (value && advertise_object_info)
|
||||
strbuf_addstr(value, "size");
|
||||
strbuf_addstr(value, "size type");
|
||||
return advertise_object_info;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ test_description='git cat-file --batch-command with remote-object-info command'
|
|||
|
||||
hello_content="Hello World"
|
||||
hello_size=$(strlen "$hello_content")
|
||||
hello_type="blob"
|
||||
hello_oid=$(echo_without_newline "$hello_content" | git hash-object --stdin)
|
||||
hello_short_oid=$(git rev-parse --short "$hello_oid")
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ unstored_oid=$(echo_without_newline "$unstored_content" | git hash-object --stdi
|
|||
# file name is hello, which is 5 characters
|
||||
# a space is 1 character and a null is 1 character
|
||||
tree_size=$(($(test_oid rawsz) + 13))
|
||||
tree_type="tree"
|
||||
|
||||
commit_message="Initial commit"
|
||||
|
||||
|
|
@ -31,6 +33,7 @@ commit_message="Initial commit"
|
|||
# An easier way to calculate is: 1. use `git cat-file commit <commit hash> | wc -c`,
|
||||
# to get 177, 2. then deduct 40 hex characters to get 137
|
||||
commit_size=$(($(test_oid hexsz) + 137))
|
||||
commit_type="commit"
|
||||
|
||||
tag_header_without_oid="type blob
|
||||
tag hellotag
|
||||
|
|
@ -44,6 +47,7 @@ $tag_description"
|
|||
|
||||
tag_oid=$(echo_without_newline "$tag_content" | git hash-object -t tag --stdin -w)
|
||||
tag_size=$(strlen "$tag_content")
|
||||
tag_type="tag"
|
||||
|
||||
set_transport_variables () {
|
||||
hello_oid=$(echo_without_newline "$hello_content" | git hash-object --stdin)
|
||||
|
|
@ -135,10 +139,10 @@ test_expect_success 'batch-command remote-object-info git:// default filter' '
|
|||
set_transport_variables "$daemon_parent" &&
|
||||
cd "$daemon_parent/daemon_client_empty" &&
|
||||
|
||||
echo "$hello_oid $hello_size" >expect &&
|
||||
echo "$tree_oid $tree_size" >>expect &&
|
||||
echo "$commit_oid $commit_size" >>expect &&
|
||||
echo "$tag_oid $tag_size" >>expect &&
|
||||
echo "$hello_oid $hello_type $hello_size" >expect &&
|
||||
echo "$tree_oid $tree_type $tree_size" >>expect &&
|
||||
echo "$commit_oid $commit_type $commit_size" >>expect &&
|
||||
echo "$tag_oid $tag_type $tag_size" >>expect &&
|
||||
|
||||
git cat-file --batch-command >actual <<-EOF &&
|
||||
remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid $tree_oid
|
||||
|
|
@ -148,28 +152,6 @@ test_expect_success 'batch-command remote-object-info git:// default filter' '
|
|||
)
|
||||
'
|
||||
|
||||
test_expect_success 'remote-object-info does not change the default format of info' '
|
||||
(
|
||||
set_transport_variables "$daemon_parent" &&
|
||||
cd "$daemon_parent/daemon_client_empty" &&
|
||||
|
||||
local_content="local object" &&
|
||||
local_oid=$(echo_without_newline "$local_content" | git hash-object -w --stdin) &&
|
||||
local_size=$(strlen "$local_content") &&
|
||||
|
||||
echo "$local_oid blob $local_size" >expect &&
|
||||
echo "$hello_oid $hello_size" >>expect &&
|
||||
echo "$local_oid blob $local_size" >>expect &&
|
||||
|
||||
git cat-file --batch-command >actual <<-EOF &&
|
||||
info $local_oid
|
||||
remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid
|
||||
info $local_oid
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'batch-command --buffer remote-object-info git://' '
|
||||
(
|
||||
set_transport_variables "$daemon_parent" &&
|
||||
|
|
@ -205,10 +187,10 @@ test_expect_success 'batch-command -Z remote-object-info git:// default filter'
|
|||
set_transport_variables "$daemon_parent" &&
|
||||
cd "$daemon_parent/daemon_client_empty" &&
|
||||
|
||||
printf "%s\0" "$hello_oid $hello_size" >expect &&
|
||||
printf "%s\0" "$tree_oid $tree_size" >>expect &&
|
||||
printf "%s\0" "$commit_oid $commit_size" >>expect &&
|
||||
printf "%s\0" "$tag_oid $tag_size" >>expect &&
|
||||
printf "%s\0" "$hello_oid $hello_type $hello_size" >expect &&
|
||||
printf "%s\0" "$tree_oid $tree_type $tree_size" >>expect &&
|
||||
printf "%s\0" "$commit_oid $commit_type $commit_size" >>expect &&
|
||||
printf "%s\0" "$tag_oid $tag_type $tag_size" >>expect &&
|
||||
|
||||
printf "%s\0" "$hello_oid missing" >>expect &&
|
||||
printf "%s\0" "$tree_oid missing" >>expect &&
|
||||
|
|
@ -256,14 +238,12 @@ test_expect_success 'remote-object-info does not die on missing oid like info' '
|
|||
)
|
||||
'
|
||||
|
||||
# This tests depends on %(objecttype) not being supported yet, once supported
|
||||
# it needs to be updated.
|
||||
test_expect_success 'unsupported placeholder on remote returns empty string' '
|
||||
test_expect_success 'objecttype is supported by remote-object-info' '
|
||||
(
|
||||
set_transport_variables "$daemon_parent" &&
|
||||
cd "$daemon_parent/daemon_client_empty" &&
|
||||
|
||||
echo "" >expect &&
|
||||
echo $hello_type >expect &&
|
||||
git cat-file --batch-command="%(objecttype)" >actual <<-EOF &&
|
||||
remote-object-info "$GIT_DAEMON_URL/parent" $hello_oid
|
||||
EOF
|
||||
|
|
@ -430,10 +410,10 @@ test_expect_success 'batch-command remote-object-info file:// default filter' '
|
|||
server_path="$(pwd)/server" &&
|
||||
cd file_client_empty &&
|
||||
|
||||
echo "$hello_oid $hello_size" >expect &&
|
||||
echo "$tree_oid $tree_size" >>expect &&
|
||||
echo "$commit_oid $commit_size" >>expect &&
|
||||
echo "$tag_oid $tag_size" >>expect &&
|
||||
echo "$hello_oid $hello_type $hello_size" >expect &&
|
||||
echo "$tree_oid $tree_type $tree_size" >>expect &&
|
||||
echo "$commit_oid $commit_type $commit_size" >>expect &&
|
||||
echo "$tag_oid $tag_type $tag_size" >>expect &&
|
||||
|
||||
git cat-file --batch-command >actual <<-EOF &&
|
||||
remote-object-info "file://${server_path}" $hello_oid $tree_oid
|
||||
|
|
@ -449,10 +429,10 @@ test_expect_success 'batch-command -Z remote-object-info file:// default filter'
|
|||
server_path="$(pwd)/server" &&
|
||||
cd file_client_empty &&
|
||||
|
||||
printf "%s\0" "$hello_oid $hello_size" >expect &&
|
||||
printf "%s\0" "$tree_oid $tree_size" >>expect &&
|
||||
printf "%s\0" "$commit_oid $commit_size" >>expect &&
|
||||
printf "%s\0" "$tag_oid $tag_size" >>expect &&
|
||||
printf "%s\0" "$hello_oid $hello_type $hello_size" >expect &&
|
||||
printf "%s\0" "$tree_oid $tree_type $tree_size" >>expect &&
|
||||
printf "%s\0" "$commit_oid $commit_type $commit_size" >>expect &&
|
||||
printf "%s\0" "$tag_oid $tag_type $tag_size" >>expect &&
|
||||
|
||||
printf "%s\0" "$hello_oid missing" >>expect &&
|
||||
printf "%s\0" "$tree_oid missing" >>expect &&
|
||||
|
|
@ -600,10 +580,10 @@ test_expect_success 'batch-command remote-object-info http:// default filter' '
|
|||
set_transport_variables "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
|
||||
cd "$HTTPD_DOCUMENT_ROOT_PATH/http_client_empty" &&
|
||||
|
||||
echo "$hello_oid $hello_size" >expect &&
|
||||
echo "$tree_oid $tree_size" >>expect &&
|
||||
echo "$commit_oid $commit_size" >>expect &&
|
||||
echo "$tag_oid $tag_size" >>expect &&
|
||||
echo "$hello_oid $hello_type $hello_size" >expect &&
|
||||
echo "$tree_oid $tree_type $tree_size" >>expect &&
|
||||
echo "$commit_oid $commit_type $commit_size" >>expect &&
|
||||
echo "$tag_oid $tag_type $tag_size" >>expect &&
|
||||
|
||||
git cat-file --batch-command >actual <<-EOF &&
|
||||
remote-object-info "$HTTPD_URL/smart/http_parent" $hello_oid $tree_oid
|
||||
|
|
@ -618,10 +598,10 @@ test_expect_success 'batch-command -Z remote-object-info http:// default filter'
|
|||
set_transport_variables "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
|
||||
cd "$HTTPD_DOCUMENT_ROOT_PATH/http_client_empty" &&
|
||||
|
||||
printf "%s\0" "$hello_oid $hello_size" >expect &&
|
||||
printf "%s\0" "$tree_oid $tree_size" >>expect &&
|
||||
printf "%s\0" "$commit_oid $commit_size" >>expect &&
|
||||
printf "%s\0" "$tag_oid $tag_size" >>expect &&
|
||||
printf "%s\0" "$hello_oid $hello_type $hello_size" >expect &&
|
||||
printf "%s\0" "$tree_oid $tree_type $tree_size" >>expect &&
|
||||
printf "%s\0" "$commit_oid $commit_type $commit_size" >>expect &&
|
||||
printf "%s\0" "$tag_oid $tag_type $tag_size" >>expect &&
|
||||
|
||||
batch_input="remote-object-info $HTTPD_URL/smart/http_parent $hello_oid $tree_oid
|
||||
remote-object-info $HTTPD_URL/smart/http_parent $commit_oid $tag_oid
|
||||
|
|
|
|||
|
|
@ -366,6 +366,33 @@ test_expect_success 'basics of object-info' '
|
|||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'type' '
|
||||
test_config transfer.advertiseObjectInfo true &&
|
||||
|
||||
test-tool pkt-line pack >in <<-EOF &&
|
||||
command=object-info
|
||||
object-format=$(test_oid algo)
|
||||
0001
|
||||
size
|
||||
type
|
||||
oid $(git rev-parse two:two.t)
|
||||
oid $(git rev-parse two:two.t)
|
||||
0000
|
||||
EOF
|
||||
|
||||
cat >expect <<-EOF &&
|
||||
size
|
||||
type
|
||||
$(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
|
||||
$(git rev-parse two:two.t) $(wc -c <two.t | xargs) blob
|
||||
0000
|
||||
EOF
|
||||
|
||||
test-tool serve-v2 --stateless-rpc <in >out &&
|
||||
test-tool pkt-line unpack <out >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success 'bare OID request' '
|
||||
test_config transfer.advertiseObjectInfo true &&
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue