* [PATCH 1/5] rev-parse: --is-bare-repository option
2007-03-17 14:34 ` Matthias Lederhofer
@ 2007-03-17 14:42 ` Matthias Lederhofer
2007-03-17 14:43 ` [PATCH 2/5] test git-rev-parse Matthias Lederhofer
` (4 subsequent siblings)
5 siblings, 0 replies; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-17 14:42 UTC (permalink / raw)
To: Junio C Hamano, git
Signed-off-by: Matthias Lederhofer <matled@gmx.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Documentation/git-rev-parse.txt | 7 +++++++
builtin-rev-parse.c | 5 +++++
git-sh-setup.sh | 6 +-----
git-svn.perl | 2 +-
4 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index ccc66aa..d024d93 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -89,6 +89,13 @@ OPTIONS
--git-dir::
Show `$GIT_DIR` if defined else show the path to the .git directory.
+--is-inside-git-dir::
+ When the current working directory is below the repository
+ directory print "true", otherwise "false".
+
+--is-bare-repository::
+ When the repository is bare print "true", otherwise "false".
+
--short, --short=number::
Instead of outputting the full SHA1 values of object names try to
abbreviate them to a shorter unique name. When no length is specified
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 37addb2..71d5162 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -352,6 +352,11 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
: "false");
continue;
}
+ if (!strcmp(arg, "--is-bare-repository")) {
+ printf("%s\n", is_bare_repository() ? "true"
+ : "false");
+ continue;
+ }
if (!prefixcmp(arg, "--since=")) {
show_datestring("--max-age=", arg+8);
continue;
diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index f24c7f2..9ac657a 100755
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -29,11 +29,7 @@ set_reflog_action() {
}
is_bare_repository () {
- git-config --bool --get core.bare ||
- case "$GIT_DIR" in
- .git | */.git) echo false ;;
- *) echo true ;;
- esac
+ git-rev-parse --is-bare-repository
}
cd_to_toplevel () {
diff --git a/git-svn.perl b/git-svn.perl
index e845789..c4e343a 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -562,7 +562,7 @@ sub post_fetch_checkout {
my $index = $ENV{GIT_INDEX_FILE} || "$ENV{GIT_DIR}/index";
return if -f $index;
- chomp(my $bare = `git config --bool --get core.bare`);
+ chomp(my $bare = `git rev-parse --is-bare-repository`);
return if $bare eq 'true';
return if command_oneline(qw/rev-parse --is-inside-git-dir/) eq 'true';
command_noisy(qw/read-tree -m -u -v HEAD HEAD/);
--
1.5.0.4.414.g32da9
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 2/5] test git-rev-parse
2007-03-17 14:34 ` Matthias Lederhofer
2007-03-17 14:42 ` [PATCH 1/5] rev-parse: --is-bare-repository option Matthias Lederhofer
@ 2007-03-17 14:43 ` Matthias Lederhofer
2007-03-27 22:07 ` [PATCH(amend)] " Matthias Lederhofer
2007-03-17 14:44 ` [PATCH 3/5] introduce GIT_WORK_TREE environment variable Matthias Lederhofer
` (3 subsequent siblings)
5 siblings, 1 reply; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-17 14:43 UTC (permalink / raw)
To: Junio C Hamano, git
this tests --is-bare-repository, --is-inside-git-dir, --show-cdup and
--show-prefix
Signed-off-by: Matthias Lederhofer <matled@gmx.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
t/t1500-rev-parse.sh | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 57 insertions(+), 0 deletions(-)
create mode 100755 t/t1500-rev-parse.sh
diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
new file mode 100755
index 0000000..c385660
--- /dev/null
+++ b/t/t1500-rev-parse.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+test_description='test git rev-parse'
+. ./test-lib.sh
+
+test_expect_success 'toplevel: is-bare-repository' \
+ 'test "false" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'toplevel: is-inside-git-dir' \
+ 'test "false" = "$(git rev-parse --is-inside-git-dir)"'
+test_expect_success 'toplevel: show-cdup' \
+ 'test "" = "$(git rev-parse --show-cdup)"'
+test_expect_success 'toplevel: show-prefix' \
+ 'test "" = "$(git rev-parse --show-prefix)"'
+
+cd .git/objects || exit 1
+test_expect_success 'in-git-dir: is-bare-repository' \
+ 'test "false" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'in-git-dir: is-inside-git-dir' \
+ 'test "true" = "$(git rev-parse --is-inside-git-dir)"'
+test_expect_success 'in-git-dir: show-cdup' \
+ 'test "../../" = "$(git rev-parse --show-cdup)"'
+test_expect_success 'in-git-dir: show-prefix' \
+ 'test ".git/objects/" = "$(git rev-parse --show-prefix)"'
+cd ../.. || exit 1
+
+mkdir sub || exit 1
+cd sub || exit 1
+test_expect_success 'subdirectory: is-bare-repository' \
+ 'test "false" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'subdirectory: is-inside-git-dir' \
+ 'test "false" = "$(git rev-parse --is-inside-git-dir)"'
+test_expect_success 'subdirectory: show-cdup' \
+ 'test "../" = "$(git rev-parse --show-cdup)"'
+test_expect_success 'subdirectory: show-prefix' \
+ 'test "sub/" = "$(git rev-parse --show-prefix)"'
+cd .. || exit 1
+
+test_expect_success 'core.bare = true: is-bare-repository' \
+ 'git config core.bare true &&
+ test "true" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'unset core.bare: is-bare-repository' \
+ 'git config --unset core.bare &&
+ test "false" = "$(git rev-parse --is-bare-repository)"'
+
+mv .git foo.git || exit 1
+export GIT_DIR=foo.git
+export GIT_CONFIG=foo.git/config
+test_expect_success 'GIT_DIR=foo.git: is-bare-repository' \
+ 'test "true" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'GIT_DIR=foo.git, core.bare = true: is-bare-repository' \
+ 'git --git-dir foo.git config core.bare true &&
+ test "true" = "$(git --git-dir foo.git rev-parse --is-bare-repository)"'
+test_expect_success 'GIT_DIR=foo.git, core.bare = false: is-bare-repository' \
+ 'git config core.bare false &&
+ test "false" = "$(git rev-parse --is-bare-repository)"'
+
+test_done
--
1.5.0.4.414.g32da9
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH(amend)] test git-rev-parse
2007-03-17 14:43 ` [PATCH 2/5] test git-rev-parse Matthias Lederhofer
@ 2007-03-27 22:07 ` Matthias Lederhofer
0 siblings, 0 replies; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-27 22:07 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
this tests --is-bare-repository, --is-inside-git-dir, --show-cdup and
--show-prefix
Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
The old version used --git-dir twice which was unnecessary.
---
t/t1500-rev-parse.sh | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 57 insertions(+), 0 deletions(-)
create mode 100755 t/t1500-rev-parse.sh
diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
new file mode 100755
index 0000000..bfc615d
--- /dev/null
+++ b/t/t1500-rev-parse.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+test_description='test git rev-parse'
+. ./test-lib.sh
+
+test_expect_success 'toplevel: is-bare-repository' \
+ 'test "false" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'toplevel: is-inside-git-dir' \
+ 'test "false" = "$(git rev-parse --is-inside-git-dir)"'
+test_expect_success 'toplevel: show-cdup' \
+ 'test "" = "$(git rev-parse --show-cdup)"'
+test_expect_success 'toplevel: show-prefix' \
+ 'test "" = "$(git rev-parse --show-prefix)"'
+
+cd .git/objects || exit 1
+test_expect_success 'in-git-dir: is-bare-repository' \
+ 'test "false" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'in-git-dir: is-inside-git-dir' \
+ 'test "true" = "$(git rev-parse --is-inside-git-dir)"'
+test_expect_success 'in-git-dir: show-cdup' \
+ 'test "../../" = "$(git rev-parse --show-cdup)"'
+test_expect_success 'in-git-dir: show-prefix' \
+ 'test ".git/objects/" = "$(git rev-parse --show-prefix)"'
+cd ../.. || exit 1
+
+mkdir sub || exit 1
+cd sub || exit 1
+test_expect_success 'subdirectory: is-bare-repository' \
+ 'test "false" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'subdirectory: is-inside-git-dir' \
+ 'test "false" = "$(git rev-parse --is-inside-git-dir)"'
+test_expect_success 'subdirectory: show-cdup' \
+ 'test "../" = "$(git rev-parse --show-cdup)"'
+test_expect_success 'subdirectory: show-prefix' \
+ 'test "sub/" = "$(git rev-parse --show-prefix)"'
+cd .. || exit 1
+
+test_expect_success 'core.bare = true: is-bare-repository' \
+ 'git config core.bare true &&
+ test "true" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'unset core.bare: is-bare-repository' \
+ 'git config --unset core.bare &&
+ test "false" = "$(git rev-parse --is-bare-repository)"'
+
+mv .git foo.git || exit 1
+export GIT_DIR=foo.git
+export GIT_CONFIG=foo.git/config
+test_expect_success 'GIT_DIR=foo.git: is-bare-repository' \
+ 'test "true" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'GIT_DIR=foo.git, core.bare = true: is-bare-repository' \
+ 'git config core.bare true &&
+ test "true" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'GIT_DIR=foo.git, core.bare = false: is-bare-repository' \
+ 'git config core.bare false &&
+ test "false" = "$(git rev-parse --is-bare-repository)"'
+
+test_done
--
1.5.1.rc2.621.gd841-dirty
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 3/5] introduce GIT_WORK_TREE environment variable
2007-03-17 14:34 ` Matthias Lederhofer
2007-03-17 14:42 ` [PATCH 1/5] rev-parse: --is-bare-repository option Matthias Lederhofer
2007-03-17 14:43 ` [PATCH 2/5] test git-rev-parse Matthias Lederhofer
@ 2007-03-17 14:44 ` Matthias Lederhofer
2007-03-18 19:43 ` Matthias Lederhofer
2007-03-18 20:12 ` Matthias Lederhofer
2007-03-17 14:44 ` [PATCH 4/5] test GIT_WORK_TREE Matthias Lederhofer
` (2 subsequent siblings)
5 siblings, 2 replies; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-17 14:44 UTC (permalink / raw)
To: Junio C Hamano, git
This environment variable can be used with GIT_DIR to
specify the working tree. When GIT_DIR is not set this
variable is ignored. As for GIT_DIR there is also the
option git --work-tree which overrides the environment
variable and a config setting core.worktree which is used as
default value.
Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
Documentation/config.txt | 4 ++
Documentation/git.txt | 17 +++++++-
cache.h | 2 +
environment.c | 11 ++++-
git.c | 12 +++++-
setup.c | 98 ++++++++++++++++++++++++++++++++++++++++++---
t/test-lib.sh | 1 +
7 files changed, 134 insertions(+), 11 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 953acae..dc1497d 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -162,6 +162,10 @@ repository that ends in "/.git" is assumed to be not bare (bare =
false), while all other repositories are assumed to be bare (bare
= true).
+core.worktree::
+ Path to the working tree when GIT_DIR is set. This can be
+ overriden by GIT_WORK_TREE.
+
core.logAllRefUpdates::
Updates to a ref <ref> is logged to the file
"$GIT_DIR/logs/<ref>", by appending the new and old
diff --git a/Documentation/git.txt b/Documentation/git.txt
index e875e83..e870ac8 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -10,7 +10,8 @@ SYNOPSIS
--------
[verse]
'git' [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate]
- [--bare] [--git-dir=GIT_DIR] [--help] COMMAND [ARGS]
+ [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE]
+ [--help] COMMAND [ARGS]
DESCRIPTION
-----------
@@ -81,6 +82,14 @@ OPTIONS
Set the path to the repository. This can also be controlled by
setting the GIT_DIR environment variable.
+--work-tree=<path>::
+ Set the path to the working tree. The value will be used only
+ in combination with $GIT_DIR or '--git-dir'. If GIT_DIR is
+ set but this option is not git will assume that the current
+ directory is also the working tree.
+ This can also be controlled by setting the GIT_WORK_TREE
+ environment variable.
+
--bare::
Same as --git-dir=`pwd`.
@@ -325,6 +334,12 @@ git so take care if using Cogito etc.
specifies a path to use instead of the default `.git`
for the base of the repository.
+'GIT_WORK_TREE'::
+ Set the path to the working tree. The value will be used only
+ in combination with $GIT_DIR or '--git-dir'. If GIT_DIR is
+ set but this option is not git will assume that the current
+ directory is also the working tree.
+
git Commits
~~~~~~~~~~~
'GIT_AUTHOR_NAME'::
diff --git a/cache.h b/cache.h
index 3818e10..ced091b 100644
--- a/cache.h
+++ b/cache.h
@@ -144,6 +144,7 @@ enum object_type {
};
#define GIT_DIR_ENVIRONMENT "GIT_DIR"
+#define GIT_WORKING_TREE_ENVIRONMENT "GIT_WORK_TREE"
#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 inside_working_tree;
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..208b7aa 100644
--- a/environment.c
+++ b/environment.c
@@ -59,8 +59,15 @@ static void setup_git_env(void)
int is_bare_repository(void)
{
const char *dir, *s;
- if (0 <= is_bare_repository_cfg)
- return is_bare_repository_cfg;
+ /* definitely bare */
+ if (is_bare_repository_cfg == 1)
+ return 1;
+ /* GIT_WORK_TREE is set, bare if cwd is outside */
+ if (inside_working_tree >= 0)
+ return !inside_working_tree;
+ /* configuration says it is not bare */
+ if (is_bare_repository_cfg == 0)
+ return 0;
dir = get_git_dir();
if (!strcmp(dir, DEFAULT_GIT_DIR_ENVIRONMENT))
diff --git a/git.c b/git.c
index dde4d07..9d7eeb3 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-tree=GIT_WORK_TREE] [--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-tree")) {
+ if (*argc < 2) {
+ fprintf(stderr, "No directory given for --work-tree.\n" );
+ usage(git_usage_string);
+ }
+ setenv(GIT_WORKING_TREE_ENVIRONMENT, (*argv)[1], 1);
+ (*argv)++;
+ (*argc)--;
+ } else if (!prefixcmp(cmd, "--work-tree=")) {
+ setenv(GIT_WORKING_TREE_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 a45ea83..ee0719a 100644
--- a/setup.c
+++ b/setup.c
@@ -192,6 +192,18 @@ int is_inside_git_dir(void)
return inside_git_dir;
}
+static char *git_work_tree;
+
+static int git_work_tree_config(const char *var, const char *value)
+{
+ if (!strcmp(var, "core.worktree")) {
+ strlcpy(git_work_tree, value, PATH_MAX);
+ }
+ return 0;
+}
+
+int inside_working_tree = -1;
+
const char *setup_git_directory_gently(int *nongit_ok)
{
static char cwd[PATH_MAX+1];
@@ -199,21 +211,93 @@ const char *setup_git_directory_gently(int *nongit_ok)
int len, offset;
/*
- * If GIT_DIR is set explicitly, we're not going
- * to do any discovery, but we still do repository
- * validation.
+ * If GIT_DIR is set explicitly, we do repository validation
+ * and check for GIT_WORK_TREE as working tree.
*/
gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
if (gitdirenv) {
+ const char *gitwt;
+ char worktree[PATH_MAX+1], gitdir[PATH_MAX+1];
+ int len;
+ int wt_rel_cwd;
+
if (PATH_MAX - 40 < strlen(gitdirenv))
die("'$%s' too big", GIT_DIR_ENVIRONMENT);
- if (is_git_directory(gitdirenv))
+ if (!is_git_directory(gitdirenv)) {
+ if (nongit_ok) {
+ *nongit_ok = 1;
+ return NULL;
+ }
+ die("Not a git repository: '%s'", gitdirenv);
+ }
+
+ gitwt = getenv(GIT_WORKING_TREE_ENVIRONMENT);
+ wt_rel_cwd = (gitwt && gitwt[0] != '/');
+ /* get worktree from config */
+ if (!gitwt) {
+ wt_rel_cwd = 0;
+ worktree[0] = '\0';
+ git_work_tree = worktree;
+ git_config(git_work_tree_config);
+ git_work_tree = NULL;
+ if (worktree[0])
+ gitwt = worktree;
+ }
+ if (!gitwt)
return NULL;
- if (nongit_ok) {
- *nongit_ok = 1;
+
+ /* run getcwd in cwd, GIT_DIR and GIT_WORK_TREE */
+ if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')
+ die("Unable to read current working directory");
+ if (chdir(gitdirenv))
+ die("Cannot change directory to '%s'", gitdirenv);
+ if (!getcwd(gitdir, sizeof(gitdir)-1) || gitdir[0] != '/')
+ die("Unable to read current working directory");
+ /* relative path from old cwd */
+ if (wt_rel_cwd && chdir(cwd))
+ die("Cannot come back to cwd");
+ if (chdir(gitwt)) {
+ if (wt_rel_cwd || gitwt[0] == '/')
+ die("Cannot change directory to working tree "
+ "'%s'", gitwt);
+ else
+ die("Cannot change directory to working tree "
+ "'%s' from $GIT_DIR", gitwt);
+ }
+ if (!getcwd(worktree, sizeof(worktree)-1) || worktree[0] != '/')
+ die("Unable to read current working directory");
+
+ len = strlen(cwd);
+ cwd[len] = '/';
+ cwd[len+1] = '\0';
+
+ len = strlen(worktree);
+ worktree[len] = '/';
+ worktree[len+1] = '\0';
+ inside_working_tree = !prefixcmp(cwd, worktree);
+
+ if (inside_working_tree) {
+ inside_git_dir = 0;
+ } else {
+ len = strlen(gitdir);
+ gitdir[len] = '/';
+ gitdir[len+1] = '\0';
+ inside_git_dir = !prefixcmp(cwd, gitdir);
+ gitdir[len] = '\0';
+ }
+
+ if (!inside_working_tree) {
+ if (chdir(cwd))
+ die("Cannot come back to cwd");
return NULL;
}
- die("Not a git repository: '%s'", gitdirenv);
+ if (gitdirenv[0] != '/')
+ setenv(GIT_DIR_ENVIRONMENT, gitdir, 1);
+
+ len = strlen(worktree);
+ if (cwd[len] == '\0')
+ return NULL;
+ return cwd+len;
}
if (!getcwd(cwd, sizeof(cwd)-1) || cwd[0] != '/')
diff --git a/t/test-lib.sh b/t/test-lib.sh
index c075474..77c6d23 100755
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -25,6 +25,7 @@ GIT_COMMITTER_EMAIL=committer@example.com
GIT_COMMITTER_NAME='C O Mitter'
unset GIT_DIFF_OPTS
unset GIT_DIR
+unset GIT_WORK_TREE
unset GIT_EXTERNAL_DIFF
unset GIT_INDEX_FILE
unset GIT_OBJECT_DIRECTORY
--
1.5.0.4.414.g32da9
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH 3/5] introduce GIT_WORK_TREE environment variable
2007-03-17 14:44 ` [PATCH 3/5] introduce GIT_WORK_TREE environment variable Matthias Lederhofer
@ 2007-03-18 19:43 ` Matthias Lederhofer
2007-03-18 20:12 ` Matthias Lederhofer
1 sibling, 0 replies; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-18 19:43 UTC (permalink / raw)
To: Junio C Hamano, git
Matthias Lederhofer <matled@gmx.net> wrote:
> diff --git a/setup.c b/setup.c
[..]
> const char *setup_git_directory_gently(int *nongit_ok)
> {
> static char cwd[PATH_MAX+1];
> @@ -199,21 +211,93 @@ const char *setup_git_directory_gently(int *nongit_ok)
> int len, offset;
>
> /*
> - * If GIT_DIR is set explicitly, we're not going
> - * to do any discovery, but we still do repository
> - * validation.
> + * If GIT_DIR is set explicitly, we do repository validation
> + * and check for GIT_WORK_TREE as working tree.
> */
> gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
> if (gitdirenv) {
> + const char *gitwt;
> + char worktree[PATH_MAX+1], gitdir[PATH_MAX+1];
> + int len;
^^^^^^^^
This is not really needed because there is already a variable len of
the same type.
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH 3/5] introduce GIT_WORK_TREE environment variable
2007-03-17 14:44 ` [PATCH 3/5] introduce GIT_WORK_TREE environment variable Matthias Lederhofer
2007-03-18 19:43 ` Matthias Lederhofer
@ 2007-03-18 20:12 ` Matthias Lederhofer
2007-03-18 20:23 ` Matthias Lederhofer
1 sibling, 1 reply; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-18 20:12 UTC (permalink / raw)
To: Junio C Hamano, git
Matthias Lederhofer <matled@gmx.net> wrote:
> + inside_working_tree = !prefixcmp(cwd, worktree);
[..]
> + inside_git_dir = !prefixcmp(cwd, gitdir);
This time a real bug: the parameters have to be the other way around.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] introduce GIT_WORK_TREE environment variable
2007-03-18 20:12 ` Matthias Lederhofer
@ 2007-03-18 20:23 ` Matthias Lederhofer
2007-03-18 20:28 ` Junio C Hamano
0 siblings, 1 reply; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-18 20:23 UTC (permalink / raw)
To: Junio C Hamano, git
Matthias Lederhofer <matled@gmx.net> wrote:
> Matthias Lederhofer <matled@gmx.net> wrote:
> > + inside_working_tree = !prefixcmp(cwd, worktree);
> [..]
> > + inside_git_dir = !prefixcmp(cwd, gitdir);
>
> This time a real bug: the parameters have to be the other way around.
Sorry, it was right. prefixcmp got me confused again when doing some
testing and the result wasn't what I expected. I'll go and copy&paste
100 times !prefixcmp(str, prefix) means "begins str with prefix?"
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/5] introduce GIT_WORK_TREE environment variable
2007-03-18 20:23 ` Matthias Lederhofer
@ 2007-03-18 20:28 ` Junio C Hamano
0 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2007-03-18 20:28 UTC (permalink / raw)
To: Matthias Lederhofer; +Cc: git
Matthias Lederhofer <matled@gmx.net> writes:
> Matthias Lederhofer <matled@gmx.net> wrote:
>> Matthias Lederhofer <matled@gmx.net> wrote:
>> > + inside_working_tree = !prefixcmp(cwd, worktree);
>> [..]
>> > + inside_git_dir = !prefixcmp(cwd, gitdir);
>>
>> This time a real bug: the parameters have to be the other way around.
>
> Sorry, it was right. prefixcmp got me confused again when doing some
> testing and the result wasn't what I expected. I'll go and copy&paste
> 100 times !prefixcmp(str, prefix) means "begins str with prefix?"
I do not mind replacing the whole set, but keeping track of
these small "oops", "oh", "ah" are confusing to me.
Could you take a deep breath, review them yourself one more
time, and resend, *after* making sure that you are confident
with them enough to feel that you would not have to issue
"oops", "sorry", "ah this is better" messages for a few days
after sending them out, pretty please?
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 4/5] test GIT_WORK_TREE
2007-03-17 14:34 ` Matthias Lederhofer
` (2 preceding siblings ...)
2007-03-17 14:44 ` [PATCH 3/5] introduce GIT_WORK_TREE environment variable Matthias Lederhofer
@ 2007-03-17 14:44 ` Matthias Lederhofer
2007-03-17 14:45 ` [PATCH 5/5] git-init: set core.worktree when GIT_WORK_TREE is specified Matthias Lederhofer
2007-03-18 8:47 ` [PATCH] git-init: set core.workdir when GIT_WORK_DIR " Junio C Hamano
5 siblings, 0 replies; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-17 14:44 UTC (permalink / raw)
To: Junio C Hamano, git
Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
t/t1501-worktree.sh | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 91 insertions(+), 0 deletions(-)
create mode 100755 t/t1501-worktree.sh
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
new file mode 100755
index 0000000..bc08994
--- /dev/null
+++ b/t/t1501-worktree.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+test_description='test GIT_WORK_TREE'
+. ./test-lib.sh
+
+export GIT_DIR=$(pwd)/repository
+export GIT_CONFIG="$GIT_DIR/config"
+top=$(pwd) || exit 1
+mv .git "$GIT_DIR" || exit 1
+mkdir -p working/tree || exit 1
+
+# test setup code and precedence of core.worktree, GIT_WORK_TREE and --work-tree
+test_expect_failure 'GIT_WORK_TREE=non-existent' \
+ 'env GIT_WORK_TREE=non-existent git rev-parse'
+test_expect_success 'GIT_WORK_TREE=working/tree' \
+ 'env GIT_WORK_TREE=working/tree git rev-parse'
+test_expect_success 'GIT_WORK_TREE=`pwd`/working/tree' \
+ 'env GIT_WORK_TREE="$(pwd)"/working/tree git rev-parse'
+
+test_expect_success '--work-tree' \
+ 'git --work-tree working/tree rev-parse'
+test_expect_success '--work-tree overrides GIT_WORK_TREE' \
+ 'env GIT_WORK_TREE=non-existent git --work-tree working/tree rev-parse'
+
+test_expect_success 'core.worktree = non-existent' \
+ 'git config core.worktree non-existent'
+test_expect_failure 'core.worktree' \
+ 'git rev-parse'
+test_expect_success 'GIT_WORK_TREE overrides core.worktree' \
+ 'env GIT_WORK_TREE=working/tree git rev-parse'
+test_expect_success '--work-tree overrides core.worktree' \
+ 'git --work-tree working/tree rev-parse'
+
+test_expect_success 'core.worktree = `pwd`/working/tree' \
+ 'git --work-tree . config core.worktree "$(pwd)"/working/tree'
+test_expect_success 'core.worktree' \
+ 'git rev-parse'
+test_expect_success 'core.worktree = ../working/tree' \
+ 'git --work-tree . config core.worktree ../working/tree'
+test_expect_success 'core.worktree' \
+ 'git rev-parse'
+
+# outside of working tree
+test_expect_success 'outside: --is-bare-repository' \
+ 'test "true" = "$(git rev-parse --is-bare-repository)"'
+
+# in toplevel working tree
+cd working/tree || exit 1
+test_expect_success 'inside: --is-bare-repository' \
+ 'test "false" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'inside: --is-inside-git-dir' \
+ 'test "false" = "$(git rev-parse --is-inside-git-dir)"'
+test_expect_success 'inside: --show-prefix' \
+ 'test "" = "$(git rev-parse --show-prefix)"'
+test_expect_success 'inside: --show-cdup' \
+ 'test "" = "$(git rev-parse --show-cdup)"'
+
+# in subdirectory
+mkdir -p a/b || exit 1
+cd a/b || exit 1
+test_expect_success 'subdirectory: --is-bare-repository' \
+ 'test "false" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'subdirectory: --is-inside-git-dir' \
+ 'test "false" = "$(git rev-parse --is-inside-git-dir)"'
+test_expect_success 'subdirectory: --show-prefix' \
+ 'test "a/b/" = "$(git rev-parse --show-prefix)"'
+test_expect_success 'subdirectory: --show-cdup' \
+ 'test "../../" = "$(git rev-parse --show-cdup)"'
+
+# in repository directory
+cd "$top/repository" || exit 1
+test_expect_success 'repository: --is-bare-repository' \
+ 'test "true" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'repository: --is-inside-git-dir' \
+ 'test "true" = "$(git rev-parse --is-inside-git-dir)"'
+cd objects || exit 1
+test_expect_success 'repository/objects: --is-inside-git-dir' \
+ 'test "true" = "$(git rev-parse --is-inside-git-dir)"'
+cd .. || exit 1
+
+# worktree is subdirectory of repository
+mkdir worktree || exit 1
+cd worktree || exit 1
+test_expect_success 'core.worktree = worktree' \
+ 'git config core.worktree worktree'
+test_expect_success 'repository/worktree: --is-bare-repository' \
+ 'test "false" = "$(git rev-parse --is-bare-repository)"'
+test_expect_success 'repository/worktree: --is-inside-git-dir' \
+ 'test "false" = "$(git rev-parse --is-inside-git-dir)"'
+
+test_done
--
1.5.0.4.414.g32da9
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH 5/5] git-init: set core.worktree when GIT_WORK_TREE is specified
2007-03-17 14:34 ` Matthias Lederhofer
` (3 preceding siblings ...)
2007-03-17 14:44 ` [PATCH 4/5] test GIT_WORK_TREE Matthias Lederhofer
@ 2007-03-17 14:45 ` Matthias Lederhofer
2007-03-18 8:47 ` [PATCH] git-init: set core.workdir when GIT_WORK_DIR " Junio C Hamano
5 siblings, 0 replies; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-17 14:45 UTC (permalink / raw)
To: Junio C Hamano, git
git init will die with an error message before doing anything if the
value of GIT_WORK_TREE is no valid directory. GIT_WORK_TREE is also
expanded to an absolute path for the config file.
Signed-off-by: Matthias Lederhofer <matled@gmx.net>
---
builtin-init-db.c | 31 ++++++++++++++++++++++++++++++-
t/t1501-worktree.sh | 15 +++++++++++++++
2 files changed, 45 insertions(+), 1 deletions(-)
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 4df9fd0..4ea8c1f 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -182,6 +182,7 @@ static int create_default_files(const char *git_dir, const char *template_path)
char repo_version_string[10];
int reinit;
int filemode;
+ const char *git_work_tree = getenv(GIT_WORKING_TREE_ENVIRONMENT);
if (len > sizeof(path)-50)
die("insane git directory %s", git_dir);
@@ -252,7 +253,7 @@ static int create_default_files(const char *git_dir, const char *template_path)
}
git_config_set("core.filemode", filemode ? "true" : "false");
- if (is_bare_repository()) {
+ if (is_bare_repository() && !git_work_tree) {
git_config_set("core.bare", "true");
}
else {
@@ -260,6 +261,8 @@ static int create_default_files(const char *git_dir, const char *template_path)
/* allow template config file to override the default */
if (log_all_ref_updates == -1)
git_config_set("core.logallrefupdates", "true");
+ if (git_work_tree)
+ git_config_set("core.worktree", git_work_tree);
}
return reinit;
}
@@ -276,6 +279,7 @@ static const char init_db_usage[] =
int cmd_init_db(int argc, const char **argv, const char *prefix)
{
const char *git_dir;
+ const char *git_work_tree;
const char *sha1_dir;
const char *template_dir = NULL;
char *path;
@@ -294,6 +298,31 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
}
/*
+ * check value of $GIT_WORK_TREE
+ * if it is set it has to be a valid directory
+ */
+ git_work_tree = getenv(GIT_WORKING_TREE_ENVIRONMENT);
+ if (git_work_tree) {
+ char cwd[PATH_MAX];
+
+ if (!getcwd(cwd, sizeof(cwd)) || cwd[0] != '/')
+ die("Unable to read current working directory");
+ if (chdir(git_work_tree))
+ die("chdir to specified working tree '%s' failed",
+ git_work_tree);
+ /* get absolute path */
+ if (git_work_tree[0] != '/') {
+ char worktree[PATH_MAX];
+ if (!getcwd(worktree, sizeof(worktree)) ||
+ worktree[0] != '/')
+ die("Unable to read current working directory");
+ setenv(GIT_WORKING_TREE_ENVIRONMENT, worktree, 1);
+ }
+ if (chdir(cwd))
+ die("Cannot come back to cwd");
+ }
+
+ /*
* Set up the default .git directory contents
*/
git_dir = getenv(GIT_DIR_ENVIRONMENT);
diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh
index bc08994..4db4b6a 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-worktree.sh
@@ -88,4 +88,19 @@ test_expect_success 'repository/worktree: --is-bare-repository' \
test_expect_success 'repository/worktree: --is-inside-git-dir' \
'test "false" = "$(git rev-parse --is-inside-git-dir)"'
+# git init
+cd "$top" || exit 1
+export GIT_DIR=$(pwd)/repository2
+test_expect_failure 'git --work-tree non-existent init' \
+ 'git --work-tree non-existent init'
+test_expect_success 'git --work-tree working/tree init' \
+ 'git --work-tree working/tree init'
+test_expect_success 'config knows core.worktree' \
+ 'git config core.worktree'
+git config --unset core.worktree || exit 1
+test_expect_success 'git --work-tree `pwd`/working init' \
+ 'git --work-tree "$(pwd)"/working init'
+test_expect_success 'config knows core.worktree' \
+ 'git config core.worktree'
+
test_done
--
1.5.0.4.414.g32da9
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH] git-init: set core.workdir when GIT_WORK_DIR is specified
2007-03-17 14:34 ` Matthias Lederhofer
` (4 preceding siblings ...)
2007-03-17 14:45 ` [PATCH 5/5] git-init: set core.worktree when GIT_WORK_TREE is specified Matthias Lederhofer
@ 2007-03-18 8:47 ` Junio C Hamano
2007-03-18 11:18 ` Matthias Lederhofer
2007-03-18 21:18 ` Matthias Lederhofer
5 siblings, 2 replies; 18+ messages in thread
From: Junio C Hamano @ 2007-03-18 8:47 UTC (permalink / raw)
To: Matthias Lederhofer; +Cc: git
Matthias Lederhofer <matled@gmx.net> writes:
> Here is a new patch series replacing ml/workdir.
>
> Changes:
> * rename GIT_WORK_DIR to GIT_WORK_TREE, --work-dir to --work-tree and
> core.workdir to core.worktree
> * use getcwd and prefixcmp instead of stat to check if cwd is below
> GIT_DIR or GIT_WORK_TREE
> * rename 'has_working_directory' to 'inside_working_tree'
>
> The first two patches have not changed except for their order in the
> series but I repost them anyway for easier review.
Thanks. I somehow felt funny to see my sign-off on some of your
patches, but it makes perfect sense with the above explanation.
A word of caution when working with me.
Almost always, I haven't thought things through more thoroughly
than the contributor did, so many of my comments of course show
a lot of cluelessness. Your explanation on the reason why you
structured is_bare_repository() check that way illustrated
issues to me and the list very well.
I often mix comments that are not serious suggestions and
questions, just to play devil's advocate. An earlier example
was "should the relative directory (either --work-dir option or
environment) be taken relative to GIT_DIR?" The expected answer
was "it should be relative to `pwd`, because expected use of
relative path at runtime (as opposed to setting in
$GIT_DIR/config) is one-shot, like this:
$ cd top-of-project/some/where
$ git --work-dir=../.. do-something
and making it relative to $GIT_DIR is just crazy, because the
top may not be related with $GIT_DIR in any easy-to-remember way
at all." I want to hear such rebuttal to make sure that the
contributor thought things through. Not amending certain parts
of the patch, with clear explanation to defend it, is always
better. Amending a patch only to satisfy such a non-serious
comment is to fail the test.
> Things I'm not sure about how/if to change (see my last mail too)
> * is_bare_repository() uses the old check
> /* definitely bare */
> if (is_bare_repository_cfg == 1)
> return 1;
> /* GIT_WORK_TREE is set, bare if cwd is outside */
> if (inside_working_tree >= 0)
> return !inside_working_tree;
> /* configuration says it is not bare */
> if (is_bare_repository_cfg == 0)
> return 0;
> * is_bare_repository() in general
There is a bit of chicken and egg involved in is_bare, because
we need to find out where GIT_DIR is in order to find where to
read GIT_DIR/config from, and only after reading the file we
would know if the user explicitly told us the repository is
bare, and setup_gently does not want to cd-up if the repository
is bare (i.e. there is no "top" to move to).
> * git init does not show the expansion of GIT_WORK_TREE to an
> absolute path, this might confuse the user
If the feature might confuse the user without extra output, it
probably is confusing to begin with, with or without it, so one
option might be to refuse relative path when running git-init.
However, as long as the expansion to absolute path is done
correctly, I do not think there is any room for confusion. Who
would want a feature that lets you set work-tree to ../.., so
that no matter where in the working tree you cd around, git
assumes that the toplevel is two level up? If you record the
work tree location in the configuration, you would want it to be
stable, and I do not think anybody would expect it be stored as
relative. So I thought having the printf() would be a good way
for debugging the absolute expansion, but after that I do not
think it is needed (but again, I may well be missing some issues
you've thought about, so please tell me otherwise).
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH] git-init: set core.workdir when GIT_WORK_DIR is specified
2007-03-18 8:47 ` [PATCH] git-init: set core.workdir when GIT_WORK_DIR " Junio C Hamano
@ 2007-03-18 11:18 ` Matthias Lederhofer
2007-03-18 21:18 ` Matthias Lederhofer
1 sibling, 0 replies; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-18 11:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Junio C Hamano <junkio@cox.net> wrote:
> Matthias Lederhofer <matled@gmx.net> writes:
> > * git init does not show the expansion of GIT_WORK_TREE to an
> > absolute path, this might confuse the user
>
> If the feature might confuse the user without extra output, it
> probably is confusing to begin with, with or without it, so one
> option might be to refuse relative path when running git-init.
>
> However, as long as the expansion to absolute path is done
> correctly, I do not think there is any room for confusion. Who
> would want a feature that lets you set work-tree to ../.., so
> that no matter where in the working tree you cd around, git
> assumes that the toplevel is two level up? If you record the
> work tree location in the configuration, you would want it to be
> stable, and I do not think anybody would expect it be stored as
> relative. So I thought having the printf() would be a good way
> for debugging the absolute expansion, but after that I do not
> think it is needed (but again, I may well be missing some issues
> you've thought about, so please tell me otherwise).
I really don't know what people would expect from git --work-tree=foo
init and therefore I thought it might help to tell them "core.worktree
= /path/to/foo". For example one could think this would work (without
the message in brackets):
~/foo$ export GIT_DIR=`pwd`/repository.git
~/foo$ mkdir src
~/foo$ git --work-tree=src init
[core.worktree = /home/user/foo/src]
Initialized empty Git repository in /home/user/foo/repository.git/
~/foo$ cd ..; mv foo bar; cd bar
~/bar$ export GIT_DIR=`pwd`/repository.git
With the message in brackets it would be clear what breaks after
renaming the directory.
Note: git config core.worktree ../src fails after moving the working
tree because the value of core.worktree checked for validity.
Either run
$ git --work-tree=. config [args]
or just do
$ git --work-tree=src init
again in the new location and git-init will set core.worktree again.
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH] git-init: set core.workdir when GIT_WORK_DIR is specified
2007-03-18 8:47 ` [PATCH] git-init: set core.workdir when GIT_WORK_DIR " Junio C Hamano
2007-03-18 11:18 ` Matthias Lederhofer
@ 2007-03-18 21:18 ` Matthias Lederhofer
[not found] ` <7vk5xensjn.fsf@assigned-by-dhcp.cox.net>
1 sibling, 1 reply; 18+ messages in thread
From: Matthias Lederhofer @ 2007-03-18 21:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Junio C Hamano <junkio@cox.net> wrote:
> Matthias Lederhofer <matled@gmx.net> writes:
> > * is_bare_repository() in general
>
> There is a bit of chicken and egg involved in is_bare, because
> we need to find out where GIT_DIR is in order to find where to
> read GIT_DIR/config from, and only after reading the file we
> would know if the user explicitly told us the repository is
> bare, and setup_gently does not want to cd-up if the repository
> is bare (i.e. there is no "top" to move to).
How about changing setup_git_directory_gently to do the following:
Find the git directory ($GIT_DIR, .git in parent directories and "."
at last).
Read configuration for core.bare and core.worktree. If core.bare is
not specified do the old guessing.
if core.bare = true:
Set GIT_DIR if it isn't set yet and stop (don't change the
directory).
if core.bare = false:
GIT_DIR specified:
use GIT_WORK_TREE, core.worktree or "." as working tree
found repository as .git directory:
use the parent directory of the .git directory as working tree
found repository in ".":
use "." as working tree
if cwd is below the working tree:
change to working tree
inside_work_tree = 1
return prefix
if cwd is outside of the working tree:
inside_work_tree = 0
return NULL
^ permalink raw reply [flat|nested] 18+ messages in thread