Git fork

bundle-uri: parse bundle.heuristic=creationToken

The bundle.heuristic value communicates that the bundle list is
organized to make use of the bundle.<id>.creationToken values that may
be provided in the bundle list. Those values will create a total order
on the bundles, allowing the Git client to download them in a specific
order and even remember previously-downloaded bundles by storing the
maximum creation token value.

Before implementing any logic that parses or uses the
bundle.<id>.creationToken values, teach Git to parse the
bundle.heuristic value from a bundle list. We can use 'test-tool
bundle-uri' to print the heuristic value and verify that the parsing
works correctly.

As an extra precaution, create the internal 'heuristics' array to be a
list of (enum, string) pairs so we can iterate through the array entries
carefully, regardless of the enum values.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Derrick Stolee and committed by
Junio C Hamano
c93c3d2f 7bc73e7b

+74
+7
Documentation/config/bundle.txt
··· 15 15 complete understanding of the bundled information (`all`) or if any one 16 16 of the listed bundle URIs is sufficient (`any`). 17 17 18 + bundle.heuristic:: 19 + If this string-valued key exists, then the bundle list is designed to 20 + work well with incremental `git fetch` commands. The heuristic signals 21 + that there are additional keys available for each bundle that help 22 + determine which subset of bundles the client should download. The 23 + only value currently understood is `creationToken`. 24 + 18 25 bundle.<id>.*:: 19 26 The `bundle.<id>.*` keys are used to describe a single item in the 20 27 bundle list, grouped under `<id>` for identification purposes.
+34
bundle-uri.c
··· 9 9 #include "config.h" 10 10 #include "remote.h" 11 11 12 + static struct { 13 + enum bundle_list_heuristic heuristic; 14 + const char *name; 15 + } heuristics[BUNDLE_HEURISTIC__COUNT] = { 16 + { BUNDLE_HEURISTIC_NONE, ""}, 17 + { BUNDLE_HEURISTIC_CREATIONTOKEN, "creationToken" }, 18 + }; 19 + 12 20 static int compare_bundles(const void *hashmap_cmp_fn_data, 13 21 const struct hashmap_entry *he1, 14 22 const struct hashmap_entry *he2, ··· 100 108 fprintf(fp, "\tversion = %d\n", list->version); 101 109 fprintf(fp, "\tmode = %s\n", mode); 102 110 111 + if (list->heuristic) { 112 + int i; 113 + for (i = 0; i < BUNDLE_HEURISTIC__COUNT; i++) { 114 + if (heuristics[i].heuristic == list->heuristic) { 115 + printf("\theuristic = %s\n", 116 + heuristics[list->heuristic].name); 117 + break; 118 + } 119 + } 120 + } 121 + 103 122 for_all_bundles_in_list(list, summarize_bundle, fp); 104 123 } 105 124 ··· 139 158 list->mode = BUNDLE_MODE_ANY; 140 159 else 141 160 return -1; 161 + return 0; 162 + } 163 + 164 + if (!strcmp(subkey, "heuristic")) { 165 + int i; 166 + for (i = 0; i < BUNDLE_HEURISTIC__COUNT; i++) { 167 + if (heuristics[i].heuristic && 168 + heuristics[i].name && 169 + !strcmp(value, heuristics[i].name)) { 170 + list->heuristic = heuristics[i].heuristic; 171 + return 0; 172 + } 173 + } 174 + 175 + /* Ignore unknown heuristics. */ 142 176 return 0; 143 177 } 144 178
+14
bundle-uri.h
··· 52 52 BUNDLE_MODE_ANY 53 53 }; 54 54 55 + enum bundle_list_heuristic { 56 + BUNDLE_HEURISTIC_NONE = 0, 57 + BUNDLE_HEURISTIC_CREATIONTOKEN, 58 + 59 + /* Must be last. */ 60 + BUNDLE_HEURISTIC__COUNT 61 + }; 62 + 55 63 /** 56 64 * A bundle_list contains an unordered set of remote_bundle_info structs, 57 65 * as well as information about the bundle listing, such as version and ··· 75 83 * advertised by the bundle list at that location. 76 84 */ 77 85 char *baseURI; 86 + 87 + /** 88 + * A list can have a heuristic, which helps reduce the number of 89 + * downloaded bundles. 90 + */ 91 + enum bundle_list_heuristic heuristic; 78 92 }; 79 93 80 94 void init_bundle_list(struct bundle_list *list);
+19
t/t5750-bundle-uri-parse.sh
··· 250 250 test_cmp_config_output expect actual 251 251 ' 252 252 253 + test_expect_success 'parse config format: creationToken heuristic' ' 254 + cat >expect <<-\EOF && 255 + [bundle] 256 + version = 1 257 + mode = all 258 + heuristic = creationToken 259 + [bundle "one"] 260 + uri = http://example.com/bundle.bdl 261 + [bundle "two"] 262 + uri = https://example.com/bundle.bdl 263 + [bundle "three"] 264 + uri = file:///usr/share/git/bundle.bdl 265 + EOF 266 + 267 + test-tool bundle-uri parse-config expect >actual 2>err && 268 + test_must_be_empty err && 269 + test_cmp_config_output expect actual 270 + ' 271 + 253 272 test_done