summaryrefslogtreecommitdiff
path: root/builtin/pack-objects.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/pack-objects.c')
-rw-r--r--builtin/pack-objects.c321
1 files changed, 240 insertions, 81 deletions
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index d2a162d528..676a586709 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1,15 +1,13 @@
+#define USE_THE_REPOSITORY_VARIABLE
#include "builtin.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
-#include "repository.h"
#include "config.h"
#include "attr.h"
#include "object.h"
-#include "blob.h"
#include "commit.h"
#include "tag.h"
-#include "tree.h"
#include "delta.h"
#include "pack.h"
#include "pack-revindex.h"
@@ -18,7 +16,6 @@
#include "diff.h"
#include "revision.h"
#include "list-objects.h"
-#include "list-objects-filter.h"
#include "list-objects-filter-options.h"
#include "pack-objects.h"
#include "progress.h"
@@ -221,13 +218,19 @@ static int thin;
static int num_preferred_base;
static struct progress *progress_state;
-static struct packed_git *reuse_packfile;
+static struct bitmapped_pack *reuse_packfiles;
+static size_t reuse_packfiles_nr;
+static size_t reuse_packfiles_used_nr;
static uint32_t reuse_packfile_objects;
static struct bitmap *reuse_packfile_bitmap;
static int use_bitmap_index_default = 1;
static int use_bitmap_index = -1;
-static int allow_pack_reuse = 1;
+static enum {
+ NO_PACK_REUSE = 0,
+ SINGLE_PACK_REUSE,
+ MULTI_PACK_REUSE,
+} allow_pack_reuse = SINGLE_PACK_REUSE;
static enum {
WRITE_BITMAP_FALSE = 0,
WRITE_BITMAP_QUIET,
@@ -236,6 +239,7 @@ static enum {
static uint16_t write_bitmap_options = BITMAP_OPT_HASH_CACHE;
static int exclude_promisor_objects;
+static int exclude_promisor_objects_best_effort;
static int use_delta_islands;
@@ -768,7 +772,7 @@ static enum write_one_status write_one(struct hashfile *f,
return WRITE_ONE_WRITTEN;
}
-static int mark_tagged(const char *path UNUSED, const struct object_id *oid,
+static int mark_tagged(const char *path UNUSED, const char *referent UNUSED, const struct object_id *oid,
int flag UNUSED, void *cb_data UNUSED)
{
struct object_id peeled;
@@ -776,7 +780,7 @@ static int mark_tagged(const char *path UNUSED, const struct object_id *oid,
if (entry)
entry->tagged = 1;
- if (!peel_iterated_oid(oid, &peeled)) {
+ if (!peel_iterated_oid(the_repository, oid, &peeled)) {
entry = packlist_find(&to_pack, &peeled);
if (entry)
entry->tagged = 1;
@@ -936,7 +940,8 @@ static struct object_entry **compute_write_order(void)
/*
* Mark objects that are at the tip of tags.
*/
- for_each_tag_ref(mark_tagged, NULL);
+ refs_for_each_tag_ref(get_main_ref_store(the_repository), mark_tagged,
+ NULL);
if (use_delta_islands) {
max_layers = compute_pack_layers(&to_pack);
@@ -1013,7 +1018,9 @@ static off_t find_reused_offset(off_t where)
return reused_chunks[lo-1].difference;
}
-static void write_reused_pack_one(size_t pos, struct hashfile *out,
+static void write_reused_pack_one(struct packed_git *reuse_packfile,
+ size_t pos, struct hashfile *out,
+ off_t pack_start,
struct pack_window **w_curs)
{
off_t offset, next, cur;
@@ -1023,7 +1030,8 @@ static void write_reused_pack_one(size_t pos, struct hashfile *out,
offset = pack_pos_to_offset(reuse_packfile, pos);
next = pack_pos_to_offset(reuse_packfile, pos + 1);
- record_reused_object(offset, offset - hashfile_total(out));
+ record_reused_object(offset,
+ offset - (hashfile_total(out) - pack_start));
cur = offset;
type = unpack_object_header(reuse_packfile, w_curs, &cur, &size);
@@ -1065,7 +1073,7 @@ static void write_reused_pack_one(size_t pos, struct hashfile *out,
fixup = find_reused_offset(offset) -
find_reused_offset(base_offset);
if (fixup) {
- unsigned char ofs_header[10];
+ unsigned char ofs_header[MAX_PACK_OBJECT_HEADER];
unsigned i, ofs_len;
off_t ofs = offset - base_offset - fixup;
@@ -1091,26 +1099,61 @@ static void write_reused_pack_one(size_t pos, struct hashfile *out,
copy_pack_data(out, reuse_packfile, w_curs, offset, next - offset);
}
-static size_t write_reused_pack_verbatim(struct hashfile *out,
+static size_t write_reused_pack_verbatim(struct bitmapped_pack *reuse_packfile,
+ struct hashfile *out,
struct pack_window **w_curs)
{
size_t pos = 0;
+ size_t end;
+
+ if (reuse_packfile->bitmap_pos) {
+ /*
+ * We can't reuse whole chunks verbatim out of
+ * non-preferred packs since we can't guarantee that
+ * all duplicate objects were resolved in favor of
+ * that pack.
+ *
+ * Even if we have a whole eword_t worth of bits that
+ * could be reused, there may be objects between the
+ * objects corresponding to the first and last bit of
+ * that word which were selected from a different
+ * pack, causing us to send duplicate or unwanted
+ * objects.
+ *
+ * Handle non-preferred packs from within
+ * write_reused_pack(), which inspects and reuses
+ * individual bits.
+ */
+ return reuse_packfile->bitmap_pos / BITS_IN_EWORD;
+ }
+
+ /*
+ * Only read through the last word whose bits all correspond
+ * to objects in the given packfile, since we must stop at a
+ * word boundary.
+ *
+ * If there is no whole word to read (i.e. the packfile
+ * contains fewer than BITS_IN_EWORD objects), then we'll
+ * inspect bits one-by-one in write_reused_pack().
+ */
+ end = reuse_packfile->bitmap_nr / BITS_IN_EWORD;
+ if (reuse_packfile_bitmap->word_alloc < end)
+ BUG("fewer words than expected in reuse_packfile_bitmap");
- while (pos < reuse_packfile_bitmap->word_alloc &&
- reuse_packfile_bitmap->words[pos] == (eword_t)~0)
+ while (pos < end && reuse_packfile_bitmap->words[pos] == (eword_t)~0)
pos++;
if (pos) {
off_t to_write;
written = (pos * BITS_IN_EWORD);
- to_write = pack_pos_to_offset(reuse_packfile, written)
+ to_write = pack_pos_to_offset(reuse_packfile->p, written)
- sizeof(struct pack_header);
/* We're recording one chunk, not one object. */
record_reused_object(sizeof(struct pack_header), 0);
hashflush(out);
- copy_pack_data(out, reuse_packfile, w_curs,
+ copy_pack_data(out, reuse_packfile->p, w_curs,
sizeof(struct pack_header), to_write);
display_progress(progress_state, written);
@@ -1118,34 +1161,71 @@ static size_t write_reused_pack_verbatim(struct hashfile *out,
return pos;
}
-static void write_reused_pack(struct hashfile *f)
+static void write_reused_pack(struct bitmapped_pack *reuse_packfile,
+ struct hashfile *f)
{
- size_t i = 0;
+ size_t i = reuse_packfile->bitmap_pos / BITS_IN_EWORD;
uint32_t offset;
+ off_t pack_start = hashfile_total(f) - sizeof(struct pack_header);
struct pack_window *w_curs = NULL;
if (allow_ofs_delta)
- i = write_reused_pack_verbatim(f, &w_curs);
+ i = write_reused_pack_verbatim(reuse_packfile, f, &w_curs);
for (; i < reuse_packfile_bitmap->word_alloc; ++i) {
eword_t word = reuse_packfile_bitmap->words[i];
size_t pos = (i * BITS_IN_EWORD);
for (offset = 0; offset < BITS_IN_EWORD; ++offset) {
+ uint32_t pack_pos;
if ((word >> offset) == 0)
break;
offset += ewah_bit_ctz64(word >> offset);
- /*
- * Can use bit positions directly, even for MIDX
- * bitmaps. See comment in try_partial_reuse()
- * for why.
- */
- write_reused_pack_one(pos + offset, f, &w_curs);
+ if (pos + offset < reuse_packfile->bitmap_pos)
+ continue;
+ if (pos + offset >= reuse_packfile->bitmap_pos + reuse_packfile->bitmap_nr)
+ goto done;
+
+ if (reuse_packfile->bitmap_pos) {
+ /*
+ * When doing multi-pack reuse on a
+ * non-preferred pack, translate bit positions
+ * from the MIDX pseudo-pack order back to their
+ * pack-relative positions before attempting
+ * reuse.
+ */
+ struct multi_pack_index *m = reuse_packfile->from_midx;
+ uint32_t midx_pos;
+ off_t pack_ofs;
+
+ if (!m)
+ BUG("non-zero bitmap position without MIDX");
+
+ midx_pos = pack_pos_to_midx(m, pos + offset);
+ pack_ofs = nth_midxed_offset(m, midx_pos);
+
+ if (offset_to_pack_pos(reuse_packfile->p,
+ pack_ofs, &pack_pos) < 0)
+ BUG("could not find expected object at offset %"PRIuMAX" in pack %s",
+ (uintmax_t)pack_ofs,
+ pack_basename(reuse_packfile->p));
+ } else {
+ /*
+ * Can use bit positions directly, even for MIDX
+ * bitmaps. See comment in try_partial_reuse()
+ * for why.
+ */
+ pack_pos = pos + offset;
+ }
+
+ write_reused_pack_one(reuse_packfile->p, pack_pos, f,
+ pack_start, &w_curs);
display_progress(progress_state, ++written);
}
}
+done:
unuse_pack(&w_curs);
}
@@ -1197,9 +1277,14 @@ static void write_pack_file(void)
offset = write_pack_header(f, nr_remaining);
- if (reuse_packfile) {
+ if (reuse_packfiles_nr) {
assert(pack_to_stdout);
- write_reused_pack(f);
+ for (j = 0; j < reuse_packfiles_nr; j++) {
+ reused_chunks_nr = 0;
+ write_reused_pack(&reuse_packfiles[j], f);
+ if (reused_chunks_nr)
+ reuse_packfiles_used_nr++;
+ }
offset = hashfile_total(f);
}
@@ -1244,6 +1329,7 @@ static void write_pack_file(void)
if (!pack_to_stdout) {
struct stat st;
struct strbuf tmpname = STRBUF_INIT;
+ struct bitmap_writer bitmap_writer;
char *idx_tmp_name = NULL;
/*
@@ -1269,9 +1355,11 @@ static void write_pack_file(void)
hash_to_hex(hash));
if (write_bitmap_index) {
- bitmap_writer_set_checksum(hash);
- bitmap_writer_build_type_index(
- &to_pack, written_list, nr_written);
+ bitmap_writer_init(&bitmap_writer,
+ the_repository, &to_pack);
+ bitmap_writer_set_checksum(&bitmap_writer, hash);
+ bitmap_writer_build_type_index(&bitmap_writer,
+ written_list);
}
if (cruft)
@@ -1288,12 +1376,17 @@ static void write_pack_file(void)
strbuf_addstr(&tmpname, "bitmap");
stop_progress(&progress_state);
- bitmap_writer_show_progress(progress);
- bitmap_writer_select_commits(indexed_commits, indexed_commits_nr, -1);
- if (bitmap_writer_build(&to_pack) < 0)
+ bitmap_writer_show_progress(&bitmap_writer,
+ progress);
+ bitmap_writer_select_commits(&bitmap_writer,
+ indexed_commits,
+ indexed_commits_nr);
+ if (bitmap_writer_build(&bitmap_writer) < 0)
die(_("failed to write bitmap index"));
- bitmap_writer_finish(written_list, nr_written,
+ bitmap_writer_finish(&bitmap_writer,
+ written_list,
tmpname.buf, write_bitmap_options);
+ bitmap_writer_free(&bitmap_writer);
write_bitmap_index = 0;
strbuf_setlen(&tmpname, tmpname_len);
}
@@ -1449,7 +1542,7 @@ static int want_object_in_pack_one(struct packed_git *p,
if (p == *found_pack)
offset = *found_offset;
else
- offset = find_pack_entry_one(oid->hash, p);
+ offset = find_pack_entry_one(oid, p);
if (offset) {
if (!*found_pack) {
@@ -1756,7 +1849,8 @@ static void add_pbase_object(struct tree_desc *tree,
tree = pbase_tree_get(&entry.oid);
if (!tree)
return;
- init_tree_desc(&sub, tree->tree_data, tree->tree_size);
+ init_tree_desc(&sub, &tree->oid,
+ tree->tree_data, tree->tree_size);
add_pbase_object(&sub, down, downlen, fullname);
pbase_tree_put(tree);
@@ -1816,7 +1910,8 @@ static void add_preferred_base_object(const char *name)
}
else {
struct tree_desc tree;
- init_tree_desc(&tree, it->pcache.tree_data, it->pcache.tree_size);
+ init_tree_desc(&tree, &it->pcache.oid,
+ it->pcache.tree_data, it->pcache.tree_size);
add_pbase_object(&tree, name, cmplen, name);
}
}
@@ -1998,7 +2093,8 @@ static void check_object(struct object_entry *entry, uint32_t object_index)
oidread(&base_ref,
use_pack(p, &w_curs,
entry->in_pack_offset + used,
- NULL));
+ NULL),
+ the_repository->hash_algo);
have_base = 1;
}
entry->in_pack_header_size = used + the_hash_algo->rawsz;
@@ -3047,12 +3143,12 @@ static void add_tag_chain(const struct object_id *oid)
}
}
-static int add_ref_tag(const char *tag UNUSED, const struct object_id *oid,
+static int add_ref_tag(const char *tag UNUSED, const char *referent UNUSED, const struct object_id *oid,
int flag UNUSED, void *cb_data UNUSED)
{
struct object_id peeled;
- if (!peel_iterated_oid(oid, &peeled) && obj_is_packed(&peeled))
+ if (!peel_iterated_oid(the_repository, oid, &peeled) && obj_is_packed(&peeled))
add_tag_chain(oid);
return 0;
}
@@ -3175,7 +3271,19 @@ static int git_pack_config(const char *k, const char *v,
return 0;
}
if (!strcmp(k, "pack.allowpackreuse")) {
- allow_pack_reuse = git_config_bool(k, v);
+ int res = git_parse_maybe_bool_text(v);
+ if (res < 0) {
+ if (!strcasecmp(v, "single"))
+ allow_pack_reuse = SINGLE_PACK_REUSE;
+ else if (!strcasecmp(v, "multi"))
+ allow_pack_reuse = MULTI_PACK_REUSE;
+ else
+ die(_("invalid pack.allowPackReuse value: '%s'"), v);
+ } else if (res) {
+ allow_pack_reuse = SINGLE_PACK_REUSE;
+ } else {
+ allow_pack_reuse = NO_PACK_REUSE;
+ }
return 0;
}
if (!strcmp(k, "pack.threads")) {
@@ -3204,7 +3312,7 @@ static int git_pack_config(const char *k, const char *v,
return 0;
}
if (!strcmp(k, "uploadpack.blobpackfileuri")) {
- struct configured_exclusion *ex = xmalloc(sizeof(*ex));
+ struct configured_exclusion *ex;
const char *oid_end, *pack_end;
/*
* Stores the pack hash. This is not a true object ID, but is
@@ -3212,6 +3320,10 @@ static int git_pack_config(const char *k, const char *v,
*/
struct object_id pack_hash;
+ if (!v)
+ return config_error_nonbool(k);
+
+ ex = xmalloc(sizeof(*ex));
if (parse_oid_hex(v, &ex->e.oid, &oid_end) ||
*oid_end != ' ' ||
parse_oid_hex(oid_end + 1, &pack_hash, &pack_end) ||
@@ -3603,7 +3715,6 @@ static void read_cruft_objects(void)
string_list_append(&discard_packs, buf.buf + 1);
else
string_list_append(&fresh_packs, buf.buf);
- strbuf_reset(&buf);
}
string_list_sort(&discard_packs);
@@ -3739,7 +3850,7 @@ static void show_object__ma_allow_promisor(struct object *obj, const char *name,
show_object(obj, name, data);
}
-static int option_parse_missing_action(const struct option *opt,
+static int option_parse_missing_action(const struct option *opt UNUSED,
const char *arg, int unset)
{
assert(arg);
@@ -3843,7 +3954,7 @@ static int add_loose_object(const struct object_id *oid, const char *path,
*/
static void add_unreachable_loose_objects(void)
{
- for_each_loose_file_in_objdir(get_object_directory(),
+ for_each_loose_file_in_objdir(repo_get_object_directory(the_repository),
add_loose_object,
NULL, NULL, NULL);
}
@@ -3859,7 +3970,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
while (p) {
if ((!p->pack_local || p->pack_keep ||
p->pack_keep_in_core) &&
- find_pack_entry_one(oid->hash, p)) {
+ find_pack_entry_one(oid, p)) {
last_found = p;
return 1;
}
@@ -3931,7 +4042,7 @@ static void loosen_unused_packed_objects(void)
*/
static int pack_options_allow_reuse(void)
{
- return allow_pack_reuse &&
+ return allow_pack_reuse != NO_PACK_REUSE &&
pack_to_stdout &&
!ignore_packed_keep_on_disk &&
!ignore_packed_keep_in_core &&
@@ -3944,13 +4055,18 @@ static int get_object_list_from_bitmap(struct rev_info *revs)
if (!(bitmap_git = prepare_bitmap_walk(revs, 0)))
return -1;
- if (pack_options_allow_reuse() &&
- !reuse_partial_packfile_from_bitmap(
- bitmap_git,
- &reuse_packfile,
- &reuse_packfile_objects,
- &reuse_packfile_bitmap)) {
- assert(reuse_packfile_objects);
+ if (pack_options_allow_reuse())
+ reuse_partial_packfile_from_bitmap(bitmap_git,
+ &reuse_packfiles,
+ &reuse_packfiles_nr,
+ &reuse_packfile_bitmap,
+ allow_pack_reuse == MULTI_PACK_REUSE);
+
+ if (reuse_packfiles) {
+ reuse_packfile_objects = bitmap_popcount(reuse_packfile_bitmap);
+ if (!reuse_packfile_objects)
+ BUG("expected non-empty reuse bitmap");
+
nr_result += reuse_packfile_objects;
nr_seen += reuse_packfile_objects;
display_progress(progress_state, nr_seen);
@@ -3974,6 +4090,7 @@ static void record_recent_commit(struct commit *commit, void *data UNUSED)
}
static int mark_bitmap_preferred_tip(const char *refname,
+ const char *referent UNUSED,
const struct object_id *oid,
int flags UNUSED,
void *data UNUSED)
@@ -3981,7 +4098,7 @@ static int mark_bitmap_preferred_tip(const char *refname,
struct object_id peeled;
struct object *object;
- if (!peel_iterated_oid(oid, &peeled))
+ if (!peel_iterated_oid(the_repository, oid, &peeled))
oid = &peeled;
object = parse_object_or_die(oid, refname);
@@ -4001,7 +4118,9 @@ static void mark_bitmap_preferred_tips(void)
return;
for_each_string_list_item(item, preferred_tips) {
- for_each_ref_in(item->string, mark_bitmap_preferred_tip, NULL);
+ refs_for_each_ref_in(get_main_ref_store(the_repository),
+ item->string, mark_bitmap_preferred_tip,
+ NULL);
}
}
@@ -4120,34 +4239,37 @@ static void add_extra_kept_packs(const struct string_list *names)
static int option_parse_quiet(const struct option *opt, const char *arg,
int unset)
{
+ int *val = opt->value;
+
BUG_ON_OPT_ARG(arg);
if (!unset)
- progress = 0;
- else if (!progress)
- progress = 1;
+ *val = 0;
+ else if (!*val)
+ *val = 1;
return 0;
}
static int option_parse_index_version(const struct option *opt,
const char *arg, int unset)
{
+ struct pack_idx_option *popts = opt->value;
char *c;
const char *val = arg;
BUG_ON_OPT_NEG(unset);
- pack_idx_opts.version = strtoul(val, &c, 10);
- if (pack_idx_opts.version > 2)
+ popts->version = strtoul(val, &c, 10);
+ if (popts->version > 2)
die(_("unsupported index version %s"), val);
if (*c == ',' && c[1])
- pack_idx_opts.off32_limit = strtoul(c+1, &c, 0);
- if (*c || pack_idx_opts.off32_limit & 0x80000000)
+ popts->off32_limit = strtoul(c+1, &c, 0);
+ if (*c || popts->off32_limit & 0x80000000)
die(_("bad index version '%s'"), val);
return 0;
}
-static int option_parse_unpack_unreachable(const struct option *opt,
+static int option_parse_unpack_unreachable(const struct option *opt UNUSED,
const char *arg, int unset)
{
if (unset) {
@@ -4162,7 +4284,7 @@ static int option_parse_unpack_unreachable(const struct option *opt,
return 0;
}
-static int option_parse_cruft_expiration(const struct option *opt,
+static int option_parse_cruft_expiration(const struct option *opt UNUSED,
const char *arg, int unset)
{
if (unset) {
@@ -4176,7 +4298,22 @@ static int option_parse_cruft_expiration(const struct option *opt,
return 0;
}
-int cmd_pack_objects(int argc, const char **argv, const char *prefix)
+static int is_not_in_promisor_pack_obj(struct object *obj, void *data UNUSED)
+{
+ struct object_info info = OBJECT_INFO_INIT;
+ if (oid_object_info_extended(the_repository, &obj->oid, &info, 0))
+ BUG("should_include_obj should only be called on existing objects");
+ return info.whence != OI_PACKED || !info.u.packed.pack->pack_promisor;
+}
+
+static int is_not_in_promisor_pack(struct commit *commit, void *data) {
+ return is_not_in_promisor_pack_obj((struct object *) commit, data);
+}
+
+int cmd_pack_objects(int argc,
+ const char **argv,
+ const char *prefix,
+ struct repository *repo UNUSED)
{
int use_internal_rev_list = 0;
int shallow = 0;
@@ -4190,7 +4327,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
LIST_OBJECTS_FILTER_INIT;
struct option pack_objects_options[] = {
- OPT_CALLBACK_F('q', "quiet", NULL, NULL,
+ OPT_CALLBACK_F('q', "quiet", &progress, NULL,
N_("do not show progress meter"),
PARSE_OPT_NOARG, option_parse_quiet),
OPT_SET_INT(0, "progress", &progress,
@@ -4200,7 +4337,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
OPT_BOOL(0, "all-progress-implied",
&all_progress_implied,
N_("similar to --all-progress when progress meter is shown")),
- OPT_CALLBACK_F(0, "index-version", NULL, N_("<version>[,<offset>]"),
+ OPT_CALLBACK_F(0, "index-version", &pack_idx_opts, N_("<version>[,<offset>]"),
N_("write the pack index file in the specified idx format version"),
PARSE_OPT_NONEG, option_parse_index_version),
OPT_MAGNITUDE(0, "max-pack-size", &pack_size_limit,
@@ -4285,6 +4422,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
option_parse_missing_action),
OPT_BOOL(0, "exclude-promisor-objects", &exclude_promisor_objects,
N_("do not pack objects in promisor packfiles")),
+ OPT_BOOL(0, "exclude-promisor-objects-best-effort",
+ &exclude_promisor_objects_best_effort,
+ N_("implies --missing=allow-any")),
OPT_BOOL(0, "delta-islands", &use_delta_islands,
N_("respect islands during delta compression")),
OPT_STRING_LIST(0, "uri-protocol", &uri_protocols,
@@ -4303,6 +4443,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
prepare_repo_settings(the_repository);
if (sparse < 0)
sparse = the_repository->settings.pack_use_sparse;
+ if (the_repository->settings.pack_use_multi_pack_reuse)
+ allow_pack_reuse = MULTI_PACK_REUSE;
}
reset_pack_idx_option(&pack_idx_opts);
@@ -4363,10 +4505,18 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
strvec_push(&rp, "--unpacked");
}
+ if (exclude_promisor_objects && exclude_promisor_objects_best_effort)
+ die(_("options '%s' and '%s' cannot be used together"),
+ "--exclude-promisor-objects", "--exclude-promisor-objects-best-effort");
if (exclude_promisor_objects) {
use_internal_rev_list = 1;
fetch_if_missing = 0;
strvec_push(&rp, "--exclude-promisor-objects");
+ } else if (exclude_promisor_objects_best_effort) {
+ use_internal_rev_list = 1;
+ fetch_if_missing = 0;
+ option_parse_missing_action(NULL, "allow-any", 0);
+ /* revs configured below */
}
if (unpack_unreachable || keep_unreachable || pack_loose_unreachable)
use_internal_rev_list = 1;
@@ -4383,7 +4533,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
if (!HAVE_THREADS && delta_search_threads != 1)
warning(_("no threads support, ignoring --threads"));
- if (!pack_to_stdout && !pack_size_limit && !cruft)
+ if (!pack_to_stdout && !pack_size_limit)
pack_size_limit = pack_size_limit_cfg;
if (pack_to_stdout && pack_size_limit)
die(_("--max-pack-size cannot be used to build a pack for transfer"));
@@ -4400,12 +4550,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
if (!rev_list_all || !rev_list_reflog || !rev_list_index)
unpack_unreachable_expiration = 0;
- if (filter_options.choice) {
- if (!pack_to_stdout)
- die(_("cannot use --filter without --stdout"));
- if (stdin_packs)
- die(_("cannot use --filter with --stdin-packs"));
- }
+ if (stdin_packs && filter_options.choice)
+ die(_("cannot use --filter with --stdin-packs"));
if (stdin_packs && use_internal_rev_list)
die(_("cannot use internal rev list with --stdin-packs"));
@@ -4415,8 +4561,6 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
die(_("cannot use internal rev list with --cruft"));
if (stdin_packs)
die(_("cannot use --stdin-packs with --cruft"));
- if (pack_size_limit)
- die(_("cannot use --max-pack-size with --cruft"));
}
/*
@@ -4492,12 +4636,17 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
repo_init_revisions(the_repository, &revs, NULL);
list_objects_filter_copy(&revs.filter, &filter_options);
+ if (exclude_promisor_objects_best_effort) {
+ revs.include_check = is_not_in_promisor_pack;
+ revs.include_check_obj = is_not_in_promisor_pack_obj;
+ }
get_object_list(&revs, rp.nr, rp.v);
release_revisions(&revs);
}
cleanup_preferred_base();
if (include_tag && nr_result)
- for_each_tag_ref(add_ref_tag, NULL);
+ refs_for_each_tag_ref(get_main_ref_store(the_repository),
+ add_ref_tag, NULL);
stop_progress(&progress_state);
trace2_region_leave("pack-objects", "enumerate-objects",
the_repository);
@@ -4521,12 +4670,22 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
fprintf_ln(stderr,
_("Total %"PRIu32" (delta %"PRIu32"),"
" reused %"PRIu32" (delta %"PRIu32"),"
- " pack-reused %"PRIu32),
+ " pack-reused %"PRIu32" (from %"PRIuMAX")"),
written, written_delta, reused, reused_delta,
- reuse_packfile_objects);
+ reuse_packfile_objects,
+ (uintmax_t)reuse_packfiles_used_nr);
+
+ trace2_data_intmax("pack-objects", the_repository, "written", written);
+ trace2_data_intmax("pack-objects", the_repository, "written/delta", written_delta);
+ trace2_data_intmax("pack-objects", the_repository, "reused", reused);
+ trace2_data_intmax("pack-objects", the_repository, "reused/delta", reused_delta);
+ trace2_data_intmax("pack-objects", the_repository, "pack-reused", reuse_packfile_objects);
+ trace2_data_intmax("pack-objects", the_repository, "packs-reused", reuse_packfiles_used_nr);
cleanup:
+ clear_packing_data(&to_pack);
list_objects_filter_release(&filter_options);
+ string_list_clear(&keep_pack_list, 0);
strvec_clear(&rp);
return 0;