grep: recurse in-process using 'struct repository'
[gitweb.git] / setup.c
diff --git a/setup.c b/setup.c
index ae3e0ddda22d9b517485a5c91b8d191c3e9ef92e..23950173fc01268320d2e23c36ef80a1b1231a5e 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -1,4 +1,6 @@
 #include "cache.h"
+#include "repository.h"
+#include "config.h"
 #include "dir.h"
 #include "string-list.h"
 
@@ -397,6 +399,11 @@ void setup_work_tree(void)
        if (getenv(GIT_WORK_TREE_ENVIRONMENT))
                setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
 
+       /*
+        * NEEDSWORK: this call can essentially be set_git_dir(get_git_dir())
+        * which can cause some problems when trying to free the old value of
+        * gitdir.
+        */
        set_git_dir(remove_leading_path(git_dir, work_tree));
        initialized = 1;
 }
@@ -967,19 +974,21 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
        }
 }
 
-const char *discover_git_directory(struct strbuf *gitdir)
+int discover_git_directory(struct strbuf *commondir,
+                          struct strbuf *gitdir)
 {
        struct strbuf dir = STRBUF_INIT, err = STRBUF_INIT;
        size_t gitdir_offset = gitdir->len, cwd_len;
+       size_t commondir_offset = commondir->len;
        struct repository_format candidate;
 
        if (strbuf_getcwd(&dir))
-               return NULL;
+               return -1;
 
        cwd_len = dir.len;
        if (setup_git_directory_gently_1(&dir, gitdir, 0) <= 0) {
                strbuf_release(&dir);
-               return NULL;
+               return -1;
        }
 
        /*
@@ -995,8 +1004,10 @@ const char *discover_git_directory(struct strbuf *gitdir)
                strbuf_insert(gitdir, gitdir_offset, dir.buf, dir.len);
        }
 
+       get_common_dir(commondir, gitdir->buf + gitdir_offset);
+
        strbuf_reset(&dir);
-       strbuf_addf(&dir, "%s/config", gitdir->buf + gitdir_offset);
+       strbuf_addf(&dir, "%s/config", commondir->buf + commondir_offset);
        read_repository_format(&candidate, dir.buf);
        strbuf_release(&dir);
 
@@ -1004,18 +1015,19 @@ const char *discover_git_directory(struct strbuf *gitdir)
                warning("ignoring git dir '%s': %s",
                        gitdir->buf + gitdir_offset, err.buf);
                strbuf_release(&err);
+               strbuf_setlen(commondir, commondir_offset);
                strbuf_setlen(gitdir, gitdir_offset);
-               return NULL;
+               return -1;
        }
 
-       return gitdir->buf + gitdir_offset;
+       return 0;
 }
 
 const char *setup_git_directory_gently(int *nongit_ok)
 {
        static struct strbuf cwd = STRBUF_INIT;
        struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT;
-       const char *prefix, *env_prefix;
+       const char *prefix;
 
        /*
         * We may have read an incomplete configuration before
@@ -1073,10 +1085,6 @@ const char *setup_git_directory_gently(int *nongit_ok)
                die("BUG: unhandled setup_git_directory_1() result");
        }
 
-       env_prefix = getenv(GIT_TOPLEVEL_PREFIX_ENVIRONMENT);
-       if (env_prefix)
-               prefix = env_prefix;
-
        if (prefix)
                setenv(GIT_PREFIX_ENVIRONMENT, prefix, 1);
        else
@@ -1085,6 +1093,27 @@ const char *setup_git_directory_gently(int *nongit_ok)
        startup_info->have_repository = !nongit_ok || !*nongit_ok;
        startup_info->prefix = prefix;
 
+       /*
+        * Not all paths through the setup code will call 'set_git_dir()' (which
+        * directly sets up the environment) so in order to guarantee that the
+        * environment is in a consistent state after setup, explicitly setup
+        * the environment if we have a repository.
+        *
+        * NEEDSWORK: currently we allow bogus GIT_DIR values to be set in some
+        * code paths so we also need to explicitly setup the environment if
+        * the user has set GIT_DIR.  It may be beneficial to disallow bogus
+        * GIT_DIR values at some point in the future.
+        */
+       if (startup_info->have_repository || getenv(GIT_DIR_ENVIRONMENT)) {
+               if (!the_repository->gitdir) {
+                       const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
+                       if (!gitdir)
+                               gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
+                       repo_set_gitdir(the_repository, gitdir);
+                       setup_git_env();
+               }
+       }
+
        strbuf_release(&dir);
        strbuf_release(&gitdir);