git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] git init: optionally allow a directory argument
@ 2009-07-24 21:59 Nanako Shiraishi
  2009-07-24 23:36 ` Junio C Hamano
  2009-07-25  6:41 ` Junio C Hamano
  0 siblings, 2 replies; 7+ messages in thread
From: Nanako Shiraishi @ 2009-07-24 21:59 UTC (permalink / raw)
  To: git

When starting a new repository, I see my students often say

    % git init newrepo

and curse git.  They could say

    % mkdir newrepo; cd newrepo; git init

but allowing it as an obvious short-cut may be nicer.

Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
---

 Please be gentle; I don't write C very well.

 Documentation/git-init.txt |    5 ++++-
 builtin-init-db.c          |   37 +++++++++++++++++++++++++++++--------
 t/t0001-init.sh            |   34 ++++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 7151d12..f081b24 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -8,7 +8,7 @@ git-init - Create an empty git repository or reinitialize an existing one
 
 SYNOPSIS
 --------
-'git init' [-q | --quiet] [--bare] [--template=<template_directory>] [--shared[=<permissions>]]
+'git init' [-q | --quiet] [--bare] [--template=<template_directory>] [--shared[=<permissions>]] [directory]
 
 
 OPTIONS
@@ -74,6 +74,9 @@ By default, the configuration flag receive.denyNonFastForwards is enabled
 in shared repositories, so that you cannot force a non fast-forwarding push
 into it.
 
+If you name a (possibly non-existent) directory at the end of the command
+line, the command is run inside the directory (possibly after creating it).
+
 --
 
 
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 4a56006..100db73 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -371,7 +371,7 @@ static int guess_repository_type(const char *git_dir)
 }
 
 static const char init_db_usage[] =
