path: drop `git_common_path()` in favor of `repo_common_path()`
Remove `git_common_path()` in favor of the `repo_common_path()` family of functions, which makes the implicit dependency on `the_repository` go away. Note that `git_common_path()` used to return a string allocated via `get_pathname()`, which uses a rotating set of statically allocated buffers. Consequently, callers didn't have to free the returned string. The same isn't true for `repo_common_path()`, so we also have to add logic to free the returned strings. This refactoring also allows us to remove `repo_common_pathv()` from the public interface. 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
07242c2a5afb2a633feb110b1aa74e2adcc37575
4 files changed
+40
-35
builtin/worktree.c
+12
-4
@@ -151,7 +151,7 @@ static int delete_git_dir(const char *id)
151
struct strbuf sb = STRBUF_INIT;
152
int ret;
153
154
- strbuf_addstr(&sb, git_common_path("worktrees/%s", id));
154
+ repo_common_path_append(the_repository, &sb, "worktrees/%s", id);
155
ret = remove_dir_recursively(&sb, 0);
156
if (ret < 0 && errno == ENOTDIR)
157
ret = unlink(sb.buf);
@@ -1102,6 +1102,7 @@ static int lock_worktree(int ac, const char **av, const char *prefix,
1102
OPT_END()
1103
};
1104
struct worktree **worktrees, *wt;
1105
+ char *path;
1106
1107
ac = parse_options(ac, av, prefix, options, git_worktree_lock_usage, 0);
1108
if (ac != 1)
@@ -1122,9 +1123,11 @@ static int lock_worktree(int ac, const char **av, const char *prefix,
1123
die(_("'%s' is already locked"), av[0]);
1124
}
1125
1125
- write_file(git_common_path("worktrees/%s/locked", wt->id),
1126
- "%s", reason);
1126
+ path = repo_common_path(the_repository, "worktrees/%s/locked", wt->id);
1127
+ write_file(path, "%s", reason);
1128
+
1129
free_worktrees(worktrees);
1130
+ free(path);
1131
return 0;
1132
}
1133
@@ -1135,6 +1138,7 @@ static int unlock_worktree(int ac, const char **av, const char *prefix,
1138
OPT_END()
1139
};
1140
struct worktree **worktrees, *wt;
1141
+ char *path;
1142
int ret;
1143
1144
ac = parse_options(ac, av, prefix, options, git_worktree_unlock_usage, 0);
@@ -1149,8 +1153,12 @@ static int unlock_worktree(int ac, const char **av, const char *prefix,
1153
die(_("The main working tree cannot be locked or unlocked"));
1154
if (!worktree_lock_reason(wt))
1155
die(_("'%s' is not locked"), av[0]);
1152
- ret = unlink_or_warn(git_common_path("worktrees/%s/locked", wt->id));
1156
+
1157
+ path = repo_common_path(the_repository, "worktrees/%s/locked", wt->id);
1158
+ ret = unlink_or_warn(path);
1159
+
1160
free_worktrees(worktrees);
1161
+ free(path);
1162
return ret;
1163
}
1164
path.c
+4
-4
@@ -634,10 +634,10 @@ const char *repo_submodule_path_replace(struct repository *repo,
634
return buf->buf;
635
}
636
637
-void repo_common_pathv(const struct repository *repo,
638
- struct strbuf *sb,
639
- const char *fmt,
640
- va_list args)
637
+static void repo_common_pathv(const struct repository *repo,
638
+ struct strbuf *sb,
639
+ const char *fmt,
640
+ va_list args)
641
{
642
strbuf_addstr(sb, repo->commondir);
643
if (sb->len && !is_dir_sep(sb->buf[sb->len - 1]))
path.h
-19
@@ -233,29 +233,10 @@ struct strbuf *get_pathname(void);
233
# include "repository.h"
234
235
/* Internal implementation details that should not be used. */
236
-void repo_common_pathv(const struct repository *repo,
237
- struct strbuf *buf,
238
- const char *fmt,
239
- va_list args);
236
void repo_git_pathv(const struct repository *repo,
237
const struct worktree *wt, struct strbuf *buf,
238
const char *fmt, va_list args);
239
244
-/*
245
- * Return a statically allocated path into the main repository's
246
- * (the_repository) common git directory.
247
- */
248
-__attribute__((format (printf, 1, 2)))
249
-static inline const char *git_common_path(const char *fmt, ...)
250
-{
251
- struct strbuf *pathname = get_pathname();
252
- va_list args;
253
- va_start(args, fmt);
254
- repo_common_pathv(the_repository, pathname, fmt, args);
255
- va_end(args);
256
- return pathname->buf;
257
-}
258
-
240
/*
241
* Return a statically allocated path into the main repository's
242
* (the_repository) git directory.
worktree.c
+24
-8
@@ -183,7 +183,7 @@ char *get_worktree_git_dir(const struct worktree *wt)
183
else if (!wt->id)
184
return xstrdup(repo_get_common_dir(the_repository));
185
else
186
- return xstrdup(git_common_path("worktrees/%s", wt->id));
186
+ return repo_common_path(the_repository, "worktrees/%s", wt->id);
187
}
188
189
static struct worktree *find_worktree_by_suffix(struct worktree **list,
@@ -314,6 +314,7 @@ int validate_worktree(const struct worktree *wt, struct strbuf *errmsg,
314
{
315
struct strbuf wt_path = STRBUF_INIT;
316
struct strbuf realpath = STRBUF_INIT;
317
+ struct strbuf buf = STRBUF_INIT;
318
char *path = NULL;
319
int err, ret = -1;
320
@@ -343,7 +344,7 @@ int validate_worktree(const struct worktree *wt, struct strbuf *errmsg,
344
if (!is_absolute_path(wt->path)) {
345
strbuf_addf_gently(errmsg,
346
_("'%s' file does not contain absolute path to the working tree location"),
346
- git_common_path("worktrees/%s/gitdir", wt->id));
347
+ repo_common_path_replace(the_repository, &buf, "worktrees/%s/gitdir", wt->id));
348
goto done;
349
}
350
@@ -365,14 +366,16 @@ int validate_worktree(const struct worktree *wt, struct strbuf *errmsg,
366
goto done;
367
}
368
368
- strbuf_realpath(&realpath, git_common_path("worktrees/%s", wt->id), 1);
369
+ strbuf_realpath(&realpath, repo_common_path_replace(the_repository, &buf, "worktrees/%s", wt->id), 1);
370
ret = fspathcmp(path, realpath.buf);
371
372
if (ret)
373
strbuf_addf_gently(errmsg, _("'%s' does not point back to '%s'"),
373
- wt->path, git_common_path("worktrees/%s", wt->id));
374
+ wt->path, repo_common_path_replace(the_repository, &buf,
375
+ "worktrees/%s", wt->id));
376
done:
377
free(path);
378
+ strbuf_release(&buf);
379
strbuf_release(&wt_path);
380
strbuf_release(&realpath);
381
return ret;
@@ -384,11 +387,13 @@ void update_worktree_location(struct worktree *wt, const char *path_,
387
struct strbuf path = STRBUF_INIT;
388
struct strbuf dotgit = STRBUF_INIT;
389
struct strbuf gitdir = STRBUF_INIT;
390
+ char *wt_gitdir;
391
392
if (is_main_worktree(wt))
393
BUG("can't relocate main worktree");
394
391
- strbuf_realpath(&gitdir, git_common_path("worktrees/%s/gitdir", wt->id), 1);
395
+ wt_gitdir = repo_common_path(the_repository, "worktrees/%s/gitdir", wt->id);
396
+ strbuf_realpath(&gitdir, wt_gitdir, 1);
397
strbuf_realpath(&path, path_, 1);
398
strbuf_addf(&dotgit, "%s/.git", path.buf);
399
if (fspathcmp(wt->path, path.buf)) {
@@ -400,6 +405,7 @@ void update_worktree_location(struct worktree *wt, const char *path_,
405
strbuf_release(&path);
406
strbuf_release(&dotgit);
407
strbuf_release(&gitdir);
408
+ free(wt_gitdir);
409
}
410
411
int is_worktree_being_rebased(const struct worktree *wt,
@@ -585,6 +591,7 @@ static void repair_gitfile(struct worktree *wt,
591
struct strbuf backlink = STRBUF_INIT;
592
char *dotgit_contents = NULL;
593
const char *repair = NULL;
594
+ char *path = NULL;
595
int err;
596
597
/* missing worktree can't be repaired */
@@ -596,7 +603,8 @@ static void repair_gitfile(struct worktree *wt,
603
goto done;
604
}
605
599
- strbuf_realpath(&repo, git_common_path("worktrees/%s", wt->id), 1);
606
+ path = repo_common_path(the_repository, "worktrees/%s", wt->id);
607
+ strbuf_realpath(&repo, path, 1);
608
strbuf_addf(&dotgit, "%s/.git", wt->path);
609
strbuf_addf(&gitdir, "%s/gitdir", repo.buf);
610
dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err));
@@ -626,6 +634,7 @@ static void repair_gitfile(struct worktree *wt,
634
635
done:
636
free(dotgit_contents);
637
+ free(path);
638
strbuf_release(&repo);
639
strbuf_release(&dotgit);
640
strbuf_release(&gitdir);
@@ -657,11 +666,13 @@ void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path
666
struct strbuf gitdir = STRBUF_INIT;
667
struct strbuf dotgit = STRBUF_INIT;
668
int is_relative_path;
669
+ char *path = NULL;
670
671
if (is_main_worktree(wt))
672
goto done;
673
664
- strbuf_realpath(&gitdir, git_common_path("worktrees/%s/gitdir", wt->id), 1);
674
+ path = repo_common_path(the_repository, "worktrees/%s/gitdir", wt->id);
675
+ strbuf_realpath(&gitdir, path, 1);
676
677
if (strbuf_read_file(&dotgit, gitdir.buf, 0) < 0)
678
goto done;
@@ -680,6 +691,7 @@ void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path
691
done:
692
strbuf_release(&gitdir);
693
strbuf_release(&dotgit);
694
+ free(path);
695
}
696
697
void repair_worktrees_after_gitdir_move(const char *old_path)
@@ -871,7 +883,11 @@ int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath,
883
ssize_t read_result;
884
885
*wtpath = NULL;
874
- strbuf_realpath(&repo, git_common_path("worktrees/%s", id), 1);
886
+
887
+ path = repo_common_path(the_repository, "worktrees/%s", id);
888
+ strbuf_realpath(&repo, path, 1);
889
+ FREE_AND_NULL(path);
890
+
891
strbuf_addf(&gitdir, "%s/gitdir", repo.buf);
892
if (!is_directory(repo.buf)) {
893
strbuf_addstr(reason, _("not a valid directory"));