Global .git directory

16 messages, 8 authors, 2016-06-15 · open the first message on its own page

Global .git directory

From: Gerhard Wiesinger <hidden>
Date: 2016-06-15 22:48:43

Hello,

I'm new to git and as far as I saw that feature is missing: Placing .git 
directory/repository on a central place for many git repositories. This 
feature ensures that data directories are kept clean from metadata of git.

I know the GIT_DIR environment variable but therefore environment has to 
be set for each repository which is IHMO not practicable. Therefore I 
suggest the following approach (which also overrides GIT_DIR when set):
#  Can be set globally for all users
export GIT_GLOBAL_DIR=$HOME/.git_global

When this environment variable is set git searches the repository in 
$HOME/.git_global/`pwd`
Example:
cd /home/gerhard/myproject
=> /home/gerhard/.git_global/home/gerhard/myproject/.git directory is used
cd /home/gerhard/myproject/subdir
=> /home/gerhard/.git_global/home/gerhard/myproject/.git directory is 
still used, base directory must also be searched for (algorithm must 
already be implemented)

I think this should be easy to implement on a centralized point.

Any feedback is welcome.

Thnx.

Ciao,
Gerhard

--
http://www.wiesinger.com/

Re: Global .git directory

From: Thomas Rast <hidden>
Date: 2016-06-15 22:48:43

Gerhard Wiesinger wrote:
Hello,

I'm new to git and as far as I saw that feature is missing: Placing .git 
directory/repository on a central place for many git repositories. This 
feature ensures that data directories are kept clean from metadata of git.
[...]
I think this should be easy to implement on a centralized point.
What problem are you trying to solve, what solution are you
attempting, and why does the .git get in the way of your proposed
solution?

(In other words, please convince us that this is actually worth
having.)

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

Re: Global .git directory

From: Gerhard Wiesinger <hidden>
Date: 2016-06-15 22:48:43

On Tue, 27 Apr 2010, Thomas Rast wrote:
Gerhard Wiesinger wrote:
quoted
Hello,

I'm new to git and as far as I saw that feature is missing: Placing .git
directory/repository on a central place for many git repositories. This
feature ensures that data directories are kept clean from metadata of git.
[...]
quoted
I think this should be easy to implement on a centralized point.
What problem are you trying to solve, what solution are you
attempting, and why does the .git get in the way of your proposed
solution?
I don't like metadata of the repository in MY file structure (e.g. .git in 
top directory, .svn in every directory in subversion, .hg in top 
directory) for several reasons:
1.) Searching might arise false results, longer output and takes longer 
(e.g. grep -ir string .)
2.) Making tarballs, diffs, etc.: One has to make ugly --exclude or some 
other workarounds when directories are traversed.
3.) From an archtectural point of view: It is not technically necessary to 
mix up user data with repository data.
(In other words, please convince us that this is actually worth
having.)
Ok, rather than convincing I've written a (fast) patch which works for 
me :-)

Any comments? Any (further) changes needed? Will you include it in main 
git?

Thnx.

Ciao,
Gerhard

--
http://www.wiesinger.com/

Re: Global .git directory

From: Erik Faye-Lund <hidden>
Date: 2016-06-15 22:48:43

On Tue, Apr 27, 2010 at 10:06 PM, Gerhard Wiesinger [off-list ref] wrote:
On Tue, 27 Apr 2010, Thomas Rast wrote:
quoted
(In other words, please convince us that this is actually worth
having.)
Ok, rather than convincing I've written a (fast) patch which works for me
:-)

Any comments? Any (further) changes needed? Will you include it in main git?
Please see Documentation/SubmittingPatches. It's difficult to comment
on a non-inlined patch.

-- 
Erik "kusma" Faye-Lund

Re: Global .git directory

From: Jacob Helwig <hidden>
Date: 2016-06-15 22:48:43

On Tue, Apr 27, 2010 at 13:06, Gerhard Wiesinger [off-list ref] wrote:
I don't like metadata of the repository in MY file structure (e.g. .git in
top directory, .svn in every directory in subversion, .hg in top directory)
for several reasons:
1.) Searching might arise false results, longer output and takes longer
(e.g. grep -ir string .)
Using ack, instead of grep is very handy here.  It'll automatically
skip common revision control directories, and (by default) only
searches known text file formats.  There is also "git grep".
2.) Making tarballs, diffs, etc.: One has to make ugly --exclude or some
other workarounds when directories are traversed.
Making tarballs: Is there a reason not to just use git-archive?  You
don't need to make any ugly --exclude rules there, unless you're
trying to exclude things that you track in revision control.

