diff options
author | Junio C Hamano <gitster@pobox.com> | 2009-08-05 12:39:33 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2009-08-05 12:39:33 -0700 |
commit | 0397ff24698ee39954f25dda7b45de5a2767f642 (patch) | |
tree | 1a9414511d358a3acd3c61440a588789fe3ce879 | |
parent | 4d4097da6b158ba5eeaa9ac0ccc5d704126f1991 (diff) | |
parent | 53d48885931614a43e414e1272a7f126f8d0c901 (diff) | |
download | git-0397ff24698ee39954f25dda7b45de5a2767f642.tar.gz |
Merge branch 'ns/init-mkdir'
* ns/init-mkdir:
git init: optionally allow a directory argument
Conflicts:
builtin-init-db.c
-rw-r--r-- | Documentation/git-init.txt | 5 | ||||
-rw-r--r-- | builtin-init-db.c | 47 | ||||
-rwxr-xr-x | t/t0001-init.sh | 77 |
3 files changed, 122 insertions, 7 deletions
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 7151d12f34..f081b24d9d 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 d68f61b9c8..dd84caecbc 100644 --- a/builtin-init-db.c +++ b/builtin-init-db.c @@ -378,7 +378,7 @@ static int shared_callback(const struct option *opt, const char *arg, int unset) } static const char *const init_db_usage[] = { - "git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]]", + "git init [-q | --quiet] [--bare] [--template=<template-directory>] [--shared[=<permissions>]] [directory]", NULL }; @@ -406,12 +406,47 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) OPT_END() }; - parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0); - - if(is_bare_repository_cfg == 1) { + argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0); + + if (argc == 1) { + int mkdir_tried = 0; + retry: + if (chdir(argv[0]) < 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[0])) { + case -3: + errno = EEXIST; + /* fallthru */ + case -1: + die_errno("cannot mkdir %s", argv[0]); + break; + default: + break; + } + shared_repository = saved; + if (mkdir(argv[0], 0777) < 0) + die_errno("cannot mkdir %s", argv[0]); + mkdir_tried = 1; + goto retry; + } + die_errno("cannot chdir to %s", argv[0]); + } + } else if (0 < argc) { + usage(init_db_usage[0]); + } + if (is_bare_repository_cfg == 1) { static char git_dir[PATH_MAX+1]; - setenv(GIT_DIR_ENVIRONMENT, getcwd(git_dir, - sizeof(git_dir)), 0); + + setenv(GIT_DIR_ENVIRONMENT, + getcwd(git_dir, sizeof(git_dir)), 0); } if (init_shared_repository != -1) diff --git a/t/t0001-init.sh b/t/t0001-init.sh index e3d846420d..49caa29061 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -208,4 +208,81 @@ 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_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 POSIXPERM 'init notices EPERM' ' + rm -fr newdir && + ( + mkdir newdir && + chmod -w newdir && + test_must_fail git init newdir/a/b + ) +' + test_done |