Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6131a76
Merge branch 'tb/incremental-midx-part-3.1' into ps/ref-peeled-tags
gitster Oct 22, 2025
f2bf477
Merge branch 'jt/repo-structure' into ps/ref-peeled-tags
gitster Oct 22, 2025
ed3305f
Merge branch 'ps/remove-packfile-store-get-packs' into ps/packed-git-…
gitster Oct 28, 2025
e78ab37
packfile: use a `strmap` to store packs by name
pks-t Oct 30, 2025
f905a85
packfile: move the MRU list into the packfile store
pks-t Oct 30, 2025
89219bc
http: refactor subsystem to use `packfile_list`s
pks-t Oct 30, 2025
02a7f6f
packfile: fix approximation of object counts
pks-t Oct 30, 2025
0d0e4b5
builtin/pack-objects: simplify logic to find kept or nonlocal objects
pks-t Oct 30, 2025
589127c
packfile: move list of packs into the packfile store
pks-t Oct 30, 2025
6aff1f2
packfile: always add packfiles to MRU when adding a pack
pks-t Oct 30, 2025
c31bad4
packfile: track packs via the MRU list exclusively
pks-t Oct 30, 2025
bdbebe5
refs: introduce wrapper struct for `each_ref_fn`
pks-t Oct 23, 2025
89baa52
refs: introduce `.ref` field for the base iterator
pks-t Oct 23, 2025
4cea042
refs: fully reset `struct ref_iterator::ref` on iteration
pks-t Oct 23, 2025
eb2934d
refs: refactor reference status flags
pks-t Oct 23, 2025
f898661
refs: expose peeled object ID via the iterator
pks-t Oct 23, 2025
adecd5f
upload-pack: convert to use `reference_get_peeled_oid()`
pks-t Oct 23, 2025
70b783c
ref-filter: propagate peeled object ID
pks-t Oct 23, 2025
feaaea4
builtin/show-ref: convert to use `reference_get_peeled_oid()`
pks-t Oct 23, 2025
5a5c735
refs: drop `current_ref_iter` hack
pks-t Oct 23, 2025
7051147
refs: drop infrastructure to peel via iterators
pks-t Oct 23, 2025
7ec8518
object: add flag to `peel_object()` to verify object type
pks-t Oct 23, 2025
6ec4c0b
refs: don't store peeled object IDs for invalid tags
pks-t Oct 23, 2025
e66077a
ref-filter: detect broken tags when dereferencing them
pks-t Oct 23, 2025
a29e2e8
ref-filter: parse objects on demand
pks-t Oct 23, 2025
bea37f1
ref-filter: fix stale parsed objects
pks-t Nov 4, 2025
61ac8ba
t7004: do not chdir around in the main process
gitster Nov 4, 2025
aec5adb
Merge branch 'ps/ref-peeled-tags' into kn/refs-optim-cleanup
gitster Nov 4, 2025
9b93ab8
refs: move to using the '.optimize' functions
KarthikNayak Oct 20, 2025
2cd99d9
refs: rename 'pack_refs_opts' to 'refs_optimize_opts'
KarthikNayak Oct 20, 2025
c113f4c
t/pack-refs-tests: move the 'test_done' to callees
KarthikNayak Oct 20, 2025
994869e
Merge branch 'ps/ref-peeled-tags' into ps/ref-peeled-tags-fixes
gitster Nov 6, 2025
7048e74
object: fix performance regression when peeling tags
pks-t Nov 6, 2025
7a75e54
Merge branch 'ps/packed-git-in-object-store'
gitster Nov 19, 2025
13134ce
Merge branch 'ps/ref-peeled-tags'
gitster Nov 19, 2025
7ccfc26
Merge branch 'kn/refs-optim-cleanup'
gitster Nov 19, 2025
ee27005
Merge branch 'ps/ref-peeled-tags-fixes'
gitster Nov 19, 2025
5e6e485
Start 2.53 cycle
gitster Nov 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Documentation/RelNotes/2.53.0.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Git v2.53 Release Notes
=======================

Performance, Internal Implementation, Development Support etc.
--------------------------------------------------------------

* The list of packfiles used in a running Git process is moved from
the packed_git structure into the packfile store.

* Some ref backend storage can hold not just the object name of an
annotated tag, but the object name of the object the tag points at.
The code to handle this information has been streamlined.
2 changes: 1 addition & 1 deletion GIT-VERSION-GEN
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

DEF_VER=v2.52.0
DEF_VER=v2.52.GIT

LF='
'
Expand Down
2 changes: 1 addition & 1 deletion RelNotes
24 changes: 10 additions & 14 deletions bisect.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,21 +450,20 @@ void find_bisection(struct commit_list **commit_list, int *reaches,
clear_commit_weight(&commit_weight);
}

