path: adjust last remaining users of `the_repository`

With the preceding refactorings we now only have a couple of implicit users of `the_repository` left in the "path" subsystem, all of which depend on global state via `calc_shared_perm()`. Make the dependency on `the_repository` explicit by passing the repo as a parameter instead and adjust callers accordingly. Note that this change bubbles up into a couple of subsystems that were previously declared as free from `the_repository`. Instead of marking all of them as `the_repository`-dependent again, we instead use the repository that is available in the calling context. There are three exceptions though with "copy.c", "pack-write.c" and "tempfile.c". Adjusting these would require us to adapt callsites all over the place, so this is left for a future iteration. Mark "path.c" as free from `the_repository`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Feb 7, 2025 at 12:03 UTC 028f618658e34230e1d65678f14b6876e0f9856d
17 files changed +64 -56
builtin/clone.c
+1 -1
@@ -1220,7 +1220,7 @@ int cmd_clone(int argc,
1220
1221 strbuf_reset(&buf);
1222 strbuf_addf(&buf, "%s/refs", git_dir);
1223 - safe_create_dir(buf.buf, 1);
1223 + safe_create_dir(the_repository, buf.buf, 1);
1224
1225 /*
1226 * additional config can be injected with -c, make sure it's included
commit-graph.c
+1 -1
@@ -2084,7 +2084,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
2084 return -1;
2085 }
2086
2087 - if (adjust_shared_perm(get_tempfile_path(graph_layer))) {
2087 + if (adjust_shared_perm(the_repository, get_tempfile_path(graph_layer))) {
2088 error(_("unable to adjust shared permissions for '%s'"),
2089 get_tempfile_path(graph_layer));
2090 return -1;
copy.c
+3 -1
@@ -1,3 +1,5 @@
1 +#define USE_THE_REPOSITORY_VARIABLE
2 +
3 #include "git-compat-util.h"
4 #include "copy.h"
5 #include "path.h"
@@ -57,7 +59,7 @@ int copy_file(const char *dst, const char *src, int mode)
59 if (close(fdo) != 0)
60 return error_errno("%s: close error", dst);
61
60 - if (!status && adjust_shared_perm(dst))
62 + if (!status && adjust_shared_perm(the_repository, dst))
63 return -1;
64
65 return status;
loose.c
+1 -1
@@ -190,7 +190,7 @@ static int write_one_object(struct repository *repo, const struct object_id *oid
190 goto errout;
191 if (close(fd))
192 goto errout;
193 - adjust_shared_perm(path.buf);
193 + adjust_shared_perm(repo, path.buf);
194 rollback_lock_file(&lock);
195 strbuf_release(&buf);
196 strbuf_release(&path);
midx-write.c
+1 -1
@@ -1336,7 +1336,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
1336 return -1;
1337 }
1338
1339 - if (adjust_shared_perm(get_tempfile_path(incr))) {
1339 + if (adjust_shared_perm(r, get_tempfile_path(incr))) {
1340 error(_("unable to adjust shared permissions for '%s'"),
1341 get_tempfile_path(incr));
1342 return -1;
object-file.c
+4 -4
@@ -388,7 +388,7 @@ int mkdir_in_gitdir(const char *path)
388 }
389 strbuf_release(&sb);
390 }
391 - return adjust_shared_perm(path);
391 + return adjust_shared_perm(the_repository, path);
392 }
393
394 static enum scld_error safe_create_leading_directories_1(char *path, int share)
@@ -437,7 +437,7 @@ static enum scld_error safe_create_leading_directories_1(char *path, int share)
437 ret = SCLD_VANISHED;
438 else
439 ret = SCLD_FAILED;
440 - } else if (share && adjust_shared_perm(path)) {
440 + } else if (share && adjust_shared_perm(the_repository, path)) {
441 ret = SCLD_PERMS;
442 }
443 *slash = slash_character;
@@ -2105,7 +2105,7 @@ retry:
2105 }
2106
2107 out:
2108 - if (adjust_shared_perm(filename))
2108 + if (adjust_shared_perm(the_repository, filename))
2109 return error(_("unable to set permission to '%s'"), filename);
2110 return 0;
2111 }
@@ -2181,7 +2181,7 @@ static int create_tmpfile(struct strbuf *tmp, const char *filename)
2181 strbuf_add(tmp, filename, dirlen - 1);
2182 if (mkdir(tmp->buf, 0777) && errno != EEXIST)
2183 return -1;
2184 - if (adjust_shared_perm(tmp->buf))
2184 + if (adjust_shared_perm(the_repository, tmp->buf))
2185 return -1;
2186
2187 /* Try again */
pack-bitmap-write.c
+1 -1
@@ -1072,7 +1072,7 @@ void bitmap_writer_finish(struct bitmap_writer *writer,
1072 finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
1073 CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE);
1074
1075 - if (adjust_shared_perm(tmp_file.buf))
1075 + if (adjust_shared_perm(the_repository, tmp_file.buf))
1076 die_errno("unable to make temporary bitmap file readable");
1077
1078 if (rename(tmp_file.buf, filename))
pack-write.c
+6 -4
@@ -1,3 +1,5 @@
1 +#define USE_THE_REPOSITORY_VARIABLE
2 +
3 #include "git-compat-util.h"
4 #include "environment.h"
5 #include "gettext.h"
@@ -287,7 +289,7 @@ char *write_rev_file_order(const struct git_hash_algo *hash_algo,
289 write_rev_index_positions(f, pack_order, nr_objects);
290 write_rev_trailer(hash_algo, f, hash);
291
290 - if (adjust_shared_perm(path) < 0)
292 + if (adjust_shared_perm(the_repository, path) < 0)
293 die(_("failed to make %s readable"), path);
294
295 finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
@@ -350,7 +352,7 @@ static char *write_mtimes_file(const struct git_hash_algo *hash_algo,
352 write_mtimes_objects(f, to_pack, objects, nr_objects);
353 write_mtimes_trailer(hash_algo, f, hash);
354
353 - if (adjust_shared_perm(mtimes_name) < 0)
355 + if (adjust_shared_perm(the_repository, mtimes_name) < 0)
356 die(_("failed to make %s readable"), mtimes_name);
357
358 finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
@@ -565,12 +567,12 @@ void stage_tmp_packfiles(const struct git_hash_algo *hash_algo,
567 char *rev_tmp_name = NULL;
568 char *mtimes_tmp_name = NULL;
569
568 - if (adjust_shared_perm(pack_tmp_name))
570 + if (adjust_shared_perm(the_repository, pack_tmp_name))
571 die_errno("unable to make temporary pack file readable");
572
573 *idx_tmp_name = (char *)write_idx_file(hash_algo, NULL, written_list,
574 nr_written, pack_idx_opts, hash);
573 - if (adjust_shared_perm(*idx_tmp_name))
575 + if (adjust_shared_perm(the_repository, *idx_tmp_name))
576 die_errno("unable to make temporary index file readable");
577
578 rev_tmp_name = write_rev_file(hash_algo, NULL, written_list, nr_written,
path.c
+12 -13
@@ -2,8 +2,6 @@
2 * Utilities for paths and pathnames
3 */
4
5 -#define USE_THE_REPOSITORY_VARIABLE
6 -
5 #include "git-compat-util.h"
6 #include "abspath.h"
7 #include "environment.h"
@@ -840,21 +838,22 @@ const char *enter_repo(const char *path, unsigned flags)
838 return NULL;
839 }
840
843 -int calc_shared_perm(int mode)
841 +int calc_shared_perm(struct repository *repo,
842 + int mode)
843 {
844 int tweak;
845
847 - if (repo_settings_get_shared_repository(the_repository) < 0)
848 - tweak = -repo_settings_get_shared_repository(the_repository);
846 + if (repo_settings_get_shared_repository(repo) < 0)
847 + tweak = -repo_settings_get_shared_repository(repo);
848 else
850 - tweak = repo_settings_get_shared_repository(the_repository);
849 + tweak = repo_settings_get_shared_repository(repo);
850
851 if (!(mode & S_IWUSR))
852 tweak &= ~0222;
853 if (mode & S_IXUSR)
854 /* Copy read bits to execute bits */
855 tweak |= (tweak & 0444) >> 2;
857 - if (repo_settings_get_shared_repository(the_repository) < 0)
856 + if (repo_settings_get_shared_repository(repo) < 0)
857 mode = (mode & ~0777) | tweak;
858 else
859 mode |= tweak;
@@ -862,17 +861,17 @@ int calc_shared_perm(int mode)
861 return mode;
862 }
863
865 -
866 -int adjust_shared_perm(const char *path)
864 +int adjust_shared_perm(struct repository *repo,
865 + const char *path)
866 {
867 int old_mode, new_mode;
868
870 - if (!repo_settings_get_shared_repository(the_repository))
869 + if (!repo_settings_get_shared_repository(repo))
870 return 0;
871 if (get_st_mode_bits(path, &old_mode) < 0)
872 return -1;
873
875 - new_mode = calc_shared_perm(old_mode);
874 + new_mode = calc_shared_perm(repo, old_mode);
875 if (S_ISDIR(old_mode)) {
876 /* Copy read bits to execute bits */
877 new_mode |= (new_mode & 0444) >> 2;
@@ -891,7 +890,7 @@ int adjust_shared_perm(const char *path)
890 return 0;
891 }
892
894 -void safe_create_dir(const char *dir, int share)
893 +void safe_create_dir(struct repository *repo, const char *dir, int share)
894 {
895 if (mkdir(dir, 0777) < 0) {
896 if (errno != EEXIST) {
@@ -899,7 +898,7 @@ void safe_create_dir(const char *dir, int share)
898 exit(1);
899 }
900 }
902 - else if (share && adjust_shared_perm(dir))
901 + else if (share && adjust_shared_perm(repo, dir))
902 die(_("Could not make %s writable by group"), dir);
903 }
904
path.h
+3 -3
@@ -141,8 +141,8 @@ const char *git_path_shallow(struct repository *r);
141
142 int ends_with_path_components(const char *path, const char *components);
143
144 -int calc_shared_perm(int mode);
145 -int adjust_shared_perm(const char *path);
144 +int calc_shared_perm(struct repository *repo, int mode);
145 +int adjust_shared_perm(struct repository *repo, const char *path);
146
147 char *interpolate_path(const char *path, int real_home);
148
@@ -219,7 +219,7 @@ char *xdg_cache_home(const char *filename);
219 * directories under $GIT_DIR. Don't use it for working tree
220 * directories.
221 */
222 -void safe_create_dir(const char *dir, int share);
222 +void safe_create_dir(struct repository *repo, const char *dir, int share);
223
224 # ifdef USE_THE_REPOSITORY_VARIABLE
225 # include "strbuf.h"
read-cache.c
+1 -1
@@ -3290,7 +3290,7 @@ static int write_shared_index(struct index_state *istate,
3290
3291 if (ret)
3292 return ret;
3293 - ret = adjust_shared_perm(get_tempfile_path(*temp));
3293 + ret = adjust_shared_perm(the_repository, get_tempfile_path(*temp));
3294 if (ret) {
3295 error(_("cannot fix permission bits on '%s'"), get_tempfile_path(*temp));
3296 return ret;
refs/files-backend.c
+5 -5
@@ -1831,7 +1831,7 @@ static int log_ref_setup(struct files_ref_store *refs,
1831 }
1832
1833 if (*logfd >= 0)
1834 - adjust_shared_perm(logfile);
1834 + adjust_shared_perm(the_repository, logfile);
1835
1836 free(logfile);
1837 return 0;
@@ -3488,8 +3488,8 @@ static int files_ref_store_create_on_disk(struct ref_store *ref_store,
3488 * they do not understand the reference format extension.
3489 */
3490 strbuf_addf(&sb, "%s/refs", ref_store->gitdir);
3491 - safe_create_dir(sb.buf, 1);
3492 - adjust_shared_perm(sb.buf);
3491 + safe_create_dir(the_repository, sb.buf, 1);
3492 + adjust_shared_perm(the_repository, sb.buf);
3493
3494 /*
3495 * There is no need to create directories for common refs when creating
@@ -3501,11 +3501,11 @@ static int files_ref_store_create_on_disk(struct ref_store *ref_store,
3501 */
3502 strbuf_reset(&sb);
3503 files_ref_path(refs, &sb, "refs/heads");
3504 - safe_create_dir(sb.buf, 1);
3504 + safe_create_dir(the_repository, sb.buf, 1);
3505
3506 strbuf_reset(&sb);
3507 files_ref_path(refs, &sb, "refs/tags");
3508 - safe_create_dir(sb.buf, 1);
3508 + safe_create_dir(the_repository, sb.buf, 1);
3509 }
3510
3511 strbuf_release(&sb);
refs/reftable-backend.c
+5 -5
@@ -380,7 +380,7 @@ static struct ref_store *reftable_be_init(struct repository *repo,
380 default:
381 BUG("unknown hash algorithm %d", repo->hash_algo->format_id);
382 }
383 - refs->write_options.default_permissions = calc_shared_perm(0666 & ~mask);
383 + refs->write_options.default_permissions = calc_shared_perm(the_repository, 0666 & ~mask);
384 refs->write_options.disable_auto_compact =
385 !git_env_bool("GIT_TEST_REFTABLE_AUTOCOMPACTION", 1);
386 refs->write_options.lock_timeout_ms = 100;
@@ -470,21 +470,21 @@ static int reftable_be_create_on_disk(struct ref_store *ref_store,
470 struct strbuf sb = STRBUF_INIT;
471
472 strbuf_addf(&sb, "%s/reftable", refs->base.gitdir);
473 - safe_create_dir(sb.buf, 1);
473 + safe_create_dir(the_repository, sb.buf, 1);
474 strbuf_reset(&sb);
475
476 strbuf_addf(&sb, "%s/HEAD", refs->base.gitdir);
477 write_file(sb.buf, "ref: refs/heads/.invalid");
478 - adjust_shared_perm(sb.buf);
478 + adjust_shared_perm(the_repository, sb.buf);
479 strbuf_reset(&sb);
480
481 strbuf_addf(&sb, "%s/refs", refs->base.gitdir);
482 - safe_create_dir(sb.buf, 1);
482 + safe_create_dir(the_repository, sb.buf, 1);
483 strbuf_reset(&sb);
484
485 strbuf_addf(&sb, "%s/refs/heads", refs->base.gitdir);
486 write_file(sb.buf, "this repository uses the reftable format");
487 - adjust_shared_perm(sb.buf);
487 + adjust_shared_perm(the_repository, sb.buf);
488
489 strbuf_release(&sb);
490 return 0;
server-info.c
+1 -1
@@ -125,7 +125,7 @@ static int update_info_file(struct repository *r, char *path,
125 uic.cur_fp = NULL;
126
127 if (uic_is_stale(&uic)) {
128 - if (adjust_shared_perm(get_tempfile_path(f)) < 0)
128 + if (adjust_shared_perm(r, get_tempfile_path(f)) < 0)
129 goto out;
130 if (rename_tempfile(&f, path) < 0)
131 goto out;
setup.c
+6 -6
@@ -2088,7 +2088,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
2088 * with the way the namespace under .git/ is organized, should
2089 * be really carefully chosen.
2090 */
2091 - safe_create_dir(path->buf, 1);
2091 + safe_create_dir(the_repository, path->buf, 1);
2092 while ((de = readdir(dir)) != NULL) {
2093 struct stat st_git, st_template;
2094 int exists = 0;
@@ -2352,7 +2352,7 @@ static int create_default_files(const char *template_path,
2352 * shared-repository settings, we would need to fix them up.
2353 */
2354 if (repo_settings_get_shared_repository(the_repository)) {
2355 - adjust_shared_perm(repo_get_git_dir(the_repository));
2355 + adjust_shared_perm(the_repository, repo_get_git_dir(the_repository));
2356 }
2357
2358 initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit);
@@ -2413,15 +2413,15 @@ static void create_object_directory(void)
2413 strbuf_addstr(&path, repo_get_object_directory(the_repository));
2414 baselen = path.len;
2415
2416 - safe_create_dir(path.buf, 1);
2416 + safe_create_dir(the_repository, path.buf, 1);
2417
2418 strbuf_setlen(&path, baselen);
2419 strbuf_addstr(&path, "/pack");
2420 - safe_create_dir(path.buf, 1);
2420 + safe_create_dir(the_repository, path.buf, 1);
2421
2422 strbuf_setlen(&path, baselen);
2423 strbuf_addstr(&path, "/info");
2424 - safe_create_dir(path.buf, 1);
2424 + safe_create_dir(the_repository, path.buf, 1);
2425
2426 strbuf_release(&path);
2427 }
@@ -2588,7 +2588,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
2588 */
2589 git_config(platform_core_config, NULL);
2590
2591 - safe_create_dir(git_dir, 0);
2591 + safe_create_dir(the_repository, git_dir, 0);
2592
2593 reinit = create_default_files(template_dir, original_git_dir,
2594 &repo_fmt, init_shared_repository);
tempfile.c
+3 -1
@@ -42,6 +42,8 @@
42 * file created by its parent.
43 */
44
45 +#define USE_THE_REPOSITORY_VARIABLE
46 +
47 #include "git-compat-util.h"
48 #include "abspath.h"
49 #include "path.h"
@@ -148,7 +150,7 @@ struct tempfile *create_tempfile_mode(const char *path, int mode)
150 return NULL;
151 }
152 activate_tempfile(tempfile);
151 - if (adjust_shared_perm(tempfile->filename.buf)) {
153 + if (adjust_shared_perm(the_repository, tempfile->filename.buf)) {
154 int save_errno = errno;
155 error("cannot fix permission bits on %s", tempfile->filename.buf);
156 delete_tempfile(&tempfile);
tmp-objdir.c
+10 -7
@@ -207,10 +207,12 @@ static int read_dir_paths(struct string_list *out, const char *path)
207 return 0;
208 }
209
210 -static int migrate_paths(struct strbuf *src, struct strbuf *dst,
210 +static int migrate_paths(struct tmp_objdir *t,
211 + struct strbuf *src, struct strbuf *dst,
212 enum finalize_object_file_flags flags);
213
213 -static int migrate_one(struct strbuf *src, struct strbuf *dst,
214 +static int migrate_one(struct tmp_objdir *t,
215 + struct strbuf *src, struct strbuf *dst,
216 enum finalize_object_file_flags flags)
217 {
218 struct stat st;
@@ -219,11 +221,11 @@ static int migrate_one(struct strbuf *src, struct strbuf *dst,
221 return -1;
222 if (S_ISDIR(st.st_mode)) {
223 if (!mkdir(dst->buf, 0777)) {
222 - if (adjust_shared_perm(dst->buf))
224 + if (adjust_shared_perm(t->repo, dst->buf))
225 return -1;
226 } else if (errno != EEXIST)
227 return -1;
226 - return migrate_paths(src, dst, flags);
228 + return migrate_paths(t, src, dst, flags);
229 }
230 return finalize_object_file_flags(src->buf, dst->buf, flags);
231 }
@@ -233,7 +235,8 @@ static int is_loose_object_shard(const char *name)
235 return strlen(name) == 2 && isxdigit(name[0]) && isxdigit(name[1]);
236 }
237
236 -static int migrate_paths(struct strbuf *src, struct strbuf *dst,
238 +static int migrate_paths(struct tmp_objdir *t,
239 + struct strbuf *src, struct strbuf *dst,
240 enum finalize_object_file_flags flags)
241 {
242 size_t src_len = src->len, dst_len = dst->len;
@@ -255,7 +258,7 @@ static int migrate_paths(struct strbuf *src, struct strbuf *dst,
258 if (is_loose_object_shard(name))
259 flags_copy |= FOF_SKIP_COLLISION_CHECK;
260
258 - ret |= migrate_one(src, dst, flags_copy);
261 + ret |= migrate_one(t, src, dst, flags_copy);
262
263 strbuf_setlen(src, src_len);
264 strbuf_setlen(dst, dst_len);
@@ -283,7 +286,7 @@ int tmp_objdir_migrate(struct tmp_objdir *t)
286 strbuf_addbuf(&src, &t->path);
287 strbuf_addstr(&dst, repo_get_object_directory(t->repo));
288
286 - ret = migrate_paths(&src, &dst, 0);
289 + ret = migrate_paths(t, &src, &dst, 0);
290
291 strbuf_release(&src);
292 strbuf_release(&dst);