summaryrefslogtreecommitdiff
path: root/builtin-init-db.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2007-08-27 00:58:06 -0700
committerJunio C Hamano <gitster@pobox.com>2007-08-27 22:36:43 -0700
commit6adcca3fe84e6859fc62df6c4ab916192ca02795 (patch)
treecbe1f3262b88759927ac07e3980fa8b590679b47 /builtin-init-db.c
parentac076c29ae8d57b72abe27f573061ea7b2eeed57 (diff)
downloadgit-6adcca3fe84e6859fc62df6c4ab916192ca02795.tar.gz
Fix initialization of a bare repository
Here is my attempt to fix this with a minimally intrusive patch. * As "git --bare init" cannot tell if it was called with --bare or just "GIT_DIR=. git init", I added an explicit assignment of is_bare_repository_cfg on the codepath for "git --bare". * GIT_WORK_TREE alone without GIT_DIR does not make any sense, nor GIT_WORK_TREE with an explicit "git --bare". Catch that mistake. It might make sense to move this check to "git.c" side as well, but I tried to shoot for the minimum change for now. * Some scripts, especially from the olden days, rely on traditional GIT_DIR behaviour in "git init". Namely, these are some notable patterns: (create a bare repository) - mkdir some.git && cd some.git && GIT_DIR=. git init - mkdir some.git && cd some.git && git --bare init (create a non-bare repository) - mkdir .git && GIT_DIR=.git git init - mkdir .git && GIT_DIR=`pwd`/.git git init This comes with a new test script and also passes the existing test suite, but there may be cases that are still broken with the current tip of master and this patch does not yet fix. I'd appreciate help in straightening this mess out. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-init-db.c')
-rw-r--r--builtin-init-db.c65
1 files changed, 60 insertions, 5 deletions
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 0d9b1e0559..af15cb2739 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