static int register_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
int flags UNUSED, void *cb_data UNUSED)
static int register_ref(const struct reference *ref, void *cb_data UNUSED)
{
struct strbuf good_prefix = STRBUF_INIT;
strbuf_addstr(&good_prefix, term_good);
strbuf_addstr(&good_prefix, "-");

if (!strcmp(refname, term_bad)) {
if (!strcmp(ref->name, term_bad)) {
free(current_bad_oid);
current_bad_oid = xmalloc(sizeof(*current_bad_oid));
oidcpy(current_bad_oid, oid);
} else if (starts_with(refname, good_prefix.buf)) {
oid_array_append(&good_revs, oid);
} else if (starts_with(refname, "skip-")) {
oid_array_append(&skipped_revs, oid);
oidcpy(current_bad_oid, ref->oid);
} else if (starts_with(ref->name, good_prefix.buf)) {
oid_array_append(&good_revs, ref->oid);
} else if (starts_with(ref->name, "skip-")) {
oid_array_append(&skipped_revs, ref->oid);
}

strbuf_release(&good_prefix);
Expand Down Expand Up @@ -1178,14 +1177,11 @@ int estimate_bisect_steps(int all)
return (e < 3 * x) ? n : n - 1;
}

static int mark_for_removal(const char *refname,
const char *referent UNUSED,
const struct object_id *oid UNUSED,
int flag UNUSED, void *cb_data)
static int mark_for_removal(const struct reference *ref, void *cb_data)
{
struct string_list *refs = cb_data;
char *ref = xstrfmt("refs/bisect%s", refname);
string_list_append(refs, ref);
char *bisect_ref = xstrfmt("refs/bisect%s", ref->name);
string_list_append(refs, bisect_ref);
return 0;
}

Expand Down
17 changes: 5 additions & 12 deletions builtin/bisect.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,7 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
return 0;
}

static int inc_nr(const char *refname UNUSED,
const char *referent UNUSED,
const struct object_id *oid UNUSED,
int flag UNUSED, void *cb_data)
static int inc_nr(const struct reference *ref UNUSED, void *cb_data)
{
unsigned int *nr = (unsigned int *)cb_data;
(*nr)++;
Expand Down Expand Up @@ -554,12 +551,11 @@ static int bisect_append_log_quoted(const char **argv)
return res;
}

static int add_bisect_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
int flags UNUSED, void *cb)
static int add_bisect_ref(const struct reference *ref, void *cb)
{
struct add_bisect_ref_data *data = cb;

add_pending_oid(data->revs, refname, oid, data->object_flags);
add_pending_oid(data->revs, ref->name, ref->oid, data->object_flags);

return 0;
}
Expand Down Expand Up @@ -1170,12 +1166,9 @@ static int bisect_visualize(struct bisect_terms *terms, int argc,
return run_command(&cmd);
}

static int get_first_good(const char *refname UNUSED,
const char *referent UNUSED,
const struct object_id *oid,
int flag UNUSED, void *cb_data)
static int get_first_good(const struct reference *ref, void *cb_data)
{
oidcpy(cb_data, oid);
oidcpy(cb_data, ref->oid);
return 1;
}

Expand Down
6 changes: 2 additions & 4 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -1063,11 +1063,9 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
report_tracking(new_branch_info);
}

static int add_pending_uninteresting_ref(const char *refname, const char *referent UNUSED,
const struct object_id *oid,
int flags UNUSED, void *cb_data)
static int add_pending_uninteresting_ref(const struct reference *ref, void *cb_data)
{
add_pending_oid(cb_data, refname, oid, UNINTERESTING);
add_pending_oid(cb_data, ref->name, ref->oid, UNINTERESTING);
return 0;
}

Expand Down
18 changes: 9 additions & 9 deletions builtin/describe.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,20 +154,19 @@ static void add_to_known_names(const char *path,
}
}

