packfile: split out packfile list logic
In the next commit we're about to introduce the "packed" object database source. This source will embed a packfile list, and consequently we'll have to include "packfile.h" to make the struct definition available. This will unfortunately lead to a cyclic dependency that we cannot resolve with a forward declaration. Split out the code that relates to the packfile list into a separate compilation unit so that both "packfile.h" and "odb/source-packed.h" can include it. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Jun 17, 2026 at 08:39 UTC
cf86a18ac3b4e49f49c2c19351de109064999827
6 files changed
+117
-105
Makefile
+1
@@ -1233,6 +1233,7 @@ LIB_OBJS += pack-refs.o
1233
LIB_OBJS += pack-revindex.o
1234
LIB_OBJS += pack-write.o
1235
LIB_OBJS += packfile.o
1236
+LIB_OBJS += packfile-list.o
1237
LIB_OBJS += pager.o
1238
LIB_OBJS += parallel-checkout.o
1239
LIB_OBJS += parse.o
meson.build
+1
@@ -421,6 +421,7 @@ libgit_sources = [
421
'pack-revindex.c',
422
'pack-write.c',
423
'packfile.c',
424
+ 'packfile-list.c',
425
'pager.c',
426
'parallel-checkout.c',
427
'parse.c',
packfile-list.c
new
+86
@@ -0,0 +1,86 @@
1
+#include "git-compat-util.h"
2
+#include "packfile.h"
3
+#include "packfile-list.h"
4
+
5
+void packfile_list_clear(struct packfile_list *list)
6
+{
7
+ struct packfile_list_entry *e, *next;
8
+
9
+ for (e = list->head; e; e = next) {
10
+ next = e->next;
11
+ free(e);
12
+ }
13
+
14
+ list->head = list->tail = NULL;
15
+}
16
+
17
+static struct packfile_list_entry *packfile_list_remove_internal(struct packfile_list *list,
18
+ struct packed_git *pack)
19
+{
20
+ struct packfile_list_entry *e, *prev;
21
+
22
+ for (e = list->head, prev = NULL; e; prev = e, e = e->next) {
23
+ if (e->pack != pack)
24
+ continue;
25
+
26
+ if (prev)
27
+ prev->next = e->next;
28
+ if (list->head == e)
29
+ list->head = e->next;
30
+ if (list->tail == e)
31
+ list->tail = prev;
32
+
33
+ return e;
34
+ }
35
+
36
+ return NULL;
37
+}
38
+
39
+void packfile_list_remove(struct packfile_list *list, struct packed_git *pack)
40
+{
41
+ free(packfile_list_remove_internal(list, pack));
42
+}
43
+
44
+void packfile_list_prepend(struct packfile_list *list, struct packed_git *pack)
45
+{
46
+ struct packfile_list_entry *entry;
47
+
48
+ entry = packfile_list_remove_internal(list, pack);
49
+ if (!entry) {
50
+ entry = xmalloc(sizeof(*entry));
51
+ entry->pack = pack;
52
+ }
53
+ entry->next = list->head;
54
+
55
+ list->head = entry;
56
+ if (!list->tail)
57
+ list->tail = entry;
58
+}
59
+
60
+void packfile_list_append(struct packfile_list *list, struct packed_git *pack)
61
+{
62
+ struct packfile_list_entry *entry;
63
+
64
+ entry = packfile_list_remove_internal(list, pack);
65
+ if (!entry) {
66
+ entry = xmalloc(sizeof(*entry));
67
+ entry->pack = pack;
68
+ }
69
+ entry->next = NULL;
70
+
71
+ if (list->tail) {
72
+ list->tail->next = entry;
73
+ list->tail = entry;
74
+ } else {
75
+ list->head = list->tail = entry;
76
+ }
77
+}
78
+
79
+struct packed_git *packfile_list_find_oid(struct packfile_list_entry *packs,
80
+ const struct object_id *oid)
81
+{
82
+ for (; packs; packs = packs->next)
83
+ if (find_pack_entry_one(oid, packs->pack))
84
+ return packs->pack;
85
+ return NULL;
86
+}
packfile-list.h
new
+28
@@ -0,0 +1,28 @@
1
+#ifndef PACKFILE_LIST_H
2
+#define PACKFILE_LIST_H
3
+
4
+struct object_id;
5
+
6
+struct packfile_list {
7
+ struct packfile_list_entry *head, *tail;
8
+};
9
+
10
+struct packfile_list_entry {
11
+ struct packfile_list_entry *next;
12
+ struct packed_git *pack;
13
+};
14
+
15
+void packfile_list_clear(struct packfile_list *list);
16
+void packfile_list_remove(struct packfile_list *list, struct packed_git *pack);
17
+void packfile_list_prepend(struct packfile_list *list, struct packed_git *pack);
18
+void packfile_list_append(struct packfile_list *list, struct packed_git *pack);
19
+
20
+/*
21
+ * Find the pack within the "packs" list whose index contains the object
22
+ * "oid". For general object lookups, you probably don't want this; use
23
+ * find_pack_entry() instead.
24
+ */
25
+struct packed_git *packfile_list_find_oid(struct packfile_list_entry *packs,
26
+ const struct object_id *oid);
27
+
28
+#endif
packfile.c
-83
@@ -48,89 +48,6 @@ static size_t pack_mapped;
48
#define SZ_FMT PRIuMAX
49
static inline uintmax_t sz_fmt(size_t s) { return s; }
50
51
-void packfile_list_clear(struct packfile_list *list)
52
-{
53
- struct packfile_list_entry *e, *next;
54
-
55
- for (e = list->head; e; e = next) {
56
- next = e->next;
57
- free(e);
58
- }
59
-
60
- list->head = list->tail = NULL;
61
-}
62
-
63
-static struct packfile_list_entry *packfile_list_remove_internal(struct packfile_list *list,
64
- struct packed_git *pack)
65
-{
66
- struct packfile_list_entry *e, *prev;
67
-
68
- for (e = list->head, prev = NULL; e; prev = e, e = e->next) {
69
- if (e->pack != pack)
70
- continue;
71
-
72
- if (prev)
73
- prev->next = e->next;
74
- if (list->head == e)
75
- list->head = e->next;
76
- if (list->tail == e)
77
- list->tail = prev;
78
-
79
- return e;
80
- }
81
-
82
- return NULL;
83
-}
84
-
85
-void packfile_list_remove(struct packfile_list *list, struct packed_git *pack)
86
-{
87
- free(packfile_list_remove_internal(list, pack));
88
-}
89
-
90
-void packfile_list_prepend(struct packfile_list *list, struct packed_git *pack)
91
-{
92
- struct packfile_list_entry *entry;
93
-
94
- entry = packfile_list_remove_internal(list, pack);
95
- if (!entry) {
96
- entry = xmalloc(sizeof(*entry));
97
- entry->pack = pack;
98
- }
99
- entry->next = list->head;
100
-
101
- list->head = entry;
102
- if (!list->tail)
103
- list->tail = entry;
104
-}
105
-
106
-void packfile_list_append(struct packfile_list *list, struct packed_git *pack)
107
-{
108
- struct packfile_list_entry *entry;
109
-
110
- entry = packfile_list_remove_internal(list, pack);
111
- if (!entry) {
112
- entry = xmalloc(sizeof(*entry));
113
- entry->pack = pack;
114
- }
115
- entry->next = NULL;
116
-
117
- if (list->tail) {
118
- list->tail->next = entry;
119
- list->tail = entry;
120
- } else {
121
- list->head = list->tail = entry;
122
- }
123
-}
124
-
125
-struct packed_git *packfile_list_find_oid(struct packfile_list_entry *packs,
126
- const struct object_id *oid)
127
-{
128
- for (; packs; packs = packs->next)
129
- if (find_pack_entry_one(oid, packs->pack))
130
- return packs->pack;
131
- return NULL;
132
-}
133
-
51
void pack_report(struct repository *repo)
52
{
53
fprintf(stderr,
packfile.h
+1
-22
@@ -6,6 +6,7 @@
6
#include "odb.h"
7
#include "odb/source-files.h"
8
#include "oidset.h"
9
+#include "packfile-list.h"
10
#include "repository.h"
11
#include "strmap.h"
12
@@ -54,28 +55,6 @@ struct packed_git {
55
char pack_name[FLEX_ARRAY]; /* more */
56
};
57
57
-struct packfile_list {
58
- struct packfile_list_entry *head, *tail;
59
-};
60
-
61
-struct packfile_list_entry {
62
- struct packfile_list_entry *next;
63
- struct packed_git *pack;
64
-};
65
-
66
-void packfile_list_clear(struct packfile_list *list);
67
-void packfile_list_remove(struct packfile_list *list, struct packed_git *pack);
68
-void packfile_list_prepend(struct packfile_list *list, struct packed_git *pack);
69
-void packfile_list_append(struct packfile_list *list, struct packed_git *pack);
70
-
71
-/*
72
- * Find the pack within the "packs" list whose index contains the object
73
- * "oid". For general object lookups, you probably don't want this; use
74
- * find_pack_entry() instead.
75
- */
76
-struct packed_git *packfile_list_find_oid(struct packfile_list_entry *packs,
77
- const struct object_id *oid);
78
-
58
/*
59
* A store that manages packfiles for a given object database.
60
*/