{"thread":{"id":"20223","subject":"[PATCH] git init: optionally allow a directory argument","startedAt":"2009-07-24T21:59:28Z","lastAt":"2009-07-25T09:26:10Z","messageCount":7,"participants":["Nanako Shiraishi","Junio C Hamano","Daniel Pittman","Alex Scarborough","Johannes Sixt"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"118663","messageId":"20090725065928.6117@nanako3.lavabit.com","threadId":"20223","inReplyTo":null,"subject":"[PATCH] git init: optionally allow a directory argument","fromName":"Nanako Shiraishi","fromEmail":"nanako3@lavabit.com","sentAt":"2009-07-24T21:59:28Z","receivedAt":"2009-07-24T21:59:28Z","isPatch":true,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"When starting a new repository, I see my students often say\n\n    % git init newrepo\n\nand curse git.  They could say\n\n    % mkdir newrepo; cd newrepo; git init\n\nbut allowing it as an obvious short-cut may be nicer.\n\nSigned-off-by: Nanako Shiraishi <nanako3@lavabit.com>\n---\n\n Please be gentle; I don't write C very well.\n\n Documentation/git-init.txt |    5 ++++-\n builtin-init-db.c          |   37 +++++++++++++++++++++++++++++--------\n t/t0001-init.sh            |   34 ++++++++++++++++++++++++++++++++++\n 3 files changed, 67 insertions(+), 9 deletions(-)\n\ndiff --git a/Documentation/git-init.txt b/Documentation/git-init.txt\nindex 7151d12..f081b24 100644\n--- a/Documentation/git-init.txt\n+++ b/Documentation/git-init.txt\n@@ -8,7 +8,7 @@ git-init - Create an empty git repository or reinitialize an existing one\n \n SYNOPSIS\n --------\n-'git init' [-q | --quiet] [--bare] [--template=<template_directory>] [--shared[=<permissions>]]\n+'git init' [-q | --quiet] [--bare] [--template=<template_directory>] [--shared[=<permissions>]] [directory]\n \n \n OPTIONS\n@@ -74,6 +74,9 @@ By default, the configuration flag receive.denyNonFastForwards is enabled\n in shared repositories, so that you cannot force a non fast-forwarding push\n into it.\n \n+If you name a (possibly non-existent) directory at the end of the command\n+line, the command is run inside the directory (possibly after creating it).\n+\n --\n \n \ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex 4a56006..100db73 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -371,7 +371,7 @@ static int guess_repository_type(const char *git_dir)\n }\n \n static const char init_db_usage[] =\n-\"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]]\";\n+\"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]] [directory]\";\n \n /*\n  * If you want to, you can share the DB area with any number of branches.\n@@ -384,27 +384,48 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \tconst char *git_dir;\n \tconst char *template_dir = NULL;\n \tunsigned int flags = 0;\n+\tint bare_given = 0;\n \tint i;\n \n \tfor (i = 1; i < argc; i++, argv++) {\n \t\tconst char *arg = argv[1];\n \t\tif (!prefixcmp(arg, \"--template=\"))\n \t\t\ttemplate_dir = arg+11;\n-\t\telse if (!strcmp(arg, \"--bare\")) {\n-\t\t\tstatic char git_dir[PATH_MAX+1];\n-\t\t\tis_bare_repository_cfg = 1;\n-\t\t\tsetenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir,\n-\t\t\t\t\t\tsizeof(git_dir)), 0);\n-\t\t} else if (!strcmp(arg, \"--shared\"))\n+\t\telse if (!strcmp(arg, \"--bare\"))\n+\t\t\tbare_given = is_bare_repository_cfg = 1;\n+\t\telse if (!strcmp(arg, \"--shared\"))\n \t\t\tinit_shared_repository = PERM_GROUP;\n \t\telse if (!prefixcmp(arg, \"--shared=\"))\n \t\t\tinit_shared_repository = git_config_perm(\"arg\", arg+9);\n \t\telse if (!strcmp(arg, \"-q\") || !strcmp(arg, \"--quiet\"))\n \t\t\tflags |= INIT_DB_QUIET;\n-\t\telse\n+\t\telse if (arg[0] == '-')\n \t\t\tusage(init_db_usage);\n+\t\telse\n+\t\t\tbreak;\n \t}\n \n+\tif (i == argc - 1) {\n+\t\tint mkdir_tried = 0;\n+\tretry:\n+\t\tif (chdir(argv[1]) < 0) {\n+\t\t\tif (!mkdir_tried) {\n+\t\t\t\tif (mkdir(argv[1], 0777) < 0)\n+\t\t\t\t\tdie_errno(\"cannot mkdir %s\", argv[1]);\n+\t\t\t\tmkdir_tried = 1;\n+\t\t\t\tgoto retry;\n+\t\t\t}\n+\t\t\tdie_errno(\"cannot chdir to %s\", argv[1]);\n+\t\t}\n+\t} else if (i < argc - 1) {\n+\t\tusage(init_db_usage);\n+\t}\n+\tif (bare_given == 1) {\n+\t\tstatic char git_dir[PATH_MAX+1];\n+\n+\t\tsetenv(GIT_DIR_ENVIRONMENT,\n+\t\t\tgetcwd(git_dir, sizeof(git_dir)), 0);\n+\t}\n \tif (init_shared_repository != -1)\n \t\tshared_repository = init_shared_repository;\n \ndiff --git a/t/t0001-init.sh b/t/t0001-init.sh\nindex e3d8464..0ded031 100755\n--- a/t/t0001-init.sh\n+++ b/t/t0001-init.sh\n@@ -208,4 +208,38 @@ test_expect_success 'init rejects insanely long --template' '\n \t)\n '\n \n+test_expect_success 'init creates a new directory' '\n+\trm -fr newdir &&\n+\t(\n+\t\tgit init newdir &&\n+\t\ttest -d newdir/.git/refs\n+\t)\n+'\n+\n+test_expect_success 'init creates a new bare directory' '\n+\trm -fr newdir &&\n+\t(\n+\t\tgit init --bare newdir &&\n+\t\ttest -d newdir/refs\n+\t)\n+'\n+\n+test_expect_success 'init recreates a directory' '\n+\trm -fr newdir &&\n+\t(\n+\t\tmkdir newdir &&\n+\t\tgit init newdir &&\n+\t\ttest -d newdir/.git/refs\n+\t)\n+'\n+\n+test_expect_success 'init recreates a new bare directory' '\n+\trm -fr newdir &&\n+\t(\n+\t\tmkdir newdir &&\n+\t\tgit init --bare newdir &&\n+\t\ttest -d newdir/refs\n+\t)\n+'\n+\n test_done\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"},{"id":"118687","messageId":"7vab2t64cg.fsf@alter.siamese.dyndns.org","threadId":"20223","inReplyTo":"20090725065928.6117@nanako3.lavabit.com","subject":"Re: [PATCH] git init: optionally allow a directory argument","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-07-24T23:36:31Z","receivedAt":"2009-07-24T23:36:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nanako Shiraishi <nanako3@lavabit.com> writes:\n\n> When starting a new repository, I see my students often say\n>\n>     % git init newrepo\n>\n> and curse git.  They could say\n>\n>     % mkdir newrepo; cd newrepo; git init\n>\n> but allowing it as an obvious short-cut may be nicer.\n>\n> Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>\n\nHmm, I didn't realize this is so common a wish among new people.\n\nThe patch seems clean.  Anybody has comments, both on code and the use\ncase?\n"},{"id":"118701","messageId":"87r5w5h2uy.fsf@rimspace.net","threadId":"20223","inReplyTo":"7vab2t64cg.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git init: optionally allow a directory argument","fromName":"Daniel Pittman","fromEmail":"daniel@rimspace.net","sentAt":"2009-07-25T03:13:09Z","receivedAt":"2009-07-25T03:13:09Z","isPatch":true,"sender":{"key":"daniel@rimspace.net","avatar":"https://gravatar.com/avatar/67f2f02d3521b163f6b7a0dec5943d33fbc5a2a6d9702ab3fef99032e59e692f?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n> Nanako Shiraishi <nanako3@lavabit.com> writes:\n>\n>> When starting a new repository, I see my students often say\n>>     % git init newrepo\n>> and curse git.  They could say\n>>     % mkdir newrepo; cd newrepo; git init\n>> but allowing it as an obvious short-cut may be nicer.\n>>\n>> Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>\n>\n> Hmm, I didn't realize this is so common a wish among new people.  The patch\n> seems clean.  Anybody has comments, both on code and the use case?\n\nIt still surprises me that git doesn't do this, since it is at odds with\nalmost every other version control system I have on hand or experience with,\nother than CVS; Subversion, svk, Bazaar and Mercurial all take a trailing\ntarget argument.\n\nCVS and monotone take an option to specify where; only darcs is like git and\nuses the current directory as the target.\n\nSo, from where I sit it makes sense to have 'git init foo' create a 'foo'\ndirectory and repository below the current location.\n\nRegards,\n        Daniel\n\n...and, yeah, I still get caught every now and then when I create a new\nrepository by hand.\n-- \n✣ Daniel Pittman            ✉ daniel@rimspace.net            ☎ +61 401 155 707\n               ♽ made with 100 percent post-consumer electrons\n"},{"id":"118702","messageId":"7v7hxxz2lt.fsf@alter.siamese.dyndns.org","threadId":"20223","inReplyTo":"20090725065928.6117@nanako3.lavabit.com","subject":"Re: [PATCH] git init: optionally allow a directory argument","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-07-25T06:41:18Z","receivedAt":"2009-07-25T06:41:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nanako Shiraishi <nanako3@lavabit.com> writes:\n\n> When starting a new repository, I see my students often say\n>\n>     % git init newrepo\n>\n> and curse git.  They could say\n>\n>     % mkdir newrepo; cd newrepo; git init\n>\n> but allowing it as an obvious short-cut may be nicer.\n>\n> Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>\n> ---\n>\n>  Please be gentle; I don't write C very well.\n\nAs I already said, the patch looked reasonable.\n\n> +\tif (i == argc - 1) {\n> +\t\tint mkdir_tried = 0;\n> +\tretry:\n> +\t\tif (chdir(argv[1]) < 0) {\n> +\t\t\tif (!mkdir_tried) {\n> +\t\t\t\tif (mkdir(argv[1], 0777) < 0)\n> +\t\t\t\t\tdie_errno(\"cannot mkdir %s\", argv[1]);\n> +\t\t\t\tmkdir_tried = 1;\n> +\t\t\t\tgoto retry;\n> +\t\t\t}\n> +\t\t\tdie_errno(\"cannot chdir to %s\", argv[1]);\n> +\t\t}\n\nBut I have to wonder if we would also want to allow\n\n\t$ git init --bare project/repo-000.git\n\nwhen you do not even have \"project\" directory.  After all, we are talking\nabout people who do not bother \"mkdir repo-000.git\", so instead of doing\nequivalent of \"mkdir project/repo-000.git\", it would make more sense to do\nan equivalent of \"mkdir -p project/repo-000.git\" instead.\n\nHere is a patch to do so on top of yours, possibly you may want to squash\nin.\n\n builtin-init-db.c |   19 +++++++++++++++++++\n t/t0001-init.sh   |   43 +++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 62 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex 100db73..b7f708d 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -410,6 +410,25 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \tretry:\n \t\tif (chdir(argv[1]) < 0) {\n \t\t\tif (!mkdir_tried) {\n+\t\t\t\tint saved;\n+\t\t\t\t/*\n+\t\t\t\t * At this point we haven't read any configuration,\n+\t\t\t\t * and we know shared_repository should always be 0;\n+\t\t\t\t * but just in case we play safe.\n+\t\t\t\t */\n+\t\t\t\tsaved = shared_repository;\n+\t\t\t\tshared_repository = 0;\n+\t\t\t\tswitch (safe_create_leading_directories_const(argv[1])) {\n+\t\t\t\tcase -3:\n+\t\t\t\t\terrno = EEXIST;\n+\t\t\t\t\t/* fallthru */\n+\t\t\t\tcase -1:\n+\t\t\t\t\tdie_errno(\"cannot mkdir %s\", argv[1]);\n+\t\t\t\t\tbreak;\n+\t\t\t\tdefault:\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t\tshared_repository = saved;\n \t\t\t\tif (mkdir(argv[1], 0777) < 0)\n \t\t\t\t\tdie_errno(\"cannot mkdir %s\", argv[1]);\n \t\t\t\tmkdir_tried = 1;\ndiff --git a/t/t0001-init.sh b/t/t0001-init.sh\nindex 0ded031..8c55404 100755\n--- a/t/t0001-init.sh\n+++ b/t/t0001-init.sh\n@@ -242,4 +242,47 @@ test_expect_success 'init recreates a new bare directory' '\n \t)\n '\n \n+test_expect_success 'init creates a new deep directory' '\n+\trm -fr newdir &&\n+\t(\n+\t\t# Leading directories should honor umask while\n+\t\t# the repository itself should follow \"shared\"\n+\t\tumask 002 &&\n+\t\tgit init --bare --shared=0660 newdir/a/b/c &&\n+\t\ttest -d newdir/a/b/c/refs &&\n+\t\tls -ld newdir/a newdir/a/b > lsab.out &&\n+\t\t! grep -v \"^drwxrw[sx]r-x\" ls.out &&\n+\t\tls -ld newdir/a/b/c > lsc.out &&\n+\t\t! grep -v \"^drwxrw[sx]---\" lsc.out\n+\t)\n+'\n+\n+test_expect_success 'init notices EEXIST (1)' '\n+\trm -fr newdir &&\n+\t(\n+\t\t>newdir &&\n+\t\ttest_must_fail git init newdir &&\n+\t\ttest -f newdir\n+\t)\n+'\n+\n+test_expect_success 'init notices EEXIST (2)' '\n+\trm -fr newdir &&\n+\t(\n+\t\tmkdir newdir &&\n+\t\t>newdir/a\n+\t\ttest_must_fail git init newdir/a/b &&\n+\t\ttest -f newdir/a\n+\t)\n+'\n+\n+test_expect_success 'init notices EPERM' '\n+\trm -fr newdir &&\n+\t(\n+\t\tmkdir newdir &&\n+\t\tchmod -w newdir &&\n+\t\ttest_must_fail git init newdir/a/b\n+\t)\n+'\n+\n test_done\n"},{"id":"118703","messageId":"EA5BDEF8-BACD-49FD-8AE9-D76D87DCFA40@garagegames.com","threadId":"20223","inReplyTo":"7vab2t64cg.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git init: optionally allow a directory argument","fromName":"Alex Scarborough","fromEmail":"alexsc@garagegames.com","sentAt":"2009-07-25T06:41:59Z","receivedAt":"2009-07-25T06:41:59Z","isPatch":true,"sender":{"key":"alexsc@garagegames.com","avatar":null},"body":"\nOn Jul 24, 2009, at 4:36 PM, Junio C Hamano wrote:\n\n> Nanako Shiraishi <nanako3@lavabit.com> writes:\n>\n>> When starting a new repository, I see my students often say\n>>\n>>    % git init newrepo\n>>\n>> and curse git.  They could say\n>>\n>>    % mkdir newrepo; cd newrepo; git init\n>>\n>> but allowing it as an obvious short-cut may be nicer.\n>>\n>> Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>\n>\n> Hmm, I didn't realize this is so common a wish among new people.\n>\n> The patch seems clean.  Anybody has comments, both on code and the use\n> case?\n\nThe use case makes sense.  This helps make git init be a bit more  \nconsistent\nwith git clone, which can take a trailing target.\n\nFor the code, I would replace the direct use of mkdir with  \nsafe_create_dir.\nOtherwise it looks fine.\n\n-Alex Scarborough\n"},{"id":"118704","messageId":"200907250945.18398.j6t@kdbg.org","threadId":"20223","inReplyTo":"7v7hxxz2lt.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git init: optionally allow a directory argument","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2009-07-25T07:45:18Z","receivedAt":"2009-07-25T07:45:18Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Samstag, 25. Juli 2009, Junio C Hamano wrote:\n> +test_expect_success 'init notices EPERM' '\n> +\trm -fr newdir &&\n> +\t(\n> +\t\tmkdir newdir &&\n> +\t\tchmod -w newdir &&\n> +\t\ttest_must_fail git init newdir/a/b\n> +\t)\n> +'\n\nThis test will require POSIXPERM prerequisite.\n\n-- Hannes\n"},{"id":"118707","messageId":"7vd47pun9p.fsf@alter.siamese.dyndns.org","threadId":"20223","inReplyTo":"200907250945.18398.j6t@kdbg.org","subject":"Re: [PATCH] git init: optionally allow a directory argument","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-07-25T09:26:10Z","receivedAt":"2009-07-25T09:26:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j6t@kdbg.org> writes:\n\n> On Samstag, 25. Juli 2009, Junio C Hamano wrote:\n>> +test_expect_success 'init notices EPERM' '\n>> +\trm -fr newdir &&\n>> +\t(\n>> +\t\tmkdir newdir &&\n>> +\t\tchmod -w newdir &&\n>> +\t\ttest_must_fail git init newdir/a/b\n>> +\t)\n>> +'\n>\n> This test will require POSIXPERM prerequisite.\n\nHeh, I knew it ;-)\n\nThanks.\n"}]}