Merge branch 'ld/discovery-limit-to-fs' (early part)
authorJunio C Hamano <gitster@pobox.com>
Fri, 21 May 2010 11:02:15 +0000 (04:02 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 21 May 2010 11:02:15 +0000 (04:02 -0700)
* 'ld/discovery-limit-to-fs' (early part):
Rename ONE_FILESYSTEM to DISCOVERY_ACROSS_FILESYSTEM
GIT_ONE_FILESYSTEM: flip the default to stop at filesystem boundaries
Add support for GIT_ONE_FILESYSTEM
truncate cwd string before printing error message
config.c: remove static keyword from git_env_bool()

Documentation/git.txt
cache.h
config.c
setup.c
index 1a6ba878232f735b9cdac84aff897ef872381bdf..bec6348dab45580d90b38dac5667434ba661bf94 100644 (file)
@@ -545,6 +545,16 @@ git so take care if using Cogito etc.
        a GIT_DIR set on the command line or in the environment.
        (Useful for excluding slow-loading network directories.)
 
+'GIT_DISCOVERY_ACROSS_FILESYSTEM'::
+       When run in a directory that does not have ".git" repository
+       directory, git tries to find such a directory in the parent
+       directories to find the top of the working tree, but by default it
+       does not cross filesystem boundaries.  This environment variable
+       can be set to true to tell git not to stop at filesystem
+       boundaries.  Like 'GIT_CEILING_DIRECTORIES', this will not affect
+       an explicit repository directory set via 'GIT_DIR' or on the
+       command line.
+
 git Commits
 ~~~~~~~~~~~
 'GIT_AUTHOR_NAME'::
diff --git a/cache.h b/cache.h
index 8270390c885ab16de68ff700e2a1eb69cee5e7cb..d00d2be320152cfdd2580468db27d6735dc59748 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -954,6 +954,7 @@ extern int git_config_set_multivar(const char *, const char *, const char *, int
 extern int git_config_rename_section(const char *, const char *);
 extern const char *git_etc_gitconfig(void);
 extern int check_repository_format_version(const char *var, const char *value, void *cb);
+extern int git_env_bool(const char *, int);
 extern int git_config_system(void);
 extern int git_config_global(void);
 extern int config_error_nonbool(const char *);
index aab53298a1a02577015a2c3481667a9b53bba1b1..9b6b1df212252901b2e577009651ba8d26e4f25a 100644 (file)
--- a/config.c
+++ b/config.c
@@ -739,7 +739,7 @@ const char *git_etc_gitconfig(void)
        return system_wide;
 }
 
-static int git_env_bool(const char *k, int def)
+int git_env_bool(const char *k, int def)
 {
        const char *v = getenv(k);
        return v ? git_config_bool(k, v) : def;
diff --git a/setup.c b/setup.c
index 5716d90b57574d045114f4aaad1bdf36fd79ed89..5a083fa77dda016d0f3f511787ebf771aaf1be08 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -323,6 +323,8 @@ const char *setup_git_directory_gently(int *nongit_ok)
        const char *gitdirenv;
        const char *gitfile_dir;
        int len, offset, ceil_offset, root_len;
+       int current_device = 0, one_filesystem = 1;
+       struct stat buf;
 
        /*
         * Let's assume that we are in a git repository.
@@ -390,6 +392,12 @@ const char *setup_git_directory_gently(int *nongit_ok)
         *   etc.
         */
        offset = len = strlen(cwd);
+       one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
+       if (one_filesystem) {
+               if (stat(".", &buf))
+                       die_errno("failed to stat '.'");
+               current_device = buf.st_dev;
+       }
        for (;;) {
                gitfile_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
                if (gitfile_dir) {
@@ -422,8 +430,27 @@ const char *setup_git_directory_gently(int *nongit_ok)
                        }
                        die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT);
                }
-               if (chdir(".."))
+               if (one_filesystem) {
+                       if (stat("..", &buf)) {
+                               cwd[offset] = '\0';
+                               die_errno("failed to stat '%s/..'", cwd);
+                       }
+                       if (buf.st_dev != current_device) {
+                               if (nongit_ok) {
+                                       if (chdir(cwd))
+                                               die_errno("Cannot come back to cwd");
+                                       *nongit_ok = 1;
+                                       return NULL;
+                               }
+                               cwd[offset] = '\0';
+                               die("Not a git repository (or any parent up to mount parent %s)\n"
+                               "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).", cwd);
+                       }
+               }
+               if (chdir("..")) {
+                       cwd[offset] = '\0';
                        die_errno("Cannot change to '%s/..'", cwd);
+               }
        }
 
        inside_git_dir = 0;