aboutsummaryrefslogtreecommitdiffstats
path: root/builtin/repack.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/repack.c')
-rw-r--r--builtin/repack.c116
1 files changed, 54 insertions, 62 deletions
diff --git a/builtin/repack.c b/builtin/repack.c
index 1e21a21ea8..6943c5ba11 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -1,11 +1,11 @@
#include "builtin.h"
-#include "alloc.h"
#include "config.h"
#include "dir.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
#include "parse-options.h"
+#include "path.h"
#include "run-command.h"
#include "server-info.h"
#include "sigchain.h"
@@ -15,7 +15,7 @@
#include "midx.h"
#include "packfile.h"
#include "prune-packed.h"
-#include "object-store.h"
+#include "object-store-ll.h"
#include "promisor-remote.h"
#include "shallow.h"
#include "pack.h"
@@ -59,7 +59,8 @@ struct pack_objects_args {
int local;
};
-static int repack_config(const char *var, const char *value, void *cb)
+static int repack_config(const char *var, const char *value,
+ const struct config_context *ctx, void *cb)
{
struct pack_objects_args *cruft_po_args = cb;
if (!strcmp(var, "repack.usedeltabaseoffset")) {
@@ -91,7 +92,7 @@ static int repack_config(const char *var, const char *value, void *cb)
return git_config_string(&cruft_po_args->depth, var, value);
if (!strcmp(var, "repack.cruftthreads"))
return git_config_string(&cruft_po_args->threads, var, value);
- return git_default_config(var, value, cb);
+ return git_default_config(var, value, ctx, cb);
}
/*
@@ -104,46 +105,38 @@ static void collect_pack_filenames(struct string_list *fname_nonkept_list,
struct string_list *fname_kept_list,
const struct string_list *extra_keep)
{
- DIR *dir;
- struct dirent *e;
- char *fname;
+ struct packed_git *p;
struct strbuf buf = STRBUF_INIT;
- if (!(dir = opendir(packdir)))
- return;
-
- while ((e = readdir(dir)) != NULL) {
- size_t len;
+ for (p = get_all_packs(the_repository); p; p = p->next) {
int i;
+ const char *base;
- if (!strip_suffix(e->d_name, ".idx", &len))
+ if (!p->pack_local)
continue;
- strbuf_reset(&buf);
- strbuf_add(&buf, e->d_name, len);
- strbuf_addstr(&buf, ".pack");
+ base = pack_basename(p);
for (i = 0; i < extra_keep->nr; i++)
- if (!fspathcmp(buf.buf, extra_keep->items[i].string))
+ if (!fspathcmp(base, extra_keep->items[i].string))
break;
- fname = xmemdupz(e->d_name, len);
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, base);
+ strbuf_strip_suffix(&buf, ".pack");
- if ((extra_keep->nr > 0 && i < extra_keep->nr) ||
- (file_exists(mkpath("%s/%s.keep", packdir, fname)))) {
- string_list_append_nodup(fname_kept_list, fname);
- } else {
+ if ((extra_keep->nr > 0 && i < extra_keep->nr) || p->pack_keep)
+ string_list_append(fname_kept_list, buf.buf);
+ else {
struct string_list_item *item;
- item = string_list_append_nodup(fname_nonkept_list,
- fname);
- if (file_exists(mkpath("%s/%s.mtimes", packdir, fname)))
+ item = string_list_append(fname_nonkept_list, buf.buf);
+ if (p->is_cruft)
item->util = (void*)(uintptr_t)CRUFT_PACK;
}
}
- closedir(dir);
- strbuf_release(&buf);
string_list_sort(fname_kept_list);
+ strbuf_release(&buf);
}
static void remove_redundant_pack(const char *dir_name, const char *base_name)
@@ -310,6 +303,8 @@ struct pack_geometry {
struct packed_git **pack;
uint32_t pack_nr, pack_alloc;
uint32_t split;
+
+ int split_factor;
};
static uint32_t geometry_pack_weight(struct packed_git *p)
@@ -331,17 +326,13 @@ static int geometry_cmp(const void *va, const void *vb)
return 0;
}
-static void init_pack_geometry(struct pack_geometry **geometry_p,
+static void init_pack_geometry(struct pack_geometry *geometry,
struct string_list *existing_kept_packs,
const struct pack_objects_args *args)
{
struct packed_git *p;
- struct pack_geometry *geometry;
struct strbuf buf = STRBUF_INIT;
- *geometry_p = xcalloc(1, sizeof(struct pack_geometry));
- geometry = *geometry_p;
-
for (p = get_all_packs(the_repository); p; p = p->next) {
if (args->local && !p->pack_local)
/*
@@ -387,7 +378,7 @@ static void init_pack_geometry(struct pack_geometry **geometry_p,
strbuf_release(&buf);
}
-static void split_pack_geometry(struct pack_geometry *geometry, int factor)
+static void split_pack_geometry(struct pack_geometry *geometry)
{
uint32_t i;
uint32_t split;
@@ -406,12 +397,14 @@ static void split_pack_geometry(struct pack_geometry *geometry, int factor)
struct packed_git *ours = geometry->pack[i];
struct packed_git *prev = geometry->pack[i - 1];
- if (unsigned_mult_overflows(factor, geometry_pack_weight(prev)))
+ if (unsigned_mult_overflows(geometry->split_factor,
+ geometry_pack_weight(prev)))
die(_("pack %s too large to consider in geometric "
"progression"),
prev->pack_name);
- if (geometry_pack_weight(ours) < factor * geometry_pack_weight(prev))
+ if (geometry_pack_weight(ours) <
+ geometry->split_factor * geometry_pack_weight(prev))
break;
}
@@ -446,10 +439,12 @@ static void split_pack_geometry(struct pack_geometry *geometry, int factor)
for (i = split; i < geometry->pack_nr; i++) {
struct packed_git *ours = geometry->pack[i];
- if (unsigned_mult_overflows(factor, total_size))
+ if (unsigned_mult_overflows(geometry->split_factor,
+ total_size))
die(_("pack %s too large to roll up"), ours->pack_name);
- if (geometry_pack_weight(ours) < factor * total_size) {
+ if (geometry_pack_weight(ours) <
+ geometry->split_factor * total_size) {
if (unsigned_add_overflows(total_size,
geometry_pack_weight(ours)))
die(_("pack %s too large to roll up"),
@@ -499,15 +494,12 @@ static struct packed_git *get_preferred_pack(struct pack_geometry *geometry)
return NULL;
}
-static void clear_pack_geometry(struct pack_geometry *geometry)
+static void free_pack_geometry(struct pack_geometry *geometry)
{
if (!geometry)
return;
free(geometry->pack);
- geometry->pack_nr = 0;
- geometry->pack_alloc = 0;
- geometry->split = 0;
}
struct midx_snapshot_ref_data {
@@ -584,7 +576,7 @@ static void midx_included_packs(struct string_list *include,
string_list_insert(include, xstrfmt("%s.idx", item->string));
for_each_string_list_item(item, names)
string_list_insert(include, xstrfmt("pack-%s.idx", item->string));
- if (geometry) {
+ if (geometry->split_factor) {
struct strbuf buf = STRBUF_INIT;
uint32_t i;
for (i = geometry->split; i < geometry->pack_nr; i++) {
@@ -728,7 +720,6 @@ static int write_cruft_pack(const struct pack_objects_args *args,
strvec_push(&cmd.args, "--honor-pack-keep");
strvec_push(&cmd.args, "--non-empty");
- strvec_push(&cmd.args, "--max-pack-size=0");
cmd.in = -1;
@@ -788,7 +779,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
struct string_list names = STRING_LIST_INIT_DUP;
struct string_list existing_nonkept_packs = STRING_LIST_INIT_DUP;
struct string_list existing_kept_packs = STRING_LIST_INIT_DUP;
- struct pack_geometry *geometry = NULL;
+ struct pack_geometry geometry = { 0 };
struct strbuf line = STRBUF_INIT;
struct tempfile *refs_snapshot = NULL;
int i, ext, ret;
@@ -802,7 +793,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
struct pack_objects_args po_args = {NULL};
struct pack_objects_args cruft_po_args = {NULL};
- int geometric_factor = 0;
int write_midx = 0;
const char *cruft_expiration = NULL;
const char *expire_to = NULL;
@@ -851,7 +841,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
N_("repack objects in packs marked with .keep")),
OPT_STRING_LIST(0, "keep-pack", &keep_pack_list, N_("name"),
N_("do not repack this pack")),
- OPT_INTEGER('g', "geometric", &geometric_factor,
+ OPT_INTEGER('g', "geometric", &geometry.split_factor,
N_("find a geometric progression with factor <N>")),
OPT_BOOL('m', "write-midx", &write_midx,
N_("write a multi-pack index of the resulting packs")),
@@ -927,11 +917,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
collect_pack_filenames(&existing_nonkept_packs, &existing_kept_packs,
&keep_pack_list);
- if (geometric_factor) {
+ if (geometry.split_factor) {
if (pack_everything)
die(_("options '%s' and '%s' cannot be used together"), "--geometric", "-A/-a");
init_pack_geometry(&geometry, &existing_kept_packs, &po_args);
- split_pack_geometry(geometry, geometric_factor);
+ split_pack_geometry(&geometry);
}
prepare_pack_objects(&cmd, &po_args, packtmp);
@@ -945,7 +935,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
strvec_pushf(&cmd.args, "--keep-pack=%s",
keep_pack_list.items[i].string);
strvec_push(&cmd.args, "--non-empty");
- if (!geometry) {
+ if (!geometry.split_factor) {
/*
* We need to grab all reachable objects, including those that
* are reachable from reflogs and the index.
@@ -992,7 +982,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
strvec_push(&cmd.args, "--pack-loose-unreachable");
}
}
- } else if (geometry) {
+ } else if (geometry.split_factor) {
strvec_push(&cmd.args, "--stdin-packs");
strvec_push(&cmd.args, "--unpacked");
} else {
@@ -1000,7 +990,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
strvec_push(&cmd.args, "--incremental");
}
- if (geometry)
+ if (geometry.split_factor)
cmd.in = -1;
else
cmd.no_stdin = 1;
@@ -1009,17 +999,17 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (ret)
goto cleanup;
- if (geometry) {
+ if (geometry.split_factor) {
FILE *in = xfdopen(cmd.in, "w");
/*
* The resulting pack should contain all objects in packs that
* are going to be rolled up, but exclude objects in packs which
* are being left alone.
*/
- for (i = 0; i < geometry->split; i++)
- fprintf(in, "%s\n", pack_basename(geometry->pack[i]));
- for (i = geometry->split; i < geometry->pack_nr; i++)
- fprintf(in, "^%s\n", pack_basename(geometry->pack[i]));
+ for (i = 0; i < geometry.split; i++)
+ fprintf(in, "%s\n", pack_basename(geometry.pack[i]));
+ for (i = geometry.split; i < geometry.pack_nr; i++)
+ fprintf(in, "^%s\n", pack_basename(geometry.pack[i]));
fclose(in);
}
@@ -1057,6 +1047,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
cruft_po_args.depth = po_args.depth;
if (!cruft_po_args.threads)
cruft_po_args.threads = po_args.threads;
+ if (!cruft_po_args.max_pack_size)
+ cruft_po_args.max_pack_size = po_args.max_pack_size;
cruft_po_args.local = po_args.local;
cruft_po_args.quiet = po_args.quiet;
@@ -1162,9 +1154,9 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (write_midx) {
struct string_list include = STRING_LIST_INIT_NODUP;
midx_included_packs(&include, &existing_nonkept_packs,
- &existing_kept_packs, &names, geometry);
+ &existing_kept_packs, &names, &geometry);
- ret = write_midx_included_packs(&include, geometry,
+ ret = write_midx_included_packs(&include, &geometry,
refs_snapshot ? get_tempfile_path(refs_snapshot) : NULL,
show_progress, write_bitmaps > 0);
@@ -1187,12 +1179,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
remove_redundant_pack(packdir, item->string);
}
- if (geometry) {
+ if (geometry.split_factor) {
struct strbuf buf = STRBUF_INIT;
uint32_t i;
- for (i = 0; i < geometry->split; i++) {
- struct packed_git *p = geometry->pack[i];
+ for (i = 0; i < geometry.split; i++) {
+ struct packed_git *p = geometry.pack[i];
if (string_list_has_string(&names,
hash_to_hex(p->hash)))
continue;
@@ -1235,7 +1227,7 @@ cleanup:
string_list_clear(&names, 1);
string_list_clear(&existing_nonkept_packs, 0);
string_list_clear(&existing_kept_packs, 0);
- clear_pack_geometry(geometry);
+ free_pack_geometry(&geometry);
return ret;
}