object-store: move and rename `odb_pack_keep()`

The function `odb_pack_keep()` creates a file at the passed-in path. If this fails, then the function re-tries by first creating any potentially missing leading directories and then trying to create the file once again. As such, this function doesn't host any kind of logic that is specific to the object store, but is rather a generic helper function. Rename the function to `safe_create_file_with_leading_directories()` and move it into "path.c". While at it, refactor it so that it loses its dependency on `the_repository`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 29, 2025 at 09:52 UTC 0b8ed25b66aedc9f4fe44d1a5cab2719290b22a9
6 files changed +24 -22
builtin/fast-import.c
+2 -1
@@ -811,7 +811,8 @@ static char *keep_pack(const char *curr_index_name)
811 int keep_fd;
812
813 odb_pack_name(pack_data->repo, &name, pack_data->hash, "keep");
814 - keep_fd = odb_pack_keep(name.buf);
814 + keep_fd = safe_create_file_with_leading_directories(pack_data->repo,
815 + name.buf);
816 if (keep_fd < 0)
817 die_errno("cannot create keep file");
818 write_or_die(keep_fd, keep_msg, strlen(keep_msg));
builtin/index-pack.c
+1 -1
@@ -1565,7 +1565,7 @@ static void write_special_file(const char *suffix, const char *msg,
1565 else
1566 filename = odb_pack_name(the_repository, &name_buf, hash, suffix);
1567
1568 - fd = odb_pack_keep(filename);
1568 + fd = safe_create_file_with_leading_directories(the_repository, filename);
1569 if (fd < 0) {
1570 if (errno != EEXIST)
1571 die_errno(_("cannot write %s file '%s'"),
object-store.c
-13
@@ -83,19 +83,6 @@ int odb_mkstemp(struct strbuf *temp_filename, const char *pattern)
83 return xmkstemp_mode(temp_filename->buf, mode);
84 }
85
86 -int odb_pack_keep(const char *name)
87 -{
88 - int fd;
89 -
90 - fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
91 - if (0 <= fd)
92 - return fd;
93 -
94 - /* slow path */
95 - safe_create_leading_directories_const(the_repository, name);
96 - return open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
97 -}
98 -
86 /*
87 * Return non-zero iff the path is usable as an alternate object database.
88 */
object-store.h
-7
@@ -189,13 +189,6 @@ void raw_object_store_clear(struct raw_object_store *o);
189 */
190 int odb_mkstemp(struct strbuf *temp_filename, const char *pattern);
191
192 -/*
193 - * Create a pack .keep file named "name" (which should generally be the output
194 - * of odb_pack_name). Returns a file descriptor opened for writing, or -1 on
195 - * error.
196 - */
197 -int odb_pack_keep(const char *name);
198 -
192 void *map_loose_object(struct repository *r, const struct object_id *oid,
193 unsigned long *size);
194
path.c
+14
@@ -1011,6 +1011,20 @@ enum scld_error safe_create_leading_directories_const(struct repository *repo,
1011 return result;
1012 }
1013
1014 +int safe_create_file_with_leading_directories(struct repository *repo,
1015 + const char *path)
1016 +{
1017 + int fd;
1018 +
1019 + fd = open(path, O_RDWR|O_CREAT|O_EXCL, 0600);
1020 + if (0 <= fd)
1021 + return fd;
1022 +
1023 + /* slow path */
1024 + safe_create_leading_directories_const(repo, path);
1025 + return open(path, O_RDWR|O_CREAT|O_EXCL, 0600);
1026 +}
1027 +
1028 static int have_same_root(const char *path1, const char *path2)
1029 {
1030 int is_abs1, is_abs2;
path.h
+7
@@ -266,6 +266,13 @@ enum scld_error safe_create_leading_directories_const(struct repository *repo,
266 const char *path);
267 enum scld_error safe_create_leading_directories_no_share(char *path);
268
269 +/*
270 + * Create a file, potentially creating its leading directories in case they
271 + * don't exist. Returns the return value of the open(3p) call.
272 + */
273 +int safe_create_file_with_leading_directories(struct repository *repo,
274 + const char *path);
275 +
276 # ifdef USE_THE_REPOSITORY_VARIABLE
277 # include "strbuf.h"
278 # include "repository.h"