Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2022-03-22 01:14:24 +0300
committerJunio C Hamano <gitster@pobox.com>2022-03-22 01:14:24 +0300
commit7391ecd338edcd0317687399c915927c1b4e25dd (patch)
tree69d298824738ca2289f96d134c9ea2c0ec3dbf95 /bundle.c
parentb6763af74ba55570deae38ce118c1d803d7b825c (diff)
parent86fdd94d723b7fa1870a64e8080d3540a434f29b (diff)
Merge branch 'ds/partial-bundles'
Bundle file format gets extended to allow a partial bundle, filtered by similar criteria you would give when making a partial/lazy clone. * ds/partial-bundles: clone: fail gracefully when cloning filtered bundle bundle: unbundle promisor packs bundle: create filtered bundles rev-list: move --filter parsing into revision.c bundle: parse filter capability list-objects: handle NULL function pointers MyFirstObjectWalk: update recommended usage list-objects: consolidate traverse_commit_list[_filtered] pack-bitmap: drop filter in prepare_bitmap_walk() pack-objects: use rev.filter when possible revision: put object filter into struct rev_info list-objects-filter-options: create copy helper index-pack: document and test the --promisor option
Diffstat (limited to 'bundle.c')
-rw-r--r--bundle.c74
1 files changed, 62 insertions, 12 deletions
diff --git a/bundle.c b/bundle.c
index 7608701a51..e359370cfc 100644
--- 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),
(uintmax_t)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."));
@@ -319,6 +332,9 @@ static int write_pack_data(int bundle_fd, struct rev_info *revs, struct strvec *
"--stdout", "--thin", "--delta-base-offset",
NULL);
strvec_pushv(&pack_objects.args, pack_options->v);
+ if (revs->filter.choice)
+ strvec_pushf(&pack_objects.args, "--filter=%s",
+ list_objects_filter_spec(&revs->filter));
pack_objects.in = -1;
pack_objects.out = bundle_fd;
pack_objects.git_cmd = 1;
@@ -486,10 +502,37 @@ int create_bundle(struct repository *r, const char *path,
int bundle_to_stdout;
int ref_count = 0;
struct rev_info revs, revs_copy;
- int min_version = the_hash_algo == &hash_algos[GIT_HASH_SHA1] ? 2 : 3;
+ int min_version = 2;
struct bundle_prerequisites_info bpi;
int i;
+ /* init revs to list objects for pack-objects later */
+ save_commit_buffer = 0;
+ repo_init_revisions(r, &revs, NULL);
+
+ /*
+ * Pre-initialize the '--objects' flag so we can parse a
+ * --filter option successfully.
+ */
+ revs.tree_objects = revs.blob_objects = 1;
+
+ argc = setup_revisions(argc, argv, &revs, NULL);
+
+ /*
+ * Reasons to require version 3:
+ *
+ * 1. @object-format is required because our hash algorithm is not
+ * SHA1.
+ * 2. @filter is required because we parsed an object filter.
+ */
+ if (the_hash_algo != &hash_algos[GIT_HASH_SHA1] || revs.filter.choice)
+ min_version = 3;
+
+ if (argc > 1) {
+ error(_("unrecognized argument: %s"), argv[1]);
+ goto err;
+ }
+
bundle_to_stdout = !strcmp(path, "-");
if (bundle_to_stdout)
bundle_fd = 1;
@@ -512,17 +555,14 @@ int create_bundle(struct repository *r, const char *path,
write_or_die(bundle_fd, capability, strlen(capability));
write_or_die(bundle_fd, the_hash_algo->name, strlen(the_hash_algo->name));
write_or_die(bundle_fd, "\n", 1);
- }
- /* init revs to list objects for pack-objects later */
- save_commit_buffer = 0;
- repo_init_revisions(r, &revs, NULL);
-
- argc = setup_revisions(argc, argv, &revs, NULL);
-
- if (argc > 1) {
- error(_("unrecognized argument: %s"), argv[1]);
- goto err;
+ if (revs.filter.choice) {
+ const char *value = expand_list_objects_filter_spec(&revs.filter);
+ capability = "@filter=";
+ write_or_die(bundle_fd, capability, strlen(capability));
+ write_or_die(bundle_fd, value, strlen(value));
+ write_or_die(bundle_fd, "\n", 1);
+ }
}
/* save revs.pending in revs_copy for later use */
@@ -544,6 +584,12 @@ int create_bundle(struct repository *r, const char *path,
die("revision walk setup failed");
bpi.fd = bundle_fd;
bpi.pending = &revs_copy.pending;
+
+ /*
+ * Remove any object walking here. We only care about commits and
+ * tags here. The revs_copy has the right instances of these values.
+ */
+ revs.blob_objects = revs.tree_objects = 0;
traverse_commit_list(&revs, write_bundle_prerequisites, NULL, &bpi);
object_array_remove_duplicates(&revs_copy.pending);
@@ -574,6 +620,10 @@ int unbundle(struct repository *r, struct bundle_header *header,
struct child_process ip = CHILD_PROCESS_INIT;
strvec_pushl(&ip.args, "index-pack", "--fix-thin", "--stdin", NULL);
+ /* If there is a filter, then we need to create the promisor pack. */
+ if (header->filter.choice)
+ strvec_push(&ip.args, "--promisor=from-bundle");
+
if (extra_index_pack_args) {
strvec_pushv(&ip.args, extra_index_pack_args->v);
strvec_clear(extra_index_pack_args);