Skip to content

Commit 714dca7

Browse files
peijianjugitster
authored andcommitted
cat-file: add remote-object-info to batch-command
Since the `info` command in `cat-file --batch-command` prints object info for a given object, it is natural to add another command in `cat-file --batch-command` to print object info for a given object from a remote. Add `remote-object-info` to `cat-file --batch-command`. While `info` takes object ids one at a time, this creates overhead when making requests to a server. So `remote-object-info` instead can take multiple object ids at once. The `cat-file --batch-command` command is generally implemented in the following manner: - Receive and parse input from user - Call respective function attached to command - Get object info, print object info In --buffer mode, this changes to: - Receive and parse input from user - Store respective function attached to command in a queue - After flush, loop through commands in queue - Call respective function attached to command - Get object info, print object info Notice how the getting and printing of object info is accomplished one at a time. As described above, this creates a problem for making requests to a server. Therefore, `remote-object-info` is implemented in the following manner: - Receive and parse input from user If command is `remote-object-info`: - Get object info from remote - Loop through and print each object info Else: - Call respective function attached to command - Parse input, get object info, print object info And finally for --buffer mode `remote-object-info`: - Receive and parse input from user - Store respective function attached to command in a queue - After flush, loop through commands in queue: If command is `remote-object-info`: - Get object info from remote - Loop through and print each object info Else: - Call respective function attached to command - Get object info, print object info To summarize, `remote-object-info` gets object info from the remote and then loops through the object info passed in, printing the info. In order for `remote-object-info` to avoid remote communication overhead in the non-buffer mode, the objects are passed in as such: remote-object-info <remote> <oid> <oid> ... <oid> rather than remote-object-info <remote> <oid> remote-object-info <remote> <oid> ... remote-object-info <remote> <oid> Helped-by: Jonathan Tan <jonathantanmy@google.com> Helped-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Eric Ju <eric.peijian@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 63c3105 commit 714dca7

File tree

5 files changed

+794
-4
lines changed

5 files changed

+794
-4
lines changed

Documentation/git-cat-file.txt

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@ info <object>::
149149
Print object info for object reference `<object>`. This corresponds to the
150150
output of `--batch-check`.
151151

152+
remote-object-info <remote> <object>...::
153+
Print object info for object references `<object>` at specified
154+
`<remote>` without downloading objects from the remote.
155+
Raise an error when the `object-info` capability is not supported by the remote.
156+
Raise an error when no object references are provided.
157+
This command may be combined with `--buffer`.
158+
152159
flush::
153160
Used with `--buffer` to execute all preceding commands that were issued
154161
since the beginning or since the last flush was issued. When `--buffer`
@@ -290,21 +297,23 @@ newline. The available atoms are:
290297
The full hex representation of the object name.
291298

292299
`objecttype`::
293-
The type of the object (the same as `cat-file -t` reports).
300+
The type of the object (the same as `cat-file -t` reports). See
301+
`CAVEATS` below. Not supported by `remote-object-info`.
294302

295303
`objectsize`::
296304
The size, in bytes, of the object (the same as `cat-file -s`
297305
reports).
298306

299307
`objectsize:disk`::
300308
The size, in bytes, that the object takes up on disk. See the
301-
note about on-disk sizes in the `CAVEATS` section below.
309+
note about on-disk sizes in the `CAVEATS` section below. Not
310+
supported by `remote-object-info`.
302311

303312
`deltabase`::
304313
If the object is stored as a delta on-disk, this expands to the
305314
full hex representation of the delta base object name.
306315
Otherwise, expands to the null OID (all zeroes). See `CAVEATS`
307-
below.
316+
below. Not supported by `remote-object-info`.
308317

309318
`rest`::
310319
If this atom is used in the output string, input lines are split
@@ -314,7 +323,10 @@ newline. The available atoms are:
314323
line) are output in place of the `%(rest)` atom.
315324

