@@ -716,7 +716,7 @@ static enum git_attr_direction direction;
void git_attr_set_direction(enum git_attr_direction new_direction)
{
- if (is_bare_repository() && new_direction != GIT_ATTR_INDEX)
+ if (repo_is_bare(the_repository) && new_direction != GIT_ATTR_INDEX)
BUG("non-INDEX attr direction in a bare repo");
if (new_direction != direction)
@@ -883,7 +883,7 @@ static struct attr_stack *read_attr(struct index_state *istate,
res = read_attr_from_index(istate, path, flags);
} else if (tree_oid) {
res = read_attr_from_blob(istate, tree_oid, path, flags);
- } else if (!is_bare_repository()) {
+ } else if (!repo_is_bare(the_repository)) {
if (direction == GIT_ATTR_CHECKOUT) {
res = read_attr_from_index(istate, path, flags);
if (!res)
@@ -705,7 +705,7 @@ static enum bisect_error bisect_start(struct bisect_terms *terms, int argc,
struct object_id oid;
const char *head;
- if (is_bare_repository())
+ if (repo_is_bare(the_repository))
no_checkout = 1;
/*
@@ -1092,7 +1092,7 @@ parse_done:
revs.disable_stdin = 1;
setup_revisions(argc, argv, &revs, NULL);
- if (!revs.pending.nr && is_bare_repository()) {
+ if (!revs.pending.nr && repo_is_bare(the_repository)) {
struct commit *head_commit;
struct object_id head_oid;
@@ -116,7 +116,7 @@ int cmd_check_attr(int argc,
struct object_id initialized_oid;
int cnt, i, doubledash, filei;
- if (!is_bare_repository())
+ if (!repo_is_bare(the_repository))
setup_work_tree();
git_config(git_default_config, NULL);
@@ -1415,7 +1415,7 @@ int cmd_clone(int argc,
repo_clear(the_repository);
/* At this point, we need the_repository to match the cloned repo. */
- if (repo_init(the_repository, git_dir, work_tree))
+ if (repo_init(the_repository, git_dir, work_tree, -1))
warning(_("failed to initialize the repo, skipping bundle URI"));
else if (fetch_bundle_uri(the_repository, bundle_uri, &has_heuristic))
warning(_("failed to fetch objects from bundle URI '%s'"),
@@ -1446,7 +1446,7 @@ int cmd_clone(int argc,
repo_clear(the_repository);
/* At this point, we need the_repository to match the cloned repo. */
- if (repo_init(the_repository, git_dir, work_tree))
+ if (repo_init(the_repository, git_dir, work_tree, -1))
warning(_("failed to initialize the repo, skipping bundle URI"));
else if (fetch_bundle_list(the_repository,
transport->bundles))
@@ -712,7 +712,7 @@ struct repository *repo UNUSED)
die(_("failed to parse gc.logExpiry value %s"), cfg.gc_log_expire);
if (cfg.pack_refs < 0)
- cfg.pack_refs = !is_bare_repository();
+ cfg.pack_refs = !repo_is_bare(the_repository);
argc = parse_options(argc, argv, prefix, builtin_gc_options,
builtin_gc_usage, 0);
@@ -89,7 +89,7 @@ int cmd_init_db(int argc,
const struct option init_db_options[] = {
OPT_STRING(0, "template", &template_dir, N_("template-directory"),
N_("directory from which templates will be used")),
- OPT_SET_INT(0, "bare", &is_bare_repository_cfg,
+ OPT_SET_INT(0, "bare", &the_repository->is_bare_cfg,
N_("create a bare repository"), 1),
{ OPTION_CALLBACK, 0, "shared", &init_shared_repository,
N_("permissions"),
@@ -109,7 +109,7 @@ int cmd_init_db(int argc,
argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0);
- if (real_git_dir && is_bare_repository_cfg == 1)
+ if (real_git_dir && the_repository->is_bare_cfg == 1)
die(_("options '%s' and '%s' cannot be used together"), "--separate-git-dir", "--bare");
if (real_git_dir && !is_absolute_path(real_git_dir))
@@ -155,7 +155,7 @@ int cmd_init_db(int argc,
} else if (0 < argc) {
usage(init_db_usage[0]);
}
- if (is_bare_repository_cfg == 1) {
+ if (the_repository->is_bare_cfg == 1) {
char *cwd = xgetcwd();
setenv(GIT_DIR_ENVIRONMENT, cwd, argc > 0);
free(cwd);
@@ -182,7 +182,7 @@ int cmd_init_db(int argc,
*/
git_dir = xstrdup_or_null(getenv(GIT_DIR_ENVIRONMENT));
work_tree = xstrdup_or_null(getenv(GIT_WORK_TREE_ENVIRONMENT));
- if ((!git_dir || is_bare_repository_cfg == 1) && work_tree)
+ if ((!git_dir || the_repository->is_bare_cfg == 1) && work_tree)
die(_("%s (or --work-tree=<directory>) not allowed without "
"specifying %s (or --git-dir=<directory>)"),
GIT_WORK_TREE_ENVIRONMENT,
@@ -218,10 +218,10 @@ int cmd_init_db(int argc,
strbuf_release(&sb);
}
- if (is_bare_repository_cfg < 0)
- is_bare_repository_cfg = guess_repository_type(git_dir);
+ if (the_repository->is_bare_cfg < 0)
+ the_repository->is_bare_cfg = guess_repository_type(git_dir);
- if (!is_bare_repository_cfg) {
+ if (!the_repository->is_bare_cfg) {
const char *git_dir_parent = strrchr(git_dir, '/');
if (git_dir_parent) {
char *rel = xstrndup(git_dir, git_dir_parent - git_dir);
@@ -1266,7 +1266,7 @@ int cmd_repack(int argc,
if (write_bitmaps < 0) {
if (!write_midx &&
- (!(pack_everything & ALL_INTO_ONE) || !is_bare_repository()))
+ (!(pack_everything & ALL_INTO_ONE) || !repo_is_bare(the_repository)))
write_bitmaps = 0;
}
if (pack_kept_objects < 0)
@@ -448,7 +448,7 @@ int cmd_reset(int argc,
if (reset_type != SOFT && (reset_type != MIXED || repo_get_work_tree(the_repository)))
setup_work_tree();
- if (reset_type == MIXED && is_bare_repository())
+ if (reset_type == MIXED && repo_is_bare(the_repository))
die(_("%s reset is not allowed in a bare repository"),
_(reset_type_names[reset_type]));
@@ -1063,7 +1063,7 @@ int cmd_rev_parse(int argc,
continue;
}
if (!strcmp(arg, "--is-bare-repository")) {
- printf("%s\n", is_bare_repository() ? "true"
+ printf("%s\n", repo_is_bare(the_repository) ? "true"
: "false");
continue;
}
@@ -1591,7 +1591,7 @@ static int add_possible_reference_from_superproject(
struct strbuf err = STRBUF_INIT;
strbuf_add(&sb, odb->path, len);
- if (repo_init(&alternate, sb.buf, NULL) < 0)
+ if (repo_init(&alternate, sb.buf, NULL, the_repository->is_bare_cfg) < 0)
die(_("could not get a repository handle for gitdir '%s'"),
sb.buf);
@@ -1441,7 +1441,7 @@ static int git_default_core_config(const char *var, const char *value,
}
if (!strcmp(var, "core.bare")) {
- is_bare_repository_cfg = git_config_bool(var, value);
+ the_repository->is_bare_cfg = git_config_bool(var, value);
return 0;
}
@@ -4008,7 +4008,7 @@ static void connect_wt_gitdir_in_nested(const char *sub_worktree,
const struct submodule *sub;
/* If the submodule has no working tree, we can ignore it. */
- if (repo_init(&subrepo, sub_gitdir, sub_worktree))
+ if (repo_init(&subrepo, sub_gitdir, sub_worktree, the_repository->is_bare_cfg))
return;
if (repo_read_index(&subrepo) < 0)
@@ -34,7 +34,6 @@ int has_symlinks = 1;
int minimum_abbrev = 4, default_abbrev = -1;
int ignore_case;
int assume_unchanged;
-int is_bare_repository_cfg = -1; /* unspecified */
int warn_on_object_refname_ambiguity = 1;
int repository_format_precious_objects;
char *git_commit_encoding;
@@ -146,12 +145,6 @@ const char *getenv_safe(struct strvec *argv, const char *name)
return argv->v[argv->nr - 1];
}
-int is_bare_repository(void)
-{
- /* if core.bare is not 'false', let's see if there is a work tree */
- return is_bare_repository_cfg && !repo_get_work_tree(the_repository);
-}
-
int have_git_dir(void)
{
return startup_info->have_repository
@@ -144,8 +144,7 @@ void set_shared_repository(int value);
int get_shared_repository(void);
void reset_shared_repository(void);
-extern int is_bare_repository_cfg;
-int is_bare_repository(void);
+int is_bare_repository(struct repository *repo);
extern char *git_work_tree_cfg;
/* Environment bits from configuration mechanism */
@@ -251,7 +251,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--bare")) {
char *cwd = xgetcwd();
- is_bare_repository_cfg = 1;
+ the_repository->is_bare_cfg = 1;
setenv(GIT_DIR_ENVIRONMENT, cwd, 0);
free(cwd);
setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);
@@ -216,10 +216,10 @@ int read_mailmap(struct string_list *map)
map->strdup_strings = 1;
map->cmp = namemap_cmp;
- if (!git_mailmap_blob && is_bare_repository())
+ if (!git_mailmap_blob && repo_is_bare(the_repository))
git_mailmap_blob = xstrdup("HEAD:.mailmap");
- if (!startup_info->have_repository || !is_bare_repository())
+ if (!startup_info->have_repository || !repo_is_bare(the_repository))
err |= read_mailmap_file(map, ".mailmap",
startup_info->have_repository ?
MAILMAP_NOFOLLOW : 0);
@@ -1779,7 +1779,7 @@ static int log_ref_setup(struct files_ref_store *refs,
char *logfile;
if (log_refs_cfg == LOG_REFS_UNSET)
- log_refs_cfg = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL;
+ log_refs_cfg = repo_is_bare(refs->base.repo) ? LOG_REFS_NONE : LOG_REFS_NORMAL;
files_reflog_path(refs, &logfile_sb, refname);
logfile = strbuf_detach(&logfile_sb, NULL);
@@ -163,7 +163,7 @@ static int should_write_log(struct reftable_ref_store *refs, const char *refname
{
enum log_refs_config log_refs_cfg = refs->log_all_ref_updates;
if (log_refs_cfg == LOG_REFS_UNSET)
- log_refs_cfg = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL;
+ log_refs_cfg = repo_is_bare(refs->base.repo) ? LOG_REFS_NONE : LOG_REFS_NORMAL;
switch (log_refs_cfg) {
case LOG_REFS_NONE:
@@ -25,7 +25,9 @@
extern struct repository *the_repository;
/* The main repository */
-static struct repository the_repo;
+static struct repository the_repo = {
+ .is_bare_cfg = -1,
+};
struct repository *the_repository = &the_repo;
/*
@@ -263,10 +265,13 @@ static int read_and_verify_repository_format(struct repository_format *format,
/*
* Initialize 'repo' based on the provided 'gitdir'.
* Return 0 upon success and a non-zero value upon failure.
+ * is_bare can be passed to indicate whether or not the repository should be
+ * treated as bare when repo_init() is used to initiate a secondary repository.
*/
int repo_init(struct repository *repo,
const char *gitdir,
- const char *worktree)
+ const char *worktree,
+ int is_bare)
{
struct repository_format format = REPOSITORY_FORMAT_INIT;
memset(repo, 0, sizeof(*repo));
@@ -283,6 +288,8 @@ int repo_init(struct repository *repo,
repo_set_compat_hash_algo(repo, format.compat_hash_algo);
repo_set_ref_storage_format(repo, format.ref_storage_format);
repo->repository_format_worktree_config = format.worktree_config;
+ if (is_bare > 0)
+ repo->is_bare_cfg = is_bare;
/* take ownership of format.partial_clone */
repo->repository_format_partial_clone = format.partial_clone;
@@ -314,7 +321,7 @@ int repo_submodule_init(struct repository *subrepo,
strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path);
strbuf_repo_worktree_path(&worktree, superproject, "%s", path);
- if (repo_init(subrepo, gitdir.buf, worktree.buf)) {
+ if (repo_init(subrepo, gitdir.buf, worktree.buf, superproject->is_bare_cfg)) {
/*
* If initialization fails then it may be due to the submodule
* not being populated in the superproject's worktree. Instead
@@ -332,7 +339,7 @@ int repo_submodule_init(struct repository *subrepo,
strbuf_reset(&gitdir);
submodule_name_to_gitdir(&gitdir, superproject, sub->name);
- if (repo_init(subrepo, gitdir.buf, NULL)) {
+ if (repo_init(subrepo, gitdir.buf, NULL, superproject->is_bare_cfg)) {
ret = -1;
goto out;
}
@@ -453,3 +460,9 @@ int repo_hold_locked_index(struct repository *repo,
BUG("the repo hasn't been setup");
return hold_lock_file_for_update(lf, repo->index_file, flags);
}
+
+int repo_is_bare(struct repository *repo)
+{
+ /* if core.bare is not 'false', let's see if there is a work tree */
+ return repo->is_bare_cfg && !repo_get_work_tree(repo);
+}
@@ -153,6 +153,14 @@ struct repository {
/* Indicate if a repository has a different 'commondir' from 'gitdir' */
unsigned different_commondir:1;
+
+ /*
+ * Indicates if the repository is set to be treated as a bare repository,
+ * through a command line argument, configuration, or environment
+ * variable.
+ * -1 means unspecified, 0 indicates non-bare, and 1 indicates bare.
+ */
+ int is_bare_cfg;
};
#ifdef USE_THE_REPOSITORY_VARIABLE
@@ -188,7 +196,7 @@ void repo_set_ref_storage_format(struct repository *repo,
enum ref_storage_format format);
void initialize_repository(struct repository *repo);
RESULT_MUST_BE_USED
-int repo_init(struct repository *r, const char *gitdir, const char *worktree);
+int repo_init(struct repository *r, const char *gitdir, const char *worktree, int is_bare);
/*
* Initialize the repository 'subrepo' as the submodule at the given path. If
@@ -232,4 +240,6 @@ void repo_update_index_if_able(struct repository *, struct lock_file *);
*/
int upgrade_repository_format(int target_version);
+int repo_is_bare(struct repository *repo);
+
#endif /* REPOSITORY_H */
@@ -722,7 +722,7 @@ static int cmd_reconfigure(int argc, const char **argv)
git_config_clear();
- if (repo_init(&r, gitdir.buf, commondir.buf))
+ if (repo_init(&r, gitdir.buf, commondir.buf, the_repository->is_bare_cfg))
goto loop_end;
old_repo = the_repository;
@@ -766,8 +766,8 @@ static int check_repository_format_gently(const char *gitdir, struct repository_
if (!has_common) {
if (candidate->is_bare != -1) {
- is_bare_repository_cfg = candidate->is_bare;
- if (is_bare_repository_cfg == 1)
+ the_repository->is_bare_cfg = candidate->is_bare;
+ if (the_repository->is_bare_cfg == 1)
inside_work_tree = -1;
}
if (candidate->work_tree) {
@@ -1030,7 +1030,7 @@ static const char *setup_explicit_git_dir(const char *gitdirenv,
/* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */
if (work_tree_env)
set_git_work_tree(work_tree_env);
- else if (is_bare_repository_cfg > 0) {
+ else if (the_repository->is_bare_cfg > 0) {
if (git_work_tree_cfg) {
/* #22.2, #30 */
warning("core.bare and core.worktree do not make sense");
@@ -1116,7 +1116,7 @@ static const char *setup_discovered_git_dir(const char *gitdir,
}
/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
- if (is_bare_repository_cfg > 0) {
+ if (the_repository->is_bare_cfg > 0) {
set_git_dir(gitdir, (offset != cwd->len));
if (chdir(cwd->buf))
die_errno(_("cannot come back to cwd"));
@@ -2323,7 +2323,7 @@ static int create_default_files(const char *template_path,
if (init_shared_repository != -1)
set_shared_repository(init_shared_repository);
- is_bare_repository_cfg = !work_tree;
+ the_repository->is_bare_cfg = !work_tree;
/*
* We would have created the above under user's umask -- under
@@ -2349,7 +2349,7 @@ static int create_default_files(const char *template_path,
}
git_config_set("core.filemode", filemode ? "true" : "false");
- if (is_bare_repository())
+ if (repo_is_bare(the_repository))
git_config_set("core.bare", "true");
else {
git_config_set("core.bare", "false");
@@ -535,7 +535,7 @@ static struct repository *open_submodule(const char *path)
struct strbuf sb = STRBUF_INIT;
struct repository *out = xmalloc(sizeof(*out));
- if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
+ if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL, -1)) {
strbuf_release(&sb);
free(out);
return NULL;
@@ -19,7 +19,7 @@ static void object_info(const char *gitdir, const char *oid_hex)
struct object_info oi = {.sizep = &size};
const char *p;
- if (repo_init(&r, gitdir, NULL))
+ if (repo_init(&r, gitdir, NULL, -1))
die("could not init repo");
if (parse_oid_hex_algop(oid_hex, &oid, &p, r.hash_algo))
die("could not parse oid");
@@ -21,7 +21,7 @@ static void test_parse_commit_in_graph(const char *gitdir, const char *worktree,
repo_clear(the_repository);
- if (repo_init(&r, gitdir, worktree))
+ if (repo_init(&r, gitdir, worktree, -1))
die("Couldn't init repo");
repo_set_hash_algo(the_repository, hash_algo_by_ptr(r.hash_algo));
@@ -51,7 +51,7 @@ static void test_get_commit_tree_in_graph(const char *gitdir,
repo_clear(the_repository);
- if (repo_init(&r, gitdir, worktree))
+ if (repo_init(&r, gitdir, worktree, -1))
die("Couldn't init repo");
repo_set_hash_algo(the_repository, hash_algo_by_ptr(r.hash_algo));
@@ -1428,7 +1428,7 @@ int transport_push(struct repository *r,
if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
TRANSPORT_RECURSE_SUBMODULES_ONLY)) &&
- !is_bare_repository()) {
+ !repo_is_bare(r)) {
struct ref *ref = remote_refs;
struct oid_array commits = OID_ARRAY_INIT;
@@ -1455,7 +1455,7 @@ int transport_push(struct repository *r,
if (((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) ||
((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
TRANSPORT_RECURSE_SUBMODULES_ONLY)) &&
- !pretend)) && !is_bare_repository()) {
+ !pretend)) && !repo_is_bare(r)) {
struct ref *ref = remote_refs;
struct string_list needs_pushing = STRING_LIST_INIT_DUP;
struct oid_array commits = OID_ARRAY_INIT;
@@ -85,8 +85,8 @@ static struct worktree *get_main_worktree(int skip_reading_head)
* This means that worktree->is_bare may be set to 0 even if the main
* worktree is configured to be bare.
*/
- worktree->is_bare = (is_bare_repository_cfg == 1) ||
- is_bare_repository();
+
+ worktree->is_bare = the_repository->is_bare_cfg == 1;
worktree->is_current = is_current_worktree(worktree);
if (!skip_reading_head)
add_head_info(worktree);