Diffs: Is "git diff" not sufficient here?  If it's not, why isn't it?
3.) From an archtectural point of view: It is not technically necessary to
mix up user data with repository data.

Re: Global .git directory

From: Gerhard Wiesinger <hidden>
Date: 2016-06-15 22:48:43

On Tue, 27 Apr 2010, Erik Faye-Lund wrote:
On Tue, Apr 27, 2010 at 10:06 PM, Gerhard Wiesinger [off-list ref] wrote:
quoted
On Tue, 27 Apr 2010, Thomas Rast wrote:
quoted
(In other words, please convince us that this is actually worth
having.)
Ok, rather than convincing I've written a (fast) patch which works for me
:-)

Any comments? Any (further) changes needed? Will you include it in main git?
Please see Documentation/SubmittingPatches. It's difficult to comment
on a non-inlined patch.
Patch done on top of HEAD.
git format-patch -M origin/master
0001-Added-global-git-directory-when-environment-variable.patch
0002-Added-global-git-directory-when-environment-variable.patch
0003-Updated-documentation-for-submitting-patches.patch
Attached.

BTW: The tutorial on http://git-scm.com/ is IHMO wrong:
git --version
git version 1.6.2.5
git commit -m 'Explain what I changed'
=>
git commit -a -m 'Explain what I changed'
=> Otherwise changed files are not committed, only added ones.
=> Therefore that are 2 commit ...

BTW2:
Why is it necessary to do:
# Displays only changed files
git diff
# Displays only added files
git diff --cached

I would like to have a full diff of my changes:
git diff -a
(or better "git diff -a" should be the default behaviour, I think 
that's very confusing for new users)

Ciao,
Gerhard

--
http://www.wiesinger.com/

Re: Global .git directory

From: Tomas Carnecky <hidden>
Date: 2016-06-15 22:48:43

On 4/28/10 7:33 AM, Gerhard Wiesinger wrote:
BTW: The tutorial on http://git-scm.com/ is IHMO wrong:
git --version
git version 1.6.2.5
git commit -m 'Explain what I changed'
=>
git commit -a -m 'Explain what I changed'
=> Otherwise changed files are not committed, only added ones.
=> Therefore that are 2 commit ...
If you mean the snippets right on the front page, it assumes that you 
add all edited files.
BTW2:
Why is it necessary to do:
# Displays only changed files
git diff
# Displays only added files
git diff --cached

I would like to have a full diff of my changes:
git diff -a
(or better "git diff -a" should be the default behaviour, I think that's
very confusing for new users)
What are 'your' changes? Between HEAD and the working tree (aka. git 
diff HEAD)?

tom

Re: Global .git directory

From: Alex Riesen <hidden>
Date: 2016-06-15 22:48:43

On Wed, Apr 28, 2010 at 07:33, Gerhard Wiesinger [off-list ref] wrote:
On Tue, 27 Apr 2010, Erik Faye-Lund wrote:
quoted
Please see Documentation/SubmittingPatches. It's difficult to
comment on a non-inlined patch.
Patch done on top of HEAD.
The patches "done on top of HEAD" are usually useless for
everyone, including the submitter. HEAD changes over time.
for instance I wont be able to apply your patches on my HEAD,
as I have a lot of changes in my Git repo.

If you about to share your modifications, you better base your
changes on stable points in history, like releases (marked by
release tags, like "v1.7.1").
BTW2:
Why is it necessary to do:
It is so you can distinguish between the changes in progress and
the changes ready to be submitted (prepared for commit).
# Displays only changed files
git diff
To be exact: the changes not yet staged for commit.
# Displays only added files
git diff --cached
No, it displays the changes ready to be committed (staged).
I would like to have a full diff of my changes:
git diff -a
You wouldn't use it. It is very useful to separate the phases of workflow.

BTW, try using "git status". It'll show you both lists of changed files.
Also "git gui", and "gitk" make the lists visible ("git gui" is more like
"git status", and you can commit from it).
(or better "git diff -a" should be the default behaviour, I think that's
very confusing for new users)
Only to unwilling to learn. You'd be probably the first to suggest
to combine the two stages of change. Usually people understand
(or get a feeling of understanding) the index even before they send
first mail to the mailing list.

Re: Global .git directory

From: Erik Faye-Lund <hidden>
Date: 2016-06-15 22:48:43

On Wed, Apr 28, 2010 at 7:33 AM, Gerhard Wiesinger [off-list ref] wrote:
On Tue, 27 Apr 2010, Erik Faye-Lund wrote:
quoted
On Tue, Apr 27, 2010 at 10:06 PM, Gerhard Wiesinger [off-list ref]
wrote:
quoted
On Tue, 27 Apr 2010, Thomas Rast wrote:
quoted
(In other words, please convince us that this is actually worth
having.)
Ok, rather than convincing I've written a (fast) patch which works for me
:-)

