threads / patch / 23042

patch, 2 partsAdd support for GIT_ONE_FILESYSTEM

Subject: [PATCH 2/2] Add support for GIT_ONE_FILESYSTEM

## tl;dr

5 messages between Mar 16, 2010 and Mar 17, 2010. Diffs are folded; open one to read it.

replies: 4people: 3as markdown or json

Lars R. Damerow· Mar 16, 2010, 22:04 UTC · lore

[PATCH 0/2] Add support for GIT_ONE_FILESYSTEM (resubmission)

Hi all,

I incorporated the feedback I got into a new patch for GIT_ONE_FILESYSTEM. It uses git_env_bool, doesn't do getenv calls within the loop, and reports better error messages.

git_env_bool was marked static in config.c, so I had to remove that to make it available in setup.c.

Lars R. Damerow (2):
      config.c: remove static keyword from git_env_bool()
      Add support for GIT_ONE_FILESYSTEM
 Documentation/git.txt |    3 +++
 cache.h               |    1 +
 config.c              |    2 +-
 setup.c               |   17 ++++++++++++++++-
 4 files changed, 21 insertions(+), 2 deletions(-)
Lars R. Damerow· Mar 16, 2010, 22:05 UTC · re: Lars R. Damerow · lore

[PATCH 1/2] config.c: remove static keyword from git_env_bool()

Since this function is the preferred way to handle boolean environment variables it's useful to have it available to other files.

Signed-off-by: Lars R. Damerow <lars@pixar.com>
---
 cache.h  |    1 +
 config.c |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)
Show changes to 2 files +2 −1

cache.h, config.c

diff --git a/cache.h b/cache.h
index 89f6a40..c29030f 100644
--- a/cache.h
+++ b/cache.h
@@ -945,6 +945,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 *);
diff --git a/config.c b/config.c
index 6963fbe..70e4600 100644
--- a/config.c
+++ b/config.c
@@ -683,7 +683,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;
-- 
1.6.5.2
Lars R. Damerow· Mar 16, 2010, 22:05 UTC · re: Lars R. Damerow · lore

This patch makes git pay attention to the GIT_ONE_FILESYSTEM environment variable. When that variable is set, git will stop searching for a GIT_DIR when it attempts to cross a filesystem boundary.

When working in an environment with too many automount points to make maintaining a GIT_CEILING_DIRECTORIES list enjoyable, GIT_ONE_FILESYSTEM gives the option of turning all such attempts off with one setting.

Signed-off-by: Lars R. Damerow <lars@pixar.com>
---
 Documentation/git.txt |    3 +++
 setup.c               |   17 ++++++++++++++++-
 2 files changed, 19 insertions(+), 1 deletions(-)
Show changes to 2 files +19 −1

Documentation/git.txt, setup.c

diff --git a/Documentation/git.txt b/Documentation/git.txt
index 35c0c79..dbb590f 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -529,6 +529,9 @@ 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_ONE_FILESYSTEM'::
+	Stop at filesystem boundaries when looking for .git or objects.
+
 git Commits
 ~~~~~~~~~~~
 'GIT_AUTHOR_NAME'::