static int get_name(const char *path, const char *referent UNUSED, const struct object_id *oid,
int flag UNUSED, void *cb_data UNUSED)
static int get_name(const struct reference *ref, void *cb_data UNUSED)
{
int is_tag = 0;
struct object_id peeled;
int is_annotated, prio;
const char *path_to_match = NULL;

if (skip_prefix(path, "refs/tags/", &path_to_match)) {
if (skip_prefix(ref->name, "refs/tags/", &path_to_match)) {
is_tag = 1;
} else if (all) {
if ((exclude_patterns.nr || patterns.nr) &&
!skip_prefix(path, "refs/heads/", &path_to_match) &&
!skip_prefix(path, "refs/remotes/", &path_to_match)) {
!skip_prefix(ref->name, "refs/heads/", &path_to_match) &&
!skip_prefix(ref->name, "refs/remotes/", &path_to_match)) {
/* Only accept reference of known type if there are match/exclude patterns */
return 0;
}
Expand Down Expand Up @@ -209,10 +208,10 @@ static int get_name(const char *path, const char *referent UNUSED, const struct
}

/* Is it annotated? */
if (!peel_iterated_oid(the_repository, oid, &peeled)) {
is_annotated = !oideq(oid, &peeled);
if (!reference_get_peeled_oid(the_repository, ref, &peeled)) {
is_annotated = !oideq(ref->oid, &peeled);
} else {
oidcpy(&peeled, oid);
oidcpy(&peeled, ref->oid);
is_annotated = 0;
}

Expand All @@ -229,7 +228,8 @@ static int get_name(const char *path, const char *referent UNUSED, const struct
else
prio = 0;

add_to_known_names(all ? path + 5 : path + 10, &peeled, prio, oid);
add_to_known_names(all ? ref->name + 5 : ref->name + 10,
&peeled, prio, ref->oid);
return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions builtin/fast-import.c
Original file line number Diff line number Diff line change
Expand Up @@ -979,7 +979,7 @@ static int store_object(
if (e->idx.offset) {
duplicate_count_by_type[type]++;
return 1;
} else if (find_oid_pack(&oid, packfile_store_get_packs(packs))) {
} else if (packfile_list_find_oid(packfile_store_get_packs(packs), &oid)) {
e->type = type;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
Expand Down Expand Up @@ -1180,7 +1180,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
duplicate_count_by_type[OBJ_BLOB]++;
truncate_pack(&checkpoint);

} else if (find_oid_pack(&oid, packfile_store_get_packs(packs))) {
} else if (packfile_list_find_oid(packfile_store_get_packs(packs), &oid)) {
e->type = OBJ_BLOB;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
Expand Down
13 changes: 4 additions & 9 deletions builtin/fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,11 @@ static struct refname_hash_entry *refname_hash_add(struct hashmap *map,
return ent;
}

static int add_one_refname(const char *refname, const char *referent UNUSED,
const struct object_id *oid,
int flag UNUSED, void *cbdata)
static int add_one_refname(const struct reference *ref, void *cbdata)
{
struct hashmap *refname_map = cbdata;

(void) refname_hash_add(refname_map, refname, oid);
(void) refname_hash_add(refname_map, ref->name, ref->oid);
return 0;
}

Expand Down Expand Up @@ -1416,14 +1414,11 @@ static void set_option(struct transport *transport, const char *name, const char
}


static int add_oid(const char *refname UNUSED,
const char *referent UNUSED,
const struct object_id *oid,
int flags UNUSED, void *cb_data)
static int add_oid(const struct reference *ref, void *cb_data)
{
struct oid_array *oids = cb_data;

oid_array_append(oids, oid);
oid_array_append(oids, ref->oid);
return 0;
}

Expand Down
33 changes: 19 additions & 14 deletions builtin/fsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,14 +530,13 @@ static int fsck_handle_reflog(const char *logname, void *cb_data)
return 0;
}

static int fsck_handle_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid,
int flag UNUSED, void *cb_data UNUSED)
static int fsck_handle_ref(const struct reference *ref, void *cb_data UNUSED)
{
struct object *obj;

obj = parse_object(the_repository, oid);
obj = parse_object(the_repository, ref->oid);
if (!obj) {
if (is_promisor_object(the_repository, oid)) {
if (is_promisor_object(the_repository, ref->oid)) {
/*
* Increment default_refs anyway, because this is a
* valid ref.
Expand All @@ -546,19 +545,19 @@ static int fsck_handle_ref(const char *refname, const char *referent UNUSED, con
return 0;
}
error(_("%s: invalid sha1 pointer %s"),
refname, oid_to_hex(oid));
ref->name, oid_to_hex(ref->oid));
errors_found |= ERROR_REACHABLE;
/* We'll continue with the rest despite the error.. */
return 0;
}
if (obj->type != OBJ_COMMIT && is_branch(refname)) {
error(_("%s: not a commit"), refname);
if (obj->type != OBJ_COMMIT && is_branch(ref->name)) {
error(_("%s: not a commit"), ref->name);
errors_found |= ERROR_REFS;
}
default_refs++;
obj->flags |= USED;
fsck_put_object_name(&fsck_walk_options,
oid, "%s", refname);
ref->oid, "%s", ref->name);
mark_object_reachable(obj);

return 0;
Expand All @@ -580,13 +579,19 @@ static void get_default_heads(void)
worktrees = get_worktrees();
for (p = worktrees; *p; p++) {
struct worktree *wt = *p;
struct strbuf ref = STRBUF_INIT;
struct strbuf refname = STRBUF_INIT;

strbuf_worktree_ref(wt, &ref, "HEAD");
fsck_head_link(ref.buf, &head_points_at, &head_oid);
if (head_points_at && !is_null_oid(&head_oid))
fsck_handle_ref(ref.buf, NULL, &head_oid, 0, NULL);
strbuf_release(&ref);
strbuf_worktree_ref(wt, &refname, "HEAD");
fsck_head_link(refname.buf, &head_points_at, &head_oid);
if (head_points_at && !is_null_oid(&head_oid)) {
struct reference ref = {
.name = refname.buf,
.oid = &head_oid,
};

fsck_handle_ref(&ref, NULL);
}
strbuf_release(&refname);

if (include_reflogs)
refs_for_each_reflog(get_worktree_ref_store(wt),
Expand Down
15 changes: 6 additions & 9 deletions builtin/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1103,24 +1103,21 @@ struct cg_auto_data {
int limit;
};

static int dfs_on_ref(const char *refname UNUSED,
const char *referent UNUSED,
const struct object_id *oid,
int flags UNUSED,
void *cb_data)
static int dfs_on_ref(const struct reference *ref, void *cb_data)
{
struct cg_auto_data *data = (struct cg_auto_data *)cb_data;
int result = 0;
const struct object_id *maybe_peeled = ref->oid;
struct object_id peeled;
struct commit_list *stack = NULL;
struct commit *commit;

if (!peel_iterated_oid(the_repository, oid, &peeled))
oid = &peeled;
if (odb_read_object_info(the_repository->objects, oid, NULL) != OBJ_COMMIT)
if (!reference_get_peeled_oid(the_repository, ref, &peeled))
maybe_peeled = &peeled;
if (odb_read_object_info(the_repository->objects, maybe_peeled, NULL) != OBJ_COMMIT)
return 0;

commit = lookup_commit(the_repository, oid);
commit = lookup_commit(the_repository, maybe_peeled);
if (!commit)
return 0;
if (repo_parse_commit(the_repository, commit) ||
Expand Down
2 changes: 1 addition & 1 deletion builtin/ls-remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ int cmd_ls_remote(int argc,
continue;
if (!tail_match(&pattern, ref->name))
continue;
item = ref_array_push(&ref_array, ref->name, &ref->old_oid);
item = ref_array_push(&ref_array, ref->name, &ref->old_oid, NULL);
item->symref = xstrdup_or_null(ref->symref);
}

Expand Down
17 changes: 8 additions & 9 deletions builtin/name-rev.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,25 +339,24 @@ static int cmp_by_tag_and_age(const void *a_, const void *b_)
return a->taggerdate != b->taggerdate;
}

static int name_ref(const char *path, const char *referent UNUSED, const struct object_id *oid,
int flags UNUSED, void *cb_data)
static int name_ref(const struct reference *ref, void *cb_data)
{
struct object *o = parse_object(the_repository, oid);
struct object *o = parse_object(the_repository, ref->oid);
struct name_ref_data *data = cb_data;
int can_abbreviate_output = data->tags_only && data->name_only;
int deref = 0;
int from_tag = 0;
struct commit *commit = NULL;
timestamp_t taggerdate = TIME_MAX;

if (data->tags_only && !starts_with(path, "refs/tags/"))
if (data->tags_only && !starts_with(ref->name, "refs/tags/"))
return 0;

if (data->exclude_filters.nr) {
struct string_list_item *item;

for_each_string_list_item(item, &data->exclude_filters) {
if (subpath_matches(path, item->string) >= 0)
if (subpath_matches(ref->name, item->string) >= 0)
return 0;
}
}
Expand All @@ -378,7 +377,7 @@ static int name_ref(const char *path, const char *referent UNUSED, const struct
* shouldn't stop when seeing 'refs/tags/v1.4' matches
* 'refs/tags/v*'. We should show it as 'v1.4'.
*/
switch (subpath_matches(path, item->string)) {
switch (subpath_matches(ref->name, item->string)) {
case -1: /* did not match */
break;
case 0: /* matched fully */
Expand Down Expand Up @@ -406,13 +405,13 @@ static int name_ref(const char *path, const char *referent UNUSED, const struct
}
if (o && o->type == OBJ_COMMIT) {
commit = (struct commit *)o;
from_tag = starts_with(path, "refs/tags/");
from_tag = starts_with(ref->name, "refs/tags/");
if (taggerdate == TIME_MAX)
taggerdate = commit->date;
}

add_to_tip_table(oid, path, can_abbreviate_output, commit, taggerdate,
from_tag, deref);
add_to_tip_table(ref->oid, ref->name, can_abbreviate_output,
commit, taggerdate, from_tag, deref);
return 0;
}

Expand Down
Loading