Any comments? Any (further) changes needed? Will you include it in main
git?
Please see Documentation/SubmittingPatches. It's difficult to comment
on a non-inlined patch.
Patch done on top of HEAD.
git format-patch -M origin/master
0001-Added-global-git-directory-when-environment-variable.patch
0002-Added-global-git-directory-when-environment-variable.patch
0003-Updated-documentation-for-submitting-patches.patch
Attached.
I was referring to that you sent the patch attached instead of inlined
(as Documentation/SubmittingPatches suggests).

By attaching patches you force everyone who wants to review the patch
to have to copy and manually quote the parts of the patch that they
have comments about instead of automatic quoting like all decent
e-mail clients do. That way you get less people interested in the
patch.

I sent this reply because you did the right thing of cooking up a
patch in the first place (as opposed to just arguing - very good), so
I think you deserve a chance of getting the patch reviewed (and
possibly included... if people agree with you, that is).

-- 
Erik "kusma" Faye-Lund

Re: Global .git directory

From: Gerhard Wiesinger <hidden>
Date: 2016-06-15 22:48:43



--
http://www.wiesinger.com/


On Wed, 28 Apr 2010, Tomas Carnecky wrote:
On 4/28/10 7:33 AM, Gerhard Wiesinger wrote:
quoted
BTW: The tutorial on http://git-scm.com/ is IHMO wrong:
git --version
git version 1.6.2.5
git commit -m 'Explain what I changed'
=>
git commit -a -m 'Explain what I changed'
=> Otherwise changed files are not committed, only added ones.
=> Therefore that are 2 commit ...
If you mean the snippets right on the front page, it assumes that you add all 
edited files.
OK, I assumed that the tutorial at
http://git.or.cz/course/svn.html
when switching from svn to git is correct, but it isn't. I unterstand now, 
that git is basically a patch management system where you add or remove 
(rm) files to a patch/commit set (adding in svn means adding or removing 
a file). So this is very different from svn and other SCM systems.

Homepage:
git add (files)
=>
git add (all edited and added files)
would clarify this, too.
quoted
BTW2:
Why is it necessary to do:
# Displays only changed files
git diff
# Displays only added files
git diff --cached

I would like to have a full diff of my changes:
git diff -a
(or better "git diff -a" should be the default behaviour, I think that's
very confusing for new users)
What are 'your' changes? Between HEAD and the working tree (aka. git diff 
HEAD)?
git diff HEAD
# no output.

Ciao,
Gerhard

Re: Global .git directory

From: Gerhard Wiesinger <hidden>
Date: 2016-06-15 22:48:43

On Wed, 28 Apr 2010, Alex Riesen wrote:
On Wed, Apr 28, 2010 at 07:33, Gerhard Wiesinger [off-list ref] wrote:
quoted
On Tue, 27 Apr 2010, Erik Faye-Lund wrote:
quoted
Please see Documentation/SubmittingPatches. It's difficult to
comment on a non-inlined patch.
Patch done on top of HEAD.
The patches "done on top of HEAD" are usually useless for
everyone, including the submitter. HEAD changes over time.
for instance I wont be able to apply your patches on my HEAD,
as I have a lot of changes in my Git repo.

