Skip to content

Commit 29e9355

Browse files
ttaylorrgitster
authored andcommitted
builtin/repack.c: remove "repack_promisor_objects()" from the builtin
Now that we have properly factored the portion of the builtin which is responsible for repacking promisor objects, we can move that function (and associated dependencies) out of the builtin entirely. Similar to previous extractions, this function is declared in repack.h, but implemented in a separate repack-promisor.c file. This is done to separate promisor-specific repacking functionality from generic repack utilities (like "existing_packs", and "generated_pack" APIs). Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent bebf941 commit 29e9355

5 files changed

Lines changed: 108 additions & 95 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,7 @@ LIB_OBJS += refs/ref-cache.o
11371137
LIB_OBJS += refspec.o
11381138
LIB_OBJS += remote.o
11391139
LIB_OBJS += repack.o
1140+
LIB_OBJS += repack-promisor.o
11401141
LIB_OBJS += replace-object.o
11411142
LIB_OBJS += repo-settings.o
11421143
LIB_OBJS += repository.o

builtin/repack.c

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -107,101 +107,6 @@ static int repack_config(const char *var, const char *value,
107107
return git_default_config(var, value, ctx, cb);
108108
}
109109

110-
struct write_oid_context {
111-
struct child_process *cmd;
112-
const struct git_hash_algo *algop;
113-
};
114-
115-
/*
116-
* Write oid to the given struct child_process's stdin, starting it first if
117-
* necessary.
118-
*/
119-
static int write_oid(const struct object_id *oid,
120-
struct packed_git *pack UNUSED,
121-
uint32_t pos UNUSED, void *data)
122-
{
123-
struct write_oid_context *ctx = data;
124-
struct child_process *cmd = ctx->cmd;
125-
126-
if (cmd->in == -1) {
127-
if (start_command(cmd))
128-
die(_("could not start pack-objects to repack promisor objects"));
129-
}
130-
131-
if (write_in_full(cmd->in, oid_to_hex(oid), ctx->algop->hexsz) < 0 ||
132-
write_in_full(cmd->in, "\n", 1) < 0)
133-
die(_("failed to feed promisor objects to pack-objects"));
134-
return 0;
135-
}
136-
137-
static void repack_promisor_objects(struct repository *repo,
138-
const struct pack_objects_args *args,
139-
struct string_list *names,
140-
const char *packtmp)
141-
{
142-
struct write_oid_context ctx;
143-
struct child_process cmd = CHILD_PROCESS_INIT;
144-
FILE *out;
145-
struct strbuf line = STRBUF_INIT;
146-
147-
prepare_pack_objects(&cmd, args, packtmp);
148-
cmd.in = -1;
149-
150-
/*
151-
* NEEDSWORK: Giving pack-objects only the OIDs without any ordering
152-
* hints may result in suboptimal deltas in the resulting pack. See if
153-
* the OIDs can be sent with fake paths such that pack-objects can use a
154-
* {type -> existing pack order} ordering when computing deltas instead
155-
* of a {type -> size} ordering, which may produce better deltas.
156-
*/
157-
ctx.cmd = &cmd;
158-
ctx.algop = repo->hash_algo;
159-
for_each_packed_object(repo, write_oid, &ctx,
160-
FOR_EACH_OBJECT_PROMISOR_ONLY);
161-
162-
if (cmd.in == -1) {
163-
/* No packed objects; cmd was never started */
164-
child_process_clear(&cmd);
165-
return;
166-
}
167-
168-
close(cmd.in);
169-
170-
out = xfdopen(cmd.out, "r");
171-
while (strbuf_getline_lf(&line, out) != EOF) {
172-
struct string_list_item *item;
173-
char *promisor_name;
174-
175-
if (line.len != repo->hash_algo->hexsz)
176-
die(_("repack: Expecting full hex object ID lines only from pack-objects."));
177-
item = string_list_append(names, line.buf);
178-
179-
/*
180-
* pack-objects creates the .pack and .idx files, but not the
181-
* .promisor file. Create the .promisor file, which is empty.
182-
*
183-
* NEEDSWORK: fetch-pack sometimes generates non-empty
184-
* .promisor files containing the ref names and associated
185-
* hashes at the point of generation of the corresponding
186-
* packfile, but this would not preserve their contents. Maybe
187-
* concatenate the contents of all .promisor files instead of
188-
* just creating a new empty file.
189-
*/
190-
promisor_name = mkpathdup("%s-%s.promisor", packtmp,
191-
line.buf);
192-
write_promisor_file(promisor_name, NULL, 0);
193-
194-
item->util = generated_pack_populate(item->string, packtmp);
195-
196-
free(promisor_name);
197-
}
198-
199-
fclose(out);
200-
if (finish_command(&cmd))
201-
die(_("could not finish pack-objects to repack promisor objects"));
202-
strbuf_release(&line);
203-
}
204-
205110
struct pack_geometry {
206111
struct packed_git **pack;
207112
uint32_t pack_nr, pack_alloc;

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ libgit_sources = [
463463
'reftable/writer.c',
464464
'remote.c',
465465
'repack.c',
466+
'repack-promisor.c',
466467
'replace-object.c',
467468
'repo-settings.c',
468469
'repository.c',

repack-promisor.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include "git-compat-util.h"
2+
#include "repack.h"
3+
#include "hex.h"
4+
#include "pack.h"
5+
#include "packfile.h"
6+
#include "path.h"
7+
#include "repository.h"
8+
#include "run-command.h"
9+
10+
struct write_oid_context {
11+
struct child_process *cmd;
12+
const struct git_hash_algo *algop;
13+
};
14+
15+
/*
16+
* Write oid to the given struct child_process's stdin, starting it first if
17+
* necessary.
18+
*/
19+
static int write_oid(const struct object_id *oid,
20+
struct packed_git *pack UNUSED,
21+
uint32_t pos UNUSED, void *data)
22+
{
23+
struct write_oid_context *ctx = data;
24+
struct child_process *cmd = ctx->cmd;
25+
26+
if (cmd->in == -1) {
27+
if (start_command(cmd))
28+
die(_("could not start pack-objects to repack promisor objects"));
29+
}
30+
31+
if (write_in_full(cmd->in, oid_to_hex(oid), ctx->algop->hexsz) < 0 ||
32+
write_in_full(cmd->in, "\n", 1) < 0)
33+
die(_("failed to feed promisor objects to pack-objects"));
34+
return 0;
35+
}
36+
37+
void repack_promisor_objects(struct repository *repo,
38+
const struct pack_objects_args *args,
39+
struct string_list *names, const char *packtmp)
40+
{
41+
struct write_oid_context ctx;
42+
struct child_process cmd = CHILD_PROCESS_INIT;
43+
FILE *out;
44+
struct strbuf line = STRBUF_INIT;
45+
46+
prepare_pack_objects(&cmd, args, packtmp);
47+
cmd.in = -1;
48+
49+
/*
50+
* NEEDSWORK: Giving pack-objects only the OIDs without any ordering
51+
* hints may result in suboptimal deltas in the resulting pack. See if
52+
* the OIDs can be sent with fake paths such that pack-objects can use a
53+
* {type -> existing pack order} ordering when computing deltas instead
54+
* of a {type -> size} ordering, which may produce better deltas.
55+
*/
56+
ctx.cmd = &cmd;
57+
ctx.algop = repo->hash_algo;
58+
for_each_packed_object(repo, write_oid, &ctx,
59+
FOR_EACH_OBJECT_PROMISOR_ONLY);
60+
61+
if (cmd.in == -1) {
62+
/* No packed objects; cmd was never started */
63+
child_process_clear(&cmd);
64+
return;
65+
}
66+
67+
close(cmd.in);
68+
69+
out = xfdopen(cmd.out, "r");
70+
while (strbuf_getline_lf(&line, out) != EOF) {
71+
struct string_list_item *item;
72+
char *promisor_name;
73+
74+
if (line.len != repo->hash_algo->hexsz)
75+
die(_("repack: Expecting full hex object ID lines only from pack-objects."));
76+
item = string_list_append(names, line.buf);
77+
78+
/*
79+
* pack-objects creates the .pack and .idx files, but not the
80+
* .promisor file. Create the .promisor file, which is empty.
81+
*
82+
* NEEDSWORK: fetch-pack sometimes generates non-empty
83+
* .promisor files containing the ref names and associated
84+
* hashes at the point of generation of the corresponding
85+
* packfile, but this would not preserve their contents. Maybe
86+
* concatenate the contents of all .promisor files instead of
87+
* just creating a new empty file.
88+
*/
89+
promisor_name = mkpathdup("%s-%s.promisor", packtmp,
90+
line.buf);
91+
write_promisor_file(promisor_name, NULL, 0);
92+
93+
item->util = generated_pack_populate(item->string, packtmp);
94+
95+
free(promisor_name);
96+
}
97+
98+
fclose(out);
99+
if (finish_command(&cmd))
100+
die(_("could not finish pack-objects to repack promisor objects"));
101+
strbuf_release(&line);
102+
}

repack.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,8 @@ int generated_pack_has_ext(const struct generated_pack *pack, const char *ext);
7474
void generated_pack_install(struct generated_pack *pack, const char *name,
7575
const char *packdir, const char *packtmp);
7676

77+
void repack_promisor_objects(struct repository *repo,
78+
const struct pack_objects_args *args,
79+
struct string_list *names, const char *packtmp);
80+
7781
#endif /* REPACK_H */

0 commit comments

Comments
 (0)