-"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]]";
+"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]] [directory]";
 
 /*
  * If you want to, you can share the DB area with any number of branches.
@@ -384,27 +384,48 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	const char *git_dir;
 	const char *template_dir = NULL;
 	unsigned int flags = 0;
+	int bare_given = 0;
 	int i;
 
 	for (i = 1; i < argc; i++, argv++) {
 		const char *arg = argv[1];
 		if (!prefixcmp(arg, "--template="))
 			template_dir = arg+11;
-		else if (!strcmp(arg, "--bare")) {
-			static char git_dir[PATH_MAX+1];
-			is_bare_repository_cfg = 1;
-			setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir,
-						sizeof(git_dir)), 0);
-		} else if (!strcmp(arg, "--shared"))
+		else if (!strcmp(arg, "--bare"))
+			bare_given = is_bare_repository_cfg = 1;
+		else if (!strcmp(arg, "--shared"))
 			init_shared_repository = PERM_GROUP;
 		else if (!prefixcmp(arg, "--shared="))
 			init_shared_repository = git_config_perm("arg", arg+9);
 		else if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet"))
 			flags |= INIT_DB_QUIET;
-		else
+		else if (arg[0] == '-')
 			usage(init_db_usage);
+		else
+			break;
 	}
 
+	if (i == argc - 1) {
+		int mkdir_tried = 0;
+	retry:
+		if (chdir(argv[1]) < 0) {
+			if (!mkdir_tried) {
+				if (mkdir(argv[1], 0777) < 0)
+					die_errno("cannot mkdir %s", argv[1]);
+				mkdir_tried = 1;
+				goto retry;
+			}
+			die_errno("cannot chdir to %s", argv[1]);
+		}
+	} else if (i < argc - 1) {
+		usage(init_db_usage);
+	}
+	if (bare_given == 1) {
+		static char git_dir[PATH_MAX+1];
+
+		setenv(GIT_DIR_ENVIRONMENT,
+			getcwd(git_dir, sizeof(git_dir)), 0);
+	}
 	if (init_shared_repository != -1)
 		shared_repository = init_shared_repository;
 
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index e3d8464..0ded031 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -208,4 +208,38 @@ test_expect_success 'init rejects insanely long --template' '
 	)
 '
 
+test_expect_success 'init creates a new directory' '
+	rm -fr newdir &&
+	(
+		git init newdir &&
+		test -d newdir/.git/refs
+	)
+'
+
+test_expect_success 'init creates a new bare directory' '
+	rm -fr newdir &&
+	(
+		git init --bare newdir &&
+		test -d newdir/refs
+	)
+'
+
+test_expect_success 'init recreates a directory' '
+	rm -fr newdir &&
+	(
+		mkdir newdir &&
+		git init newdir &&
+		test -d newdir/.git/refs
+	)
+'
+
+test_expect_success 'init recreates a new bare directory' '
+	rm -fr newdir &&
+	(
+		mkdir newdir &&
+		git init --bare newdir &&
+		test -d newdir/refs
+	)
+'
+
 test_done

-- 
Nanako Shiraishi
http://ivory.ap.teacup.com/nanako3/

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] git init: optionally allow a directory argument
  2009-07-24 21:59 [PATCH] git init: optionally allow a directory argument Nanako Shiraishi
@ 2009-07-24 23:36 ` Junio C Hamano
  2009-07-25  3:13   ` Daniel Pittman
  2009-07-25  6:41   ` Alex Scarborough
  2009-07-25  6:41 ` Junio C Hamano
  1 sibling, 2 replies; 7+ messages in thread
From: Junio C Hamano @ 2009-07-24 23:36 UTC (permalink / raw)
  To: Nanako Shiraishi; +Cc: git

Nanako Shiraishi <nanako3@lavabit.com> writes:

> When starting a new repository, I see my students often say
>
>     % git init newrepo
>
> and curse git.  They could say
>
>     % mkdir newrepo; cd newrepo; git init
>
> but allowing it as an obvious short-cut may be nicer.
>
> Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>

Hmm, I didn't realize this is so common a wish among new people.

The patch seems clean.  Anybody has comments, both on code and the use
case?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] git init: optionally allow a directory argument
  2009-07-24 23:36 ` Junio C Hamano
@ 2009-07-25  3:13   ` Daniel Pittman
  2009-07-25  6:41   ` Alex Scarborough
  1 sibling, 0 replies; 7+ messages in thread
From: Daniel Pittman @ 2009-07-25  3:13 UTC (permalink / raw)
  To: git

Junio C Hamano <gitster@pobox.com> writes:
> Nanako Shiraishi <nanako3@lavabit.com> writes:
>
>> When starting a new repository, I see my students often say
>>     % git init newrepo
>> and curse git.  They could say
>>     % mkdir newrepo; cd newrepo; git init
>> but allowing it as an obvious short-cut may be nicer.
>>
>> Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
>
> Hmm, I didn't realize this is so common a wish among new people.  The patch
> seems clean.  Anybody has comments, both on code and the use case?

It still surprises me that git doesn't do this, since it is at odds with
almost every other version control system I have on hand or experience with,
other than CVS; Subversion, svk, Bazaar and Mercurial all take a trailing
target argument.

CVS and monotone take an option to specify where; only darcs is like git and
uses the current directory as the target.

So, from where I sit it makes sense to have 'git init foo' create a 'foo'
directory and repository below the current location.

Regards,
        Daniel

...and, yeah, I still get caught every now and then when I create a new
repository by hand.
-- 
✣ Daniel Pittman            ✉ daniel@rimspace.net            ☎ +61 401 155 707
               ♽ made with 100 percent post-consumer electrons

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] git init: optionally allow a directory argument
  2009-07-24 21:59 [PATCH] git init: optionally allow a directory argument Nanako Shiraishi
  2009-07-24 23:36 ` Junio C Hamano
@ 2009-07-25  6:41 ` Junio C Hamano
  2009-07-25  7:45   ` Johannes Sixt
  1 sibling, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2009-07-25  6:41 UTC (permalink / raw)
  To: Nanako Shiraishi; +Cc: git

Nanako Shiraishi <nanako3@lavabit.com> writes:

> When starting a new repository, I see my students often say
>
>     % git init newrepo
>
> and curse git.  They could say
>
>     % mkdir newrepo; cd newrepo; git init
>
> but allowing it as an obvious short-cut may be nicer.
>
> Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
> ---
>
>  Please be gentle; I don't write C very well.

As I already said, the patch looked reasonable.

> +	if (i == argc - 1) {
> +		int mkdir_tried = 0;
> +	retry:
> +		if (chdir(argv[1]) < 0) {
> +			if (!mkdir_tried) {
> +				if (mkdir(argv[1], 0777) < 0)
> +					die_errno("cannot mkdir %s", argv[1]);
> +				mkdir_tried = 1;
> +				goto retry;
> +			}
> +			die_errno("cannot chdir to %s", argv[1]);
> +		}

But I have to wonder if we would also want to allow

	$ git init --bare project/repo-000.git

when you do not even have "project" directory.  After all, we are talking
about people who do not bother "mkdir repo-000.git", so instead of doing
equivalent of "mkdir project/repo-000.git", it would make more sense to do
an equivalent of "mkdir -p project/repo-000.git" instead.

Here is a patch to do so on top of yours, possibly you may want to squash
in.

 builtin-init-db.c |   19 +++++++++++++++++++
 t/t0001-init.sh   |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/builtin-init-db.c b/builtin-init-db.c
index 100db73..b7f708d 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -410,6 +410,25 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	retry:
 		if (chdir(argv[1]) < 0) {
 			if (!mkdir_tried) {
+				int saved;
+				/*
+				 * At this point we haven't read any configuration,
+				 * and we know shared_repository should always be 0;
+				 * but just in case we play safe.
+				 */
+				saved = shared_repository;
+				shared_repository = 0;
+				switch (safe_create_leading_directories_const(argv[1])) {
+				case -3:
+					errno = EEXIST;
+					/* fallthru */
+				case -1:
+					die_errno("cannot mkdir %s", argv[1]);
+					break;
+				default:
+					break;
+				}
+				shared_repository = saved;
 				if (mkdir(argv[1], 0777) < 0)
 					die_errno("cannot mkdir %s", argv[1]);
 				mkdir_tried = 1;
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 0ded031..8c55404 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -242,4 +242,47 @@ test_expect_success 'init recreates a new bare directory' '
 	)
 '
 
