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

[PATCH v6 07/11] multi-pack-index: prepare 'repack' subcommand

From
Derrick Stolee <stolee@gmail.com>
Date
May 14, 2019, 18:47 UTC
Message-ID
<20190514184754.3196-8-dstolee@microsoft.com>
In-Reply-To
<20190514184754.3196-1-dstolee@microsoft.com>

In an environment where the multi-pack-index is useful, it is due to many pack-files and an inability to repack the object store into a single pack-file. However, it is likely that many of these pack-files are rather small, and could be repacked into a slightly larger pack-file without too much effort. It may also be important to ensure the object store is highly available and the repack operation does not interrupt concurrent git commands.

Introduce a 'repack' subcommand to 'git multi-pack-index' that takes a '--batch-size' option. The subcommand will inspect the multi-pack-index for referenced pack-files whose size is smaller than the batch size, until collecting a list of pack-files whose sizes sum to larger than the batch size. Then, a new pack-file will be created containing the objects from those pack-files that are referenced by the multi-pack-index. The resulting pack is likely to actually be smaller than the batch size due to compression and the fact that there may be objects in the pack- files that have duplicate copies in other pack-files.

The current change introduces the command-line arguments, and we add a test that ensures we parse these options properly. Since we specify a small batch size, we will guarantee that future implementations do not change the list of pack-files.

In addition, we hard-code the modified times of the packs in the pack directory to ensure the list of packs sorted by modified time matches the order if sorted by size (ascending). This will be important in a future test.

Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
---
 Documentation/git-multi-pack-index.txt | 17 +++++++++++++++++
 builtin/multi-pack-index.c             | 12 ++++++++++--
 midx.c                                 |  5 +++++
 midx.h                                 |  1 +
 t/t5319-multi-pack-index.sh            | 20 +++++++++++++++++++-
 5 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-multi-pack-index.txt b/Documentation/git-multi-pack-index.txt
index 6186c4c936..233b2b7862 100644
--- a/Documentation/git-multi-pack-index.txt
+++ b/Documentation/git-multi-pack-index.txt
@@ -36,6 +36,23 @@ expire::
 	have no objects referenced by the MIDX. Rewrite the MIDX file
 	afterward to remove all references to these pack-files.
 