If you about to share your modifications, you better base your
changes on stable points in history, like releases (marked by
release tags, like "v1.7.1").
Patch is made on top of v1.7.1 (it was HEAD at the time of the last pull) 
according to git log.
quoted
BTW2:
Why is it necessary to do:
It is so you can distinguish between the changes in progress and
the changes ready to be submitted (prepared for commit).
quoted
# Displays only changed files
git diff
To be exact: the changes not yet staged for commit.
quoted
# Displays only added files
git diff --cached
No, it displays the changes ready to be committed (staged).
quoted
I would like to have a full diff of my changes:
git diff -a
You wouldn't use it. It is very useful to separate the phases of workflow.

BTW, try using "git status". It'll show you both lists of changed files.
Also "git gui", and "gitk" make the lists visible ("git gui" is more like
"git status", and you can commit from it).
quoted
(or better "git diff -a" should be the default behaviour, I think that's
very confusing for new users)
Only to unwilling to learn. You'd be probably the first to suggest
to combine the two stages of change. Usually people understand
(or get a feeling of understanding) the index even before they send
first mail to the mailing list.
Ok, as explained in previous mail, confusion was introduced from the 
tutorial at: http://git.or.cz/course/svn.html

Thnx for explaination so far.

Ciao,
Gerhard

--
http://www.wiesinger.com/

Re: Global .git directory

From: Gerhard Wiesinger <hidden>
Date: 2016-06-15 22:48:43

On Wed, 28 Apr 2010, Erik Faye-Lund wrote:
On Wed, Apr 28, 2010 at 7:33 AM, Gerhard Wiesinger [off-list ref] wrote:
quoted
On Tue, 27 Apr 2010, Erik Faye-Lund wrote:
quoted
On Tue, Apr 27, 2010 at 10:06 PM, Gerhard Wiesinger [off-list ref]
wrote:
quoted
On Tue, 27 Apr 2010, Thomas Rast wrote:
quoted
Ok, rather than convincing I've written a (fast) patch which works for me
:-)

Any comments? Any (further) changes needed? Will you include it in main
git?
I was referring to that you sent the patch attached instead of inlined
(as Documentation/SubmittingPatches suggests).

By attaching patches you force everyone who wants to review the patch
to have to copy and manually quote the parts of the patch that they
have comments about instead of automatic quoting like all decent
e-mail clients do. That way you get less people interested in the
patch.

I sent this reply because you did the right thing of cooking up a
patch in the first place (as opposed to just arguing - very good), so
I think you deserve a chance of getting the patch reviewed (and
possibly included... if people agree with you, that is).
Sorry, was in a hurry, and just wanted to get the patch "out there". No
problem, patch is inline now and hopefully in the right format.

Patch is done after V1.7.1.
From 87cc9d17ec52a6ff2b71b9851c5b61f9e1da72be Mon Sep 17 00:00:00 2001
From: Gerhard Wiesinger <redacted>
Date: Wed, 28 Apr 2010 06:46:28 +0200
Subject: [PATCH 1/2] Added global git directory when environment variable GIT_DIR_GLOBAL is set, e.g. export GIT_DIR_GLOBAL=/home/gerhard/.git_global

---
  environment.h |    8 ++++++++
  setup.h       |    6 ++++++
  2 files changed, 14 insertions(+), 0 deletions(-)
  create mode 100644 environment.h
  create mode 100644 setup.h
diff --git a/environment.h b/environment.h
new file mode 100644
index 0000000..fb6a368
--- /dev/null
+++ b/environment.h
@@ -0,0 +1,8 @@
+#ifndef ENVIRONMENT_H
+#define ENVIRONMENT_H
+
+char *get_git_dir_global_base_dir(void);
+char *get_git_dir_from_environment(void);
+int is_git_dir_global_environment(void);
+
+#endif /* ENVIRONMENT_H */
diff --git a/setup.h b/setup.h
new file mode 100644
index 0000000..2047ba5
--- /dev/null
+++ b/setup.h
@@ -0,0 +1,6 @@
+#ifndef SETUP_H
+#define SETUP_H
+
+int is_git_directory(const char *suspect);
+
+#endif /* SETUP_H */
-- 
1.6.2.5

>From ac2dfd8fcbbafafa92e68b17cb9c419aad0134ed Mon Sep 17 00:00:00 2001
From: Gerhard Wiesinger <lists@wiesinger.com>
Date: Wed, 28 Apr 2010 07:13:09 +0200
Subject: [PATCH 2/2] Added global git directory when environment variable GIT_DIR_GLOBAL is set, missing files, e.g. export GIT_DIR_GLOBAL=${HOME}/.git_global

