From: Gerhard Wiesinger <lists@wiesinger.com>
To: kusmabite@gmail.com
Cc: Thomas Rast <trast@student.ethz.ch>, git@vger.kernel.org
Subject: Re: Global .git directory
Date: Wed, 28 Apr 2010 22:22:49 +0200 (CEST) [thread overview]
Message-ID: <alpine.LFD.2.00.1004282211431.29101@bbs.intern> (raw)
In-Reply-To: <q2k40aa078e1004280550o322dc5b8jca74d401a5eb1abe@mail.gmail.com>
On Wed, 28 Apr 2010, Erik Faye-Lund wrote:
> On Wed, Apr 28, 2010 at 7:33 AM, Gerhard Wiesinger <lists@wiesinger.com> wrote:
>> On Tue, 27 Apr 2010, Erik Faye-Lund wrote:
>>
>>> On Tue, Apr 27, 2010 at 10:06 PM, Gerhard Wiesinger <lists@wiesinger.com>
>>> wrote:
>>>>
>>>> On Tue, 27 Apr 2010, Thomas Rast wrote:
>>>>>
>>>> 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 <lists@wiesinger.com>
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/
next prev parent reply other threads:[~2010-04-28 20:24 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-27 5:14 Global .git directory Gerhard Wiesinger
2010-04-27 9:59 ` Thomas Rast
2010-04-27 20:06 ` Gerhard Wiesinger
2010-04-27 20:26 ` Erik Faye-Lund
2010-04-28 5:33 ` Gerhard Wiesinger
2010-04-28 6:22 ` Tomas Carnecky
2010-04-28 20:03 ` Gerhard Wiesinger
2010-04-28 8:01 ` Alex Riesen
2010-04-28 20:10 ` Gerhard Wiesinger
2010-04-28 12:50 ` Erik Faye-Lund
2010-04-28 20:22 ` Gerhard Wiesinger [this message]
2010-05-04 5:07 ` Gerhard Wiesinger
2010-05-04 5:40 ` Andrew Ruder
2010-05-04 6:02 ` Andreas Ericsson
2010-05-04 6:07 ` Gerhard Wiesinger
2010-05-04 16:55 ` Junio C Hamano
2010-04-27 20:37 ` Jacob Helwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LFD.2.00.1004282211431.29101@bbs.intern \
--to=lists@wiesinger.com \
--cc=git@vger.kernel.org \
--cc=kusmabite@gmail.com \
--cc=trast@student.ethz.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).