316325
If no format is specified, the default format is `%(objectname)
317-
%(objecttype) %(objectsize)`.
326+
%(objecttype) %(objectsize)`, except for `remote-object-info` commands which use
327+
`%(objectname) %(objectsize)` for now because "%(objecttype)" is not supported yet.
328+
WARNING: When "%(objecttype)" is supported, the default format WILL be unified, so
329+
DO NOT RELY on the current default format to stay the same!!!
318330

319331
If `--batch` is specified, or if `--batch-command` is used with the `contents`
320332
command, the object information is followed by the object contents (consisting
@@ -396,6 +408,10 @@ scripting purposes.
396408
CAVEATS
397409
-------
398410

411+
Note that since %(objecttype), %(objectsize:disk) and %(deltabase) are
412+
currently not supported by the `remote-object-info` command, we will raise
413+
an error and exit when they appear in the format string.
414+
399415
Note that the sizes of objects on disk are reported accurately, but care
400416
should be taken in drawing conclusions about which refs or objects are
401417
responsible for disk usage. The size of a packed non-delta object may be

builtin/cat-file.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#include "promisor-remote.h"
2828
#include "mailmap.h"
2929
#include "write-or-die.h"
30+
#include "alias.h"
31+
#include "remote.h"
32+
#include "transport.h"
3033

3134
enum batch_mode {
3235
BATCH_MODE_CONTENTS,
@@ -48,6 +51,8 @@ struct batch_options {
4851
};
4952

5053
static const char *force_path;
54+
static struct object_info *remote_object_info;
55+
static struct oid_array object_info_oids = OID_ARRAY_INIT;
5156

5257
static struct string_list mailmap = STRING_LIST_INIT_NODUP;
5358
static int use_mailmap;
@@ -579,6 +584,61 @@ static void batch_one_object(const char *obj_name,
579584
object_context_release(&ctx);
580585
}
581586

587+
static int get_remote_info(struct batch_options *opt, int argc, const char **argv)
588+
{
589+
int retval = 0;
590+
struct remote *remote = NULL;
591+
struct object_id oid;
592+
struct string_list object_info_options = STRING_LIST_INIT_NODUP;
593+
static struct transport *gtransport;
594+
595+
/*
596+
* Change the format to "%(objectname) %(objectsize)" when
597+
* remote-object-info command is used. Once we start supporting objecttype
598+
* the default format should change to DEFAULT_FORMAT.
599+
*/
600+
if (!opt->format)
601+
opt->format = "%(objectname) %(objectsize)";
602+
603+
remote = remote_get(argv[0]);
604+
if (!remote)
605+
die(_("must supply valid remote when using remote-object-info"));
606+
607+
oid_array_clear(&object_info_oids);
608+
for (size_t i = 1; i < argc; i++) {
609+
if (get_oid_hex(argv[i], &oid))
610+
die(_("Not a valid object name %s"), argv[i]);
611+
oid_array_append(&object_info_oids, &oid);
612+
}
613+
if (!object_info_oids.nr)
614+
die(_("remote-object-info requires objects"));
615+
616+
gtransport = transport_get(remote, NULL);
617+
if (gtransport->smart_options) {
618+
CALLOC_ARRAY(remote_object_info, object_info_oids.nr);
619+
gtransport->smart_options->object_info = 1;
620+
gtransport->smart_options->object_info_oids = &object_info_oids;
621+
622+
/* 'objectsize' is the only option currently supported */
623+
if (!strstr(opt->format, "%(objectsize)"))
624+
die(_("%s is currently not supported with remote-object-info"), opt->format);
625+
626+
string_list_append(&object_info_options, "size");
627+
628+
if (object_info_options.nr > 0) {
629+
gtransport->smart_options->object_info_options = &object_info_options;
630+
gtransport->smart_options->object_info_data = remote_object_info;
631+
retval = transport_fetch_refs(gtransport, NULL);
632+
}
633+
} else {
634+
retval = -1;
635+
}
636+
637+
string_list_clear(&object_info_options, 0);
638+
transport_disconnect(gtransport);
639+
return retval;
640+
}
641+
582642
struct object_cb_data {
583643
struct batch_options *opt;
584644
struct expand_data *expand;
@@ -670,6 +730,41 @@ static void parse_cmd_info(struct batch_options *opt,
670730
batch_one_object(line, output, opt, data);
671731
}
672732

733+
static void parse_cmd_remote_object_info(struct batch_options *opt,
734+
const char *line, struct strbuf *output,
735+
struct expand_data *data)
736+
{
737+
int count;
738+
const char **argv;
739+
740+
char *line_to_split = xstrdup_or_null(line);
741+
count = split_cmdline(line_to_split, &argv);
742+
if (get_remote_info(opt, count, argv))
743+
goto cleanup;
744+
745+
data->skip_object_info = 1;
746+
for (size_t i = 0; i < object_info_oids.nr; i++) {
747+
data->oid = object_info_oids.oid[i];
748+
if (remote_object_info[i].sizep) {
749+
/*
750+
* When reaching here, it means remote-object-info can retrieve
751+
* information from server without downloading them.
752+
*/
753+
data->size = *remote_object_info[i].sizep;
754+
opt->batch_mode = BATCH_MODE_INFO;
755+
batch_object_write(argv[i+1], output, opt, data, NULL, 0);
756+
}
757+
}
758+
data->skip_object_info = 0;
759+
760+
cleanup:
761+
for (size_t i = 0; i < object_info_oids.nr; i++)
762+
free_object_info_contents(&remote_object_info[i]);
763+
free(line_to_split);
764+
free(argv);
765+
free(remote_object_info);
766+
}
767+
673768
static void dispatch_calls(struct batch_options *opt,
674769
struct strbuf *output,
675770
struct expand_data *data,
@@ -701,6 +796,7 @@ static const struct parse_cmd {
701796
} commands[] = {
702797
{ "contents", parse_cmd_contents, 1},
703798
{ "info", parse_cmd_info, 1},
799+
{ "remote-object-info", parse_cmd_remote_object_info, 1},
704800
{ "flush", NULL, 0},
705801
};
706802

object-file.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3128,3 +3128,14 @@ int read_loose_object(const char *path,
31283128
munmap(map, mapsize);
31293129
return ret;
31303130
}
3131+
3132+
void free_object_info_contents(struct object_info *object_info)
3133+
{
3134+
if (!object_info)
3135+
return;
3136+
free(object_info->typep);
3137+
free(object_info->sizep);
3138+
free(object_info->disk_sizep);
3139+
free(object_info->delta_base_oid);
3140+
free(object_info->type_name);
3141+
}

object-store-ll.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,4 +553,7 @@ int for_each_object_in_pack(struct packed_git *p,
553553
int for_each_packed_object(struct repository *repo, each_packed_object_fn cb,
554554
void *data, enum for_each_object_flags flags);
555555

556+
/* Free pointers inside of object_info, but not object_info itself */
557+
void free_object_info_contents(struct object_info *object_info);
558+
556559
#endif /* OBJECT_STORE_LL_H */

0 commit comments

Comments
 (0)