---
  builtin/init-db.c   |   38 +++++++++++++++-
  builtin/rev-parse.c |    3 +-
  cache.h             |    2 +
  environment.c       |  125 ++++++++++++++++++++++++++++++++++++++++++++++++++-
  setup.c             |    5 +-
  5 files changed, 167 insertions(+), 6 deletions(-)

diff --git a/builtin/init-db.c b/builtin/init-db.c
index edc40ff..a91e762 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -7,6 +7,7 @@
  #include "builtin.h"
  #include "exec_cmd.h"
  #include "parse-options.h"
+#include "environment.h"

  #ifndef DEFAULT_GIT_TEMPLATE_DIR
  #define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates"
@@ -34,6 +35,27 @@ static void safe_create_dir(const char *dir, int share)
  		die("Could not make %s writable by group", dir);
  }

+static void mkdir_recusive(char *directory)
+{
+	char tmp[PATH_MAX+1];
+	char *p = NULL;
+	size_t len;
+
+	snprintf(tmp, sizeof(tmp), "%s", directory);
+	len = strlen(tmp);
+	if(is_dir_sep(tmp[len - 1]))
+		tmp[len - 1] = 0;
+
+	for(p = tmp + 1; *p; p++)
+		if(is_dir_sep(*p)) {
+			char c = *p;
+			*p = 0;
+			safe_create_dir(tmp, 1);
+			*p = c;
+		}
+	safe_create_dir(tmp,1);
+}
+
  static void copy_templates_1(char *path, int baselen,
  			     char *template, int template_baselen,
  			     DIR *dir)
@@ -473,7 +495,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
  	 * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
  	 * without --bare.  Catch the error early.
  	 */
