Skip to content

Commit 105c6f1

Browse files
derrickstoleegitster
authored andcommitted
bundle: parse filter capability
The v3 bundle format has capabilities, allowing newer versions of Git to create bundles with newer features. Older versions that do not understand these new capabilities will fail with a helpful warning. Create a new capability allowing Git to understand that the contained pack-file is filtered according to some object filter. Typically, this filter will be "blob:none" for a blobless partial clone. This change teaches Git to parse this capability, place its value in the bundle header, and demonstrate this understanding by adding a message to 'git bundle verify'. Since we will use gently_parse_list_objects_filter() outside of list-objects-filter-options.c, make it an external method and move its API documentation to before its declaration. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4f33a63 commit 105c6f1

File tree

6 files changed

+50
-22
lines changed

6 files changed

+50
-22
lines changed

Documentation/git-bundle.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,11 @@ verify <file>::
7575
cleanly to the current repository. This includes checks on the
7676
bundle format itself as well as checking that the prerequisite
7777
commits exist and are fully linked in the current repository.
78-
'git bundle' prints a list of missing commits, if any, and exits
79-
with a non-zero status.
78+
Information about additional capabilities, such as "object filter",
79+
is printed. See "Capabilities" in link:technical/bundle-format.html
80+
for more information. Finally, 'git bundle' prints a list of
81+
missing commits, if any. The exit code is zero for success, but
82+
will be nonzero if the bundle file is invalid.
8083

8184
list-heads <file>::
8285
Lists the references defined in the bundle. If followed by a

Documentation/technical/bundle-format.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ and the Git bundle v2 format cannot represent a shallow clone repository.
7171
== Capabilities
7272

7373
Because there is no opportunity for negotiation, unknown capabilities cause 'git
74-
bundle' to abort. The only known capability is `object-format`, which specifies
75-
the hash algorithm in use, and can take the same values as the
76-
`extensions.objectFormat` configuration value.
74+
bundle' to abort.
75+
76+
* `object-format` specifies the hash algorithm in use, and can take the same
77+
values as the `extensions.objectFormat` configuration value.
78+
79+
* `filter` specifies an object filter as in the `--filter` option in
80+
linkgit:git-rev-list[1]. The resulting pack-file must be marked as a
81+
`.promisor` pack-file after it is unbundled.

bundle.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "run-command.h"
1212
#include "refs.h"
1313
#include "strvec.h"
14-
14+
#include "list-objects-filter-options.h"
1515

1616
static const char v2_bundle_signature[] = "# v2 git bundle\n";
1717
static const char v3_bundle_signature[] = "# v3 git bundle\n";
@@ -33,6 +33,7 @@ void bundle_header_release(struct bundle_header *header)
3333
{
3434
string_list_clear(&header->prerequisites, 1);
3535
string_list_clear(&header->references, 1);
36+
list_objects_filter_release(&header->filter);
3637
}
3738

3839
static int parse_capability(struct bundle_header *header, const char *capability)
@@ -45,6 +46,10 @@ static int parse_capability(struct bundle_header *header, const char *capability
4546
header->hash_algo = &hash_algos[algo];
4647
return 0;
4748
}
49+
if (skip_prefix(capability, "filter=", &arg)) {
50+
parse_list_objects_filter(&header->filter, arg);
51+
return 0;
52+
}
4853
return error(_("unknown capability '%s'"), capability);
4954
}
5055

@@ -220,6 +225,8 @@ int verify_bundle(struct repository *r,
220225
req_nr = revs.pending.nr;
221226
setup_revisions(2, argv, &revs, NULL);
222227

228+
list_objects_filter_copy(&revs.filter, &header->filter);
229+
223230
if (prepare_revision_walk(&revs))
224231
die(_("revision walk setup failed"));
225232

@@ -259,6 +266,12 @@ int verify_bundle(struct repository *r,
259266
r->nr),
260267
r->nr);
261268
list_refs(r, 0, NULL);
269+
270+
if (header->filter.choice) {
271+
printf_ln("The bundle uses this filter: %s",
272+
list_objects_filter_spec(&header->filter));
273+
}
274+
262275
r = &header->prerequisites;
263276
if (!r->nr) {
264277
printf_ln(_("The bundle records a complete history."));

bundle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
#include "strvec.h"
55
#include "cache.h"
66
#include "string-list.h"
7+
#include "list-objects-filter-options.h"
78

89
struct bundle_header {
910
unsigned version;
1011
struct string_list prerequisites;
1112
struct string_list references;
1213
const struct git_hash_algo *hash_algo;
14+
struct list_objects_filter_options filter;
1315
};
1416

1517
#define BUNDLE_HEADER_INIT \

list-objects-filter-options.c

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,7 @@ const char *list_object_filter_config_name(enum list_objects_filter_choice c)
4040
BUG("list_object_filter_config_name: invalid argument '%d'", c);
4141
}
4242

43-
/*
44-
* Parse value of the argument to the "filter" keyword.
45-
* On the command line this looks like:
46-
* --filter=<arg>
47-
* and in the pack protocol as:
48-
* "filter" SP <arg>
49-
*
50-
* The filter keyword will be used by many commands.
51-
* See Documentation/rev-list-options.txt for allowed values for <arg>.
52-
*
53-
* Capture the given arg as the "filter_spec". This can be forwarded to
54-
* subordinate commands when necessary (although it's better to pass it through
55-
* expand_list_objects_filter_spec() first). We also "intern" the arg for the
56-
* convenience of the current command.
57-
*/
58-
static int gently_parse_list_objects_filter(
43+
int gently_parse_list_objects_filter(
5944
struct list_objects_filter_options *filter_options,
6045
const char *arg,
6146
struct strbuf *errbuf)

list-objects-filter-options.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@ struct list_objects_filter_options {
7272
/* Normalized command line arguments */
7373
#define CL_ARG__FILTER "filter"
7474

75+
/*
76+
* Parse value of the argument to the "filter" keyword.
77+
* On the command line this looks like:
78+
* --filter=<arg>
79+
* and in the pack protocol as:
80+
* "filter" SP <arg>
81+
*
82+
* The filter keyword will be used by many commands.
83+
* See Documentation/rev-list-options.txt for allowed values for <arg>.
84+
*
85+
* Capture the given arg as the "filter_spec". This can be forwarded to
86+
* subordinate commands when necessary (although it's better to pass it through
87+
* expand_list_objects_filter_spec() first). We also "intern" the arg for the
88+
* convenience of the current command.
89+
*/
90+
int gently_parse_list_objects_filter(
91+
struct list_objects_filter_options *filter_options,
92+
const char *arg,
93+
struct strbuf *errbuf);
94+
7595
void list_objects_filter_die_if_populated(
7696
struct list_objects_filter_options *filter_options);
7797

0 commit comments

Comments
 (0)