+test_expect_success 'init creates a new deep directory' '
+	rm -fr newdir &&
+	(
+		# Leading directories should honor umask while
+		# the repository itself should follow "shared"
+		umask 002 &&
+		git init --bare --shared=0660 newdir/a/b/c &&
+		test -d newdir/a/b/c/refs &&
+		ls -ld newdir/a newdir/a/b > lsab.out &&
+		! grep -v "^drwxrw[sx]r-x" ls.out &&
+		ls -ld newdir/a/b/c > lsc.out &&
+		! grep -v "^drwxrw[sx]---" lsc.out
+	)
+'
+
+test_expect_success 'init notices EEXIST (1)' '
+	rm -fr newdir &&
+	(
+		>newdir &&
+		test_must_fail git init newdir &&
+		test -f newdir
+	)
+'
+
+test_expect_success 'init notices EEXIST (2)' '
+	rm -fr newdir &&
+	(
+		mkdir newdir &&
+		>newdir/a
+		test_must_fail git init newdir/a/b &&
+		test -f newdir/a
+	)
+'
+
+test_expect_success 'init notices EPERM' '
+	rm -fr newdir &&
+	(
+		mkdir newdir &&
+		chmod -w newdir &&
+		test_must_fail git init newdir/a/b
+	)
+'
+
 test_done

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] git init: optionally allow a directory argument
  2009-07-24 23:36 ` Junio C Hamano
  2009-07-25  3:13   ` Daniel Pittman
@ 2009-07-25  6:41   ` Alex Scarborough
  1 sibling, 0 replies; 7+ messages in thread
From: Alex Scarborough @ 2009-07-25  6:41 UTC (permalink / raw)
  To: git; +Cc: Nanako Shiraishi


On Jul 24, 2009, at 4:36 PM, Junio C Hamano wrote:

> Nanako Shiraishi <nanako3@lavabit.com> writes:
>
>> When starting a new repository, I see my students often say
>>
>>    % git init newrepo
>>
>> and curse git.  They could say
>>
>>    % mkdir newrepo; cd newrepo; git init
>>
>> but allowing it as an obvious short-cut may be nicer.
>>
>> Signed-off-by: Nanako Shiraishi <nanako3@lavabit.com>
>
> Hmm, I didn't realize this is so common a wish among new people.
>
> The patch seems clean.  Anybody has comments, both on code and the use
> case?

The use case makes sense.  This helps make git init be a bit more  
consistent
with git clone, which can take a trailing target.

For the code, I would replace the direct use of mkdir with  
safe_create_dir.
Otherwise it looks fine.

-Alex Scarborough

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] git init: optionally allow a directory argument
  2009-07-25  6:41 ` Junio C Hamano
@ 2009-07-25  7:45   ` Johannes Sixt
  2009-07-25  9:26     ` Junio C Hamano
  0 siblings, 1 reply; 7+ messages in thread
From: Johannes Sixt @ 2009-07-25  7:45 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Nanako Shiraishi, git

On Samstag, 25. Juli 2009, Junio C Hamano wrote:
> +test_expect_success 'init notices EPERM' '
> +	rm -fr newdir &&
> +	(
> +		mkdir newdir &&
> +		chmod -w newdir &&
> +		test_must_fail git init newdir/a/b
> +	)
> +'

This test will require POSIXPERM prerequisite.

-- Hannes

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] git init: optionally allow a directory argument
  2009-07-25  7:45   ` Johannes Sixt
@ 2009-07-25  9:26     ` Junio C Hamano
  0 siblings, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2009-07-25  9:26 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Nanako Shiraishi, git

Johannes Sixt <j6t@kdbg.org> writes:

> On Samstag, 25. Juli 2009, Junio C Hamano wrote:
>> +test_expect_success 'init notices EPERM' '
>> +	rm -fr newdir &&
>> +	(
>> +		mkdir newdir &&
>> +		chmod -w newdir &&
>> +		test_must_fail git init newdir/a/b
>> +	)
>> +'
>
> This test will require POSIXPERM prerequisite.

Heh, I knew it ;-)

Thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-07-25  9:26 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-24 21:59 [PATCH] git init: optionally allow a directory argument Nanako Shiraishi
2009-07-24 23:36 ` Junio C Hamano
2009-07-25  3:13   ` Daniel Pittman
2009-07-25  6:41   ` Alex Scarborough
2009-07-25  6:41 ` Junio C Hamano
2009-07-25  7:45   ` Johannes Sixt
2009-07-25  9:26     ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).