@@ -137,6 +137,14 @@ depth is 4095.
a larger and slower repository; see the discussion in
`pack.packSizeLimit`.
+--filter=<filter-spec>::
+ Omits certain objects (usually blobs) from the resulting
+ packfile. WARNING: this could easily corrupt the current repo
+ and lose data if ANY of the omitted objects hasn't been already
+ pushed to a remote. Be very careful about objects that might
+ have been created locally! See linkgit:git-rev-list[1] for valid
+ `<filter-spec>` forms.
+
-b::
--write-bitmap-index::
Write a reachability bitmap index as part of the repack. This
@@ -50,6 +50,7 @@ struct pack_objects_args {
const char *depth;
const char *threads;
const char *max_pack_size;
+ const char *filter;
int no_reuse_delta;
int no_reuse_object;
int quiet;
@@ -201,6 +202,8 @@ static void prepare_pack_objects(struct child_process *cmd,
strvec_pushf(&cmd->args, "--threads=%s", args->threads);
if (args->max_pack_size)
strvec_pushf(&cmd->args, "--max-pack-size=%s", args->max_pack_size);
+ if (args->filter)
+ strvec_pushf(&cmd->args, "--filter=%s", args->filter);
if (args->no_reuse_delta)
strvec_pushf(&cmd->args, "--no-reuse-delta");
if (args->no_reuse_object)
@@ -268,6 +271,13 @@ static unsigned populate_pack_exts(char *name)
return ret;
}
+static void write_promisor_file_1(char *p)
+{
+ char *promisor_name = mkpathdup("%s-%s.promisor", packtmp, p);
+ write_promisor_file(promisor_name, NULL, 0);
+ free(promisor_name);
+}
+
static void repack_promisor_objects(const struct pack_objects_args *args,
struct string_list *names)
{
@@ -299,7 +309,6 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
out = xfdopen(cmd.out, "r");
while (strbuf_getline_lf(&line, out) != EOF) {
struct string_list_item *item;
- char *promisor_name;
if (line.len != the_hash_algo->hexsz)
die(_("repack: Expecting full hex object ID lines only from pack-objects."));
@@ -316,13 +325,8 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
* concatenate the contents of all .promisor files instead of
* just creating a new empty file.
*/
- promisor_name = mkpathdup("%s-%s.promisor", packtmp,
- line.buf);
- write_promisor_file(promisor_name, NULL, 0);
-
+ write_promisor_file_1(line.buf);
item->util = (void *)(uintptr_t)populate_pack_exts(item->string);
-
- free(promisor_name);
}
fclose(out);
if (finish_command(&cmd))
@@ -786,6 +790,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
N_("limits the maximum number of threads")),
OPT_STRING(0, "max-pack-size", &po_args.max_pack_size, N_("bytes"),
N_("maximum size of each packfile")),
+ OPT_STRING(0, "filter", &po_args.filter, N_("args"),
+ N_("object filtering")),
OPT_BOOL(0, "pack-kept-objects", &pack_kept_objects,
N_("repack objects in packs marked with .keep")),
OPT_STRING_LIST(0, "keep-pack", &keep_pack_list, N_("name"),
@@ -955,6 +961,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (line.len != the_hash_algo->hexsz)
die(_("repack: Expecting full hex object ID lines only from pack-objects."));
string_list_append(&names, line.buf);
+ if (po_args.filter)
+ write_promisor_file_1(line.buf);
}
fclose(out);
ret = finish_command(&cmd);
@@ -237,6 +237,21 @@ test_expect_success 'auto-bitmaps do not complain if unavailable' '
test_must_be_empty actual
'
+test_expect_success 'repacking with a filter works' '
+ test_when_finished "rm -rf server client" &&
+ test_create_repo server &&
+ git -C server config uploadpack.allowFilter true &&
+ git -C server config uploadpack.allowAnySHA1InWant true &&
+ test_commit -C server 1 &&
+ git clone --bare --no-local server client &&
+ git -C client config remote.origin.promisor true &&
+ git -C client rev-list --objects --all --missing=print >objects &&
+ test $(grep "^?" objects | wc -l) = 0 &&
+ git -C client -c repack.writebitmaps=false repack -a -d --filter=blob:none &&
+ git -C client rev-list --objects --all --missing=print >objects &&
+ test $(grep "^?" objects | wc -l) = 1
+'
+
objdir=.git/objects
midx=$objdir/pack/multi-pack-index