+repack::
+	Create a new pack-file containing objects in small pack-files
+	referenced by the multi-pack-index. If the size given by the
+	`--batch-size=<size>` argument is zero, then create a pack
+	containing all objects referenced by the multi-pack-index. For
+	a non-zero batch size, Select the pack-files by examining packs
+	from oldest-to-newest, computing the "expected size" by counting
+	the number of objects in the pack referenced by the
+	multi-pack-index, then divide by the total number of objects in
+	the pack and multiply by the pack size. We select packs with
+	expected size below the batch size until the set of packs have
+	total expected size at least the batch size. If the total size
+	does not reach the batch size, then do nothing. If a new pack-
+	file is created, rewrite the multi-pack-index to reference the
+	new pack-file. A later run of 'git multi-pack-index expire' will
+	delete the pack-files that were part of this batch.
+
 
 EXAMPLES
 --------
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index ad10d40512..b1ea1a6aa1 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -6,12 +6,13 @@
 #include "trace2.h"
 
 static char const * const builtin_multi_pack_index_usage[] = {
-	N_("git multi-pack-index [--object-dir=<dir>] (write|verify|expire)"),
+	N_("git multi-pack-index [--object-dir=<dir>] (write|verify|expire|repack --batch-size=<size>)"),
 	NULL
 };
 
 static struct opts_multi_pack_index {
 	const char *object_dir;
+	unsigned long batch_size;
 } opts;
 
 int cmd_multi_pack_index(int argc, const char **argv,
@@ -20,6 +21,8 @@ int cmd_multi_pack_index(int argc, const char **argv,
 	static struct option builtin_multi_pack_index_options[] = {
 		OPT_FILENAME(0, "object-dir", &opts.object_dir,
 		  N_("object directory containing set of packfile and pack-index pairs")),
+		OPT_MAGNITUDE(0, "batch-size", &opts.batch_size,
+		  N_("during repack, collect pack-files of smaller size into a batch that is larger than this size")),
 		OPT_END(),
 	};
 
@@ -43,6 +46,11 @@ int cmd_multi_pack_index(int argc, const char **argv,
 
 	trace2_cmd_mode(argv[0]);
 
+	if (!strcmp(argv[0], "repack"))
+		return midx_repack(the_repository, opts.object_dir, (size_t)opts.batch_size);
+	if (opts.batch_size)
+		die(_("--batch-size option is only for 'repack' subcommand"));
+
 	if (!strcmp(argv[0], "write"))
 		return write_midx_file(opts.object_dir);
 	if (!strcmp(argv[0], "verify"))
@@ -50,5 +58,5 @@ int cmd_multi_pack_index(int argc, const char **argv,
 	if (!strcmp(argv[0], "expire"))
 		return expire_midx_packs(the_repository, opts.object_dir);
 
-	die(_("unrecognized verb: %s"), argv[0]);
+	die(_("unrecognized subcommand: %s"), argv[0]);
 }
diff --git a/midx.c b/midx.c
index 9b0b4c1520..fbed8a8adb 100644
--- a/midx.c
+++ b/midx.c
@@ -1226,3 +1226,8 @@ int expire_midx_packs(struct repository *r, const char *object_dir)
 	string_list_clear(&packs_to_drop, 0);
 	return result;
 }
+
+int midx_repack(struct repository *r, const char *object_dir, size_t batch_size)
+{
+	return 0;
+}
diff --git a/midx.h b/midx.h
index 505f1431b7..f0ae656b5d 100644
--- a/midx.h
+++ b/midx.h
@@ -51,6 +51,7 @@ int write_midx_file(const char *object_dir);
 void clear_midx_file(struct repository *r);
 int verify_midx_file(struct repository *r, const char *object_dir);
 int expire_midx_packs(struct repository *r, const char *object_dir);
+int midx_repack(struct repository *r, const char *object_dir, size_t batch_size);
 
 void close_midx(struct multi_pack_index *m);
 
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index 12570fe7ac..133d5b7068 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -398,7 +398,8 @@ test_expect_success 'setup expire tests' '
 		git pack-objects --revs .git/objects/pack/pack-E <<-EOF &&
 		refs/heads/E
 		EOF
-		git multi-pack-index write
+		git multi-pack-index write &&
+		cp -r .git/objects/pack .git/objects/pack-backup
 	)
 '
 
@@ -432,4 +433,21 @@ test_expect_success 'expire removes unreferenced packs' '
 	)
 '
 
