From: Taylor Blau <ttaylorr@openai.com>
To: git@vger.kernel.org, git@vger.kernel.org
Cc: Jeff King <peff@peff.net>, Junio C Hamano <gitster@pobox.com>
Subject: [PATCH 1/4] t/helper: teach pack-deltas to list delta entries
Date: Sun, 12 Jul 2026 18:11:53 -0700 [thread overview]
Message-ID: <alQ7WKITYDXfiVn9@com-79390> (raw)
In-Reply-To: <cover.1783905084.git.ttaylorr@openai.com>
In the following commit(s), some tests will need to distinguish between
`REF_DELTA`s and `OFS_DELTA`s to exercise a new '--no-ref-delta' option
for 'pack-objects'.
Existing tools report delta relationships, but not how their bases are
represented in the pack.
Teach 'test-tool pack-deltas' a '--list-deltas' mode. For each delta
entry, print the object ID, its REF_DELTA or OFS_DELTA type, and the
base object ID or pack offset, respectively. This lets tests inspect
pack headers without open-coding a parser.
Signed-off-by: Taylor Blau <ttaylorr@openai.com>
---
t/helper/test-pack-deltas.c | 69 +++++++++++++++++++++++++++++++++++++
t/t5300-pack-object.sh | 8 +++--
2 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/t/helper/test-pack-deltas.c b/t/helper/test-pack-deltas.c
index 840797cf0d..4ba6fe2dd3 100644
--- a/t/helper/test-pack-deltas.c
+++ b/t/helper/test-pack-deltas.c
@@ -7,6 +7,7 @@
#include "hash.h"
#include "hex.h"
#include "pack.h"
+#include "packfile.h"
#include "pack-objects.h"
#include "parse-options.h"
#include "setup.h"
@@ -15,6 +16,7 @@
static const char *usage_str[] = {
"test-tool pack-deltas --num-objects <num-objects>",
+ "test-tool pack-deltas --list-deltas <pack>.idx",
NULL
};
@@ -80,19 +82,86 @@ static void write_ref_delta(struct hashfile *f,
free(delta_buf);
}
+static int list_delta(const struct object_id *oid,
+ struct packed_git *p,
+ uint32_t pos,
+ void *_w_curs)
+{
+ struct pack_window **w_curs = _w_curs;
+ off_t obj_offset = nth_packed_object_offset(p, pos);
+ off_t cur = obj_offset;
+ size_t size;
+ enum object_type type = unpack_object_header(p, w_curs, &cur,
+ &size);
+
+ if (type < 0)
+ die("unable to parse object at position %"PRIu32, pos);
+ if (type != OBJ_REF_DELTA && type != OBJ_OFS_DELTA)
+ return 0;
+
+ if (type == OBJ_REF_DELTA) {
+ struct object_id base_oid;
+ const unsigned char *base = use_pack(p, w_curs, cur,
+ NULL);
+
+ oidread(&base_oid, base, p->repo->hash_algo);
+ printf("%s REF_DELTA %s\n", oid_to_hex(oid),
+ oid_to_hex(&base_oid));
+ } else {
+ off_t base_offset = get_delta_base(p, w_curs, &cur,
+ type, obj_offset);
+
+ if (!base_offset)
+ die("unable to read base of object %s", oid_to_hex(oid));
+ printf("%s OFS_DELTA %"PRIuMAX"\n", oid_to_hex(oid),
+ (uintmax_t)base_offset);
+ }
+
+ return 0;
+}
+
+static void list_deltas(const char *idx_name)
+{
+ struct packed_git *p;
+ struct pack_window *w_curs = NULL;
+
+ p = add_packed_git(the_repository, idx_name, strlen(idx_name), 1);
+ if (!p || open_pack_index(p))
+ die("unable to open pack index %s", idx_name);
+
+ if (for_each_object_in_pack(p, list_delta, &w_curs,
+ ODB_FOR_EACH_OBJECT_PACK_ORDER))
+ die("unable to iterate over objects in %s", idx_name);
+
+ unuse_pack(&w_curs);
+ close_pack(p);
+ free(p);
+}
+
int cmd__pack_deltas(int argc, const char **argv)
{
int num_objects = -1;
+ int list_deltas_mode = 0;
struct hashfile *f;
struct strbuf line = STRBUF_INIT;
struct option options[] = {
OPT_INTEGER('n', "num-objects", &num_objects, N_("the number of objects to write")),
+ OPT_BOOL(0, "list-deltas", &list_deltas_mode,
+ N_("list REF_DELTA and OFS_DELTA entries")),
OPT_END()
};
argc = parse_options(argc, argv, NULL,
options, usage_str, 0);
+ if (list_deltas_mode) {
+ if (argc != 1 || num_objects >= 0)
+ usage_with_options(usage_str, options);
+ setup_git_directory(the_repository);
+ list_deltas(argv[0]);
+ return 0;
+ }
+
if (argc || num_objects < 0)
usage_with_options(usage_str, options);
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index 73445782e7..4bee490ff6 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -190,7 +190,9 @@ test_expect_success 'unpack without delta (core.fsyncmethod=batch)' '
test_expect_success 'pack with REF_DELTA' '
packname_2=$(git pack-objects --progress test-2 <obj-list 2>stderr) &&
- check_deltas stderr -gt 0
+ check_deltas stderr -gt 0 &&
+ test-tool pack-deltas --list-deltas test-2-$packname_2.idx >deltas &&
+ test_grep " REF_DELTA " deltas
'
test_expect_success 'unpack with REF_DELTA' '
@@ -204,7 +206,9 @@ test_expect_success 'unpack with REF_DELTA (core.fsyncmethod=batch)' '
test_expect_success 'pack with OFS_DELTA' '
packname_3=$(git pack-objects --progress --delta-base-offset test-3 \
<obj-list 2>stderr) &&
- check_deltas stderr -gt 0
+ check_deltas stderr -gt 0 &&
+ test-tool pack-deltas --list-deltas test-3-$packname_3.idx >deltas &&
+ test_grep " OFS_DELTA " deltas
'
test_expect_success 'unpack with OFS_DELTA' '
--
2.55.0
next parent reply other threads:[~2026-07-13 1:11 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1783905084.git.ttaylorr@openai.com>
2026-07-13 1:11 ` Taylor Blau [this message]
2026-07-13 1:11 ` [PATCH 2/4] pack-objects: introduce `--no-ref-delta` Taylor Blau
2026-07-13 1:12 ` [PATCH 3/4] pack-objects: support reuse with `--no-ref-delta` Taylor Blau
2026-07-13 1:12 ` [PATCH 4/4] send-pack: honor `no-ref-delta` capability Taylor Blau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alQ7WKITYDXfiVn9@com-79390 \
--to=ttaylorr@openai.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.