From: Matthias Lederhofer <matled@gmx.net>
To: git@vger.kernel.org, Nguyen Thai Ngoc Duy <pclouds@gmail.com>
Subject: [RFC] introduce GIT_WORK_DIR environment variable
Date: Sun, 11 Mar 2007 05:32:50 +0100 [thread overview]
Message-ID: <20070311043250.GA21331@moooo.ath.cx> (raw)
This environment variable can be used with GIT_DIR to
specify the toplevel working directory. When GIT_DIR is not
set this variable is ignored. As for GIT_DIR there is also
the option git --work-dir which overrides the environment
variable.
---
Missing:
Documentation update but if this feature should not get accepted..
therefore I'll wait for feedback first.
Idea:
Add some way to configure tho working directory for one repository
and set GIT_WORK_DIR automatically when GIT_DIR is used. I think of:
* a subdirectory in the repository directory
e.g. .git/work_dir which is supposed to be a symlink (or a textfile
containing the path for windows compatibility?)
or
* a configuration variable
Considerations:
Without running setup_git_directory_gently is_bare_repository and
is_inside_git_dir may return wrong values. Except for cmd_init_db I
found no place calling on of the functions without calling
setup_git_directory_gently before.
To do:
git init should probably set bare = false when GIT_WORK_DIR is
exported. And if the idea about configurable working directories gets
implemented it could also set this option accordingly.
---
cache.h | 2 +
environment.c | 2 +
git.c | 12 +++++++++-
setup.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 80 insertions(+), 6 deletions(-)
diff --git a/cache.h b/cache.h
index ae25759..042734c 100644
--- a/cache.h
+++ b/cache.h
@@ -144,6 +144,7 @@ enum object_type {
};
#define GIT_DIR_ENVIRONMENT "GIT_DIR"
+#define GIT_WORKING_DIR_ENVIRONMENT "GIT_WORK_DIR"
#define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
#define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
@@ -164,6 +165,7 @@ extern char *get_graft_file(void);
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
+extern int has_working_directory;
extern const char **get_pathspec(const char *prefix, const char **pathspec);
extern const char *setup_git_directory_gently(int *);
extern const char *setup_git_directory(void);
diff --git a/environment.c b/environment.c
index 0151ad0..5c30c9b 100644
--- a/environment.c
+++ b/environment.c
@@ -61,6 +61,8 @@ int is_bare_repository(void)
const char *dir, *s;
if (0 <= is_bare_repository_cfg)
return is_bare_repository_cfg;
+ if (0 <= has_working_directory)
+ return !has_working_directory;
dir = get_git_dir();
if (!strcmp(dir, DEFAULT_GIT_DIR_ENVIRONMENT))
diff --git a/git.c b/git.c
index 04fc99a..3cf7ce2 100644
--- a/git.c
+++ b/git.c
@@ -4,7 +4,7 @@
#include "quote.h"
const char git_usage_string[] =
- "git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]";
+ "git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate] [--bare] [--git-dir=GIT_DIR] [--work-dir=GIT_WORK_DIR] [--help] COMMAND [ARGS]";
static void prepend_to_path(const char *dir, int len)
{
@@ -68,6 +68,16 @@ static int handle_options(const char*** argv, int* argc)
(*argc)--;
} else if (!prefixcmp(cmd, "--git-dir=")) {
setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
+ } else if (!strcmp(cmd, "--work-dir")) {
+ if (*argc < 2) {
+ fprintf(stderr, "No directory given for --work-dir.\n" );
+ usage(git_usage_string);
+ }
+ setenv(GIT_WORKING_DIR_ENVIRONMENT, (*argv)[1], 1);
+ (*argv)++;
+ (*argc)--;
+ } else if (!prefixcmp(cmd, "--work-dir=")) {
+ setenv(GIT_WORKING_DIR_ENVIRONMENT, cmd + 11, 1);
} else if (!strcmp(cmd, "--bare")) {
static char git_dir[PATH_MAX+1];
setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 1);
diff --git a/setup.c b/setup.c
index dda67d2..7f5d73b 100644
--- a/setup.c
+++ b/setup.c
@@ -192,6 +192,8 @@ int is_inside_git_dir(void)
return inside_git_dir;
}
+int has_working_directory = -1;
+
const char *setup_git_directory_gently(int *nongit_ok)
{
static char cwd[PATH_MAX+1];
@@ -205,15 +207,73 @@ const char *setup_git_directory_gently(int *nongit_ok)
*/
gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
if (gitdirenv) {
+ struct stat st, st_work, st_git;
+ const char *gitwd;
+ char *prefix;
+ char c;
+ int len;
+
if (PATH_MAX - 40 < strlen(gitdirenv))
die("'$%s' too big", GIT_DIR_ENVIRONMENT);
- if (is_git_directory(gitdirenv))
- return NULL;
- if (nongit_ok) {
- *nongit_ok = 1;
+ if (!is_git_directory(gitdirenv)) {
+ if (nongit_ok) {
+ *nongit_ok = 1;
+ return NULL;
+ }
+ die("Not a git repository: '%s'", gitdirenv);
+ }
+
+ gitwd = getenv(GIT_WORKING_DIR_ENVIRONMENT);
+ if (!gitwd || stat(gitwd, &st_work))
return NULL;
+ if (inside_git_dir == -1 && stat(gitdirenv, &st_git))
+ die("Unable to stat git directory");
+ if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')
+ die("Unable to read current working directory");
+ len = strlen(cwd);
+
+ prefix = cwd+len;
+ for (;;) {
+ c = *prefix;
+ *prefix = '\0';
+ if (stat(cwd, &st))
+ die("Unable to stat '%s'", cwd);
+ if (st_work.st_dev == st.st_dev &&
+ st_work.st_ino == st.st_ino)
+ break;
+ if (inside_git_dir == -1 &&
+ st_git.st_dev == st.st_dev &&
+ st_git.st_ino == st.st_ino)
+ inside_git_dir = 1;
+ *prefix = c;
+
+ if (prefix == cwd+1) {
+ has_working_directory = 0;
+ return NULL;
+ }
+ while (*(--prefix) != '/')
+ ; /* do nothing */
+ if (prefix == cwd)
+ prefix++;
+ }
+
+ if (chdir(cwd))
+ die("Cannot change directory to '%s'", cwd);
+
+ if (c) {
+ *prefix = c;
+ prefix++;
+ cwd[len] = '/';
+ cwd[len+1] = '\0';
+ } else {
+ prefix = NULL;
}
- die("Not a git repository: '%s'", gitdirenv);
+
+ has_working_directory = 1;
+ if (inside_git_dir == -1)
+ inside_git_dir = 0;
+
+ return prefix;
}
if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
--
1.5.0.3
next reply other threads:[~2007-03-11 4:34 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-11 4:32 Matthias Lederhofer [this message]
2007-03-11 5:34 ` [RFC] introduce GIT_WORK_DIR environment variable Junio C Hamano
2007-03-11 8:26 ` Andy Parkins
2007-03-11 16:22 ` Matthias Lederhofer
2007-03-11 20:10 ` Junio C Hamano
2007-03-11 21:43 ` Johannes Schindelin
2007-03-11 20:37 ` Linus Torvalds
2007-03-11 21:04 ` Junio C Hamano
2007-03-11 21:13 ` Linus Torvalds
2007-03-12 8:08 ` A.J. Rossini
2007-04-01 7:42 ` Andy Parkins
2007-03-11 12:42 ` Nguyen Thai Ngoc Duy
2007-03-11 13:33 ` Matthias Lederhofer
2007-03-11 13:46 ` Nguyen Thai Ngoc Duy
2007-03-11 14:05 ` Matthias Lederhofer
2007-03-11 14:18 ` Nguyen Thai Ngoc Duy
2007-03-11 15:56 ` [PATCH(amend)] " Matthias Lederhofer
2007-03-11 16:25 ` Nguyen Thai Ngoc Duy
2007-03-11 21:29 ` [PATCH] use $GIT_DIR/workdir as working directory with $GIT_DIR Matthias Lederhofer
2007-03-13 23:10 ` [PATCH] core.workdir config variable Matthias Lederhofer
2007-03-13 23:57 ` [PATCH(amend)] " Matthias Lederhofer
2007-03-14 6:01 ` Shawn O. Pearce
2007-03-14 7:48 ` Junio C Hamano
2007-03-14 14:20 ` Shawn O. Pearce
2007-03-11 13:27 ` [RFC] introduce GIT_WORK_DIR environment variable Nguyen Thai Ngoc Duy
2007-03-11 15:05 ` [PATCH] rev-parse: --is-bare-repository option Matthias Lederhofer
2007-03-12 11:53 ` [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set Matthias Lederhofer
2007-03-12 12:12 ` Joshua N Pritikin
2007-03-12 12:52 ` Matthias Lederhofer
2007-03-12 13:12 ` Matthias Lederhofer
2007-03-12 13:36 ` Nguyen Thai Ngoc Duy
2007-03-12 14:08 ` Matthias Lederhofer
2007-03-12 17:31 ` Junio C Hamano
2007-03-12 18:08 ` Matthias Lederhofer
2007-03-12 19:18 ` [PATCH] always interpret GIT_WORK_DIR relative to $GIT_DIR Matthias Lederhofer
2007-03-12 19:53 ` [PATCH] GIT_WORK_DIR: documentation for relative path Matthias Lederhofer
2007-03-12 20:05 ` [PATCH] git-init: set up GIT_DIR/workdir if GIT_WORK_DIR is set Junio C Hamano
2007-03-12 20:40 ` Matthias Lederhofer
2007-03-12 19:23 ` [PATCH(amend)] " Matthias Lederhofer
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=20070311043250.GA21331@moooo.ath.cx \
--to=matled@gmx.net \
--cc=git@vger.kernel.org \
--cc=pclouds@gmail.com \
/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).