29
29
#include "promisor-remote.h"
30
30
#include "mailmap.h"
31
31
#include "write-or-die.h"
32
+ #include "alias.h"
33
+ #include "remote.h"
34
+ #include "transport.h"
35
+
36
+ /* Maximum length for a remote URL. While no universal standard exists,
37
+ * 8K is assumed to be a reasonable limit.
38
+ */
39
+ #define MAX_REMOTE_URL_LEN (8*1024)
40
+ /* Maximum number of objects allowed in a single remote-object-info request. */
41
+ #define MAX_ALLOWED_OBJ_LIMIT 10000
42
+ /* Maximum input size permitted for the remote-object-info command. */
43
+ #define MAX_REMOTE_OBJ_INFO_LINE (MAX_REMOTE_URL_LEN + MAX_ALLOWED_OBJ_LIMIT * (GIT_MAX_HEXSZ + 1))
32
44
33
45
enum batch_mode {
34
46
BATCH_MODE_CONTENTS ,
@@ -51,6 +63,8 @@ struct batch_options {
51
63
};
52
64
53
65
static const char * force_path ;
66
+ static struct object_info * remote_object_info ;
67
+ static struct oid_array object_info_oids = OID_ARRAY_INIT ;
54
68
55
69
static struct string_list mailmap = STRING_LIST_INIT_NODUP ;
56
70
static int use_mailmap ;
@@ -628,6 +642,61 @@ static void batch_one_object(const char *obj_name,
628
642
object_context_release (& ctx );
629
643
}
630
644
645
+ static int get_remote_info (struct batch_options * opt , int argc , const char * * argv )
646
+ {
647
+ int retval = 0 ;
648
+ struct remote * remote = NULL ;
649
+ struct object_id oid ;
650
+ struct string_list object_info_options = STRING_LIST_INIT_NODUP ;
651
+ static struct transport * gtransport ;
652
+
653
+ /*
654
+ * Change the format to "%(objectname) %(objectsize)" when
655
+ * remote-object-info command is used. Once we start supporting objecttype
656
+ * the default format should change to DEFAULT_FORMAT.
657
+ */
658
+ if (!opt -> format )
659
+ opt -> format = "%(objectname) %(objectsize)" ;
660
+
661
+ remote = remote_get (argv [0 ]);
662
+ if (!remote )
663
+ die (_ ("must supply valid remote when using remote-object-info" ));
664
+
665
+ oid_array_clear (& object_info_oids );
666
+ for (size_t i = 1 ; i < argc ; i ++ ) {
667
+ if (get_oid_hex (argv [i ], & oid ))
668
+ die (_ ("Not a valid object name %s" ), argv [i ]);
669
+ oid_array_append (& object_info_oids , & oid );
670
+ }
671
+ if (!object_info_oids .nr )
672
+ die (_ ("remote-object-info requires objects" ));
673
+
674
+ gtransport = transport_get (remote , NULL );
675
+ if (gtransport -> smart_options ) {
676
+ CALLOC_ARRAY (remote_object_info , object_info_oids .nr );
677
+ gtransport -> smart_options -> object_info = 1 ;
678
+ gtransport -> smart_options -> object_info_oids = & object_info_oids ;
679
+
680
+ /* 'objectsize' is the only option currently supported */
681
+ if (!strstr (opt -> format , "%(objectsize)" ))
682
+ die (_ ("%s is currently not supported with remote-object-info" ), opt -> format );
683
+
684
+ string_list_append (& object_info_options , "size" );
685
+
686
+ if (object_info_options .nr > 0 ) {
687
+ gtransport -> smart_options -> object_info_options = & object_info_options ;
688
+ gtransport -> smart_options -> object_info_data = remote_object_info ;
689
+ retval = transport_fetch_refs (gtransport , NULL );
690
+ }
691
+ } else {
692
+ retval = -1 ;
693
+ }
694
+
695
+ string_list_clear (& object_info_options , 0 );
696
+ transport_disconnect (gtransport );
697
+ return retval ;
698
+ }
699
+
631
700
struct object_cb_data {
632
701
struct batch_options * opt ;
633
702
struct expand_data * expand ;
@@ -695,28 +764,68 @@ static void parse_cmd_info(struct batch_options *opt,
695
764
batch_one_object (line , output , opt , data );
696
765
}
697
766
767
+ static void parse_cmd_remote_object_info (struct batch_options * opt ,
768
+ const char * line , struct strbuf * output ,
769
+ struct expand_data * data )
770
+ {
771
+ int count ;
772
+ const char * * argv ;
773
+ char * line_to_split ;
774
+
775
+ if (strlen (line ) >= MAX_REMOTE_OBJ_INFO_LINE )
776
+ die (_ ("remote-object-info command input overflow "
777
+ "(no more than %d objects are allowed)" ),
778
+ MAX_ALLOWED_OBJ_LIMIT );
779
+
780
+ line_to_split = xstrdup (line );
781
+ count = split_cmdline (line_to_split , & argv );
782
+ if (count < 0 )
783
+ die (_ ("split remote-object-info command" ));
784
+
785
+ if (get_remote_info (opt , count , argv ))
786
+ goto cleanup ;
787
+
788
+ data -> skip_object_info = 1 ;
789
+ for (size_t i = 0 ; i < object_info_oids .nr ; i ++ ) {
790
+ data -> oid = object_info_oids .oid [i ];
791
+ if (remote_object_info [i ].sizep ) {
792
+ /*
793
+ * When reaching here, it means remote-object-info can retrieve
794
+ * information from server without downloading them.
795
+ */
796
+ data -> size = * remote_object_info [i ].sizep ;
797
+ opt -> batch_mode = BATCH_MODE_INFO ;
798
+ batch_object_write (argv [i + 1 ], output , opt , data , NULL , 0 );
799
+ }
800
+ }
801
+ data -> skip_object_info = 0 ;
802
+
803
+ cleanup :
804
+ for (size_t i = 0 ; i < object_info_oids .nr ; i ++ )
805
+ free_object_info_contents (& remote_object_info [i ]);
806
+ free (line_to_split );
807
+ free (argv );
808
+ free (remote_object_info );
809
+ }
810
+
698
811
static void dispatch_calls (struct batch_options * opt ,
699
812
struct strbuf * output ,
700
813
struct expand_data * data ,
701
814
struct queued_cmd * cmd ,
702
815
int nr )
703
816
{
704
- int i ;
705
-
706
817
if (!opt -> buffer_output )
707
818
die (_ ("flush is only for --buffer mode" ));
708
819
709
- for (i = 0 ; i < nr ; i ++ )
820
+ for (size_t i = 0 ; i < nr ; i ++ )
710
821
cmd [i ].fn (opt , cmd [i ].line , output , data );
711
822
712
823
fflush (stdout );
713
824
}
714
825
715
826
static void free_cmds (struct queued_cmd * cmd , size_t * nr )
716
827
{
717
- size_t i ;
718
-
719
- for (i = 0 ; i < * nr ; i ++ )
828
+ for (size_t i = 0 ; i < * nr ; i ++ )
720
829
FREE_AND_NULL (cmd [i ].line );
721
830
722
831
* nr = 0 ;
@@ -730,6 +839,7 @@ static const struct parse_cmd {
730
839
} commands [] = {
731
840
{ "contents" , parse_cmd_contents , 1 },
732
841
{ "info" , parse_cmd_info , 1 },
842
+ { "remote-object-info" , parse_cmd_remote_object_info , 1 },
733
843
{ "flush" , NULL , 0 },
734
844
};
735
845
@@ -742,7 +852,6 @@ static void batch_objects_command(struct batch_options *opt,
742
852
size_t alloc = 0 , nr = 0 ;
743
853
744
854
while (strbuf_getdelim_strip_crlf (& input , stdin , opt -> input_delim ) != EOF ) {
745
- int i ;
746
855
const struct parse_cmd * cmd = NULL ;
747
856
const char * p = NULL , * cmd_end ;
748
857
struct queued_cmd call = {0 };
@@ -752,7 +861,7 @@ static void batch_objects_command(struct batch_options *opt,
752
861
if (isspace (* input .buf ))
753
862
die (_ ("whitespace before command: '%s'" ), input .buf );
754
863
755
- for (i = 0 ; i < ARRAY_SIZE (commands ); i ++ ) {
864
+ for (size_t i = 0 ; i < ARRAY_SIZE (commands ); i ++ ) {
756
865
if (!skip_prefix (input .buf , commands [i ].name , & cmd_end ))
757
866
continue ;
758
867
0 commit comments