On Fri, Jun 25, 2021 at 01:45:46AM +0200, Ævar Arnfjörð Bjarmason wrote: > > On Mon, Jun 21 2021, Taylor Blau wrote: > > +* Write a MIDX file for the packfiles in the current .git folder with a > > +corresponding bitmap. > > ++ > > +------------------------------------------------------------- > > +$ git multi-pack-index write --preferred-pack <pack> --bitmap > > +------------------------------------------------------------- > > + > > I wondered if this was a <pack> positional argument, but it's just the > argument for --preferred-pack, even though the synopsis uses the "=" > style for it. Even if parse-options.c is loose about it, let's use one > or the other in examples consistently. The example below (for writing a MIDX in an alternate object store) doesn't include the '=', but probably would be clearer if it did. I think it's a good suggestion, though, so I'll fix up my addition here. > > + memset(pdata, 0, sizeof(struct packing_data)); > > We initialize this on the stack in write_midx_bitmap(), shouldn't we > just there do: > > struct packing_data pdata = {0} > > Instead of: > > struct packing_data pdata; > > And then doing this memset() here? I could go either way. Part of me prefers the memset() since it lets callers of prepare_midx_packing_data() pass in anything they want, including a pointer to uninitialized memory. Of course, there is only one such caller, so it probably doesn't really matter. And the other caller of prepare_packing_data() which is in builtin/pack-objects.c operates on a pointer to a statically allocated variable, so its bytes are already zero'd. I don't feel strongly about it, though, so I'd just as soon err on the side of flexibility than changing the declaration. > > +{ > > + struct rev_info revs; > > + struct bitmap_commit_cb cb; > > + > > + memset(&cb, 0, sizeof(struct bitmap_commit_cb)); > > Another case of s/memset/"= {0}"/g ? Ah, in this case I'd prefer the aggregate-style initialization, since we're zero-ing it out in the same function. > > static int write_midx_internal(const char *object_dir, struct multi_pack_index *m, > > struct string_list *packs_to_drop, > > const char *preferred_pack_name, > > @@ -930,9 +1100,16 @@ static int write_midx_internal(const char *object_dir, struct multi_pack_index * > > for (i = 0; i < ctx.m->num_packs; i++) { > > ALLOC_GROW(ctx.info, ctx.nr + 1, ctx.alloc); > > > > + if (prepare_midx_pack(the_repository, ctx.m, i)) { > > + error(_("could not load pack %s"), > > + ctx.m->pack_names[i]); > > Isn't the prepare_midx_pack() tasked with populating that pack_names[i] > that you can't load (the strbuf_addf() it does), but it can also exit > before that, do we get an empty string here then? Maybe I'm misreading > it (I haven't run this, just skimmed the code). Nice catch, we can't rely on ctx->m.pack_names[i] being safe to read (and at the same time know that we're going to get a non-empty string). Since prepare_midx_pack() can fail because the pack itself couldn't be loaded, I think the easiest thing to do here is to just opaquely say "could not load pack" without adding any pack name that we may or may not have. > > @@ -1132,6 +1342,9 @@ static int write_midx_internal(const char *object_dir, struct multi_pack_index * > > free(ctx.pack_perm); > > free(ctx.pack_order); > > free(midx_name); > > + if (ctx.m) > > + close_midx(ctx.m); > > + > > I see Stolee made close_midx() just return silently if !ctx.m in > 1dcd9f2043a (midx: close multi-pack-index on repack, 2018-10-12), but > grepping the uses of it it seems calls to it are similarly guarded by > "if"'s. > > Just a nit, weird to have a free-like function not invoked like > free. Perhaps (and maybe better for an unrelated cleanup) to either drop > the conditionals, or make it BUG() if it's called with NULL, but at > least we should pick one :) I agree with the direction of 1dcd9f2043a, so I'm happy to just drop the conditional and call close_midx() with an argument that may or may not be NULL. Thanks, Taylor