-	git_dir = getenv(GIT_DIR_ENVIRONMENT);
+	git_dir = get_git_dir_from_environment();
  	if ((!git_dir || is_bare_repository_cfg == 1)
  	    && getenv(GIT_WORK_TREE_ENVIRONMENT))
  		die("%s (or --work-tree=<directory>) not allowed without "
@@ -490,7 +512,19 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
  	if (is_bare_repository_cfg < 0)
  		is_bare_repository_cfg = guess_repository_type(git_dir);

-	if (!is_bare_repository_cfg) {
+	if (is_git_dir_global_environment()) {
+		char *global_base_dir = get_git_dir_global_base_dir();
+		mkdir_recusive(global_base_dir);
+		if (!git_work_tree_cfg) {
+			git_work_tree_cfg = xcalloc(PATH_MAX, 1);
+			strncpy(git_work_tree_cfg, global_base_dir, PATH_MAX);
+		}
+		if (access(get_git_work_tree(), X_OK))
+			die_errno ("Cannot access work tree '%s'",
+				   get_git_work_tree());
+	}
+ 
+	if (!is_bare_repository_cfg && !is_git_dir_global_environment()) {
  		if (git_dir) {
  			const char *git_dir_parent = strrchr(git_dir, '/');
  			if (git_dir_parent) {
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 8fbf9d0..b64260f 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -9,6 +9,7 @@
  #include "quote.h"
  #include "builtin.h"
  #include "parse-options.h"
+#include "environment.h"

  #define DO_REVS		1
  #define DO_NOREV	2
@@ -642,7 +643,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
  				continue;
  			}
  			if (!strcmp(arg, "--git-dir")) {
-				const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
+				const char *gitdir = get_git_dir_from_environment();
  				static char cwd[PATH_MAX];
  				int len;
  				if (gitdir) {
diff --git a/cache.h b/cache.h
index 5eb0573..57a647d 100644
--- a/cache.h
+++ b/cache.h
@@ -372,6 +372,8 @@ static inline enum object_type object_type(unsigned int mode)
  }

  #define GIT_DIR_ENVIRONMENT "GIT_DIR"
+#define GIT_DIR_GLOBAL_ENVIRONMENT "GIT_DIR_GLOBAL"
+#define GIT_DIR_GLOBAL_SPECIAL_ROOT_DIRECTORY "/SPECIAL_ROOT_DIRECTORY"
  #define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
  #define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
  #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
diff --git a/environment.c b/environment.c
index 876c5e5..d9768a9 100644
--- a/environment.c
+++ b/environment.c
@@ -8,6 +8,9 @@
   * are.
   */
  #include "cache.h"
+#include "setup.h"
+
+#define DIR_SEPARATOR "/"

  char git_default_email[MAX_GITNAME];
  char git_default_name[MAX_GITNAME];
@@ -80,9 +83,129 @@ const char * const local_repo_env[LOCAL_REPO_ENV_SIZE + 1] = {
  	NULL
  };

+char* path_shorten(char *path)
+{
+	int index = strlen(path);
+
+	while (index > 0) {
+		index--;
+		if (is_dir_sep(path[index])) {
+			path[index] = 0;
+			return path;
+		}
+	}
+
+	// should never get here
+	return "";
+}
+
+static char *get_dir_global_environment(void)
+{
+	return getenv(GIT_DIR_GLOBAL_ENVIRONMENT);
+}
+
+char *get_git_dir_global_base_dir(void)
+{
+	static char cwd_buf[PATH_MAX+1];
+	static char dir_global_buf[PATH_MAX+1];
+	static char git_dir_buf[PATH_MAX+1];
+	int global_environment_len = 0;
+	char *git_dir_global_environment = get_dir_global_environment();
+
+	if (!getcwd(cwd_buf, sizeof(cwd_buf)-1))
+		die_errno("Unable to read current working directory");
+
+	if (!is_absolute_path(git_dir_global_environment))
+		die_errno("Global environment variable" GIT_DIR_GLOBAL_ENVIRONMENT " needs absolute path!");
+
+	strncpy(dir_global_buf, git_dir_global_environment, sizeof(dir_global_buf));
+	global_environment_len = strlen(dir_global_buf);
+	if (is_dir_sep(dir_global_buf[global_environment_len]))
+		dir_global_buf[global_environment_len] = 0;
+
+	return mksnpath(git_dir_buf, sizeof(git_dir_buf), "%s%s", dir_global_buf, cwd_buf);
+}
+
+char *get_git_dir_from_global_environment(char *git_dir_global_environment)
+{
+	static char cwd_buf[PATH_MAX+1];
+	static char cwd_original_buf[PATH_MAX+1];
+	static char dir_global_buf[PATH_MAX+1];
+	static char git_dir_buf[PATH_MAX+1];
+	char *cwd = cwd_buf;
+	char *git_dir = git_dir_buf;
+	int found = 0;
+	int global_environment_len = 0;
+
+	if (!getcwd(cwd_buf, sizeof(cwd_buf)-1))
+		die_errno("Unable to read current working directory");
+
+	if (!is_absolute_path(git_dir_global_environment))
+		die_errno("Global environment variable" GIT_DIR_GLOBAL_ENVIRONMENT " needs absolute path!");
+
+	strncpy(dir_global_buf, git_dir_global_environment, sizeof(dir_global_buf));
+	global_environment_len = strlen(dir_global_buf);
+	if (is_dir_sep(dir_global_buf[global_environment_len]))
+		dir_global_buf[global_environment_len] = 0;
+
+	if (strlen(cwd) == 1 && is_dir_sep(cwd[0]))
+	{
+		// special case for / git repository
+		git_dir = mksnpath(git_dir_buf, sizeof(git_dir_buf), "%s%s" DIR_SEPARATOR "%s", dir_global_buf, GIT_DIR_GLOBAL_SPECIAL_ROOT_DIRECTORY, DEFAULT_GIT_DIR_ENVIRONMENT);
+		return git_dir;
+	}
+
+	strncpy(cwd_original_buf, cwd, sizeof(cwd_original_buf));
+
+	/*
+	 * Test in the following order (relative to the cwd):
+	 * - .git (file containing "gitdir: <path>")
+	 * - .git/
+	 * - ./ (bare)
+	 * - ../.git
+	 * - ../.git/
+	 * - ../ (bare)
+	 * - ../../.git/
+	 *   etc.
+	 */
+	for (;;) {
+		if (*cwd == '\0') {
+			break;
+		}
+
+		git_dir = mksnpath(git_dir_buf, sizeof(git_dir_buf), "%s%s" DIR_SEPARATOR "%s", dir_global_buf, cwd, DEFAULT_GIT_DIR_ENVIRONMENT);
+		if (is_git_directory(git_dir)) {
+			found = 1;
+			break;
+		}
+
+		cwd = path_shorten(cwd);
+	}
+
+	if (!found) {
+		git_dir = mksnpath(git_dir_buf, sizeof(git_dir_buf), "%s%s/%s", dir_global_buf, cwd_original_buf, DEFAULT_GIT_DIR_ENVIRONMENT);
+		return git_dir;
+	}
+
+	return git_dir;
+}
+
+int is_git_dir_global_environment(void)
+{
+	return (get_dir_global_environment() != NULL);
+}
+
+char *get_git_dir_from_environment(void)
+{
+	char *git_dir_global_environment = get_dir_global_environment();
+	if (git_dir_global_environment) return get_git_dir_from_global_environment(git_dir_global_environment);
+
+	return getenv(GIT_DIR_ENVIRONMENT);
+}
+
  static void setup_git_env(void)
  {
-	git_dir = getenv(GIT_DIR_ENVIRONMENT);
+	git_dir = get_git_dir_from_environment();
  	if (!git_dir)
  		git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
  	if (!git_dir)
diff --git a/setup.c b/setup.c
index 5716d90..6ee3a59 100644
--- a/setup.c
+++ b/setup.c
@@ -1,5 +1,6 @@
  #include "cache.h"
  #include "dir.h"
+#include "environment.h"

  static int inside_git_dir = -1;
  static int inside_work_tree = -1;
@@ -165,7 +166,7 @@ const char **get_pathspec(const char *prefix, const char **pathspec)
   *    a proper "ref:", or a regular file HEAD that has a properly
   *    formatted sha1 object name.
   */
-static int is_git_directory(const char *suspect)
+int is_git_directory(const char *suspect)
  {
  	char path[PATH_MAX];
  	size_t len = strlen(suspect);
@@ -337,7 +338,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
  	 * to do any discovery, but we still do repository
  	 * validation.
  	 */
-	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
+	gitdirenv = get_git_dir_from_environment();
  	if (gitdirenv) {
  		if (PATH_MAX - 40 < strlen(gitdirenv))
  			die("'$%s' too big", GIT_DIR_ENVIRONMENT);
-- 
1.6.2.5

>From cca30ca806f9758bb0271f08808e2c830d9aba5e Mon Sep 17 00:00:00 2001
From: Gerhard Wiesinger <lists@wiesinger.com>
Date: Wed, 28 Apr 2010 07:30:01 +0200
Subject: [PATCH 3/3] Updated documentation for submitting patches

---
  Documentation/SubmittingPatches |    2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index abc65de..e871032 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -23,7 +23,7 @@ Checklist (and a short version for the impatient):

  	Patch:

-	- use "git format-patch -M" to create the patch
+	- use "git format-patch -M" to create the patch (e.g. git format-patch -M origin/master)
  	- do not PGP sign your patch
  	- do not attach your patch, but read in the mail
  	  body, unless you cannot teach your mailer to
-- 
1.6.2.5


Ciao,
Gerhard

--
http://www.wiesinger.com/

Re: Global .git directory

From: Gerhard Wiesinger <hidden>
Date: 2016-06-15 22:48:44

On Wed, 28 Apr 2010, Gerhard Wiesinger wrote:
Sorry, was in a hurry, and just wanted to get the patch "out there". No
problem, patch is inline now and hopefully in the right format.

Patch is done after V1.7.1.
Still got no feedback ...

Ciao,
Gerhard

--
http://www.wiesinger.com/

Re: Global .git directory

From: Andrew Ruder <hidden>
Date: 2016-06-15 22:48:44

On Tue, May 04, 2010 at 07:07:08AM +0200, Gerhard Wiesinger wrote:
Still got no feedback ...
I'm not really a person that will be doing the reviewing but as a
frequent lurker on the list, I'm going to try to help you out some.
I'll bite, but I think the lack of response is still due to a major case
of RTFM.  Here's the things from SubmittingPatches that appear to still
be wrong and are most likely keeping your patch from being properly
reviewed:
Commits:

- make commits of logical units
Your patches aren't really in logical units.  Patch 1/2 makes changes to
a header file and creates several function declarations which don't even
exist until 2/2.  So in this case you really would just want one patch
there.

Or even better, perhaps separate the EXISTING functionality into the API
you are eventually shooting for and then add your feature into the next
patch.  I'm sure if done cleanly, some of the changes like
get_git_dir_from_environment() could be done entirely separately from
your feature.  Once everybody agrees that it looks good and works the
same as it always has, it makes the task of reviewing your feature patch
even easier as it will be simply adding a feature and not adding a
feature AND adding a new GIT_DIR API simultaneously.

- the first line of the commit message should be a short
  description and should skip the full stop
- the body should provide a meaningful commit message, which:
	- uses the imperative, present tense: "change",
	  not "changed" or "changes".
	- includes motivation for the change, and contrasts
	  its implementation with previous behaviour
Your commit messages are very under-detailed.  At the very least you
should include at least as much detail as you did in your original
e-mail to the list!  Look through git log some, you'll see that it isn't
uncommon for patches to actually end up much shorter than the patch
itself.  At the very least, the "Subject" of your patch should be much
shorter.
- if you want your work included in git.git, add a
  "Signed-off-by: Your Name [off-list ref]" line to the
  commit message (or just use the option "-s" when
  committing) to confirm that you agree to the Developer's
  Certificate of Origin
git takes this one pretty seriously.  Put this in your patches now to
avoid headaches down the line.
- make sure that you have tests for the bug you are fixing
While you're not exactly fixing a bug, this would benefit from a
testcase.
Patch:

- use "git format-patch -M" to create the patch
You did this, but typically patches are one per e-mail, the subject
being the [PATCH ...] line and the body being the rest rather than
multiple patches all just copy-pasted inline.
- if you change, add, or remove a command line option or
  make some other user interface change, the associated
  documentation should be updated as well.
As the person who added the above to the documentation, it sure is nice
when people edit the appropriate manpages with their proposed changes
:).

I know it all seems nit-picky, but if you want to see your changes make
it into git.git you're best off making it as EASY AS POSSIBLE for the
reviewer to take your patch and apply it and be done with it.  This just
isn't possible without testcases, documentation updates, etc..
Especially for feature additions (vs bug fixes) you really have to make
life as simple (and normal) as possible for reviewers, maintainers,
etc.. After all, it is a lot easier living without a feature than it is
a documented bug-fix!

Just a random lurker trying to help you out here!

Cheers,
Andy

P.S. I'd also double-check the patch, typos (like mkdir_recusive) make
things look sloppy and can turn people off from reviewing (especially
when it is almost the first line of the patch!)

-- 
Andrew Ruder [off-list ref]
http://www.aeruder.net

Re: Global .git directory

From: Andreas Ericsson <hidden>
Date: 2016-06-15 22:48:44

On 05/04/2010 07:40 AM, Andrew Ruder wrote:

[ an exemplary breakdown of why the patch hasn't been reviewed ]

I'll stash this for use in other projects. Thanks a lot Andrew :)

Cc-list culled a bit.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.

Re: Global .git directory

From: Gerhard Wiesinger <hidden>
Date: 2016-06-15 22:48:44

On Mon, 3 May 2010, Andrew Ruder wrote:
On Tue, May 04, 2010 at 07:07:08AM +0200, Gerhard Wiesinger wrote:
I know it all seems nit-picky, but if you want to see your changes make
it into git.git you're best off making it as EASY AS POSSIBLE for the
reviewer to take your patch and apply it and be done with it.  This just
isn't possible without testcases, documentation updates, etc..
Especially for feature additions (vs bug fixes) you really have to make
life as simple (and normal) as possible for reviewers, maintainers,
etc.. After all, it is a lot easier living without a feature than it is
a documented bug-fix!

Just a random lurker trying to help you out here!
Thnx for your feedback. Will rework some of the parts you mentioned.

I think such a strict process should be valid for final commits to the git 
repository. But for a first patch ready for discussion I think one 
shouldn't make such strict process rules. I think we are at the state 
whether such a patch *might* be accepted and reviewers should look at the 
content first to have a decision for digging further (e.g. rework some 
parts of the patch) or for "ok this makes no sense at all". I think this 
saves time of the reviewers and also my time (I could now make all the 
formal stuff of the patch you mentioned but when there is something 
fundamental wrong there e.g in concept all the work was useless when not 
accepted. I think there should be agreement of the roadmap of a feature 
and then a focus on formalism to finally commit a pathc. So I'm a fan of 
discussion and incremental work to minimise useless and typically 
frustrating effort.)

Ciao,
Gerhard

--
http://www.wiesinger.com/
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help