338
* Flags about when an object info is being fetched from remote.
339
*/
340
unsigned is_remote:1;
341
-};
342
-
343
-#define EXPAND_DATA_INIT { .mode = S_IFINVALID, .type = OBJ_BAD }
341
345
-static const char *remote_object_info_atoms[] = {
346
- "objectname",
347
- "objectsize",
342
+ /*
343
+ * List of atoms (i.e. "objectsize") that the server supports. Built
344
+ * from the server's object-info advertised capabilities.
345
+ */
346
+ struct string_list remote_allowed_atoms;
347
};
348
349
+#define EXPAND_DATA_INIT { .mode = S_IFINVALID, \
350
+ .type = OBJ_BAD, \
351
+ .remote_allowed_atoms = STRING_LIST_INIT_NODUP }
352
+
353
static int is_atom(const char *atom, const char *s, int slen)
354
{
355
int alen = strlen(atom);
360
struct expand_data *data)
361
{
362
if (data->is_remote) {
360
- size_t i, allowed_nr = ARRAY_SIZE(remote_object_info_atoms);
361
- for (i = 0; i < allowed_nr; i++)
362
- if (is_atom(remote_object_info_atoms[i], atom, len))
363
+ size_t i;
364
+ for (i = 0; i < data->remote_allowed_atoms.nr; i++)
365
+ if (is_atom(data->remote_allowed_atoms.items[i].string,
366
+ atom, len))
367
break;
364
-
365
- /*
366
- * On remote, skip unsupported atoms returning an empty sb,
367
- * honoring how for-each-ref handles known but inapplicable
368
- * atoms (e.g. %(tagger)).
369
- */
370
- if (i == allowed_nr)
368
+ if (i == data->remote_allowed_atoms.nr)
369
return 1;
370
}
371
681
static int get_remote_info(int argc,
682
const char **argv,
683
struct object_info **remote_object_info,
686
- struct oid_array *object_info_oids)
684
+ struct oid_array *object_info_oids,
685
+ struct string_list *object_info_options)
686
{
687
int retval = 0;
688
struct remote *remote = NULL;
689
struct object_id oid;
691
- struct string_list object_info_options = STRING_LIST_INIT_NODUP;
690
struct transport *gtransport;
691
692
remote = remote_get(argv[0]);
726
CALLOC_ARRAY(*remote_object_info, object_info_oids->nr);
727
gtransport->smart_options->object_info_oids = object_info_oids;
728
731
- string_list_append(&object_info_options, "size");
732
-
733
- gtransport->smart_options->object_info_options = &object_info_options;
729
+ gtransport->smart_options->object_info_options = object_info_options;
730
gtransport->smart_options->object_info_data = *remote_object_info;
731
retval = transport_fetch_object_info(gtransport);
732
cleanup:
737
- string_list_clear(&object_info_options, 0);
733
transport_disconnect(gtransport);
734
return retval;
735
}
815
load_mailmap();
816
}
817
818
+struct protocol_placeholder_entry {
819
+ const char *option;
820
+ const char *atom;
821
+};
822
+
823
+static const struct protocol_placeholder_entry remote_atom_map[] = {
824
+ {"size", "objectsize"},
825
+ {"type", "objecttype"},
826
+ /*
827
+ * Add new protocol options here. Even if the server doesn't support
828
+ * them the allow_list will drop them if the server doesn't advertise
829
+ * them.
830
+ */
831
+};
832
+
833
static void parse_cmd_remote_object_info(struct batch_options *opt,
834
const char *line, struct strbuf *output,
835
struct expand_data *data)
839
char *line_to_split;
840
struct object_info *remote_object_info = NULL;
841
struct oid_array object_info_oids = OID_ARRAY_INIT;
842
+ struct string_list object_info_options = STRING_LIST_INIT_NODUP;
843
const char *saved_format = opt->format;
844
845
if (strlen(line) >= MAX_REMOTE_OBJ_INFO_LINE)
859
die(_("remote-object-info supports at most %d objects"),
860
MAX_ALLOWED_OBJ_LIMIT);
861
862
+ if (data->info.sizep)
863
+ string_list_append(&object_info_options, "size");
864
+ if (data->info.typep)
865
+ string_list_append(&object_info_options, "type");
866
+
867
if (get_remote_info(count, argv, &remote_object_info,
852
- &object_info_oids))
868
+ &object_info_oids, &object_info_options))
869
die(_("failed to get object info from the remote: %s"), argv[0]);
870
871
+ string_list_clear(&data->remote_allowed_atoms, 0);
872
+ string_list_append(&data->remote_allowed_atoms, "objectname");
873
+ for (size_t i = 0; i < ARRAY_SIZE(remote_atom_map); i++)
874
+ if (unsorted_string_list_has_string(&object_info_options, remote_atom_map[i].option))
875
+ string_list_append(&data->remote_allowed_atoms,
876
+ remote_atom_map[i].atom);
877
+
878
data->skip_object_info = 1;
879
for (size_t i = 0; i < object_info_oids.nr; i++) {
880
data->oid = object_info_oids.oid[i];
885
continue;
886
}
887
888
+ /*
889
+ * When reaching here, it means remote-object-info can retrieve
890
+ * information from server without downloading them.
891
+ */
892
if (remote_object_info[i].sizep) {
866
- /*
867
- * When reaching here, it means remote-object-info can retrieve
868
- * information from server without downloading them.
869
- */
893
data->size = *remote_object_info[i].sizep;
871
- opt->batch_mode = BATCH_MODE_INFO;
872
- data->is_remote = 1;
873
- batch_object_write(argv[i + 1], output, opt, data, NULL, 0);
874
- data->is_remote = 0;
875
- } else {
876
- report_object_status(opt, oid_to_hex(&data->oid), &data->oid, "missing");
894
}
895
+
896
+ if (remote_object_info[i].typep) {
897
+ data->type = *remote_object_info[i].typep;
898
+ }
899
+
900
+ opt->batch_mode = BATCH_MODE_INFO;
901
+ data->is_remote = 1;
902
+ batch_object_write(argv[i + 1], output, opt, data, NULL, 0);
903
+ data->is_remote = 0;
904
}
905
data->skip_object_info = 0;
906
opt->format = saved_format;
907
908
for (size_t i = 0; i < object_info_oids.nr; i++)
909
free_object_info_contents(&remote_object_info[i]);
910
+ string_list_clear(&object_info_options, 0);
911
free(line_to_split);
912
free(argv);
913
free(remote_object_info);
1227
cleanup:
1228
strbuf_release(&input);
1229
strbuf_release(&output);
1230
+ string_list_clear(&data.remote_allowed_atoms, 0);
1231
cfg->warn_on_object_refname_ambiguity = save_warning;
1232
return retval;
1233
}