diff --git a/setup.c b/setup.c
index 5716d90..d40e2e6 100644
--- a/setup.c
+++ b/setup.c
@@ -319,10 +319,12 @@ const char *setup_git_directory_gently(int *nongit_ok)
 {
 	const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
 	const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
-	static char cwd[PATH_MAX+1];
+	static char cwd[PATH_MAX+1], err_cwd[PATH_MAX+1];
 	const char *gitdirenv;
 	const char *gitfile_dir;
 	int len, offset, ceil_offset, root_len;
+	int current_device = 0, one_filesystem = 0;
+	struct stat buf;
 
 	/*
 	 * Let's assume that we are in a git repository.
@@ -390,6 +392,11 @@ const char *setup_git_directory_gently(int *nongit_ok)
 	 *   etc.
 	 */
 	offset = len = strlen(cwd);
+	if ((one_filesystem = git_env_bool("GIT_ONE_FILESYSTEM", 0))) {
+		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,6 +429,14 @@ 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 (one_filesystem) {
+			if (stat("..", &buf))
+				die_errno("failed to stat '%s/..'", getcwd(err_cwd, sizeof(err_cwd)-1));
+			if (buf.st_dev != current_device)
+				die("Not a git repository (or any parent up to %s/..)\n"
+					"Stopping at filesystem boundary since GIT_ONE_FILESYSTEM is set.",
+					getcwd(err_cwd, sizeof(err_cwd)-1));
+		}
 		if (chdir(".."))
 			die_errno("Cannot change to '%s/..'", cwd);
 	}
-- 
1.6.5.2
Nguyen Thai Ngoc Duy· Mar 17, 2010, 00:45 UTC · re: Lars R. Damerow · lore

Re: [PATCH 2/2] Add support for GIT_ONE_FILESYSTEM

On 3/17/10, Lars R. Damerow <lars@pixar.com> wrote:
Show 15 quoted lines
>  @@ -422,6 +429,14 @@ 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 (one_filesystem) {
>  +                       if (stat("..", &buf))
>  +                               die_errno("failed to stat '%s/..'", getcwd(err_cwd, sizeof(err_cwd)-1));
>  +                       if (buf.st_dev != current_device)
>  +                               die("Not a git repository (or any parent up to %s/..)\n"
>  +                                       "Stopping at filesystem boundary since GIT_ONE_FILESYSTEM is set.",
>  +                                       getcwd(err_cwd, sizeof(err_cwd)-1));
>  +               }
>                 if (chdir(".."))
>                         die_errno("Cannot change to '%s/..'", cwd);
>         }

It should not die() if nongit_ok != NULL (gentle mode). Maybe something like this on top:

Show changes to setup.c +8 −1
diff --git a/setup.c b/setup.c
index 500c03e..625fb35 100644
--- a/setup.c
+++ b/setup.c
@@ -499,10 +499,17 @@ static const char
*setup_git_directory_gently_1(int *nongit_ok)
 		if (one_filesystem) {
 			if (stat("..", &buf))
 				die_errno("failed to stat '%s/..'", getcwd(err_cwd, sizeof(err_cwd)-1));
-			if (buf.st_dev != current_device)
+			if (buf.st_dev != current_device) {
+				if (nongit_ok) {
+					if (chdir(cwd))
+						die_errno("Cannot come back to cwd");
+					*nongit_ok = 1;
+					return NULL;
+				}
 				die("Not a git repository (or any parent up to %s/..)\n"
 					"Stopping at filesystem boundary since GIT_ONE_FILESYSTEM is set.",
 					getcwd(err_cwd, sizeof(err_cwd)-1));
+			}
 		}
 		if (chdir(".."))
 			die_errno("Cannot change to '%s/..'", cwd);

Another thing. Is err_cwd needed? I think "cwd" can be used, like
die_errno("Cannot change to %s/..", cwd) above. Hmm.. that die_errno
needs "cwd[offset] = '\0';" first. Maybe you can fix it too ;-)
-- 
Duy
Johannes Sixt· Mar 17, 2010, 07:09 UTC · re: Lars R. Damerow · lore

Re: [PATCH 2/2] Add support for GIT_ONE_FILESYSTEM

Lars R. Damerow schrieb:
Show 7 quoted lines
> @@ -422,6 +429,14 @@ 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 (one_filesystem) {
> +			if (stat("..", &buf))
> +				die_errno("failed to stat '%s/..'", getcwd(err_cwd, sizeof(err_cwd)-1));

When stat of .. fails, then it is not unlikely that getcwd fails, too. Then you would report the errno produced by getcwd.

But can't you avoid this getcwd()? The die() call in the context below uses cwd.

Show 8 quoted lines
> +			if (buf.st_dev != current_device)
> +				die("Not a git repository (or any parent up to %s/..)\n"
> +					"Stopping at filesystem boundary since GIT_ONE_FILESYSTEM is set.",
> +					getcwd(err_cwd, sizeof(err_cwd)-1));
> +		}
>  		if (chdir(".."))
>  			die_errno("Cannot change to '%s/..'", cwd);
>  	}
-- Hannes

← back to recent threads