object-file: move `mkdir_in_gitdir()` into "path.c"

The `mkdir_in_gitdir()` function is similar to `safe_create_dir()`, but the former is hosted in "object-file.c" whereas the latter is hosted in "path.c". The latter code unit makes way more sense though as the logic has nothing to do with object files in particular. Move the file into "path.c". While at it, we: - Rename the function to `safe_create_dir_in_gitdir()` so that the function names are similar to one another. - Remove the dependency on `the_repository` by making the callers pass the repository instead. Adjust callers accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Apr 15, 2025 at 11:38 UTC d1fa670de07ec9d08fc1333b3addf746c7d304e2
6 files changed +47 -36
builtin/rebase.c
+2 -1
@@ -267,7 +267,8 @@ static int init_basic_state(struct replay_opts *opts, const char *head_name,
267 {
268 FILE *interactive;
269
270 - if (!is_directory(merge_dir()) && mkdir_in_gitdir(merge_dir()))
270 + if (!is_directory(merge_dir()) &&
271 + safe_create_dir_in_gitdir(the_repository, merge_dir()))
272 return error_errno(_("could not create temporary %s"), merge_dir());
273
274 refs_delete_reflog(get_main_ref_store(the_repository), "REBASE_HEAD");
object-file.c
+2 -31
@@ -90,36 +90,6 @@ static int get_conv_flags(unsigned flags)
90 return 0;
91 }
92
93 -
94 -int mkdir_in_gitdir(const char *path)
95 -{
96 - if (mkdir(path, 0777)) {
97 - int saved_errno = errno;
98 - struct stat st;
99 - struct strbuf sb = STRBUF_INIT;
100 -
101 - if (errno != EEXIST)
102 - return -1;
103 - /*
104 - * Are we looking at a path in a symlinked worktree
105 - * whose original repository does not yet have it?
106 - * e.g. .git/rr-cache pointing at its original
107 - * repository in which the user hasn't performed any
108 - * conflict resolution yet?
109 - */
110 - if (lstat(path, &st) || !S_ISLNK(st.st_mode) ||
111 - strbuf_readlink(&sb, path, st.st_size) ||
112 - !is_absolute_path(sb.buf) ||
113 - mkdir(sb.buf, 0777)) {
114 - strbuf_release(&sb);
115 - errno = saved_errno;
116 - return -1;
117 - }
118 - strbuf_release(&sb);
119 - }
120 - return adjust_shared_perm(the_repository, path);
121 -}
122 -
93 static enum scld_error safe_create_leading_directories_1(char *path, int share)
94 {
95 char *next_component = path + offset_1st_component(path);
@@ -2196,7 +2166,8 @@ int stream_loose_object(struct input_stream *in_stream, size_t len,
2166 struct strbuf dir = STRBUF_INIT;
2167 strbuf_add(&dir, filename.buf, dirlen);
2168
2199 - if (mkdir_in_gitdir(dir.buf) && errno != EEXIST) {
2169 + if (safe_create_dir_in_gitdir(the_repository, dir.buf) &&
2170 + errno != EEXIST) {
2171 err = error_errno(_("unable to create directory %s"), dir.buf);
2172 strbuf_release(&dir);
2173 goto cleanup;
object-file.h
-2
@@ -54,8 +54,6 @@ enum scld_error safe_create_leading_directories(char *path);
54 enum scld_error safe_create_leading_directories_const(const char *path);
55 enum scld_error safe_create_leading_directories_no_share(char *path);
56
57 -int mkdir_in_gitdir(const char *path);
58 -
57 int git_open_cloexec(const char *name, int flags);
58 #define git_open(name) git_open_cloexec(name, O_RDONLY)
59
path.c
+29
@@ -902,6 +902,35 @@ void safe_create_dir(struct repository *repo, const char *dir, int share)
902 die(_("Could not make %s writable by group"), dir);
903 }
904
905 +int safe_create_dir_in_gitdir(struct repository *repo, const char *path)
906 +{
907 + if (mkdir(path, 0777)) {
908 + int saved_errno = errno;
909 + struct stat st;
910 + struct strbuf sb = STRBUF_INIT;
911 +
912 + if (errno != EEXIST)
913 + return -1;
914 + /*
915 + * Are we looking at a path in a symlinked worktree
916 + * whose original repository does not yet have it?
917 + * e.g. .git/rr-cache pointing at its original
918 + * repository in which the user hasn't performed any
919 + * conflict resolution yet?
920 + */
921 + if (lstat(path, &st) || !S_ISLNK(st.st_mode) ||
922 + strbuf_readlink(&sb, path, st.st_size) ||
923 + !is_absolute_path(sb.buf) ||
924 + mkdir(sb.buf, 0777)) {
925 + strbuf_release(&sb);
926 + errno = saved_errno;
927 + return -1;
928 + }
929 + strbuf_release(&sb);
930 + }
931 + return adjust_shared_perm(repo, path);
932 +}
933 +
934 static int have_same_root(const char *path1, const char *path2)
935 {
936 int is_abs1, is_abs2;
path.h
+11
@@ -221,6 +221,17 @@ char *xdg_cache_home(const char *filename);
221 */
222 void safe_create_dir(struct repository *repo, const char *dir, int share);
223
224 +/*
225 + * Similar to `safe_create_dir()`, but with two differences:
226 + *
227 + * - It knows to resolve gitlink files for symlinked worktrees.
228 + *
229 + * - It always adjusts shared permissions.
230 + *
231 + * Returns a negative erorr code on error, 0 on success.
232 + */
233 +int safe_create_dir_in_gitdir(struct repository *repo, const char *path);
234 +
235 # ifdef USE_THE_REPOSITORY_VARIABLE
236 # include "strbuf.h"
237 # include "repository.h"
rerere.c
+3 -2
@@ -860,7 +860,7 @@ static int do_plain_rerere(struct repository *r,
860 string_list_insert(rr, path)->util = id;
861
862 /* Ensure that the directory exists. */
863 - mkdir_in_gitdir(rerere_path(&buf, id, NULL));
863 + safe_create_dir_in_gitdir(the_repository, rerere_path(&buf, id, NULL));
864 }
865
866 for (i = 0; i < rr->nr; i++)
@@ -895,7 +895,8 @@ static int is_rerere_enabled(void)
895 if (rerere_enabled < 0)
896 return rr_cache_exists;
897
898 - if (!rr_cache_exists && mkdir_in_gitdir(git_path_rr_cache()))
898 + if (!rr_cache_exists &&
899 + safe_create_dir_in_gitdir(the_repository, git_path_rr_cache()))
900 die(_("could not create directory '%s'"), git_path_rr_cache());
901 return 1;
902 }