alternates: provide helper for allocating alternate

Allocating a struct alternate_object_database is tricky, as
we must over-allocate the buffer to provide scratch space,
and then put in particular '/' and NUL markers.

Let's encapsulate this in a function so that the complexity
doesn't leak into callers (and so that we can modify it
later).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2016-10-03 16:35:31 -04:00 коммит произвёл Junio C Hamano
Родитель a5b34d2152
Коммит 7f0fa2c02a
3 изменённых файлов: 26 добавлений и 15 удалений

Просмотреть файл

@ -1392,6 +1392,12 @@ extern char *compute_alternate_path(const char *path, struct strbuf *err);
typedef int alt_odb_fn(struct alternate_object_database *, void *);
extern int foreach_alt_odb(alt_odb_fn, void*);
/*
* Allocate a "struct alternate_object_database" but do _not_ actually
* add it to the list of alternates.
*/
struct alternate_object_database *alloc_alt_odb(const char *dir);
/*
* Add the directory to the on-disk alternates file; the new entry will also
* take effect in the current process.

Просмотреть файл

@ -283,7 +283,6 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
int depth, const char *normalized_objdir)
{
struct alternate_object_database *ent;
size_t entlen;
struct strbuf pathbuf = STRBUF_INIT;
if (!is_absolute_path(entry) && relative_base) {
@ -311,14 +310,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
return -1;
}
entlen = st_add(pathbuf.len, 43); /* '/' + 2 hex + '/' + 38 hex + NUL */
ent = xmalloc(st_add(sizeof(*ent), entlen));
memcpy(ent->base, pathbuf.buf, pathbuf.len);
ent->name = ent->base + pathbuf.len + 1;
ent->base[pathbuf.len] = '/';
ent->base[pathbuf.len + 3] = '/';
ent->base[entlen-1] = 0;
ent = alloc_alt_odb(pathbuf.buf);
/* add the alternate entry */
*alt_odb_tail = ent;
@ -395,6 +387,24 @@ void read_info_alternates(const char * relative_base, int depth)
munmap(map, mapsz);
}
struct alternate_object_database *alloc_alt_odb(const char *dir)
{
struct alternate_object_database *ent;
size_t dirlen = strlen(dir);
size_t entlen;
entlen = st_add(dirlen, 43); /* '/' + 2 hex + '/' + 38 hex + NUL */
ent = xmalloc(st_add(sizeof(*ent), entlen));
memcpy(ent->base, dir, dirlen);
ent->name = ent->base + dirlen + 1;
ent->base[dirlen] = '/';
ent->base[dirlen + 3] = '/';
ent->base[entlen-1] = 0;
return ent;
}
void add_to_alternates_file(const char *reference)
{
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));

Просмотреть файл

@ -86,12 +86,7 @@ static void find_short_object_filename(int len, const char *hex_pfx, struct disa
* alt->name/alt->base while iterating over the
* object databases including our own.
*/
const char *objdir = get_object_directory();
size_t objdir_len = strlen(objdir);
fakeent = xmalloc(st_add3(sizeof(*fakeent), objdir_len, 43));
memcpy(fakeent->base, objdir, objdir_len);
fakeent->name = fakeent->base + objdir_len + 1;
fakeent->name[-1] = '/';
fakeent = alloc_alt_odb(get_object_directory());
}
fakeent->next = alt_odb_list;