aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin-init-db.c65
-rw-r--r--git.c1
-rwxr-xr-xt/t0001-init.sh116
3 files changed, 177 insertions, 5 deletions
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 0d9b1e055..af15cb273 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -267,6 +267,44 @@ static int create_default_files(const char *git_dir, const char *template_path)
return reinit;
}
+static void guess_repository_type(const char *git_dir)
+{
+ char cwd[PATH_MAX];
+ const char *slash;
+
+ if (0 <= is_bare_repository_cfg)
+ return;
+ if (!git_dir)
+ return;
+
+ /*
+ * "GIT_DIR=. git init" is always bare.
+ * "GIT_DIR=`pwd` git init" too.
+ */
+ if (!strcmp(".", git_dir))
+ goto force_bare;
+ if (!getcwd(cwd, sizeof(cwd)))
+ die("cannot tell cwd");
+ if (!strcmp(git_dir, cwd))
+ goto force_bare;
+ /*
+ * "GIT_DIR=.git or GIT_DIR=something/.git is usually not.
+ */
+ if (!strcmp(git_dir, ".git"))
+ return;
+ slash = strrchr(git_dir, '/');
+ if (slash && !strcmp(slash, "/.git"))
+ return;
+
+ /*
+ * Otherwise it is often bare. At this point
+ * we are just guessing.
+ */
+ force_bare:
+ is_bare_repository_cfg = 1;
+ return;
+}
+
static const char init_db_usage[] =
"git-init [-q | --quiet] [--template=<template-directory>] [--shared]";
@@ -299,11 +337,28 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
usage(init_db_usage);
}
- git_work_tree_cfg = xcalloc(PATH_MAX, 1);
- if (!getcwd(git_work_tree_cfg, PATH_MAX))
- die ("Cannot access current working directory.");
- if (access(get_git_work_tree(), X_OK))
- die ("Cannot access work tree '%s'", get_git_work_tree());
+ /*
+ * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
+ * without --bare. Catch the error early.
+ */
+ git_dir = getenv(GIT_DIR_ENVIRONMENT);
+ if ((!git_dir || is_bare_repository_cfg == 1)
+ && getenv(GIT_WORK_TREE_ENVIRONMENT))
+ die("%s (or --work-tree=<directory>) not allowed without "
+ "specifying %s (or --git-dir=<directory>)",
+ GIT_WORK_TREE_ENVIRONMENT,
+ GIT_DIR_ENVIRONMENT);
+
+ guess_repository_type(git_dir);
+
+ if (is_bare_repository_cfg <= 0) {
+ git_work_tree_cfg = xcalloc(PATH_MAX, 1);
+ if (!getcwd(git_work_tree_cfg, PATH_MAX))
+ die ("Cannot access current working directory.");
+ if (access(get_git_work_tree(), X_OK))
+ die ("Cannot access work tree '%s'",
+ get_git_work_tree());
+ }
/*
* Set up the default .git directory contents
diff --git a/git.c b/git.c
index c46691e97..b6e292e29 100644
--- a/git.c
+++ b/git.c
@@ -93,6 +93,7 @@ static int handle_options(const char*** argv, int* argc, int* envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--bare")) {
static char git_dir[PATH_MAX+1];
+ is_bare_repository_cfg = 1;
setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, sizeof(git_dir)), 1);
if (envchanged)
*envchanged = 1;
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
new file mode 100755
index 000000000..b14b3ec39
--- /dev/null
+++ b/t/t0001-init.sh
@@ -0,0 +1,116 @@
+#!/bin/sh
+
+test_description='git init'
+
+. ./test-lib.sh
+
+check_config () {
+ if test -d "$1" && test -f "$1/config" && test -d "$1/refs"
+ then
+ : happy
+ else
+ echo "expected a directory $1, a file $1/config and $1/refs"
+ return 1
+ fi
+ bare=$(GIT_CONFIG="$1/config" git config --bool core.bare)
+ worktree=$(GIT_CONFIG="$1/config" git config core.worktree) ||
+ worktree=unset
+
+ test "$bare" = "$2" && test "$worktree" = "$3" || {
+ echo "expected bare=$2 worktree=$3"
+ echo " got bare=$bare worktree=$worktree"
+ return 1
+ }
+}
+
+test_expect_success 'plain' '
+ (
+ unset GIT_DIR GIT_WORK_TREE &&
+ mkdir plain &&
+ cd plain &&
+ git init
+ ) &&
+ check_config plain/.git false unset
+'
+
+test_expect_success 'plain with GIT_WORK_TREE' '
+ if (
+ unset GIT_DIR &&
+ mkdir plain-wt &&
+ cd plain-wt &&
+ GIT_WORK_TREE=$(pwd) git init
+ )
+ then
+ echo Should have failed -- GIT_WORK_TREE should not be used
+ false
+ fi
+'
+
+test_expect_success 'plain bare' '
+ (
+ unset GIT_DIR GIT_WORK_TREE GIT_CONFIG &&
+ mkdir plain-bare-1 &&
+ cd plain-bare-1 &&
+ git --bare init
+ ) &&
+ check_config plain-bare-1 true unset
+'
+
+test_expect_success 'plain bare with GIT_WORK_TREE' '
+ if (
+ unset GIT_DIR GIT_CONFIG &&
+ mkdir plain-bare-2 &&
+ cd plain-bare-2 &&
+ GIT_WORK_TREE=$(pwd) git --bare init
+ )
+ then
+ echo Should have failed -- GIT_WORK_TREE should not be used
+ false
+ fi
+'
+
+test_expect_success 'GIT_DIR bare' '
+
+ (
+ unset GIT_CONFIG &&
+ mkdir git-dir-bare.git &&
+ GIT_DIR=git-dir-bare.git git init
+ ) &&
+ check_config git-dir-bare.git true unset
+'
+
+test_expect_success 'GIT_DIR non-bare' '
+
+ (
+ unset GIT_CONFIG &&
+ mkdir non-bare &&
+ cd non-bare &&
+ GIT_DIR=.git git init
+ ) &&
+ check_config non-bare/.git false unset
+'
+
+test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' '
+
+ (
+ unset GIT_CONFIG &&
+ mkdir git-dir-wt-1.git &&
+ GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init
+ ) &&
+ check_config git-dir-wt-1.git false "$(pwd)"
+'
+
+test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' '
+
+ if (
+ unset GIT_CONFIG &&
+ mkdir git-dir-wt-2.git &&
+ GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-2.git git --bare init
+ )
+ then
+ echo Should have failed -- --bare should not be used
+ false
+ fi
+'
+
+test_done