+test_expect_success 'repack with minimum size does not alter existing packs' '
+	(
+		cd dup &&
+		rm -rf .git/objects/pack &&
+		mv .git/objects/pack-backup .git/objects/pack &&
+		touch -m -t 201901010000 .git/objects/pack/pack-D* &&
+		touch -m -t 201901010001 .git/objects/pack/pack-C* &&
+		touch -m -t 201901010002 .git/objects/pack/pack-B* &&
+		touch -m -t 201901010003 .git/objects/pack/pack-A* &&
+		ls .git/objects/pack >expect &&
+		MINSIZE=$(ls -l .git/objects/pack/*pack | awk "{print \$5;}" | sort -n | head -n 1) &&
+		git multi-pack-index repack --batch-size=$MINSIZE &&
+		ls .git/objects/pack >actual &&
+		test_cmp expect actual
+	)
+'
+
 test_done
-- 
2.22.0.rc0
Previous: Derrick StoleeNext: Derrick Stolee
Message 84 of 92 in “Create 'expire' and 'repack' verbs for git-multi-pack-index”
  1. 0/5 Create 'expire' and 'repack' verbs for git-multi-pack-indexDerrick Stolee via GitGitGadget, Dec 10, 2018
  2. 1/5 multi-pack-index: prepare for 'expire' verbDerrick Stolee via GitGitGadget, Dec 10, 2018
  3. Stefan BellerDec 11, 2018
  4. SZEDER GáborDec 11, 2018
  5. Derrick StoleeDec 11, 2018
  6. 3/5 multi-pack-index: implement 'expire' verbDerrick Stolee via GitGitGadget, Dec 10, 2018
  7. 2/5 midx: refactor permutation logicDerrick Stolee via GitGitGadget, Dec 10, 2018
  8. 4/5 multi-pack-index: prepare 'repack' verbDerrick Stolee via GitGitGadget, Dec 10, 2018
  9. Stefan BellerDec 11, 2018
  10. Derrick StoleeDec 11, 2018
  11. 5/5 midx: implement midx_repack()Derrick Stolee via GitGitGadget, Dec 10, 2018
  12. Stefan BellerDec 11, 2018
  13. Derrick StoleeDec 11, 2018
  14. Junio C HamanoDec 12, 2018
  15. Junio C HamanoDec 13, 2018
  16. 0/7 Create 'expire' and 'repack' verbs for git-multi-pack-indexDerrick Stolee via GitGitGadget, Dec 21, 2018
  17. 1/7 repack: refactor pack deletion for future useDerrick Stolee via GitGitGadget, Dec 21, 2018
  18. 2/7 Docs: rearrange subcommands for multi-pack-indexDerrick Stolee via GitGitGadget, Dec 21, 2018
  19. 3/7 multi-pack-index: prepare for 'expire' subcommandDerrick Stolee via GitGitGadget, Dec 21, 2018
  20. 6/7 multi-pack-index: prepare 'repack' subcommandDerrick Stolee via GitGitGadget, Dec 21, 2018
  21. 5/7 multi-pack-index: implement 'expire' verbDerrick Stolee via GitGitGadget, Dec 21, 2018
  22. 7/7 midx: implement midx_repack()Derrick Stolee via GitGitGadget, Dec 21, 2018
  23. 4/7 midx: refactor permutation logicDerrick Stolee via GitGitGadget, Dec 21, 2018
  24. 0/9 Create 'expire' and 'repack' verbs for git-multi-pack-indexDerrick Stolee via GitGitGadget, Jan 9, 2019
  25. 1/9 repack: refactor pack deletion for future useDerrick Stolee via GitGitGadget, Jan 9, 2019
  26. 3/9 multi-pack-index: prepare for 'expire' subcommandDerrick Stolee via GitGitGadget, Jan 9, 2019
  27. 4/9 midx: simplify computation of pack name lengthsDerrick Stolee via GitGitGadget, Jan 9, 2019
  28. 6/9 multi-pack-index: implement 'expire' verbDerrick Stolee via GitGitGadget, Jan 9, 2019
  29. SZEDER GáborJan 9, 2019
  30. Junio C HamanoJan 10, 2019
  31. Jonathan TanJan 23, 2019
  32. Derrick StoleeJan 24, 2019
  33. 5/9 midx: refactor permutation logic and pack sortingDerrick Stolee via GitGitGadget, Jan 9, 2019
  34. Jonathan TanJan 23, 2019
  35. Derrick StoleeJan 24, 2019
  36. Derrick StoleeJan 24, 2019
  37. 8/9 midx: implement midx_repack()Derrick Stolee via GitGitGadget, Jan 9, 2019
  38. Jonathan TanJan 23, 2019
  39. 9/9 multi-pack-index: test expire while adding packsDerrick Stolee via GitGitGadget, Jan 9, 2019
  40. 7/9 multi-pack-index: prepare 'repack' subcommandDerrick Stolee via GitGitGadget, Jan 9, 2019
  41. SZEDER GáborJan 9, 2019
  42. Jonathan TanJan 23, 2019
  43. Derrick StoleeJan 24, 2019
  44. Jonathan TanJan 24, 2019
  45. 2/9 Docs: rearrange subcommands for multi-pack-indexDerrick Stolee via GitGitGadget, Jan 9, 2019
  46. Derrick StoleeJan 17, 2019
  47. Jonathan TanJan 23, 2019
  48. 00/10 Create 'expire' and 'repack' verbs for git-multi-pack-indexDerrick Stolee via GitGitGadget, Jan 24, 2019
  49. 01/10 repack: refactor pack deletion for future useDerrick Stolee via GitGitGadget, Jan 24, 2019
  50. 02/10 Docs: rearrange subcommands for multi-pack-indexDerrick Stolee via GitGitGadget, Jan 24, 2019
  51. 04/10 midx: simplify computation of pack name lengthsDerrick Stolee via GitGitGadget, Jan 24, 2019
  52. 05/10 midx: refactor permutation logic and pack sortingDerrick Stolee via GitGitGadget, Jan 24, 2019
  53. 06/10 multi-pack-index: implement 'expire' subcommandDerrick Stolee via GitGitGadget, Jan 24, 2019
  54. 03/10 multi-pack-index: prepare for 'expire' subcommandDerrick Stolee via GitGitGadget, Jan 24, 2019
  55. 08/10 midx: implement midx_repack()Derrick Stolee via GitGitGadget, Jan 24, 2019
  56. Derrick StoleeJan 26, 2019
  57. Junio C HamanoJan 27, 2019
  58. 09/10 multi-pack-index: test expire while adding packsDerrick Stolee via GitGitGadget, Jan 24, 2019
  59. 10/10 midx: add test that 'expire' respects .keep filesDerrick Stolee via GitGitGadget, Jan 24, 2019
  60. 07/10 multi-pack-index: prepare 'repack' subcommandDerrick Stolee via GitGitGadget, Jan 24, 2019
  61. Josh SteadmonJan 25, 2019
  62. Jonathan TanJan 24, 2019
  63. Josh SteadmonJan 25, 2019
  64. 00/11 Create 'expire' and 'repack' verbs for git-multi-pack-indexDerrick Stolee, Apr 24, 2019
  65. 01/11 repack: refactor pack deletion for future useDerrick Stolee, Apr 24, 2019
  66. 03/11 multi-pack-index: prepare for 'expire' subcommandDerrick Stolee, Apr 24, 2019
  67. 02/11 Docs: rearrange subcommands for multi-pack-indexDerrick Stolee, Apr 24, 2019
  68. 04/11 midx: simplify computation of pack name lengthsDerrick Stolee, Apr 24, 2019
  69. 07/11 multi-pack-index: prepare 'repack' subcommandDerrick Stolee, Apr 24, 2019
  70. 08/11 midx: implement midx_repack()Derrick Stolee, Apr 24, 2019
  71. 09/11 multi-pack-index: test expire while adding packsDerrick Stolee, Apr 24, 2019
  72. 10/11 midx: add test that 'expire' respects .keep filesDerrick Stolee, Apr 24, 2019
  73. 11/11 t5319-multi-pack-index.sh: test batch size zeroDerrick Stolee, Apr 24, 2019
  74. 06/11 multi-pack-index: implement 'expire' subcommandDerrick Stolee, Apr 24, 2019
  75. 05/11 midx: refactor permutation logic and pack sortingDerrick Stolee, Apr 24, 2019
  76. Junio C HamanoApr 25, 2019
  77. Derrick StoleeApr 25, 2019
  78. 00/11 Create 'expire' and 'repack' verbs for git-multi-pack-indexDerrick Stolee, May 14, 2019
  79. 01/11 repack: refactor pack deletion for future useDerrick Stolee, May 14, 2019
  80. 02/11 Docs: rearrange subcommands for multi-pack-indexDerrick Stolee, May 14, 2019
  81. 05/11 midx: refactor permutation logic and pack sortingDerrick Stolee, May 14, 2019
  82. 06/11 multi-pack-index: implement 'expire' subcommandDerrick Stolee, May 14, 2019
  83. 03/11 multi-pack-index: prepare for 'expire' subcommandDerrick Stolee, May 14, 2019
  84. 07/11 multi-pack-index: prepare 'repack' subcommandDerrick Stolee, May 14, 2019
  85. 09/11 multi-pack-index: test expire while adding packsDerrick Stolee, May 14, 2019
  86. 10/11 midx: add test that 'expire' respects .keep filesDerrick Stolee, May 14, 2019
  87. 11/11 t5319-multi-pack-index.sh: test batch size zeroDerrick Stolee, May 14, 2019
  88. 08/11 midx: implement midx_repack()Derrick Stolee, May 14, 2019
  89. 04/11 midx: simplify computation of pack name lengthsDerrick Stolee, May 14, 2019
  90. Derrick StoleeJun 10, 2019
  91. Junio C HamanoJun 10, 2019
  92. Derrick StoleeJun 10, 2019

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.