Skip to content

Commit eb9635d

Browse files
pks-tgitster
authored andcommitted
odb/source: make write_alternate() function pluggable
Introduce a new callback function in `struct odb_source` to make the function pluggable. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 7ae2363 commit eb9635d

3 files changed

Lines changed: 82 additions & 52 deletions

File tree

odb.c

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -236,58 +236,6 @@ static struct odb_source *odb_add_alternate_recursively(struct object_database *
236236
return alternate;
237237
}
238238

239-
static int odb_source_write_alternate(struct odb_source *source,
240-
const char *alternate)
241-
{
242-
struct lock_file lock = LOCK_INIT;
243-
char *path = xstrfmt("%s/%s", source->path, "info/alternates");
244-
FILE *in, *out;
245-
int found = 0;
246-
int ret;
247-
248-
hold_lock_file_for_update(&lock, path, LOCK_DIE_ON_ERROR);
249-
out = fdopen_lock_file(&lock, "w");
250-
if (!out) {
251-
ret = error_errno(_("unable to fdopen alternates lockfile"));
252-
goto out;
253-
}
254-
255-
in = fopen(path, "r");
256-
if (in) {
257-
struct strbuf line = STRBUF_INIT;
258-
259-
while (strbuf_getline(&line, in) != EOF) {
260-
if (!strcmp(alternate, line.buf)) {
261-
found = 1;
262-
break;
263-
}
264-
fprintf_or_die(out, "%s\n", line.buf);
265-
}
266-
267-
strbuf_release(&line);
268-
fclose(in);
269-
} else if (errno != ENOENT) {
270-
ret = error_errno(_("unable to read alternates file"));
271-
goto out;
272-
}
273-
274-
if (found) {
275-
rollback_lock_file(&lock);
276-
} else {
277-
fprintf_or_die(out, "%s\n", alternate);
278-
if (commit_lock_file(&lock)) {
279-
ret = error_errno(_("unable to move new alternates file into place"));
280-
goto out;
281-
}
282-
}
283-
284-
ret = 0;
285-
286-
out:
287-
free(path);
288-
return ret;
289-
}
290-
291239
void odb_add_to_alternates_file(struct object_database *odb,
292240
const char *dir)
293241
{

odb/source-files.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#include "git-compat-util.h"
22
#include "abspath.h"
33
#include "chdir-notify.h"
4+
#include "gettext.h"
5+
#include "lockfile.h"
46
#include "object-file.h"
57
#include "odb.h"
68
#include "odb/source.h"
79
#include "odb/source-files.h"
810
#include "packfile.h"
911
#include "strbuf.h"
12+
#include "write-or-die.h"
1013

1114
static void odb_source_files_reparent(const char *name UNUSED,
1215
const char *old_cwd,
@@ -138,6 +141,58 @@ static int odb_source_files_read_alternates(struct odb_source *source,
138141
return 0;
139142
}
140143

144+
static int odb_source_files_write_alternate(struct odb_source *source,
145+
const char *alternate)
146+
{
147+
struct lock_file lock = LOCK_INIT;
148+
char *path = xstrfmt("%s/%s", source->path, "info/alternates");
149+
FILE *in, *out;
150+
int found = 0;
151+
int ret;
152+
153+
hold_lock_file_for_update(&lock, path, LOCK_DIE_ON_ERROR);
154+
out = fdopen_lock_file(&lock, "w");
155+
if (!out) {
156+
ret = error_errno(_("unable to fdopen alternates lockfile"));
157+
goto out;
158+
}
159+
160+
in = fopen(path, "r");
161+
if (in) {
162+
struct strbuf line = STRBUF_INIT;
163+
164+
while (strbuf_getline(&line, in) != EOF) {
165+
if (!strcmp(alternate, line.buf)) {
166+
found = 1;
167+
break;
168+
}
169+
fprintf_or_die(out, "%s\n", line.buf);
170+
}
171+
172+
strbuf_release(&line);
173+
fclose(in);
174+
} else if (errno != ENOENT) {
175+
ret = error_errno(_("unable to read alternates file"));
176+
goto out;
177+
}
178+
179+
if (found) {
180+
rollback_lock_file(&lock);
181+
} else {
182+
fprintf_or_die(out, "%s\n", alternate);
183+
if (commit_lock_file(&lock)) {
184+
ret = error_errno(_("unable to move new alternates file into place"));
185+
goto out;
186+
}
187+
}
188+
189+
ret = 0;
190+
191+
out:
192+
free(path);
193+
return ret;
194+
}
195+
141196
struct odb_source_files *odb_source_files_new(struct object_database *odb,
142197
const char *path,
143198
bool local)
@@ -159,6 +214,7 @@ struct odb_source_files *odb_source_files_new(struct object_database *odb,
159214
files->base.write_object = odb_source_files_write_object;
160215
files->base.write_object_stream = odb_source_files_write_object_stream;
161216
files->base.read_alternates = odb_source_files_read_alternates;
217+
files->base.write_alternate = odb_source_files_write_alternate;
162218

163219
/*
164220
* Ideally, we would only ever store absolute paths in the source. This

odb/source.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,19 @@ struct odb_source {
245245
*/
246246
int (*read_alternates)(struct odb_source *source,
247247
struct strvec *out);
248+
249+
/*
250+
* This callback is expected to persist the singular alternate passed
251+
* to it into its list of alternates. Any pre-existing alternates are
252+
* expected to remain active. Subsequent calls to `read_alternates` are
253+
* thus expected to yield the pre-existing list of alternates plus the
254+
* newly added alternate appended to its end.
255+
*
256+
* The callback is expected to return 0 on success, a negative error
257+
* code otherwise.
258+
*/
259+
int (*write_alternate)(struct odb_source *source,
260+
const char *alternate);
248261
};
249262

250263
/*
@@ -412,4 +425,17 @@ static inline int odb_source_read_alternates(struct odb_source *source,
412425
return source->read_alternates(source, out);
413426
}
414427

428+
/*
429+
* Write and persist a new alternate object database source for the given
430+
* source. Any preexisting alternates are expected to stay valid, and the new
431+
* alternate shall be appended to the end of the list.
432+
*
433+
* Returns 0 on success, a negative error code otherwise.
434+
*/
435+
static inline int odb_source_write_alternate(struct odb_source *source,
436+
const char *alternate)
437+
{
438+
return source->write_alternate(source, alternate);
439+
}
440+
415441
#endif

0 commit comments

Comments
 (0)