Skip to content

Commit bff03c4

Browse files
derrickstoleegitster
authored andcommitted
bundle-uri: create base key-value pair parsing
There will be two primary ways to advertise a bundle list: as a list of packet lines in Git's protocol v2 and as a config file served from a bundle URI. Both of these fundamentally use a list of key-value pairs. We will use the same set of key-value pairs across these formats. Create a new bundle_list_update() method that is currently unusued, but will be used in the next change. It inspects each key to see if it is understood and then applies it to the given bundle_list. Here are the keys that we teach Git to understand: * bundle.version: This value should be an integer. Git currently understands only version 1 and will ignore the list if the version is any other value. This version can be increased in the future if we need to add new keys that Git should not ignore. We can add new "heuristic" keys without incrementing the version. * bundle.mode: This value should be one of "all" or "any". If this mode is not understood, then Git will ignore the list. This mode indicates whether Git needs all of the bundle list items to make a complete view of the content or if any single item is sufficient. The rest of the keys use a bundle identifier "<id>" as part of the key name. Keys using the same "<id>" describe a single bundle list item. * bundle.<id>.uri: This stores the URI of the bundle item. This currently is expected to be an absolute URI, but will be relaxed to be a relative URI in the future. While parsing, return an error if a URI key is repeated, since we can make that restriction with bundle lists. Make the git_parse_int() method global so we can parse the integer version value carefully. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0634f71 commit bff03c4

File tree

5 files changed

+104
-1
lines changed

5 files changed

+104
-1
lines changed

Documentation/config.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@ include::config/branch.txt[]
387387

388388
include::config/browser.txt[]
389389

390+
include::config/bundle.txt[]
391+
390392
include::config/checkout.txt[]
391393

392394
include::config/clean.txt[]

Documentation/config/bundle.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
bundle.*::
2+
The `bundle.*` keys may appear in a bundle list file found via the
3+
`git clone --bundle-uri` option. These keys currently have no effect
4+
if placed in a repository config file, though this will change in the
5+
future. See link:technical/bundle-uri.html[the bundle URI design
6+
document] for more details.
7+
8+
bundle.version::
9+
This integer value advertises the version of the bundle list format
10+
used by the bundle list. Currently, the only accepted value is `1`.
11+
12+
bundle.mode::
13+
This string value should be either `all` or `any`. This value describes
14+
whether all of the advertised bundles are required to unbundle a
15+
complete understanding of the bundled information (`all`) or if any one
16+
of the listed bundle URIs is sufficient (`any`).
17+
18+
bundle.<id>.*::
19+
The `bundle.<id>.*` keys are used to describe a single item in the
20+
bundle list, grouped under `<id>` for identification purposes.
21+
22+
bundle.<id>.uri::
23+
This string value defines the URI by which Git can reach the contents
24+
of this `<id>`. This URI may be a bundle file or another bundle list.

bundle-uri.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "run-command.h"
77
#include "hashmap.h"
88
#include "pkt-line.h"
9+
#include "config.h"
910

1011
static int compare_bundles(const void *hashmap_cmp_fn_data,
1112
const struct hashmap_entry *he1,
@@ -65,6 +66,81 @@ int for_all_bundles_in_list(struct bundle_list *list,
6566
return 0;
6667
}
6768

69+
/**
70+
* Given a key-value pair, update the state of the given bundle list.
71+
* Returns 0 if the key-value pair is understood. Returns -1 if the key
72+
* is not understood or the value is malformed.
73+
*/
74+
MAYBE_UNUSED
75+
static int bundle_list_update(const char *key, const char *value,
76+
struct bundle_list *list)
77+
{
78+
struct strbuf id = STRBUF_INIT;
79+
struct remote_bundle_info lookup = REMOTE_BUNDLE_INFO_INIT;
80+
struct remote_bundle_info *bundle;
81+
const char *subsection, *subkey;
82+
size_t subsection_len;
83+
84+
if (parse_config_key(key, "bundle", &subsection, &subsection_len, &subkey))
85+
return -1;
86+
87+
if (!subsection_len) {
88+
if (!strcmp(subkey, "version")) {
89+
int version;
90+
if (!git_parse_int(value, &version))
91+
return -1;
92+
if (version != 1)
93+
return -1;
94+
95+
list->version = version;
96+
return 0;
97+
}
98+
99+
if (!strcmp(subkey, "mode")) {
100+
if (!strcmp(value, "all"))
101+
list->mode = BUNDLE_MODE_ALL;
102+
else if (!strcmp(value, "any"))
103+
list->mode = BUNDLE_MODE_ANY;
104+
else
105+
return -1;
106+
return 0;
107+
}
108+
109+
/* Ignore other unknown global keys. */
110+
return 0;
111+
}
112+
113+
strbuf_add(&id, subsection, subsection_len);
114+
115+
/*
116+
* Check for an existing bundle with this <id>, or create one
117+
* if necessary.
118+
*/
119+
lookup.id = id.buf;
120+
hashmap_entry_init(&lookup.ent, strhash(lookup.id));
121+
if (!(bundle = hashmap_get_entry(&list->bundles, &lookup, ent, NULL))) {
122+
CALLOC_ARRAY(bundle, 1);
123+
bundle->id = strbuf_detach(&id, NULL);
124+
hashmap_entry_init(&bundle->ent, strhash(bundle->id));
125+
hashmap_add(&list->bundles, &bundle->ent);
126+
}
127+
strbuf_release(&id);
128+
129+
if (!strcmp(subkey, "uri")) {
130+
if (bundle->uri)
131+
return -1;
132+
bundle->uri = xstrdup(value);
133+
return 0;
134+
}
135+
136+
/*
137+
* At this point, we ignore any information that we don't
138+
* understand, assuming it to be hints for a heuristic the client
139+
* does not currently understand.
140+
*/
141+
return 0;
142+
}
143+
68144
static char *find_temp_filename(void)
69145
{
70146
int fd;

config.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,7 @@ static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
12141214
return 0;
12151215
}
12161216

1217-
static int git_parse_int(const char *value, int *ret)
1217+
int git_parse_int(const char *value, int *ret)
12181218
{
12191219
intmax_t tmp;
12201220
if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int)))

config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ int config_with_options(config_fn_t fn, void *,
206206

207207
int git_parse_ssize_t(const char *, ssize_t *);
208208
int git_parse_ulong(const char *, unsigned long *);
209+
int git_parse_int(const char *value, int *ret);
209210

210211
/**
211212
* Same as `git_config_bool`, except that it returns -1 on error rather

0 commit comments

Comments
 (0)