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
3134enum batch_mode {
3235 BATCH_MODE_CONTENTS ,
@@ -48,6 +51,8 @@ struct batch_options {
4851};
4952
5053static const char * force_path ;
54+ static struct object_info * remote_object_info ;
55+ static struct oid_array object_info_oids = OID_ARRAY_INIT ;
5156
5257static struct string_list mailmap = STRING_LIST_INIT_NODUP ;
5358static 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+
582642struct object_cb_data {
583643 struct batch_options * opt ;
584644 struct expand_data * expand ;
@@ -670,28 +730,59 @@ 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+
673768static void dispatch_calls (struct batch_options * opt ,
674769 struct strbuf * output ,
675770 struct expand_data * data ,
676771 struct queued_cmd * cmd ,
677772 int nr )
678773{
679- int i ;
680-
681774 if (!opt -> buffer_output )
682775 die (_ ("flush is only for --buffer mode" ));
683776
684- for (i = 0 ; i < nr ; i ++ )
777+ for (size_t i = 0 ; i < nr ; i ++ )
685778 cmd [i ].fn (opt , cmd [i ].line , output , data );
686779
687780 fflush (stdout );
688781}
689782
690783static void free_cmds (struct queued_cmd * cmd , size_t * nr )
691784{
692- size_t i ;
693-
694- for (i = 0 ; i < * nr ; i ++ )
785+ for (size_t i = 0 ; i < * nr ; i ++ )
695786 FREE_AND_NULL (cmd [i ].line );
696787
697788 * nr = 0 ;
@@ -705,6 +796,7 @@ static const struct parse_cmd {
705796} commands [] = {
706797 { "contents" , parse_cmd_contents , 1 },
707798 { "info" , parse_cmd_info , 1 },
799+ { "remote-object-info" , parse_cmd_remote_object_info , 1 },
708800 { "flush" , NULL , 0 },
709801};
710802
@@ -717,7 +809,6 @@ static void batch_objects_command(struct batch_options *opt,
717809 size_t alloc = 0 , nr = 0 ;
718810
719811 while (strbuf_getdelim_strip_crlf (& input , stdin , opt -> input_delim ) != EOF ) {
720- int i ;
721812 const struct parse_cmd * cmd = NULL ;
722813 const char * p = NULL , * cmd_end ;
723814 struct queued_cmd call = {0 };
@@ -727,7 +818,7 @@ static void batch_objects_command(struct batch_options *opt,
727818 if (isspace (* input .buf ))
728819 die (_ ("whitespace before command: '%s'" ), input .buf );
729820
730- for (i = 0 ; i < ARRAY_SIZE (commands ); i ++ ) {
821+ for (size_t i = 0 ; i < ARRAY_SIZE (commands ); i ++ ) {
731822 if (!skip_prefix (input .buf , commands [i ].name , & cmd_end ))
732823 continue ;
733824
0 commit comments