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

[PATCH 2/9] pack-objects: add `--print-filtered` to print omitted objects

From
Christian Couder <christian.couder@gmail.com>
Date
Jun 14, 2023, 19:25 UTC
Message-ID
<20230614192541.1599256-3-christian.couder@gmail.com>
In-Reply-To
<20230614192541.1599256-1-christian.couder@gmail.com>

When using the `--filter=<filter-spec>` option, `git pack-objects` will omit some objects from the resulting packfile(s) it produces. It could be useful to know about these omitted objects though.

For example, we might want to write these objects into a separate packfile by piping them into another `git pack-object` process. Or we might want to check if these objects are available from a promisor remote.

Anyway, this patch implements a simple way to let us know about these objects by simply printing their oid, one per line, on stdout when the new `--print-filtered` flag is passed.

As `--print-filtered` doesn't make sense without `--filter`, it is disallowed to use the former without the latter.

Using `--stdout` is likely to make the `--print-filtered` output difficult to find or parse, so we also disallow using these two options together.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
 Documentation/git-pack-objects.txt     | 10 ++++++
 builtin/pack-objects.c                 | 47 ++++++++++++++++++++++++--
 t/t5317-pack-objects-filter-objects.sh | 27 +++++++++++++++
 3 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt
index 583270a85f..6469080029 100644
--- a/Documentation/git-pack-objects.txt
+++ b/Documentation/git-pack-objects.txt
@@ -305,6 +305,16 @@ So does `git bundle` (see linkgit:git-bundle[1]) when it creates a bundle.
 --no-filter::
 	Turns off any previous `--filter=` argument.
 
+--print-filtered::
+	Requires `--filter=`. Prints on stdout, one per line, the
+	object IDs of the objects that are filtered out from the
+	resulting packfile by the filter. This is incompatible with
+	`--stdout`. As <SHA-1> hashes are already written to stdout
+	based on the resulting pack contents (see the `base-name`
+	argument), a line containing only six `-` characters is
+	written after those <SHA-1> hashes, before the filtered object
+	IDs.
+
 --missing=<missing-action>::
 	A debug option to help with future "partial clone" development.
 	This option specifies how missing objects are handled.
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index af007868c1..c8e2b6b859 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -266,6 +266,12 @@ static struct oidmap configured_exclusions;
 
 static struct oidset excluded_by_config;
 
+/*
+ * Objects omitted by filter
+ */
+static int print_filtered_out;
+static struct oidset *omitted_by_filter;
+
 /*
  * stats
  */
@@ -4065,11 +4071,18 @@ static void get_object_list(struct rev_info *revs, int ac, const char **av)
 		die(_("revision walk setup failed"));
 	mark_edges_uninteresting(revs, show_edge, sparse);
 
+	if (print_filtered_out) {
+		omitted_by_filter = xmalloc(sizeof(*omitted_by_filter));
+		oidset_init(omitted_by_filter, 0);
+	}
+
 	if (!fn_show_object)
 		fn_show_object = show_object;
