setup: make startup_info available everywhere
authorJeff King <peff@peff.net>
Sat, 5 Mar 2016 22:10:27 +0000 (17:10 -0500)
committerJunio C Hamano <gitster@pobox.com>
Mon, 7 Mar 2016 01:17:37 +0000 (17:17 -0800)
Commit a60645f (setup: remember whether repository was
found, 2010-08-05) introduced the startup_info structure,
which records some parts of the setup_git_directory()
process (notably, whether we actually found a repository or
not).

One of the uses of this data is for functions to behave
appropriately based on whether we are in a repo. But the
startup_info struct is just a pointer to storage provided by
the main program, and the only program that sets it up is
the git.c wrapper. Thus builtins have access to
startup_info, but externally linked programs do not.

Worse, library code which is accessible from both has to be
careful about accessing startup_info. This can be used to
trigger a die("BUG") via get_sha1():

$ git fast-import <<-\EOF
tag foo
from HEAD:./whatever
EOF

fatal: BUG: startup_info struct is not initialized.

Obviously that's fairly nonsensical input to feed to
fast-import, but we should never hit a die("BUG"). And there
may be other ways to trigger it if other non-builtins
resolve sha1s.

So let's point the storage for startup_info to a static
variable in setup.c, making it available to all users of the
library code. We _could_ turn startup_info into a regular
extern struct, but doing so would mean tweaking all of the
existing use sites. So let's leave the pointer indirection
in place. We can, however, drop any checks for NULL, as
they will always be false (and likewise, we can drop the
test covering this case, which was a rather artificial
situation using one of the test-* programs).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
cache.h
environment.c
git.c
setup.c
sha1_name.c
t/t1506-rev-parse-diagnosis.sh
diff --git a/cache.h b/cache.h
index b829410f6da0afc14353b4621d2fdf874181a9f7..9f09540bbca587cb2ba0135a69d65aa966b09622 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1771,7 +1771,7 @@ int split_cmdline(char *cmdline, const char ***argv);
 /* Takes a negative value returned by split_cmdline */
 const char *split_cmdline_strerror(int cmdline_errno);
 
-/* git.c */
+/* setup.c */
 struct startup_info {
        int have_repository;
        const char *prefix;
index 6dec9d0403f11579a7ab316db87a1dbbc58e71b2..6cc0a7780f790d6cea3774acd989a57e52934f91 100644 (file)
@@ -64,7 +64,6 @@ int grafts_replace_parents = 1;
 int core_apply_sparse_checkout;
 int merge_log_config = -1;
 int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
-struct startup_info *startup_info;
 unsigned long pack_size_limit_cfg;
 
 #ifndef PROTECT_HFS_DEFAULT
diff --git a/git.c b/git.c
index 6cc0c077f9761f9b56e5fb7e666722b437c4fae4..968a8a464588f10c5c1564440e06d5e5afe8d37a 100644 (file)
--- a/git.c
+++ b/git.c
@@ -15,7 +15,6 @@ const char git_more_info_string[] =
           "concept guides. See 'git help <command>' or 'git help <concept>'\n"
           "to read about a specific subcommand or concept.");
 
-static struct startup_info git_startup_info;
 static int use_pager = -1;
 static char *orig_cwd;
 static const char *env_names[] = {
@@ -637,8 +636,6 @@ int main(int argc, char **av)
        const char *cmd;
        int done_help = 0;
 
-       startup_info = &git_startup_info;
-
        cmd = git_extract_argv0_path(argv[0]);
        if (!cmd)
                cmd = "git-help";
diff --git a/setup.c b/setup.c
index de1a2a7ea5973fef256328a26730117466c15172..fa7a306287a9daee48b6d970b4e2e7c3f96cd46e 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -7,6 +7,9 @@ static int inside_work_tree = -1;
 static int work_tree_config_is_bogus;
 static struct string_list unknown_extensions = STRING_LIST_INIT_DUP;
 
+static struct startup_info the_startup_info;
+struct startup_info *startup_info = &the_startup_info;
+
 /*
  * The input parameter must contain an absolute path, and it must already be
  * normalized.
@@ -905,10 +908,9 @@ const char *setup_git_directory_gently(int *nongit_ok)
        else
                setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
 
-       if (startup_info) {
-               startup_info->have_repository = !nongit_ok || !*nongit_ok;
-               startup_info->prefix = prefix;
-       }
+       startup_info->have_repository = !nongit_ok || !*nongit_ok;
+       startup_info->prefix = prefix;
+
        return prefix;
 }
 
index 3acf221f92f7a0857f17c0210044cacc325c8ce0..776101e8d709b924033a141efa38e3f734837c79 100644 (file)
@@ -1353,9 +1353,6 @@ static char *resolve_relative_path(const char *rel)
        if (!starts_with(rel, "./") && !starts_with(rel, "../"))
                return NULL;
 
-       if (!startup_info)
-               die("BUG: startup_info struct is not initialized.");
-
        if (!is_inside_work_tree())
                die("relative path syntax can't be used outside working tree.");
 
index 613d9bfe1bbb153d1c2e647aee26a60e07a6af86..86c2ff255d43d644caf81e6258d29dcea1db8e53 100755 (executable)
@@ -166,11 +166,6 @@ test_expect_success 'relative path when cwd is outside worktree' '
        grep "relative path syntax can.t be used outside working tree." error
 '
 
-test_expect_success 'relative path when startup_info is NULL' '
-       test_must_fail test-match-trees HEAD:./file.txt HEAD:./file.txt 2>error &&
-       grep "BUG: startup_info struct is not initialized." error
-'
-
 test_expect_success '<commit>:file correctly diagnosed after a pathname' '
        test_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error &&
        test_i18ngrep ! "exists on disk" error &&