aboutsummaryrefslogtreecommitdiffstats
path: root/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'setup.c')
-rw-r--r--setup.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/setup.c b/setup.c
index 1bfec288ab..19cce5afa7 100644
--- a/setup.c
+++ b/setup.c
@@ -7,16 +7,22 @@
#include "exec-cmd.h"
#include "gettext.h"
#include "hex.h"
+#include "object-file.h"
#include "object-name.h"
#include "refs.h"
+#include "replace-object.h"
#include "repository.h"
#include "config.h"
#include "dir.h"
#include "setup.h"
+#include "shallow.h"
#include "string-list.h"
+#include "strvec.h"
#include "chdir-notify.h"
#include "path.h"
#include "quote.h"
+#include "tmp-objdir.h"
+#include "trace.h"
#include "trace2.h"
#include "worktree.h"
#include "exec-cmd.h"
@@ -1613,6 +1619,106 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
return result;
}
+void setup_git_env(const char *git_dir)
+{
+ char *git_replace_ref_base;
+ const char *shallow_file;
+ const char *replace_ref_base;
+ struct set_gitdir_args args = { NULL };
+ struct strvec to_free = STRVEC_INIT;
+
+ args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);
+ args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);
+ args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);
+ args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
+ args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);
+ if (getenv(GIT_QUARANTINE_ENVIRONMENT)) {
+ args.disable_ref_updates = 1;
+ }
+
+ repo_set_gitdir(the_repository, git_dir, &args);
+ strvec_clear(&to_free);
+
+ if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
+ disable_replace_refs();
+ replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT);
+ git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base
+ : "refs/replace/");
+ update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base);
+
+ shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT);
+ if (shallow_file)
+ set_alternate_shallow_file(the_repository, shallow_file, 0);
+
+ if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0))
+ fetch_if_missing = 0;
+}
+
+static void set_git_dir_1(const char *path)
+{
+ xsetenv(GIT_DIR_ENVIRONMENT, path, 1);
+ setup_git_env(path);
+}
+
+static void update_relative_gitdir(const char *name UNUSED,
+ const char *old_cwd,
+ const char *new_cwd,
+ void *data UNUSED)
+{
+ char *path = reparent_relative_path(old_cwd, new_cwd,
+ repo_get_git_dir(the_repository));
+ struct tmp_objdir *tmp_objdir = tmp_objdir_unapply_primary_odb();
+
+ trace_printf_key(&trace_setup_key,
+ "setup: move $GIT_DIR to '%s'",
+ path);
+ set_git_dir_1(path);
+ if (tmp_objdir)
+ tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd);
+ free(path);
+}
+
+void set_git_dir(const char *path, int make_realpath)
+{
+ struct strbuf realpath = STRBUF_INIT;
+
+ if (make_realpath) {
+ strbuf_realpath(&realpath, path, 1);
+ path = realpath.buf;
+ }
+
+ set_git_dir_1(path);
+ if (!is_absolute_path(path))
+ chdir_notify_register(NULL, update_relative_gitdir, NULL);
+
+ strbuf_release(&realpath);
+}
+
+static int git_work_tree_initialized;
+
+/*
+ * Note. This works only before you used a work tree. This was added
+ * primarily to support git-clone to work in a new repository it just
+ * created, and is not meant to flip between different work trees.
+ */
+void set_git_work_tree(const char *new_work_tree)
+{
+ if (git_work_tree_initialized) {
+ struct strbuf realpath = STRBUF_INIT;
+
+ strbuf_realpath(&realpath, new_work_tree, 1);
+ new_work_tree = realpath.buf;
+ if (strcmp(new_work_tree, the_repository->worktree))
+ die("internal error: work tree has already been set\n"
+ "Current worktree: %s\nNew worktree: %s",
+ the_repository->worktree, new_work_tree);
+ strbuf_release(&realpath);
+ return;
+ }
+ git_work_tree_initialized = 1;
+ repo_set_worktree(the_repository, new_work_tree);
+}
+
const char *setup_git_directory_gently(int *nongit_ok)
{
static struct strbuf cwd = STRBUF_INIT;