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 { \
350
+ .mode = S_IFINVALID, \
351
+ .type = OBJ_BAD, \
352
+ .remote_allowed_atoms = STRING_LIST_INIT_NODUP, \
353
+}
354
+
355
static int is_atom(const char *atom, const char *s, int slen)
356
{
357
int alen = strlen(atom);
362
struct expand_data *data)
363
{
364
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))
365
+ size_t i;
366
+ for (i = 0; i < data->remote_allowed_atoms.nr; i++)
367
+ if (is_atom(data->remote_allowed_atoms.items[i].string,
368
+ atom, len))
369
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)
370
+ if (i == data->remote_allowed_atoms.nr)
371
return 1;
372
}
373
683
static int get_remote_info(int argc,
684
const char **argv,
685
struct object_info **remote_object_info,
686
- struct oid_array *object_info_oids)
686
+ struct oid_array *object_info_oids,
687
+ struct string_list *object_info_options)
688
{
689
int retval = 0;
690
struct remote *remote = NULL;
691
struct object_id oid;
691
- struct string_list object_info_options = STRING_LIST_INIT_NODUP;
692
struct transport *gtransport;
693
694
remote = remote_get(argv[0]);
728
CALLOC_ARRAY(*remote_object_info, object_info_oids->nr);
729
gtransport->smart_options->object_info_oids = object_info_oids;
730
731
- string_list_append(&object_info_options, "size");
732
-
733
- gtransport->smart_options->object_info_options = &object_info_options;
731
+ gtransport->smart_options->object_info_options = object_info_options;
732
gtransport->smart_options->object_info_data = *remote_object_info;
733
retval = transport_fetch_object_info(gtransport);
734
cleanup:
737
- string_list_clear(&object_info_options, 0);
735
transport_disconnect(gtransport);
736
return retval;
737
}
817
load_mailmap();
818
}
819
820
+struct protocol_placeholder_entry {
821
+ const char *option;
822
+ const char *atom;
823
+};
824
+
825
+static const struct protocol_placeholder_entry remote_atom_map[] = {
826
+ {"size", "objectsize"},
827
+ {"type", "objecttype"},
828
+ /*
829
+ * Add new protocol options here. Even if the server doesn't support
830
+ * them the allow_list will drop them if the server doesn't advertise
831
+ * them.
832
+ */
833
+};
834
+
835
static void parse_cmd_remote_object_info(struct batch_options *opt,
836
const char *line, struct strbuf *output,
837
struct expand_data *data)
841
char *line_to_split;
842
struct object_info *remote_object_info = NULL;
843
struct oid_array object_info_oids = OID_ARRAY_INIT;
844
+ struct string_list object_info_options = STRING_LIST_INIT_NODUP;
845
const char *saved_format = opt->format;
846
847
if (strlen(line) >= MAX_REMOTE_OBJ_INFO_LINE)
861
die(_("remote-object-info supports at most %d objects"),
862
MAX_ALLOWED_OBJ_LIMIT);
863
864
+ if (data->info.sizep)
865
+ string_list_append(&object_info_options, "size");
866
+ if (data->info.typep)
867
+ string_list_append(&object_info_options, "type");
868
+
869
if (get_remote_info(count, argv, &remote_object_info,
852
- &object_info_oids))
870
+ &object_info_oids, &object_info_options))
871
die(_("failed to get object info from the remote: %s"), argv[0]);
872
873
+ string_list_clear(&data->remote_allowed_atoms, 0);
874
+ string_list_append(&data->remote_allowed_atoms, "objectname");
875
+ for (size_t i = 0; i < ARRAY_SIZE(remote_atom_map); i++)
876
+ if (unsorted_string_list_has_string(&object_info_options, remote_atom_map[i].option))
877
+ string_list_append(&data->remote_allowed_atoms,
878
+ remote_atom_map[i].atom);
879
+
880
data->skip_object_info = 1;
881
for (size_t i = 0; i < object_info_oids.nr; i++) {
882
data->oid = object_info_oids.oid[i];
887
continue;
888
}
889
890
+ /*
891
+ * When reaching here, it means remote-object-info can retrieve
892
+ * information from server without downloading them.
893
+ */
894
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
- */
895
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");
896
}
897
+
898
+ if (remote_object_info[i].typep) {
899
+ data->type = *remote_object_info[i].typep;
900
+ }
901
+
902
+ opt->batch_mode = BATCH_MODE_INFO;
903
+ data->is_remote = 1;
904
+ batch_object_write(argv[i + 1], output, opt, data, NULL, 0);
905
+ data->is_remote = 0;
906
}
907
data->skip_object_info = 0;
908
opt->format = saved_format;
909
910
for (size_t i = 0; i < object_info_oids.nr; i++)
911
free_object_info_contents(&remote_object_info[i]);
912
+ string_list_clear(&object_info_options, 0);
913
free(line_to_split);
914
free(argv);
915
free(remote_object_info);
1229
cleanup:
1230
strbuf_release(&input);
1231
strbuf_release(&output);
1232
+ string_list_clear(&data.remote_allowed_atoms, 0);
1233
cfg->warn_on_object_refname_ambiguity = save_warning;
1234
return retval;
1235
}