In the following commits we will need some functions that were internal to sha1_file.c, so let's first make them non static and declare them in "cache.h". While at it, let's rename 'create_tmpfile()' to 'create_object_tmpfile()' to make its name less generic. Let's also split out 'sha1_file_name_alt()' from 'sha1_file_name()' and 'open_sha1_file_alt()' from 'open_sha1_file()', as we will need both of these new functions too. Helped-by: Jeff King <peff@xxxxxxxx> Signed-off-by: Christian Couder <chriscool@xxxxxxxxxxxxx> --- cache.h | 8 ++++++++ sha1_file.c | 49 ++++++++++++++++++++++++++++++------------------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/cache.h b/cache.h index 4aa0129cf8..e6fd9b97ec 100644 --- a/cache.h +++ b/cache.h @@ -951,6 +951,12 @@ extern void check_repository_format(void); */ extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1); +/* + * Like sha1_file_name, but put in `buf` the filename within a + * specific alternate object directory. + */ +extern void sha1_file_name_alt(struct strbuf *buf, const char *objdir, const unsigned char *sha1); + /* * Return an abbreviated sha1 unique within this repository's object database. * The result will be at least `len` characters long, and will be NUL @@ -1247,6 +1253,8 @@ extern int parse_sha1_header(const char *hdr, unsigned long *sizep); extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type); +extern int create_object_tmpfile(struct strbuf *tmp, const char *filename); +extern void close_sha1_file(int fd); extern int finalize_object_file(const char *tmpfile, const char *filename); /* diff --git a/sha1_file.c b/sha1_file.c index f2e078e840..c460eb2658 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -320,13 +320,18 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1) } } -void sha1_file_name(struct strbuf *buf, const unsigned char *sha1) +void sha1_file_name_alt(struct strbuf *buf, const char *objdir, const unsigned char *sha1) { - strbuf_addstr(buf, get_object_directory()); + strbuf_addstr(buf, objdir); strbuf_addch(buf, '/'); fill_sha1_path(buf, sha1); } +void sha1_file_name(struct strbuf *buf, const unsigned char *sha1) +{ + return sha1_file_name_alt(buf, get_object_directory(), sha1); +} + struct strbuf *alt_scratch_buf(struct alternate_object_database *alt) { strbuf_setlen(&alt->scratch, alt->base_len); @@ -905,6 +910,25 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st, return -1; } +static int open_sha1_file_alt(const unsigned char *sha1, const char **path) +{ + struct alternate_object_database *alt; + int most_interesting_errno = errno; + + prepare_alt_odb(); + for (alt = alt_odb_list; alt; alt = alt->next) { + int fd; + *path = alt_sha1_path(alt, sha1); + fd = git_open(*path); + if (fd >= 0) + return fd; + if (most_interesting_errno == ENOENT) + most_interesting_errno = errno; + } + errno = most_interesting_errno; + return -1; +} + /* * Like stat_sha1_file(), but actually open the object and return the * descriptor. See the caveats on the "path" parameter above. @@ -912,8 +936,6 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st, static int open_sha1_file(const unsigned char *sha1, const char **path) { int fd; - struct alternate_object_database *alt; - int most_interesting_errno; static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); @@ -923,19 +945,8 @@ static int open_sha1_file(const unsigned char *sha1, const char **path) fd = git_open(*path); if (fd >= 0) return fd; - most_interesting_errno = errno; - prepare_alt_odb(); - for (alt = alt_odb_list; alt; alt = alt->next) { - *path = alt_sha1_path(alt, sha1); - fd = git_open(*path); - if (fd >= 0) - return fd; - if (most_interesting_errno == ENOENT) - most_interesting_errno = errno; - } - errno = most_interesting_errno; - return -1; + return open_sha1_file_alt(sha1, path); } /* @@ -1537,7 +1548,7 @@ int hash_object_file(const void *buf, unsigned long len, const char *type, } /* Finalize a file on disk, and close it. */ -static void close_sha1_file(int fd) +void close_sha1_file(int fd) { if (fsync_object_files) fsync_or_die(fd, "sha1 file"); @@ -1561,7 +1572,7 @@ static inline int directory_size(const char *filename) * We want to avoid cross-directory filename renames, because those * can have problems on various filesystems (FAT, NFS, Coda). */ -static int create_tmpfile(struct strbuf *tmp, const char *filename) +int create_object_tmpfile(struct strbuf *tmp, const char *filename) { int fd, dirlen = directory_size(filename); @@ -1605,7 +1616,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr, strbuf_reset(&filename); sha1_file_name(&filename, oid->hash); - fd = create_tmpfile(&tmp_file, filename.buf); + fd = create_object_tmpfile(&tmp_file, filename.buf); if (fd < 0) { if (errno == EACCES) return error("insufficient permission for adding an object to repository database %s", get_object_directory()); -- 2.17.0.rc0.37.g8f476fabe9