From: Derrick Stolee <dsto...@microsoft.com>

The multi-pack-index tracks objects in a collection of pack-files.
Only one copy of each object is indexed, using the modified time
of the pack-files to determine tie-breakers. It is possible to
have a pack-file with no referenced objects because all objects
have a duplicate in a newer pack-file.

Introduce a new 'expire' subcommand to the multi-pack-index builtin.
This subcommand will delete these unused pack-files and rewrite the
multi-pack-index to no longer refer to those files. More details
about the specifics will follow as the method is implemented.

Add a test that verifies the 'expire' subcommand is correctly wired,
but will still be valid when the verb is implemented. Specifically,
create a set of packs that should all have referenced objects and
should not be removed during an 'expire' operation. The packs are
created carefully to ensure they have a specific order when sorted
by size. This will be important in a later test.

Signed-off-by: Derrick Stolee <dsto...@microsoft.com>
---
 Documentation/git-multi-pack-index.txt |  5 +++
 builtin/multi-pack-index.c             |  4 ++-
 midx.c                                 |  5 +++
 midx.h                                 |  1 +
 t/t5319-multi-pack-index.sh            | 49 ++++++++++++++++++++++++++
 5 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-multi-pack-index.txt 
b/Documentation/git-multi-pack-index.txt
index 1af406aca2..6186c4c936 100644
--- a/Documentation/git-multi-pack-index.txt
+++ b/Documentation/git-multi-pack-index.txt
@@ -31,6 +31,11 @@ write::
 verify::
        Verify the contents of the MIDX file.
 
+expire::
+       Delete the pack-files that are tracked  by the MIDX file, but
+       have no objects referenced by the MIDX. Rewrite the MIDX file
+       afterward to remove all references to these pack-files.
+
 
 EXAMPLES
 --------
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index fca70f8e4f..145de3a46c 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -5,7 +5,7 @@
 #include "midx.h"
 
 static char const * const builtin_multi_pack_index_usage[] = {
-       N_("git multi-pack-index [--object-dir=<dir>] (write|verify)"),
+       N_("git multi-pack-index [--object-dir=<dir>] (write|verify|expire)"),
        NULL
 };
 
@@ -44,6 +44,8 @@ int cmd_multi_pack_index(int argc, const char **argv,
                return write_midx_file(opts.object_dir);
        if (!strcmp(argv[0], "verify"))
                return verify_midx_file(opts.object_dir);
+       if (!strcmp(argv[0], "expire"))
+               return expire_midx_packs(opts.object_dir);
 
        die(_("unrecognized verb: %s"), argv[0]);
 }
diff --git a/midx.c b/midx.c
index 730ff84dff..bb825ef816 100644
--- a/midx.c
+++ b/midx.c
@@ -1025,3 +1025,8 @@ int verify_midx_file(const char *object_dir)
 
        return verify_midx_error;
 }
+
+int expire_midx_packs(const char *object_dir)
+{
+       return 0;
+}
diff --git a/midx.h b/midx.h
index 774f652530..e3a2b740b5 100644
--- a/midx.h
+++ b/midx.h
@@ -49,6 +49,7 @@ int prepare_multi_pack_index_one(struct repository *r, const 
char *object_dir, i
 int write_midx_file(const char *object_dir);
 void clear_midx_file(struct repository *r);
 int verify_midx_file(const char *object_dir);
+int expire_midx_packs(const char *object_dir);
 
 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 70926b5bc0..a8528f7da0 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -348,4 +348,53 @@ test_expect_success 'verify incorrect 64-bit offset' '
                "incorrect object offset"
 '
 
+test_expect_success 'setup expire tests' '
+       mkdir dup &&
+       (
+               cd dup &&
+               git init &&
+               test-tool genrandom "data" 4096 >large_file.txt &&
+               git update-index --add large_file.txt &&
+               for i in $(test_seq 1 20)
+               do
+                       test_commit $i
+               done &&
+               git branch A HEAD &&
+               git branch B HEAD~8 &&
+               git branch C HEAD~13 &&
+               git branch D HEAD~16 &&
+               git branch E HEAD~18 &&
+               git pack-objects --revs .git/objects/pack/pack-A <<-EOF &&
+               refs/heads/A
+               ^refs/heads/B
+               EOF
+               git pack-objects --revs .git/objects/pack/pack-B <<-EOF &&
+               refs/heads/B
+               ^refs/heads/C
+               EOF
+               git pack-objects --revs .git/objects/pack/pack-C <<-EOF &&
+               refs/heads/C
+               ^refs/heads/D
+               EOF
+               git pack-objects --revs .git/objects/pack/pack-D <<-EOF &&
+               refs/heads/D
+               ^refs/heads/E
+               EOF
+               git pack-objects --revs .git/objects/pack/pack-E <<-EOF &&
+               refs/heads/E
+               EOF
+               git multi-pack-index write
+       )
+'
+
+test_expect_success 'expire does not remove any packs' '
+       (
+               cd dup &&
+               ls .git/objects/pack >expect &&
+               git multi-pack-index expire &&
+               ls .git/objects/pack >actual &&
+               test_cmp expect actual
+       )
+'
+
 test_done
-- 
gitgitgadget

Reply via email to