Taylor Blau wrote: > A subsequent patch will teach `want_object_in_pack()` to set its > `*found_pack` and `*found_offset` poitners to NULL when the provided s/poitners/pointers > pack does not pass the `is_pack_valid()` check. > > The `--stdin-packs` mode of `pack-objects` is not quite prepared to > handle this. To prepare it for this change, do the following two things: > > - Ensure provided packs pass the `is_pack_valid()` check when > collecting the caller-provided packs into the "included" and > "excluded" lists. > Is the 'is_pack_valid()' check happening for the "excluded" packs? It looks like you only added it for the packs in the "included" list in this patch. > - Gracefully handle any _invalid_ packs being passed to > `want_object_in_pack()`. > > Calling `is_pack_valid()` early on makes it substantially less likely > that we will have to deal with a pack going away, since we'll have an > open file descriptor on its contents much earlier. > > But even packs with open descriptors can become invalid in the future if > we (a) hit our open descriptor limit, forcing us to close some open > packs, and (b) one of those just-closed packs has gone away in the > meantime. > > `add_object_entry_from_pack()` depends on having a non-NULL > `*found_pack`, since it passes that pointer to `packed_object_info()`, > meaning that we would SEGV if the pointer became NULL (like we propose > to do in `want_object_in_pack()` in the following patch). > > But avoiding calling `packed_object_info()` entirely is OK, too, since > its only purpose is to identify which objects in the included packs are > commits, so that they can form the tips of the advisory traversal used > to discover the object namehashes. > > Failing to do this means that at worst we will produce lower-quality > deltas, but it does not prevent us from generating the pack as long as > we can find a copy of each object from the disappearing pack in some > other part of the repository. > The rest of this makes sense and (as far as I can tell) lines up with the implementation below. > Co-authored-by: Victoria Dye <vdye@xxxxxxxxxx> > Signed-off-by: Taylor Blau <me@xxxxxxxxxxxx> > --- > builtin/pack-objects.c | 35 ++++++++++++++++++++--------------- > 1 file changed, 20 insertions(+), 15 deletions(-) > > diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c > index ec3193fd95..ffeaecd1d8 100644 > --- a/builtin/pack-objects.c > +++ b/builtin/pack-objects.c > @@ -3201,10 +3201,8 @@ static int add_object_entry_from_pack(const struct object_id *oid, > uint32_t pos, > void *_data) > { > - struct rev_info *revs = _data; > - struct object_info oi = OBJECT_INFO_INIT; > off_t ofs; > - enum object_type type; > + enum object_type type = OBJ_NONE; > > display_progress(progress_state, ++nr_seen); > > @@ -3215,20 +3213,25 @@ static int add_object_entry_from_pack(const struct object_id *oid, > if (!want_object_in_pack(oid, 0, &p, &ofs)) > return 0; > > - oi.typep = &type; > - if (packed_object_info(the_repository, p, ofs, &oi) < 0) > - die(_("could not get type of object %s in pack %s"), > - oid_to_hex(oid), p->pack_name); > - else if (type == OBJ_COMMIT) { > - /* > - * commits in included packs are used as starting points for the > - * subsequent revision walk > - */ > - add_pending_oid(revs, NULL, oid, 0); > + if (p) { > + struct rev_info *revs = _data; > + struct object_info oi = OBJECT_INFO_INIT; > + > + oi.typep = &type; > + if (packed_object_info(the_repository, p, ofs, &oi) < 0) { > + die(_("could not get type of object %s in pack %s"), > + oid_to_hex(oid), p->pack_name); > + } else if (type == OBJ_COMMIT) { > + /* > + * commits in included packs are used as starting points for the > + * subsequent revision walk > + */ > + add_pending_oid(revs, NULL, oid, 0); > + } > + > + stdin_packs_found_nr++; > } > > - stdin_packs_found_nr++; > - > create_object_entry(oid, type, 0, 0, 0, p, ofs); > > return 0; > @@ -3346,6 +3349,8 @@ static void read_packs_list_from_stdin(void) > struct packed_git *p = item->util; > if (!p) > die(_("could not find pack '%s'"), item->string); > + if (!is_pack_valid(p)) > + die(_("packfile %s cannot be accessed"), p->pack_name); > } > > /*