git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 2/2] repack: add --filter=<filter-spec> option

From
Christian Couder <christian.couder@gmail.com>
Date
Oct 25, 2022, 12:28 UTC
Message-ID
<20221025122856.20204-3-christian.couder@gmail.com>
In-Reply-To
<20221025122856.20204-1-christian.couder@gmail.com>
From: Christian Couder <chriscool@tuxfamily.org>

After cloning with --filter=<filter-spec>, for example to avoid getting unneeded large files on a user machine, it's possible that some of these large files still get fetched for some reasons (like checking out old branches) over time.

In this case the repo size could grow too much for no good reason and `git repack --filter=<filter-spec>` would be useful to remove the unneeded large files.

This command could be dangerous to use though, as it might remove local objects that haven't been pushed which would lose data and corrupt the repo. On a server, this command could also corrupt a repo unless ALL the removed objects aren't already available in another remote that clients can access.

Signed-off-by: John Cai <johncai86@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 Documentation/git-repack.txt |  8 ++++++++
 builtin/repack.c             | 22 +++++++++++++++-------
 t/t7700-repack.sh            | 15 +++++++++++++++
 3 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt
index 0bf13893d8..d28bb68cfc 100644
--- a/Documentation/git-repack.txt
+++ b/Documentation/git-repack.txt
@@ -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
diff --git a/builtin/repack.c b/builtin/repack.c
index a5bacc7797..d8b8a58f73 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -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);
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index ca45c4cd2c..363eaf8fea 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -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
 
-- 
2.38.1.145.g80cce38e46.dirty
Previous: Christian CouderNext: Taylor Blau
Message 13 of 46 in “Implement filtering repacks”
  1. 0/3 Implement filtering repacksChristian Couder, Oct 12, 2022
  2. 1/3 pack-objects: allow --filter without --stdoutChristian Couder, Oct 12, 2022
  3. 2/3 repack: add --filter=<filter-spec> optionChristian Couder, Oct 12, 2022
  4. 3/3 repack: introduce --force to force filteringChristian Couder, Oct 12, 2022
  5. Junio C HamanoOct 14, 2022
  6. Christian CouderOct 20, 2022
  7. Taylor BlauOct 28, 2022
  8. Junio C HamanoOct 28, 2022
  9. Christian CouderNov 7, 2022
  10. Christian CouderNov 7, 2022
  11. 0/2 Implement filtering repacksChristian Couder, Oct 25, 2022
  12. 1/2 pack-objects: allow --filter without --stdoutChristian Couder, Oct 25, 2022
  13. 2/2 repack: add --filter=<filter-spec> optionChristian Couder, Oct 25, 2022
  14. Taylor BlauOct 28, 2022
  15. Christian CouderNov 7, 2022
  16. 0/2 Implement filtering repacksChristian Couder, Nov 22, 2022
  17. 1/2 pack-objects: allow --filter without --stdoutChristian Couder, Nov 22, 2022
  18. 2/2 repack: add --filter=<filter-spec> optionChristian Couder, Nov 22, 2022
  19. Junio C HamanoNov 23, 2022
  20. Christian CouderDec 21, 2022
  21. Junio C HamanoNov 23, 2022
  22. 0/3 Implement filtering repacksChristian Couder, Dec 21, 2022
  23. 1/3 pack-objects: allow --filter without --stdoutChristian Couder, Dec 21, 2022
  24. Patrick SteinhardtJan 4, 2023
  25. 2/3 repack: add --filter=<filter-spec> optionChristian Couder, Dec 21, 2022
  26. Patrick SteinhardtJan 4, 2023
  27. Junio C HamanoJan 5, 2023
  28. 3/3 gc: add gc.repackFilter config optionChristian Couder, Dec 21, 2022
  29. Patrick SteinhardtJan 4, 2023
  30. 0/3 upload-pack: support a missing-actionChristian Couder, May 15, 2024
  31. 1/3 rev-list: refactor --missing=<missing-action>Christian Couder, May 15, 2024
  32. Junio C HamanoMay 15, 2024
  33. 2/3 pack-objects: use the missing action APIChristian Couder, May 15, 2024
  34. Junio C HamanoMay 15, 2024
  35. Christian CouderMay 24, 2024
  36. 3/3 upload-pack: allow configuring a missing-actionChristian Couder, May 15, 2024
  37. Junio C HamanoMay 15, 2024
  38. Christian CouderMay 24, 2024
  39. Junio C HamanoMay 24, 2024
  40. Christian CouderMay 28, 2024
  41. Junio C HamanoMay 28, 2024
  42. Christian CouderMay 31, 2024
  43. Junio C HamanoJun 1, 2024
  44. Christian CouderJun 3, 2024
  45. Junio C HamanoJun 3, 2024
  46. Christian CouderMay 15, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.