1090
strbuf_release(&realpath);
1091
}
1092
1093
-static const char *setup_explicit_git_dir(struct repository *repo,
1094
- const char *gitdirenv,
1095
- struct strbuf *cwd,
1096
- struct repository_format *repo_fmt,
1097
- int *nongit_ok)
1093
+struct repo_discovery {
1094
+ char *gitdir;
1095
+ char *worktree;
1096
+};
1097
+
1098
+#define REPO_DISCOVERY_INIT { 0 }
1099
+
1100
+static void repo_discovery_release(struct repo_discovery *r)
1101
+{
1102
+ free(r->gitdir);
1103
+ free(r->worktree);
1104
+}
1105
+
1106
+static void repo_discovery_set_gitdir(struct repo_discovery *r,
1107
+ const char *gitdir,
1108
+ int make_realpath)
1109
+{
1110
+ free(r->gitdir);
1111
+ if (make_realpath) {
1112
+ struct strbuf realpath = STRBUF_INIT;
1113
+ strbuf_realpath(&realpath, gitdir, 1);
1114
+ r->gitdir = strbuf_detach(&realpath, NULL);
1115
+ } else {
1116
+ r->gitdir = xstrdup(gitdir);
1117
+ }
1118
+}
1119
+
1120
+static void repo_discovery_set_worktree(struct repo_discovery *r,
1121
+ const char *worktree)
1122
+{
1123
+ free(r->worktree);
1124
+ r->worktree = real_pathdup(worktree, 1);
1125
+}
1126
+
1127
+static const char *repo_discover_explicit_gitdir(struct repo_discovery *discovery,
1128
+ const char *gitdirenv,
1129
+ struct strbuf *cwd,
1130
+ struct repository_format *repo_fmt,
1131
+ int *nongit_ok)
1132
{
1133
const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
1100
- const char *worktree;
1134
char *gitfile;
1135
int offset;
1136
1166
* we have to explicitly unset the configuration.
1167
*/
1168
FREE_AND_NULL(repo_fmt->work_tree);
1136
- set_git_work_tree(repo, work_tree_env);
1169
+ repo_discovery_set_worktree(discovery, work_tree_env);
1170
} else if (repo_fmt->is_bare > 0) {
1171
/* #18, #26 */
1139
- apply_and_export_relative_gitdir(repo, gitdirenv, 0);
1172
+ repo_discovery_set_gitdir(discovery, gitdirenv, 0);
1173
free(gitfile);
1174
return NULL;
1175
} else if (repo_fmt->work_tree) { /* #6, #14 */
1176
if (is_absolute_path(repo_fmt->work_tree)) {
1144
- set_git_work_tree(repo, repo_fmt->work_tree);
1177
+ repo_discovery_set_worktree(discovery, repo_fmt->work_tree);
1178
} else {
1179
char *core_worktree;
1180
if (chdir(gitdirenv))
1184
core_worktree = xgetcwd();
1185
if (chdir(cwd->buf))
1186
die_errno(_("cannot come back to cwd"));
1154
- set_git_work_tree(repo, core_worktree);
1187
+ repo_discovery_set_worktree(discovery, core_worktree);
1188
free(core_worktree);
1189
}
1190
} else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {
1191
/* #16d */
1159
- apply_and_export_relative_gitdir(repo, gitdirenv, 0);
1192
+ repo_discovery_set_gitdir(discovery, gitdirenv, 0);
1193
free(gitfile);
1194
return NULL;
1195
} else { /* #2, #10 */
1163
- set_git_work_tree(repo, ".");
1196
+ repo_discovery_set_worktree(discovery, ".");
1197
}
1198
1166
- /* set_git_work_tree() must have been called by now */
1167
- worktree = repo_get_work_tree(repo);
1168
-
1169
- /* both repo_get_work_tree() and cwd are already normalized */
1170
- if (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */
1171
- apply_and_export_relative_gitdir(repo, gitdirenv, 0);
1199
+ /* both the worktree and cwd are already normalized */
1200
+ if (!strcmp(cwd->buf, discovery->worktree)) { /* cwd == worktree */
1201
+ repo_discovery_set_gitdir(discovery, gitdirenv, 0);
1202
free(gitfile);
1203
return NULL;
1204
}
1205
1176
- offset = dir_inside_of(cwd->buf, worktree);
1177
- if (offset >= 0) { /* cwd inside worktree? */
1178
- apply_and_export_relative_gitdir(repo, gitdirenv, 1);
1179
- if (chdir(worktree))
1180
- die_errno(_("cannot chdir to '%s'"), worktree);
1206
+ offset = dir_inside_of(cwd->buf, discovery->worktree);
1207
+ if (offset >= 0) { /* cwd inside discovery->worktree? */
1208
+ repo_discovery_set_gitdir(discovery, gitdirenv, 1);
1209
+ if (chdir(discovery->worktree))
1210
+ die_errno(_("cannot chdir to '%s'"), discovery->worktree);
1211
strbuf_addch(cwd, '/');
1212
free(gitfile);
1213
return cwd->buf + offset;
1214
}
1215
1216
/* cwd outside worktree */
1187
- apply_and_export_relative_gitdir(repo, gitdirenv, 0);
1217
+ repo_discovery_set_gitdir(discovery, gitdirenv, 0);
1218
free(gitfile);
1219
return NULL;
1220
}
1221
1192
-static const char *setup_discovered_git_dir(struct repository *repo,
1193
- const char *gitdir,
1194
- struct strbuf *cwd, int offset,
1195
- struct repository_format *repo_fmt,
1196
- int *nongit_ok)
1222
+static const char *repo_discover_implicit_gitdir(struct repo_discovery *discovery,
1223
+ const char *gitdir,
1224
+ struct strbuf *cwd, int offset,
1225
+ struct repository_format *repo_fmt,
1226
+ int *nongit_ok)
1227
{
1228
if (read_and_verify_repository_format(repo_fmt, gitdir, nongit_ok))
1229
return NULL;
1237
gitdir = to_free = real_pathdup(gitdir, 1);
1238
if (chdir(cwd->buf))
1239
die_errno(_("cannot come back to cwd"));
1210
- ret = setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);
1240
+ ret = repo_discover_explicit_gitdir(discovery, gitdir, cwd,
1241
+ repo_fmt, nongit_ok);
1242
free(to_free);
1243
return ret;
1244
}
1245
1246
/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
1247
if (repo_fmt->is_bare > 0) {
1217
- apply_and_export_relative_gitdir(repo, gitdir, (offset != cwd->len));
1248
+ repo_discovery_set_gitdir(discovery, gitdir, (offset != cwd->len));
1249
if (chdir(cwd->buf))
1250
die_errno(_("cannot come back to cwd"));
1251
return NULL;
1252
}
1253
1254
/* #0, #1, #5, #8, #9, #12, #13 */
1224
- set_git_work_tree(repo, ".");
1255
+ repo_discovery_set_worktree(discovery, ".");
1256
if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
1226
- apply_and_export_relative_gitdir(repo, gitdir, 0);
1257
+ repo_discovery_set_gitdir(discovery, gitdir, 0);
1258
if (offset >= cwd->len)
1259
return NULL;
1260
1267
}
1268
1269
/* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */
1239
-static const char *setup_bare_git_dir(struct repository *repo,
1240
- struct strbuf *cwd, int offset,
1241
- struct repository_format *repo_fmt,
1242
- int *nongit_ok)
1270
+static const char *repo_discover_bare_gitdir(struct repo_discovery *discovery,
1271
+ struct strbuf *cwd, int offset,
1272
+ struct repository_format *repo_fmt,
1273
+ int *nongit_ok)
1274
{
1275
int root_len;
1276
1286
gitdir = offset == cwd->len ? "." : xmemdupz(cwd->buf, offset);
1287
if (chdir(cwd->buf))
1288
die_errno(_("cannot come back to cwd"));
1258
- return setup_explicit_git_dir(repo, gitdir, cwd, repo_fmt, nongit_ok);
1289
+ return repo_discover_explicit_gitdir(discovery, gitdir, cwd,
1290
+ repo_fmt, nongit_ok);
1291
}
1292
1293
if (offset != cwd->len) {
1295
die_errno(_("cannot come back to cwd"));
1296
root_len = offset_1st_component(cwd->buf);
1297
strbuf_setlen(cwd, offset > root_len ? offset : root_len);
1266
- apply_and_export_relative_gitdir(repo, cwd->buf, 0);
1298
+ repo_discovery_set_gitdir(discovery, cwd->buf, 0);
1299
}
1300
else
1269
- apply_and_export_relative_gitdir(repo, ".", 0);
1301
+ repo_discovery_set_gitdir(discovery, ".", 0);
1302
return NULL;
1303
}
1304
1557
* the discovered .git/ directory, if any. If `gitdir` is not absolute, it
1558
* is relative to `dir` (i.e. *not* necessarily the cwd).
1559
*/
1528
-static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
1529
- struct strbuf *gitdir,
1530
- struct strbuf *report,
1531
- int die_on_error)
1560
+static enum discovery_result repo_discovery_find_dir(struct strbuf *dir,
1561
+ struct strbuf *gitdir,
1562
+ struct strbuf *report,
1563
+ int die_on_error)
1564
{
1565
const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
1566
struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
1727
return GIT_DIR_CWD_FAILURE;
1728
1729
cwd_len = dir.len;
1698
- result = setup_git_directory_gently_1(&dir, gitdir, NULL, 0);
1730
+ result = repo_discovery_find_dir(&dir, gitdir, NULL, 0);
1731
if (result <= 0) {
1732
strbuf_release(&dir);
1733
return result;
1934
{
1935
static struct strbuf cwd = STRBUF_INIT;
1936
struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;
1937
+ struct repo_discovery discovery = REPO_DISCOVERY_INIT;
1938
const char *prefix = NULL;
1939
struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
1940
1959
die_errno(_("Unable to read current working directory"));
1960
strbuf_addbuf(&dir, &cwd);
1961
1929
- switch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {
1962
+ switch (repo_discovery_find_dir(&dir, &gitdir, &report, 1)) {
1963
case GIT_DIR_EXPLICIT:
1931
- prefix = setup_explicit_git_dir(repo, gitdir.buf, &cwd, &repo_fmt, nongit_ok);
1964
+ prefix = repo_discover_explicit_gitdir(&discovery, gitdir.buf, &cwd,
1965
+ &repo_fmt, 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);
1936
- prefix = setup_discovered_git_dir(repo, gitdir.buf, &cwd, dir.len,
1937
- &repo_fmt, nongit_ok);
1970
+ prefix = repo_discover_implicit_gitdir(&discovery, gitdir.buf, &cwd, dir.len,
1971
+ &repo_fmt, 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);
1942
- prefix = setup_bare_git_dir(repo, &cwd, dir.len, &repo_fmt, nongit_ok);
1976
+ prefix = repo_discover_bare_gitdir(&discovery, &cwd, dir.len,
1977
+ &repo_fmt, nongit_ok);
1978
break;
1979
case GIT_DIR_HIT_CEILING:
1980
if (!nongit_ok)
2015
case GIT_DIR_CWD_FAILURE:
2016
case GIT_DIR_INVALID_FORMAT:
2017
/*
1983
- * As a safeguard against setup_git_directory_gently_1 returning
2018
+ * As a safeguard against repo_discovery_find_dir returning
2019
* these values, fallthrough to BUG. Otherwise it is possible to
2020
* set startup_info->have_repository to 1 when we did nothing to
2021
* find a repository.
2022
*/
2023
default:
1989
- BUG("unhandled setup_git_directory_gently_1() result");
2024
+ BUG("unhandled repo_discovery_find_dir() result");
2025
}
2026
2027
/*
2040
startup_info->have_repository = 1;
2041
2042
/*
2008
- * Not all paths through the setup code will call 'apply_and_export_relative_gitdir()' (which
2009
- * directly sets up the environment) so in order to guarantee that the
2010
- * environment is in a consistent state after setup, explicitly setup
2011
- * the environment if we have a repository.
2043
+ * Not all paths through the setup code will have recorded a gitdir
2044
+ * above, so in order to guarantee that the environment is in a
2045
+ * consistent state after setup, explicitly set up the gitdir and
2046
+ * environment if we have a repository.
2047
*
2048
* NEEDSWORK: currently we allow bogus GIT_DIR values to be set in some
2049
* code paths so we also need to explicitly setup the environment if
2054
startup_info->have_repository ||
2055
/* GIT_DIR_EXPLICIT */
2056
getenv(GIT_DIR_ENVIRONMENT)) {
2022
- if (!repo->gitdir) {
2057
+ if (discovery.worktree)
2058
+ set_git_work_tree(repo, discovery.worktree);
2059
+
2060
+ if (discovery.gitdir) {
2061
+ apply_and_export_relative_gitdir(repo, discovery.gitdir, 0);
2062
+ } else {
2063
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
2064
if (!gitdir)
2065
gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
2114
2115
setup_original_cwd(repo);
2116
2117
+ repo_discovery_release(&discovery);
2118
strbuf_release(&dir);
2119
strbuf_release(&gitdir);
2120
strbuf_release(&report);