setup: embed repository format in discovery
All functions related to repository discovery receive both a `struct repository_discovery` and `struct repository_format` as input, and the expectation is that both will be populated. Refactor this so that the repository format is part of the discovery result. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Jul 7, 2026 at 09:21 UTC
abe894164f8b8f4acd6a20c738bfca7867db0608
1 file changed
+29
-31
setup.c
+29
-31
@@ -1091,14 +1091,18 @@ static void apply_and_export_relative_gitdir(struct repository *repo, const char
1091
}
1092
1093
struct repo_discovery {
1094
+ struct repository_format format;
1095
char *gitdir;
1096
char *worktree;
1097
};
1098
1098
-#define REPO_DISCOVERY_INIT { 0 }
1099
+#define REPO_DISCOVERY_INIT { \
1100
+ .format = REPOSITORY_FORMAT_INIT, \
1101
+}
1102
1103
static void repo_discovery_release(struct repo_discovery *r)
1104
{
1105
+ clear_repository_format(&r->format);
1106
free(r->gitdir);
1107
free(r->worktree);
1108
}
@@ -1127,7 +1131,6 @@ static void repo_discovery_set_worktree(struct repo_discovery *r,
1131
static const char *repo_discover_explicit_gitdir(struct repo_discovery *discovery,
1132
const char *gitdirenv,
1133
struct strbuf *cwd,
1130
- struct repository_format *repo_fmt,
1134
int *nongit_ok)
1135
{
1136
const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
@@ -1152,7 +1155,7 @@ static const char *repo_discover_explicit_gitdir(struct repo_discovery *discover
1155
die(_("not a git repository: '%s'"), gitdirenv);
1156
}
1157
1155
- if (read_and_verify_repository_format(repo_fmt, gitdirenv, nongit_ok)) {
1158
+ if (read_and_verify_repository_format(&discovery->format, gitdirenv, nongit_ok)) {
1159
free(gitfile);
1160
return NULL;
1161
}
@@ -1165,22 +1168,22 @@ static const char *repo_discover_explicit_gitdir(struct repo_discovery *discover
1168
* bogus where we have both "core.worktree" and "core.bare", so
1169
* we have to explicitly unset the configuration.
1170
*/
1168
- FREE_AND_NULL(repo_fmt->work_tree);
1171
+ FREE_AND_NULL(discovery->format.work_tree);
1172
repo_discovery_set_worktree(discovery, work_tree_env);
1170
- } else if (repo_fmt->is_bare > 0) {
1173
+ } else if (discovery->format.is_bare > 0) {
1174
/* #18, #26 */
1175
repo_discovery_set_gitdir(discovery, gitdirenv, 0);
1176
free(gitfile);
1177
return NULL;
1175
- } else if (repo_fmt->work_tree) { /* #6, #14 */
1176
- if (is_absolute_path(repo_fmt->work_tree)) {
1177
- repo_discovery_set_worktree(discovery, repo_fmt->work_tree);
1178
+ } else if (discovery->format.work_tree) { /* #6, #14 */
1179
+ if (is_absolute_path(discovery->format.work_tree)) {
1180
+ repo_discovery_set_worktree(discovery, discovery->format.work_tree);
1181
} else {
1182
char *core_worktree;
1183
if (chdir(gitdirenv))
1184
die_errno(_("cannot chdir to '%s'"), gitdirenv);
1182
- if (chdir(repo_fmt->work_tree))
1183
- die_errno(_("cannot chdir to '%s'"), repo_fmt->work_tree);
1185
+ if (chdir(discovery->format.work_tree))
1186
+ die_errno(_("cannot chdir to '%s'"), discovery->format.work_tree);
1187
core_worktree = xgetcwd();
1188
if (chdir(cwd->buf))
1189
die_errno(_("cannot come back to cwd"));
@@ -1222,14 +1225,13 @@ static const char *repo_discover_explicit_gitdir(struct repo_discovery *discover
1225
static const char *repo_discover_implicit_gitdir(struct repo_discovery *discovery,
1226
const char *gitdir,
1227
struct strbuf *cwd, int offset,
1225
- struct repository_format *repo_fmt,
1228
int *nongit_ok)
1229
{
1228
- if (read_and_verify_repository_format(repo_fmt, gitdir, nongit_ok))
1230
+ if (read_and_verify_repository_format(&discovery->format, gitdir, nongit_ok))
1231
return NULL;
1232
1233
/* --work-tree is set without --git-dir; use discovered one */
1232
- if (getenv(GIT_WORK_TREE_ENVIRONMENT) || repo_fmt->work_tree) {
1234
+ if (getenv(GIT_WORK_TREE_ENVIRONMENT) || discovery->format.work_tree) {
1235
char *to_free = NULL;
1236
const char *ret;
1237
@@ -1238,13 +1240,13 @@ static const char *repo_discover_implicit_gitdir(struct repo_discovery *discover
1240
if (chdir(cwd->buf))
1241
die_errno(_("cannot come back to cwd"));
1242
ret = repo_discover_explicit_gitdir(discovery, gitdir, cwd,
1241
- repo_fmt, nongit_ok);
1243
+ nongit_ok);
1244
free(to_free);
1245
return ret;
1246
}
1247
1248
/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
1247
- if (repo_fmt->is_bare > 0) {
1249
+ if (discovery->format.is_bare > 0) {
1250
repo_discovery_set_gitdir(discovery, gitdir, (offset != cwd->len));
1251
if (chdir(cwd->buf))
1252
die_errno(_("cannot come back to cwd"));
@@ -1269,25 +1271,24 @@ static const char *repo_discover_implicit_gitdir(struct repo_discovery *discover
1271
/* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */
1272
static const char *repo_discover_bare_gitdir(struct repo_discovery *discovery,
1273
struct strbuf *cwd, int offset,
1272
- struct repository_format *repo_fmt,
1274
int *nongit_ok)
1275
{
1276
int root_len;
1277
1277
- if (read_and_verify_repository_format(repo_fmt, ".", nongit_ok))
1278
+ if (read_and_verify_repository_format(&discovery->format, ".", nongit_ok))
1279
return NULL;
1280
1281
setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);
1282
1283
/* --work-tree is set without --git-dir; use discovered one */
1283
- if (getenv(GIT_WORK_TREE_ENVIRONMENT) || repo_fmt->work_tree) {
1284
+ if (getenv(GIT_WORK_TREE_ENVIRONMENT) || discovery->format.work_tree) {
1285
static const char *gitdir;
1286
1287
gitdir = offset == cwd->len ? "." : xmemdupz(cwd->buf, offset);
1288
if (chdir(cwd->buf))
1289
die_errno(_("cannot come back to cwd"));
1290
return repo_discover_explicit_gitdir(discovery, gitdir, cwd,
1290
- repo_fmt, nongit_ok);
1291
+ nongit_ok);
1292
}
1293
1294
if (offset != cwd->len) {
@@ -1936,7 +1937,6 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
1937
struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;
1938
struct repo_discovery discovery = REPO_DISCOVERY_INIT;
1939
const char *prefix = NULL;
1939
- struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
1940
1941
/*
1942
* We may have read an incomplete configuration before
@@ -1962,19 +1962,19 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
1962
switch (repo_discovery_find_dir(&dir, &gitdir, &report, 1)) {
1963
case GIT_DIR_EXPLICIT:
1964
prefix = repo_discover_explicit_gitdir(&discovery, gitdir.buf, &cwd,
1965
- &repo_fmt, nongit_ok);
1965
+ nongit_ok);
1966
break;
1967
case GIT_DIR_DISCOVERED:
1968
if (dir.len < cwd.len && chdir(dir.buf))
1969
die(_("cannot change to '%s'"), dir.buf);
1970
prefix = repo_discover_implicit_gitdir(&discovery, gitdir.buf, &cwd, dir.len,
1971
- &repo_fmt, nongit_ok);
1971
+ nongit_ok);
1972
break;
1973
case GIT_DIR_BARE:
1974
if (dir.len < cwd.len && chdir(dir.buf))
1975
die(_("cannot change to '%s'"), dir.buf);
1976
prefix = repo_discover_bare_gitdir(&discovery, &cwd, dir.len,
1977
- &repo_fmt, nongit_ok);
1977
+ nongit_ok);
1978
break;
1979
case GIT_DIR_HIT_CEILING:
1980
if (!nongit_ok)
@@ -2078,21 +2078,21 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
2078
if (ref_backend_uri) {
2079
char *format;
2080
2081
- free(repo_fmt.ref_storage_payload);
2081
+ free(discovery.format.ref_storage_payload);
2082
2083
- parse_reference_uri(ref_backend_uri, &format, &repo_fmt.ref_storage_payload);
2084
- repo_fmt.ref_storage_format = ref_storage_format_by_name(format);
2085
- if (repo_fmt.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
2083
+ parse_reference_uri(ref_backend_uri, &format, &discovery.format.ref_storage_payload);
2084
+ discovery.format.ref_storage_format = ref_storage_format_by_name(format);
2085
+ if (discovery.format.ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
2086
die(_("unknown ref storage format: '%s'"), format);
2087
2088
free(format);
2089
}
2090
2091
- if (apply_repository_format(repo, &repo_fmt,
2091
+ if (apply_repository_format(repo, &discovery.format,
2092
APPLY_REPOSITORY_FORMAT_HONOR_ENV, &err) < 0)
2093
die("%s", err.buf);
2094
2095
- clear_repository_format(&repo_fmt);
2095
+ clear_repository_format(&discovery.format);
2096
strbuf_release(&err);
2097
}
2098
}
@@ -2118,8 +2118,6 @@ const char *setup_git_directory_gently(struct repository *repo, int *nongit_ok)
2118
strbuf_release(&dir);
2119
strbuf_release(&gitdir);
2120
strbuf_release(&report);
2121
- clear_repository_format(&repo_fmt);
2122
-
2121
return prefix;
2122
}
2123