{"thread":{"id":"13163","subject":"[PATCH 7/8] Provide API access to init_db()","startedAt":"2008-04-17T23:32:40Z","lastAt":"2008-04-19T18:11:50Z","messageCount":2,"participants":["Daniel Barkalow","Johan Herland"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"74695","messageId":"alpine.LNX.1.00.0804171932050.19665@iabervon.org","threadId":"13163","inReplyTo":null,"subject":"[PATCH 7/8] Provide API access to init_db()","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-04-17T23:32:40Z","receivedAt":"2008-04-17T23:32:40Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"The caller first calls set_git_dir() to specify the GIT_DIR, and then\ncalls init_db() to initialize it. This also cleans up various parts of\nthe code to account for the fact that everything is done with GIT_DIR\nset, so it's unnecessary to pass the specified directory around.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\n builtin-init-db.c |  180 +++++++++++++++++++++++++++-------------------------\n cache.h           |    4 +\n 2 files changed, 97 insertions(+), 87 deletions(-)\n\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex 2854868..f5ee209 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -104,12 +104,14 @@ static void copy_templates_1(char *path, int baselen,\n \t}\n }\n \n-static void copy_templates(const char *git_dir, int len, const char *template_dir)\n+static void copy_templates(const char *template_dir)\n {\n \tchar path[PATH_MAX];\n \tchar template_path[PATH_MAX];\n \tint template_len;\n \tDIR *dir;\n+\tconst char *git_dir = get_git_dir();\n+\tint len = strlen(git_dir);\n \n \tif (!template_dir)\n \t\ttemplate_dir = getenv(TEMPLATE_DIR_ENVIRONMENT);\n@@ -156,6 +158,8 @@ static void copy_templates(const char *git_dir, int len, const char *template_di\n \t}\n \n \tmemcpy(path, git_dir, len);\n+\tif (len && path[len - 1] != '/')\n+\t\tpath[len++] = '/';\n \tpath[len] = 0;\n \tcopy_templates_1(path, len,\n \t\t\t template_path, template_len,\n@@ -163,8 +167,9 @@ static void copy_templates(const char *git_dir, int len, const char *template_di\n \tclosedir(dir);\n }\n \n-static int create_default_files(const char *git_dir, const char *template_path)\n+static int create_default_files(const char *template_path)\n {\n+\tconst char *git_dir = get_git_dir();\n \tunsigned len = strlen(git_dir);\n \tstatic char path[PATH_MAX];\n \tstruct stat st1;\n@@ -183,19 +188,15 @@ static int create_default_files(const char *git_dir, const char *template_path)\n \t/*\n \t * Create .git/refs/{heads,tags}\n \t */\n-\tstrcpy(path + len, \"refs\");\n-\tsafe_create_dir(path, 1);\n-\tstrcpy(path + len, \"refs/heads\");\n-\tsafe_create_dir(path, 1);\n-\tstrcpy(path + len, \"refs/tags\");\n-\tsafe_create_dir(path, 1);\n+\tsafe_create_dir(git_path(\"refs\"), 1);\n+\tsafe_create_dir(git_path(\"refs/heads\"), 1);\n+\tsafe_create_dir(git_path(\"refs/tags\"), 1);\n \n \t/* First copy the templates -- we might have the default\n \t * config file there, in which case we would want to read\n \t * from it after installing.\n \t */\n-\tpath[len] = 0;\n-\tcopy_templates(path, len, template_path);\n+\tcopy_templates(template_path);\n \n \tgit_config(git_default_config);\n \n@@ -204,14 +205,10 @@ static int create_default_files(const char *git_dir, const char *template_path)\n \t * shared-repository settings, we would need to fix them up.\n \t */\n \tif (shared_repository) {\n-\t\tpath[len] = 0;\n-\t\tadjust_shared_perm(path);\n-\t\tstrcpy(path + len, \"refs\");\n-\t\tadjust_shared_perm(path);\n-\t\tstrcpy(path + len, \"refs/heads\");\n-\t\tadjust_shared_perm(path);\n-\t\tstrcpy(path + len, \"refs/tags\");\n-\t\tadjust_shared_perm(path);\n+\t\tadjust_shared_perm(get_git_dir());\n+\t\tadjust_shared_perm(git_path(\"refs\"));\n+\t\tadjust_shared_perm(git_path(\"refs/heads\"));\n+\t\tadjust_shared_perm(git_path(\"refs/tags\"));\n \t}\n \n \t/*\n@@ -251,8 +248,10 @@ static int create_default_files(const char *git_dir, const char *template_path)\n \t\t/* allow template config file to override the default */\n \t\tif (log_all_ref_updates == -1)\n \t\t    git_config_set(\"core.logallrefupdates\", \"true\");\n-\t\tif (work_tree != git_work_tree_cfg)\n+\t\tif (prefixcmp(git_dir, work_tree) ||\n+\t\t    strcmp(git_dir + strlen(work_tree), \"/.git\")) {\n \t\t\tgit_config_set(\"core.worktree\", work_tree);\n+\t\t}\n \t}\n \n \t/* Check if symlink is supported in the work tree */\n@@ -272,42 +271,83 @@ static int create_default_files(const char *git_dir, const char *template_path)\n \treturn reinit;\n }\n \n-static void guess_repository_type(const char *git_dir)\n+int init_db(const char *template_dir, unsigned int flags)\n+{\n+\tconst char *sha1_dir;\n+\tchar *path;\n+\tint len, reinit;\n+\n+\tsafe_create_dir(get_git_dir(), 0);\n+\n+\t/* Check to see if the repository version is right.\n+\t * Note that a newly created repository does not have\n+\t * config file, so this will not fail.  What we are catching\n+\t * is an attempt to reinitialize new repository with an old tool.\n+\t */\n+\tcheck_repository_format();\n+\n+\treinit = create_default_files(template_dir);\n+\n+\tsha1_dir = get_object_directory();\n+\tlen = strlen(sha1_dir);\n+\tpath = xmalloc(len + 40);\n+\tmemcpy(path, sha1_dir, len);\n+\n+\tsafe_create_dir(sha1_dir, 1);\n+\tstrcpy(path+len, \"/pack\");\n+\tsafe_create_dir(path, 1);\n+\tstrcpy(path+len, \"/info\");\n+\tsafe_create_dir(path, 1);\n+\n+\tif (shared_repository) {\n+\t\tchar buf[10];\n+\t\t/* We do not spell \"group\" and such, so that\n+\t\t * the configuration can be read by older version\n+\t\t * of git.\n+\t\t */\n+\t\tsprintf(buf, \"%d\", shared_repository);\n+\t\tgit_config_set(\"core.sharedrepository\", buf);\n+\t\tgit_config_set(\"receive.denyNonFastforwards\", \"true\");\n+\t}\n+\n+\tif (!(flags & INIT_DB_QUIET))\n+\t\tprintf(\"%s%s Git repository in %s/\\n\",\n+\t\t       reinit ? \"Reinitialized existing\" : \"Initialized empty\",\n+\t\t       shared_repository ? \" shared\" : \"\",\n+\t\t       get_git_dir());\n+\n+\treturn 0;\n+}\n+\n+static int guess_repository_type(const char *git_dir)\n {\n \tchar cwd[PATH_MAX];\n \tconst char *slash;\n \n-\tif (0 <= is_bare_repository_cfg)\n-\t\treturn;\n-\tif (!git_dir)\n-\t\treturn;\n-\n \t/*\n \t * \"GIT_DIR=. git init\" is always bare.\n \t * \"GIT_DIR=`pwd` git init\" too.\n \t */\n \tif (!strcmp(\".\", git_dir))\n-\t\tgoto force_bare;\n+\t\treturn 1;\n \tif (!getcwd(cwd, sizeof(cwd)))\n \t\tdie(\"cannot tell cwd\");\n \tif (!strcmp(git_dir, cwd))\n-\t\tgoto force_bare;\n+\t\treturn 1;\n \t/*\n \t * \"GIT_DIR=.git or GIT_DIR=something/.git is usually not.\n \t */\n \tif (!strcmp(git_dir, \".git\"))\n-\t\treturn;\n+\t\treturn 0;\n \tslash = strrchr(git_dir, '/');\n \tif (slash && !strcmp(slash, \"/.git\"))\n-\t\treturn;\n+\t\treturn 0;\n \n \t/*\n \t * Otherwise it is often bare.  At this point\n \t * we are just guessing.\n \t */\n- force_bare:\n-\tis_bare_repository_cfg = 1;\n-\treturn;\n+\treturn 1;\n }\n \n static const char init_db_usage[] =\n@@ -322,11 +362,9 @@ static const char init_db_usage[] =\n int cmd_init_db(int argc, const char **argv, const char *prefix)\n {\n \tconst char *git_dir;\n-\tconst char *sha1_dir;\n \tconst char *template_dir = NULL;\n-\tchar *path;\n-\tint len, i, reinit;\n-\tint quiet = 0;\n+\tunsigned int flags = 0;\n+\tint i;\n \n \tfor (i = 1; i < argc; i++, argv++) {\n \t\tconst char *arg = argv[1];\n@@ -337,7 +375,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \t\telse if (!prefixcmp(arg, \"--shared=\"))\n \t\t\tshared_repository = git_config_perm(\"arg\", arg+9);\n \t\telse if (!strcmp(arg, \"-q\") || !strcmp(arg, \"--quiet\"))\n-\t\t        quiet = 1;\n+\t\t\tflags |= INIT_DB_QUIET;\n \t\telse\n \t\t\tusage(init_db_usage);\n \t}\n@@ -354,64 +392,32 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \t\t    GIT_WORK_TREE_ENVIRONMENT,\n \t\t    GIT_DIR_ENVIRONMENT);\n \n-\tguess_repository_type(git_dir);\n-\n-\tif (is_bare_repository_cfg <= 0) {\n-\t\tgit_work_tree_cfg = xcalloc(PATH_MAX, 1);\n-\t\tif (!getcwd(git_work_tree_cfg, PATH_MAX))\n-\t\t\tdie (\"Cannot access current working directory.\");\n-\t\tif (access(get_git_work_tree(), X_OK))\n-\t\t\tdie (\"Cannot access work tree '%s'\",\n-\t\t\t     get_git_work_tree());\n-\t}\n-\n \t/*\n \t * Set up the default .git directory contents\n \t */\n-\tgit_dir = getenv(GIT_DIR_ENVIRONMENT);\n \tif (!git_dir)\n \t\tgit_dir = DEFAULT_GIT_DIR_ENVIRONMENT;\n-\tsafe_create_dir(git_dir, 0);\n \n-\t/* Check to see if the repository version is right.\n-\t * Note that a newly created repository does not have\n-\t * config file, so this will not fail.  What we are catching\n-\t * is an attempt to reinitialize new repository with an old tool.\n-\t */\n-\tcheck_repository_format();\n-\n-\treinit = create_default_files(git_dir, template_dir);\n+\tif (is_bare_repository_cfg < 0)\n+\t\tis_bare_repository_cfg = guess_repository_type(git_dir);\n \n-\t/*\n-\t * And set up the object store.\n-\t */\n-\tsha1_dir = get_object_directory();\n-\tlen = strlen(sha1_dir);\n-\tpath = xmalloc(len + 40);\n-\tmemcpy(path, sha1_dir, len);\n-\n-\tsafe_create_dir(sha1_dir, 1);\n-\tstrcpy(path+len, \"/pack\");\n-\tsafe_create_dir(path, 1);\n-\tstrcpy(path+len, \"/info\");\n-\tsafe_create_dir(path, 1);\n-\n-\tif (shared_repository) {\n-\t\tchar buf[10];\n-\t\t/* We do not spell \"group\" and such, so that\n-\t\t * the configuration can be read by older version\n-\t\t * of git.\n-\t\t */\n-\t\tsprintf(buf, \"%d\", shared_repository);\n-\t\tgit_config_set(\"core.sharedrepository\", buf);\n-\t\tgit_config_set(\"receive.denyNonFastforwards\", \"true\");\n+\tif (!is_bare_repository_cfg) {\n+\t\tif (git_dir) {\n+\t\t\tconst char *git_dir_parent = strrchr(git_dir, '/');\n+\t\t\tif (git_dir_parent)\n+\t\t\t\tgit_work_tree_cfg = strdup(make_absolute_path(xstrndup(git_dir, git_dir_parent - git_dir)));\n+\t\t}\n+\t\tif (!git_work_tree_cfg) {\n+\t\t\tgit_work_tree_cfg = xcalloc(PATH_MAX, 1);\n+\t\t\tif (!getcwd(git_work_tree_cfg, PATH_MAX))\n+\t\t\t\tdie (\"Cannot access current working directory.\");\n+\t\t}\n+\t\tif (access(get_git_work_tree(), X_OK))\n+\t\t\tdie (\"Cannot access work tree '%s'\",\n+\t\t\t     get_git_work_tree());\n \t}\n \n-\tif (!quiet)\n-\t\tprintf(\"%s%s Git repository in %s/\\n\",\n-\t\t       reinit ? \"Reinitialized existing\" : \"Initialized empty\",\n-\t\t       shared_repository ? \" shared\" : \"\",\n-\t\t       git_dir);\n+\tset_git_dir(make_absolute_path(git_dir));\n \n-\treturn 0;\n+\treturn init_db(template_dir, flags);\n }\ndiff --git a/cache.h b/cache.h\nindex d88a4e2..0411b4a 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -324,6 +324,10 @@ extern const char *prefix_filename(const char *prefix, int len, const char *path\n extern void verify_filename(const char *prefix, const char *name);\n extern void verify_non_filename(const char *prefix, const char *name);\n \n+#define INIT_DB_QUIET 0x0001\n+\n+extern int init_db(const char *template_dir, unsigned int flags);\n+\n #define alloc_nr(x) (((x)+16)*3/2)\n \n /*\n-- \n1.5.4.3.610.gea6cd\n"},{"id":"74763","messageId":"200804192011.50628.johan@herland.net","threadId":"13163","inReplyTo":"alpine.LNX.1.00.0804171932050.19665@iabervon.org","subject":"Re: [PATCH 7/8] Provide API access to init_db()","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2008-04-19T18:11:50Z","receivedAt":"2008-04-19T18:11:50Z","isPatch":true,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Friday 18 April 2008, Daniel Barkalow wrote:\n> The caller first calls set_git_dir() to specify the GIT_DIR, and then\n> calls init_db() to initialize it. This also cleans up various parts of\n> the code to account for the fact that everything is done with GIT_DIR\n> set, so it's unnecessary to pass the specified directory around.\n> \n> Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>\n> ---\n>  builtin-init-db.c |  180 +++++++++++++++++++++++++++-------------------------\n>  cache.h           |    4 +\n>  2 files changed, 97 insertions(+), 87 deletions(-)\n> \n> diff --git a/builtin-init-db.c b/builtin-init-db.c\n> index 2854868..f5ee209 100644\n> --- a/builtin-init-db.c\n> +++ b/builtin-init-db.c\n\n[... snip snip ...]\n\n> @@ -354,64 +392,32 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n>  \t\t    GIT_WORK_TREE_ENVIRONMENT,\n>  \t\t    GIT_DIR_ENVIRONMENT);\n>  \n> -\tguess_repository_type(git_dir);\n> -\n> -\tif (is_bare_repository_cfg <= 0) {\n> -\t\tgit_work_tree_cfg = xcalloc(PATH_MAX, 1);\n> -\t\tif (!getcwd(git_work_tree_cfg, PATH_MAX))\n> -\t\t\tdie (\"Cannot access current working directory.\");\n> -\t\tif (access(get_git_work_tree(), X_OK))\n> -\t\t\tdie (\"Cannot access work tree '%s'\",\n> -\t\t\t     get_git_work_tree());\n> -\t}\n> -\n>  \t/*\n>  \t * Set up the default .git directory contents\n>  \t */\n> -\tgit_dir = getenv(GIT_DIR_ENVIRONMENT);\n>  \tif (!git_dir)\n>  \t\tgit_dir = DEFAULT_GIT_DIR_ENVIRONMENT;\n> -\tsafe_create_dir(git_dir, 0);\n>  \n> -\t/* Check to see if the repository version is right.\n> -\t * Note that a newly created repository does not have\n> -\t * config file, so this will not fail.  What we are catching\n> -\t * is an attempt to reinitialize new repository with an old tool.\n> -\t */\n> -\tcheck_repository_format();\n> -\n> -\treinit = create_default_files(git_dir, template_dir);\n> +\tif (is_bare_repository_cfg < 0)\n> +\t\tis_bare_repository_cfg = guess_repository_type(git_dir);\n>  \n> -\t/*\n> -\t * And set up the object store.\n> -\t */\n> -\tsha1_dir = get_object_directory();\n> -\tlen = strlen(sha1_dir);\n> -\tpath = xmalloc(len + 40);\n> -\tmemcpy(path, sha1_dir, len);\n> -\n> -\tsafe_create_dir(sha1_dir, 1);\n> -\tstrcpy(path+len, \"/pack\");\n> -\tsafe_create_dir(path, 1);\n> -\tstrcpy(path+len, \"/info\");\n> -\tsafe_create_dir(path, 1);\n> -\n> -\tif (shared_repository) {\n> -\t\tchar buf[10];\n> -\t\t/* We do not spell \"group\" and such, so that\n> -\t\t * the configuration can be read by older version\n> -\t\t * of git.\n> -\t\t */\n> -\t\tsprintf(buf, \"%d\", shared_repository);\n> -\t\tgit_config_set(\"core.sharedrepository\", buf);\n> -\t\tgit_config_set(\"receive.denyNonFastforwards\", \"true\");\n> +\tif (!is_bare_repository_cfg) {\n> +\t\tif (git_dir) {\n> +\t\t\tconst char *git_dir_parent = strrchr(git_dir, '/');\n> +\t\t\tif (git_dir_parent)\n> +\t\t\t\tgit_work_tree_cfg = strdup(make_absolute_path(xstrndup(git_dir, git_dir_parent - git_dir)));\n\n1. Aren't we leaking the xstrndup()?\n2. s/strdup/xstrdup/?\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"}]}