[GSoC PATCH v4 3/5] repack-promisor: preserve content of promisor files after repack
- From
LorenzoPegorari <lorenzo.pegorari2002@gmail.com>
- Date
- Apr 10, 2026, 15:03 UTC
- Message-ID
- <72ef2378b9cd50941b1c0c485bcbacb820e798c9.1775832056.git.lorenzo.pegorari2002@gmail.com>
- In-Reply-To
- <cover.1775832056.git.lorenzo.pegorari2002@gmail.com>
When a repack involving promisor packfiles happens, the new ".promisor" file is created empty, losing all the debug info that might be present inside the ".promisor" files before the repack.
Use the "copy_promisor_content()" function created previously to preserve the contents of all ".promisor" files inside the first ".promisor" file created by the repack.
For geometric repacking, we have to create a `strset` that contains the basenames of all excluded packs. For "normal" repacking this is not necessary, since there should be no excluded packs.
Also, update the documentation accordingly.
Signed-off-by: LorenzoPegorari <lorenzo.pegorari2002@gmail.com> --- Documentation/git-repack.adoc | 4 ++-- repack-promisor.c | 30 +++++++++++++++++------------- 2 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/Documentation/git-repack.adoc b/Documentation/git-repack.adoc index 673ce91083..33d3c8afbd 100644 --- a/Documentation/git-repack.adoc +++ b/Documentation/git-repack.adoc @@ -45,8 +45,8 @@ other objects in that pack they already have locally. + Promisor packfiles are repacked separately: if there are packfiles that have an associated ".promisor" file, these packfiles will be repacked -into another separate pack, and an empty ".promisor" file corresponding -to the new separate pack will be written. +into another separate pack, and a ".promisor" file corresponding to the +new separate pack will be written (with arbitrary contents). -A:: Same as `-a`, unless `-d` is used. Then any unreachable diff --git a/repack-promisor.c b/repack-promisor.c index 797314d7b9..0c373c8820 100644 --- a/repack-promisor.c +++ b/repack-promisor.c @@ -153,7 +153,8 @@ static void copy_promisor_content(struct repository *repo, static void finish_repacking_promisor_objects(struct repository *repo, struct child_process *cmd, struct string_list *names, - const char *packtmp) + const char *packtmp, + struct strset *not_repacked_basenames) { struct strbuf line = STRBUF_INIT; FILE *out; @@ -171,19 +172,15 @@ static void finish_repacking_promisor_objects(struct repository *repo, /* * pack-objects creates the .pack and .idx files, but not the - * .promisor file. Create the .promisor file, which is empty. - * - * NEEDSWORK: fetch-pack sometimes generates non-empty - * .promisor files containing the ref names and associated - * hashes at the point of generation of the corresponding - * packfile, but this would not preserve their contents. Maybe - * concatenate the contents of all .promisor files instead of - * just creating a new empty file. + * .promisor file. Create the .promisor file. */ promisor_name = mkpathdup("%s-%s.promisor", packtmp, line.buf); write_promisor_file(promisor_name, NULL, 0); + /* Now let's fill the content of the newly created .promisor file */ + copy_promisor_content(repo, line.buf, packtmp, not_repacked_basenames); + item->util = generated_pack_populate(item->string, packtmp); free(promisor_name); @@ -223,7 +220,7 @@ void repack_promisor_objects(struct repository *repo, return; } - finish_repacking_promisor_objects(repo, &cmd, names, packtmp); + finish_repacking_promisor_objects(repo, &cmd, names, packtmp, NULL); } void pack_geometry_repack_promisors(struct repository *repo, @@ -234,6 +231,7 @@ void pack_geometry_repack_promisors(struct repository *repo, { struct child_process cmd = CHILD_PROCESS_INIT; FILE *in; + struct strset not_repacked_basenames = STRSET_INIT; if (!geometry->promisor_split) return; @@ -247,9 +245,15 @@ void pack_geometry_repack_promisors(struct repository *repo, in = xfdopen(cmd.in, "w"); for (size_t i = 0; i < geometry->promisor_split; i++) fprintf(in, "%s\n", pack_basename(geometry->promisor_pack[i])); - for (size_t i = geometry->promisor_split; i < geometry->promisor_pack_nr; i++) - fprintf(in, "^%s\n", pack_basename(geometry->promisor_pack[i])); + for (size_t i = geometry->promisor_split; i < geometry->promisor_pack_nr; i++) { + const char *name = pack_basename(geometry->promisor_pack[i]); + fprintf(in, "^%s\n", name); + strset_add(¬_repacked_basenames, name); + } fclose(in); - finish_repacking_promisor_objects(repo, &cmd, names, packtmp); + finish_repacking_promisor_objects(repo, &cmd, names, packtmp, + strset_get_size(¬_repacked_basenames) ? ¬_repacked_basenames : NULL); + + strset_clear(¬_repacked_basenames); }
-- 2.53.0.585.ge25071d955