]> git.ipfire.org Git - thirdparty/git.git/commitdiff
bundle: parse filter capability
authorDerrick Stolee <derrickstolee@github.com>
Wed, 9 Mar 2022 16:01:39 +0000 (16:01 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 9 Mar 2022 18:25:27 +0000 (10:25 -0800)
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 <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-bundle.txt
Documentation/technical/bundle-format.txt
bundle.c
bundle.h
list-objects-filter-options.c
list-objects-filter-options.h

index 72ab81390525cd23aa8b63a43d0070986620db17..ac4c4352aae8ae12bdaf9f10413eb6ac12a7eb6d 100644 (file)
@@ -75,8 +75,11 @@ verify <file>::
        cleanly to the current repository.  This includes checks on the
        bundle format itself as well as checking that the prerequisite
        commits exist and are fully linked in the current repository.
-       'git bundle' prints a list of missing commits, if any, and exits
-       with a non-zero status.
+       Information about additional capabilities, such as "object filter",
+       is printed. See "Capabilities" in link:technical/bundle-format.html
+       for more information. Finally, 'git bundle' prints a list of
+       missing commits, if any. The exit code is zero for success, but
+       will be nonzero if the bundle file is invalid.
 
 list-heads <file>::
        Lists the references defined in the bundle.  If followed by a
index bac558d049a36f4b4fbb132c7aa1dd5af4770102..b9be8644cf5d53161b7190f580be935b28d402a3 100644 (file)
@@ -71,6 +71,11 @@ and the Git bundle v2 format cannot represent a shallow clone repository.
 == Capabilities
 
 Because there is no opportunity for negotiation, unknown capabilities cause 'git
-bundle' to abort.  The only known capability is `object-format`, which specifies
-the hash algorithm in use, and can take the same values as the
-`extensions.objectFormat` configuration value.
+bundle' to abort.
+
+* `object-format` specifies the hash algorithm in use, and can take the same
+  values as the `extensions.objectFormat` configuration value.
+
+* `filter` specifies an object filter as in the `--filter` option in
+  linkgit:git-rev-list[1]. The resulting pack-file must be marked as a
+  `.promisor` pack-file after it is unbundled.
index 7ba60a573d73c92a02ab609bc67203d6032b6658..41e75efab9a293ad21745d0b567ba2bc12905b62 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -11,7 +11,7 @@
 #include "run-command.h"
 #include "refs.h"
 #include "strvec.h"
-
+#include "list-objects-filter-options.h"
 
 static const char v2_bundle_signature[] = "# v2 git bundle\n";
 static const char v3_bundle_signature[] = "# v3 git bundle\n";
@@ -33,6 +33,7 @@ void bundle_header_release(struct bundle_header *header)
 {
        string_list_clear(&header->prerequisites, 1);
        string_list_clear(&header->references, 1);
+       list_objects_filter_release(&header->filter);
 }
 
 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
                header->hash_algo = &hash_algos[algo];
                return 0;
        }
+       if (skip_prefix(capability, "filter=", &arg)) {
+               parse_list_objects_filter(&header->filter, arg);
+               return 0;
+       }
        return error(_("unknown capability '%s'"), capability);
 }
 
@@ -220,6 +225,8 @@ int verify_bundle(struct repository *r,
        req_nr = revs.pending.nr;
        setup_revisions(2, argv, &revs, NULL);
 
+       list_objects_filter_copy(&revs.filter, &header->filter);
+
        if (prepare_revision_walk(&revs))
                die(_("revision walk setup failed"));
 
@@ -259,6 +266,12 @@ int verify_bundle(struct repository *r,
                             r->nr),
                          r->nr);
                list_refs(r, 0, NULL);
+
+               if (header->filter.choice) {
+                       printf_ln("The bundle uses this filter: %s",
+                                 list_objects_filter_spec(&header->filter));
+               }
+
                r = &header->prerequisites;
                if (!r->nr) {
                        printf_ln(_("The bundle records a complete history."));
index 06009fe6b1f00b939350ba88ba7bf8f72565de4c..7fef2108f436861726ca4efb6937f9d434e61d7e 100644 (file)
--- a/bundle.h
+++ b/bundle.h
@@ -4,12 +4,14 @@
 #include "strvec.h"
 #include "cache.h"
 #include "string-list.h"
+#include "list-objects-filter-options.h"
 
 struct bundle_header {
        unsigned version;
        struct string_list prerequisites;
        struct string_list references;
        const struct git_hash_algo *hash_algo;
+       struct list_objects_filter_options filter;
 };
 
 #define BUNDLE_HEADER_INIT \
index 449d53af69f466d73aa8fd8cfd2c7e1f2743dcf7..f02d8df1422f61077dc9e032befe68e755e88c56 100644 (file)
@@ -40,22 +40,7 @@ const char *list_object_filter_config_name(enum list_objects_filter_choice c)
        BUG("list_object_filter_config_name: invalid argument '%d'", c);
 }
 
-/*
- * Parse value of the argument to the "filter" keyword.
- * On the command line this looks like:
- *       --filter=<arg>
- * and in the pack protocol as:
- *       "filter" SP <arg>
- *
- * The filter keyword will be used by many commands.
- * See Documentation/rev-list-options.txt for allowed values for <arg>.
- *
- * Capture the given arg as the "filter_spec".  This can be forwarded to
- * subordinate commands when necessary (although it's better to pass it through
- * expand_list_objects_filter_spec() first).  We also "intern" the arg for the
- * convenience of the current command.
- */
-static int gently_parse_list_objects_filter(
+int gently_parse_list_objects_filter(
        struct list_objects_filter_options *filter_options,
        const char *arg,
        struct strbuf *errbuf)
index 425c38cae9da43830e92965c1b3904c4f52b94ae..2eb6c983949db0354b0041f10c36e24dc2885116 100644 (file)
@@ -72,6 +72,26 @@ struct list_objects_filter_options {
 /* Normalized command line arguments */
 #define CL_ARG__FILTER "filter"
 
+/*
+ * Parse value of the argument to the "filter" keyword.
+ * On the command line this looks like:
+ *       --filter=<arg>
+ * and in the pack protocol as:
+ *       "filter" SP <arg>
+ *
+ * The filter keyword will be used by many commands.
+ * See Documentation/rev-list-options.txt for allowed values for <arg>.
+ *
+ * Capture the given arg as the "filter_spec".  This can be forwarded to
+ * subordinate commands when necessary (although it's better to pass it through
+ * expand_list_objects_filter_spec() first).  We also "intern" the arg for the
+ * convenience of the current command.
+ */
+int gently_parse_list_objects_filter(
+       struct list_objects_filter_options *filter_options,
+       const char *arg,
+       struct strbuf *errbuf);
+
 void list_objects_filter_die_if_populated(
        struct list_objects_filter_options *filter_options);