summaryrefslogtreecommitdiff
path: root/builtin/repack.c
diff options
context:
space:
mode:
authorLibravatar Taylor Blau <me@ttaylorr.com>2021-09-28 21:55:20 -0400
committerLibravatar Junio C Hamano <gitster@pobox.com>2021-09-28 21:20:56 -0700
commit6d08b9d4caa230441b7d9e2b4f23deaf9ff74c13 (patch)
tree998a9f118f75eac980c677a0e41a16e2e0cd4a9d /builtin/repack.c
parentbuiltin/repack.c: support writing a MIDX while repacking (diff)
downloadtgif-6d08b9d4caa230441b7d9e2b4f23deaf9ff74c13.tar.xz
builtin/repack.c: make largest pack preferred
When repacking into a geometric series and writing a multi-pack bitmap, it is beneficial to have the largest resulting pack be the preferred object source in the bitmap's MIDX, since selecting the large packs can lead to fewer broken delta chains and better compression. Teach 'git repack' to identify this pack and pass it to the MIDX write machinery in order to mark it as preferred. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/repack.c')
-rw-r--r--builtin/repack.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/builtin/repack.c b/builtin/repack.c
index dbbb14b3b4..f940e2bafe 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -423,6 +423,25 @@ static void split_pack_geometry(struct pack_geometry *geometry, int factor)
geometry->split = split;
}
+static struct packed_git *get_largest_active_pack(struct pack_geometry *geometry)
+{
+ if (!geometry) {
+ /*
+ * No geometry means either an all-into-one repack (in which
+ * case there is only one pack left and it is the largest) or an
+ * incremental one.
+ *
+ * If repacking incrementally, then we could check the size of
+ * all packs to determine which should be preferred, but leave
+ * this for later.
+ */
+ return NULL;
+ }
+ if (geometry->split == geometry->pack_nr)
+ return NULL;
+ return geometry->pack[geometry->pack_nr - 1];
+}
+
static void clear_pack_geometry(struct pack_geometry *geometry)
{
if (!geometry)
@@ -468,10 +487,12 @@ static void midx_included_packs(struct string_list *include,
}
static int write_midx_included_packs(struct string_list *include,
+ struct pack_geometry *geometry,
int show_progress, int write_bitmaps)
{
struct child_process cmd = CHILD_PROCESS_INIT;
struct string_list_item *item;
+ struct packed_git *largest = get_largest_active_pack(geometry);
FILE *in;
int ret;
@@ -492,6 +513,10 @@ static int write_midx_included_packs(struct string_list *include,
if (write_bitmaps)
strvec_push(&cmd.args, "--bitmap");
+ if (largest)
+ strvec_pushf(&cmd.args, "--preferred-pack=%s",
+ pack_basename(largest));
+
ret = start_command(&cmd);
if (ret)
return ret;
@@ -783,7 +808,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
midx_included_packs(&include, &existing_nonkept_packs,
&existing_kept_packs, &names, geometry);
- ret = write_midx_included_packs(&include,
+ ret = write_midx_included_packs(&include, geometry,
show_progress, write_bitmaps > 0);
string_list_clear(&include, 0);