-	traverse_commit_list(revs,
-			     show_commit, fn_show_object,
-			     NULL);
+	traverse_commit_list_filtered(revs,
+				      show_commit,
+				      fn_show_object,
+				      NULL,
+				      omitted_by_filter);
 
 	if (unpack_unreachable_expiration) {
 		revs->ignore_missing_links = 1;
@@ -4165,6 +4178,23 @@ static int option_parse_cruft_expiration(const struct option *opt,
 	return 0;
 }
 
+static void print_omitted_by_filter(void)
+{
+	struct oidset_iter iter;
+	const struct object_id *oid;
+
+	fprintf_ln(stdout, "%s", "------");
+	fprintf_ln(stderr, "%s", _("Printing objects omitted by filter"));
+
+	oidset_iter_init(omitted_by_filter, &iter);
+
+	while ((oid = oidset_iter_next(&iter)))
+		fprintf_ln(stdout, "%s", oid_to_hex(oid));
+
+	oidset_clear(omitted_by_filter);
+	FREE_AND_NULL(omitted_by_filter);
+}
+
 int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 {
 	int use_internal_rev_list = 0;
@@ -4278,6 +4308,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 		OPT_STRING_LIST(0, "uri-protocol", &uri_protocols,
 				N_("protocol"),
 				N_("exclude any configured uploadpack.blobpackfileuri with this protocol")),
+		OPT_BOOL(0, "print-filtered", &print_filtered_out,
+			 N_("print filtered out objects to stdout")),
 		OPT_END(),
 	};
 
@@ -4394,6 +4426,12 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 	if (stdin_packs && use_internal_rev_list)
 		die(_("cannot use internal rev list with --stdin-packs"));
 
+	if (print_filtered_out && !filter_options.choice)
+		die(_("cannot use --print-filtered without --filter"));
+
+	if (print_filtered_out && pack_to_stdout)
+		die(_("cannot use --print-filtered with --stdout"));
+
 	if (cruft) {
 		if (use_internal_rev_list)
 			die(_("cannot use internal rev list with --cruft"));
@@ -4509,6 +4547,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
 			   written, written_delta, reused, reused_delta,
 			   reuse_packfile_objects);
 
+	if (omitted_by_filter)
+		print_omitted_by_filter();
+
 cleanup:
 	list_objects_filter_release(&filter_options);
 	strvec_clear(&rp);
diff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh
index b26d476c64..ec3a03d90a 100755
--- a/t/t5317-pack-objects-filter-objects.sh
+++ b/t/t5317-pack-objects-filter-objects.sh
@@ -438,6 +438,33 @@ test_expect_success 'verify sparse:oid=oid-ish' '
 	test_cmp expected observed
 '
 
+# Test pack-objects with --print-filtered option
+
+test_expect_success 'pack-objects fails w/ both --print-filtered and --stdout' '
+	test_must_fail git -C r1 pack-objects --revs --stdout \
+		--filter=blob:none --print-filtered >filter.out <<-EOF
+	HEAD
+	EOF
+'
+
+test_expect_success 'pack-objects w/ --print-filtered and a pack name' '
+	git -C r1 pack-objects --revs --filter=blob:none \
+		--print-filtered filtered-pack >filter.out <<-EOF &&
+	HEAD
+	EOF
+
+	# Check that the second line contains "------"
+	head -n 2 filter.out | tail -n 1 >actual &&
+	echo "------" >expected &&
+	test_cmp expected actual &&
+
+	# Remove the first two lines and check there are all the blobs
+	tail -n +3 filter.out | sort >actual &&
+	git -C r1 cat-file --batch-check --batch-all-objects | grep blob |
+		sed -e "s/ blob.*//" | sort >expected &&
+	test_cmp expected actual
+'
+
 # Delete some loose objects and use pack-objects, but WITHOUT any filtering.
 # This models previously omitted objects that we did not receive.
 
-- 
2.41.0.37.gae45d9845e
Previous: Christian CouderNext: Junio C Hamano
Message 5 of 161 in “Repack objects into separate packfiles based on a filter”
  1. 0/9 Repack objects into separate packfiles based on a filterChristian Couder, Jun 14, 2023
  2. 1/9 pack-objects: allow `--filter` without `--stdout`Christian Couder, Jun 14, 2023
  3. Taylor BlauJun 21, 2023
  4. Christian CouderJul 5, 2023
  5. 2/9 pack-objects: add `--print-filtered` to print omitted objectsChristian Couder, Jun 14, 2023
  6. Junio C HamanoJun 15, 2023
  7. Taylor BlauJun 21, 2023
  8. Christian CouderJun 21, 2023
  9. Taylor BlauJun 21, 2023
  10. 3/9 t/helper: add 'find-pack' test-toolChristian Couder, Jun 14, 2023
  11. Junio C HamanoJun 15, 2023
  12. Christian CouderJun 21, 2023
  13. Taylor BlauJun 21, 2023
  14. 5/9 repack: refactor finishing pack-objects commandChristian Couder, Jun 14, 2023
  15. Junio C HamanoJun 16, 2023
  16. Taylor BlauJun 21, 2023
  17. Christian CouderJun 21, 2023
  18. Taylor BlauJun 21, 2023
  19. 4/9 repack: refactor piping an oid to a commandChristian Couder, Jun 14, 2023
  20. Junio C HamanoJun 15, 2023
  21. Taylor BlauJun 21, 2023
  22. Christian CouderJun 21, 2023
  23. 6/9 repack: add `--filter=<filter-spec>` optionChristian Couder, Jun 14, 2023
  24. Junio C HamanoJun 16, 2023
  25. Taylor BlauJun 21, 2023
  26. Christian CouderJun 21, 2023
  27. Taylor BlauJun 22, 2023
  28. Christian CouderJun 21, 2023
  29. Junio C HamanoJun 21, 2023
  30. Christian CouderJun 22, 2023
  31. Junio C HamanoJun 22, 2023
  32. Taylor BlauJun 21, 2023
  33. Christian CouderJul 5, 2023
  34. 8/9 repack: implement `--filter-to` for storing filtered out objectsChristian Couder, Jun 14, 2023
  35. Junio C HamanoJun 16, 2023
  36. Taylor BlauJun 21, 2023
  37. Christian CouderJun 21, 2023
  38. Taylor BlauJun 21, 2023
  39. Junio C HamanoJun 21, 2023
  40. Christian CouderJul 5, 2023
  41. 7/9 gc: add `gc.repackFilter` config optionChristian Couder, Jun 14, 2023
  42. 9/9 gc: add `gc.repackFilterTo` config optionChristian Couder, Jun 14, 2023
  43. Junio C HamanoJun 16, 2023
  44. Junio C HamanoJun 14, 2023
  45. Junio C HamanoJun 16, 2023
  46. 0/8 Repack objects into separate packfiles based on a filterChristian Couder, Jul 5, 2023
  47. 1/8 pack-objects: allow `--filter` without `--stdout`Christian Couder, Jul 5, 2023
  48. 2/8 t/helper: add 'find-pack' test-toolChristian Couder, Jul 5, 2023
  49. 3/8 repack: refactor finishing pack-objects commandChristian Couder, Jul 5, 2023
  50. 4/8 repack: refactor finding pack prefixChristian Couder, Jul 5, 2023
  51. 5/8 repack: add `--filter=<filter-spec>` optionChristian Couder, Jul 5, 2023
  52. Junio C HamanoJul 5, 2023
  53. Christian CouderJul 24, 2023
  54. Junio C HamanoJul 24, 2023
  55. Christian CouderJul 25, 2023
  56. Junio C HamanoJul 25, 2023
  57. Junio C HamanoJul 25, 2023
  58. Christian CouderAug 8, 2023
  59. Taylor BlauAug 9, 2023
  60. Junio C HamanoAug 9, 2023
  61. Junio C HamanoAug 9, 2023
  62. Jeff KingAug 10, 2023
  63. Junio C HamanoJul 5, 2023
  64. Christian CouderJul 24, 2023
  65. 6/8 gc: add `gc.repackFilter` config optionChristian Couder, Jul 5, 2023
  66. 8/8 gc: add `gc.repackFilterTo` config optionChristian Couder, Jul 5, 2023
  67. 7/8 repack: implement `--filter-to` for storing filtered out objectsChristian Couder, Jul 5, 2023
  68. Junio C HamanoJul 5, 2023
  69. Christian CouderJul 24, 2023
  70. Junio C HamanoJul 24, 2023
  71. Robert CoupJul 25, 2023
  72. Junio C HamanoJul 25, 2023
  73. Christian CouderJul 25, 2023
  74. 0/8 Repack objects into separate packfiles based on a filterChristian Couder, Jul 24, 2023
  75. 1/8 pack-objects: allow `--filter` without `--stdout`Christian Couder, Jul 24, 2023
  76. Taylor BlauJul 25, 2023
  77. Junio C HamanoJul 25, 2023
  78. 3/8 repack: refactor finishing pack-objects commandChristian Couder, Jul 24, 2023
  79. Taylor BlauJul 25, 2023
  80. 4/8 repack: refactor finding pack prefixChristian Couder, Jul 24, 2023
  81. Taylor BlauJul 25, 2023
  82. Christian CouderAug 8, 2023
  83. 2/8 t/helper: add 'find-pack' test-toolChristian Couder, Jul 24, 2023
  84. Taylor BlauJul 25, 2023
  85. Christian CouderAug 8, 2023
  86. 5/8 repack: add `--filter=<filter-spec>` optionChristian Couder, Jul 24, 2023
  87. Taylor BlauJul 25, 2023
  88. Christian CouderAug 8, 2023
  89. Taylor BlauAug 9, 2023
  90. 6/8 gc: add `gc.repackFilter` config optionChristian Couder, Jul 24, 2023
  91. Taylor BlauJul 25, 2023
  92. Christian CouderAug 8, 2023
  93. Taylor BlauAug 9, 2023
  94. 8/8 gc: add `gc.repackFilterTo` config optionChristian Couder, Jul 24, 2023
  95. 7/8 repack: implement `--filter-to` for storing filtered out objectsChristian Couder, Jul 24, 2023
  96. Taylor BlauJul 25, 2023
  97. 0/8 Repack objects into separate packfiles based on a filterChristian Couder, Aug 8, 2023
  98. 7/8 repack: implement `--filter-to` for storing filtered out objectsChristian Couder, Aug 8, 2023
  99. 5/8 repack: add `--filter=<filter-spec>` optionChristian Couder, Aug 8, 2023
  100. Taylor BlauAug 9, 2023
  101. 4/8 repack: refactor finding pack prefixChristian Couder, Aug 8, 2023
  102. Taylor BlauAug 9, 2023
  103. 3/8 repack: refactor finishing pack-objects commandChristian Couder, Aug 8, 2023
  104. 6/8 gc: add `gc.repackFilter` config optionChristian Couder, Aug 8, 2023
  105. 8/8 gc: add `gc.repackFilterTo` config optionChristian Couder, Aug 8, 2023
  106. 1/8 pack-objects: allow `--filter` without `--stdout`Christian Couder, Aug 8, 2023
  107. 2/8 t/helper: add 'find-pack' test-toolChristian Couder, Aug 8, 2023
  108. Taylor BlauAug 9, 2023
  109. Taylor BlauAug 9, 2023
  110. Junio C HamanoAug 9, 2023
  111. Christian CouderAug 12, 2023
  112. 0/8 Repack objects into separate packfiles based on a filterChristian Couder, Aug 12, 2023
  113. 1/8 pack-objects: allow `--filter` without `--stdout`Christian Couder, Aug 12, 2023
  114. 2/8 t/helper: add 'find-pack' test-toolChristian Couder, Aug 12, 2023
  115. 3/8 repack: refactor finishing pack-objects commandChristian Couder, Aug 12, 2023
  116. 4/8 repack: refactor finding pack prefixChristian Couder, Aug 12, 2023
  117. 5/8 repack: add `--filter=<filter-spec>` optionChristian Couder, Aug 12, 2023
  118. 6/8 gc: add `gc.repackFilter` config optionChristian Couder, Aug 12, 2023
  119. 7/8 repack: implement `--filter-to` for storing filtered out objectsChristian Couder, Aug 12, 2023
  120. 8/8 gc: add `gc.repackFilterTo` config optionChristian Couder, Aug 12, 2023
  121. Junio C HamanoAug 15, 2023
  122. Taylor BlauAug 15, 2023
  123. Junio C HamanoAug 15, 2023
  124. Taylor BlauAug 15, 2023
  125. Junio C HamanoAug 15, 2023
  126. Taylor BlauAug 16, 2023
  127. Junio C HamanoAug 16, 2023
  128. Christian CouderSep 11, 2023
  129. 0/9 Repack objects into separate packfiles based on a filterChristian Couder, Sep 11, 2023
  130. 4/9 repack: refactor finding pack prefixChristian Couder, Sep 11, 2023
  131. 5/9 pack-bitmap-write: rebuild using new bitmap when remappingChristian Couder, Sep 11, 2023
  132. 2/9 t/helper: add 'find-pack' test-toolChristian Couder, Sep 11, 2023
  133. 6/9 repack: add `--filter=<filter-spec>` optionChristian Couder, Sep 11, 2023
  134. 1/9 pack-objects: allow `--filter` without `--stdout`Christian Couder, Sep 11, 2023
  135. 8/9 repack: implement `--filter-to` for storing filtered out objectsChristian Couder, Sep 11, 2023
  136. 7/9 gc: add `gc.repackFilter` config optionChristian Couder, Sep 11, 2023
  137. 3/9 repack: refactor finishing pack-objects commandChristian Couder, Sep 11, 2023
  138. 9/9 gc: add `gc.repackFilterTo` config optionChristian Couder, Sep 11, 2023
  139. 0/9 Repack objects into separate packfiles based on a filterChristian Couder, Sep 25, 2023
  140. 1/9 pack-objects: allow `--filter` without `--stdout`Christian Couder, Sep 25, 2023
  141. 2/9 t/helper: add 'find-pack' test-toolChristian Couder, Sep 25, 2023
  142. 3/9 repack: refactor finishing pack-objects commandChristian Couder, Sep 25, 2023
  143. 4/9 repack: refactor finding pack prefixChristian Couder, Sep 25, 2023
  144. 5/9 pack-bitmap-write: rebuild using new bitmap when remappingChristian Couder, Sep 25, 2023
  145. 7/9 gc: add `gc.repackFilter` config optionChristian Couder, Sep 25, 2023
  146. 6/9 repack: add `--filter=<filter-spec>` optionChristian Couder, Sep 25, 2023
  147. 8/9 repack: implement `--filter-to` for storing filtered out objectsChristian Couder, Sep 25, 2023
  148. 9/9 gc: add `gc.repackFilterTo` config optionChristian Couder, Sep 25, 2023
  149. Junio C HamanoSep 25, 2023
  150. Taylor BlauSep 25, 2023
  151. 0/9 Repack objects into separate packfiles based on a filterChristian Couder, Oct 2, 2023
  152. 1/9 pack-objects: allow `--filter` without `--stdout`Christian Couder, Oct 2, 2023
  153. 2/9 t/helper: add 'find-pack' test-toolChristian Couder, Oct 2, 2023
  154. 3/9 repack: refactor finishing pack-objects commandChristian Couder, Oct 2, 2023
  155. 4/9 repack: refactor finding pack prefixChristian Couder, Oct 2, 2023
  156. 5/9 pack-bitmap-write: rebuild using new bitmap when remappingChristian Couder, Oct 2, 2023
  157. 7/9 gc: add `gc.repackFilter` config optionChristian Couder, Oct 2, 2023
  158. 9/9 gc: add `gc.repackFilterTo` config optionChristian Couder, Oct 2, 2023
  159. 8/9 repack: implement `--filter-to` for storing filtered out objectsChristian Couder, Oct 2, 2023
  160. 6/9 repack: add `--filter=<filter-spec>` optionChristian Couder, Oct 2, 2023
  161. Taylor BlauOct 2, 2023

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.