summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cache.h13
-rw-r--r--sha1_file.c28
-rw-r--r--sha1_name.c9
3 files changed, 32 insertions, 18 deletions
diff --git a/cache.h b/cache.h
index 555ba713de..5d36ffa1f2 100644
--- a/cache.h
+++ b/cache.h
@@ -1384,8 +1384,9 @@ extern void remove_scheduled_dirs(void);
extern struct alternate_object_database {
struct alternate_object_database *next;
- char *name;
- char *scratch;
+ /* see alt_scratch_buf() */
+ struct strbuf scratch;
+ size_t base_len;
char path[FLEX_ARRAY];
} *alt_odb_list;
@@ -1414,6 +1415,14 @@ extern void add_to_alternates_file(const char *dir);
*/
extern void add_to_alternates_memory(const char *dir);
+/*
+ * Returns a scratch strbuf pre-filled with the alternate object directory,
+ * including a trailing slash, which can be used to access paths in the
+ * alternate. Always use this over direct access to alt->scratch, as it
+ * cleans up any previous use of the scratch buffer.
+ */
+extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);
+
struct pack_window {
struct pack_window *next;
unsigned char *base;
diff --git a/sha1_file.c b/sha1_file.c
index da7b922605..51d40241a7 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -204,11 +204,24 @@ const char *sha1_file_name(const unsigned char *sha1)
return buf;
}
+struct strbuf *alt_scratch_buf(struct alternate_object_database *alt)
+{
+ strbuf_setlen(&alt->scratch, alt->base_len);
+ return &alt->scratch;
+}
+
static const char *alt_sha1_path(struct alternate_object_database *alt,
const unsigned char *sha1)
{
- fill_sha1_path(alt->name, sha1);
- return alt->scratch;
+ /* hex sha1 plus internal "/" */
+ size_t len = GIT_SHA1_HEXSZ + 1;
+ struct strbuf *buf = alt_scratch_buf(alt);
+
+ strbuf_grow(buf, len);
+ fill_sha1_path(buf->buf + buf->len, sha1);
+ strbuf_setlen(buf, buf->len + len);
+
+ return buf->buf;
}
/*
@@ -396,16 +409,11 @@ void read_info_alternates(const char * relative_base, int depth)
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 */
FLEX_ALLOC_STR(ent, path, dir);
- ent->scratch = xmalloc(entlen);
- xsnprintf(ent->scratch, entlen, "%s/", dir);
-
- ent->name = ent->scratch + dirlen + 1;
- ent->scratch[dirlen] = '/';
+ strbuf_init(&ent->scratch, 0);
+ strbuf_addf(&ent->scratch, "%s/", dir);
+ ent->base_len = ent->scratch.len;
return ent;
}
diff --git a/sha1_name.c b/sha1_name.c
index 770ea4fe80..defbb3eb05 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -92,15 +92,12 @@ static void find_short_object_filename(int len, const char *hex_pfx, struct disa
xsnprintf(hex, sizeof(hex), "%.2s", hex_pfx);
for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {
+ struct strbuf *buf = alt_scratch_buf(alt);
struct dirent *de;
DIR *dir;
- /*
- * every alt_odb struct has 42 extra bytes after the base
- * for exactly this purpose
- */
- xsnprintf(alt->name, 42, "%.2s/", hex_pfx);
- dir = opendir(alt->scratch);
+ strbuf_addf(buf, "%.2s/", hex_pfx);
+ dir = opendir(buf->buf);
if (!dir)
continue;