{"thread":{"id":"26791","subject":"[PATCH 1/2] git-init.txt: move description section up","startedAt":"2011-03-19T15:16:55Z","lastAt":"2011-03-19T16:13:10Z","messageCount":4,"participants":["Nguyễn Thái Ngọc Duy","Matthieu Moy","Nguyen Thai Ngoc Duy"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"163752","messageId":"1300547816-4768-1-git-send-email-pclouds@gmail.com","threadId":"26791","inReplyTo":null,"subject":"[PATCH 1/2] git-init.txt: move description section up","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-03-19T15:16:55Z","receivedAt":"2011-03-19T15:16:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"It's more or less standard that synopsis is followed by description,\nthen options.\n\nThis is not just a clean move though:\n\n - The paragraphs are realigned a bit\n - The text mentioning git-init-db is dropped. init-db is\n   deprecated, no need to confuse new users\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n Documentation/git-init.txt |   46 +++++++++++++++++++------------------------\n 1 files changed, 20 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/git-init.txt b/Documentation/git-init.txt\nindex 5931925..0a4a20e 100644\n--- a/Documentation/git-init.txt\n+++ b/Documentation/git-init.txt\n@@ -11,6 +11,26 @@ SYNOPSIS\n 'git init' [-q | --quiet] [--bare] [--template=<template_directory>] [--shared[=<permissions>]] [directory]\n \n \n+DESCRIPTION\n+-----------\n+\n+This command creates an empty git repository - basically a `.git`\n+directory with subdirectories for `objects`, `refs/heads`,\n+`refs/tags`, and template files.  An initial `HEAD` file that\n+references the HEAD of the master branch is also created.\n+\n+If the `$GIT_DIR` environment variable is set then it specifies a path\n+to use instead of `./.git` for the base of the repository.\n+\n+If the object storage directory is specified via the\n+`$GIT_OBJECT_DIRECTORY` environment variable then the sha1 directories\n+are created underneath - otherwise the default `$GIT_DIR/objects`\n+directory is used.\n+\n+Running 'git init' in an existing repository is safe. It will not\n+overwrite things that are already there. The primary reason for\n+rerunning 'git init' is to pick up newly added templates.\n+\n OPTIONS\n -------\n \n@@ -74,32 +94,6 @@ line, the command is run inside the directory (possibly after creating it).\n --\n \n \n-DESCRIPTION\n------------\n-This command creates an empty git repository - basically a `.git` directory\n-with subdirectories for `objects`, `refs/heads`, `refs/tags`, and\n-template files.\n-An initial `HEAD` file that references the HEAD of the master branch\n-is also created.\n-\n-If the `$GIT_DIR` environment variable is set then it specifies a path\n-to use instead of `./.git` for the base of the repository.\n-\n-If the object storage directory is specified via the `$GIT_OBJECT_DIRECTORY`\n-environment variable then the sha1 directories are created underneath -\n-otherwise the default `$GIT_DIR/objects` directory is used.\n-\n-Running 'git init' in an existing repository is safe. It will not overwrite\n-things that are already there. The primary reason for rerunning 'git init'\n-is to pick up newly added templates.\n-\n-Note that 'git init' is the same as 'git init-db'.  The command\n-was primarily meant to initialize the object database, but over\n-time it has become responsible for setting up the other aspects\n-of the repository, such as installing the default hooks and\n-setting the configuration variables.  The old name is retained\n-for backward compatibility reasons.\n-\n TEMPLATE DIRECTORY\n ------------------\n \n-- \n1.7.4.74.g639db\n"},{"id":"163754","messageId":"1300547816-4768-2-git-send-email-pclouds@gmail.com","threadId":"26791","inReplyTo":"1300547816-4768-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 2/2 nd/init-gitdir] init, clone: support --separate-git-dir for .git file","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-03-19T15:16:56Z","receivedAt":"2011-03-19T15:16:56Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"--separate-git-dir tells git to create git dir at the specified\nlocation, instead of where it is supposed to be. A .git file that\npoints to that location will be put in place so that it appears normal\nto repo discovery process.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n  - rebased on top of master because it uses real_path().\n  - implemented repo move if \"git init --separate-git-dir\" is run on\n    an existing repo.\n  - docs\n  - tests\n\n Documentation/git-clone.txt |   10 ++++++\n Documentation/git-init.txt  |   17 +++++++++-\n builtin/clone.c             |    8 ++++-\n builtin/init-db.c           |   68 +++++++++++++++++++++++++++++++++++++++++--\n cache.h                     |    1 +\n t/t0001-init.sh             |   46 +++++++++++++++++++++++++++++\n t/t5601-clone.sh            |   13 ++++++++\n 7 files changed, 157 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt\nindex 8577480..86eb4c9 100644\n--- a/Documentation/git-clone.txt\n+++ b/Documentation/git-clone.txt\n@@ -12,6 +12,7 @@ SYNOPSIS\n 'git clone' [--template=<template_directory>]\n \t  [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]\n \t  [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]\n+\t  [--separate-git-dir|-L <git dir>]\n \t  [--depth <depth>] [--recursive|--recurse-submodules] [--] <repository>\n \t  [<directory>]\n \n@@ -176,6 +177,15 @@ objects from the source repository into a pack in the cloned repository.\n \trepository does not have a worktree/checkout (i.e. if any of\n \t`--no-checkout`/`-n`, `--bare`, or `--mirror` is given)\n \n+-L=<git dir>::\n+--separate-git-dir=<git dir>::\n+\tInstead of placing the cloned repository where it is supposed\n+\tto be, place the cloned repository at the specified directory,\n+\tthen make a filesytem-agnostic git symbolic link to there.\n+\tThe result is git repository can be separated from working\n+\ttree.\n+\n+\n <repository>::\n \tThe (possibly remote) repository to clone from.  See the\n \t<<URLS,URLS>> section below for more information on specifying\ndiff --git a/Documentation/git-init.txt b/Documentation/git-init.txt\nindex 0a4a20e..58cd011 100644\n--- a/Documentation/git-init.txt\n+++ b/Documentation/git-init.txt\n@@ -8,7 +8,9 @@ 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>]] [directory]\n+'git init' [-q | --quiet] [--bare] [--template=<template_directory>]\n+\t  [--separate-git-dir|-L <git dir>]\n+\t  [--shared[=<permissions>]] [directory]\n \n \n DESCRIPTION\n@@ -29,7 +31,8 @@ directory is used.\n \n Running 'git init' in an existing repository is safe. It will not\n overwrite things that are already there. The primary reason for\n-rerunning 'git init' is to pick up newly added templates.\n+rerunning 'git init' is to pick up newly added templates (or to move\n+the repository to another place if --separate-git-dir is given).\n \n OPTIONS\n -------\n@@ -51,6 +54,16 @@ current working directory.\n Specify the directory from which templates will be used.  (See the \"TEMPLATE\n DIRECTORY\" section below.)\n \n+-L=<git dir>::\n+--separate-git-dir=<git dir>::\n+\n+Instead of initializing the repository where it is supposed to be,\n+place a filesytem-agnostic git symbolic link there, pointing to the\n+specified git path, and initialize a git repository at the path. The\n+result is git repository can be separated from working tree. If this\n+is reinitialization, the repository will be moved to the specified\n+path.\n+\n --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::\n \n Specify that the git repository is to be shared amongst several users.  This\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 404f589..097beca 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -42,6 +42,7 @@ static int option_local, option_no_hardlinks, option_shared, option_recursive;\n static char *option_template, *option_reference, *option_depth;\n static char *option_origin = NULL;\n static char *option_branch = NULL;\n+static const char *real_git_dir;\n static char *option_upload_pack = \"git-upload-pack\";\n static int option_verbosity;\n static int option_progress;\n@@ -80,6 +81,8 @@ static struct option builtin_clone_options[] = {\n \t\t   \"path to git-upload-pack on the remote\"),\n \tOPT_STRING(0, \"depth\", &option_depth, \"depth\",\n \t\t    \"create a shallow clone of that depth\"),\n+\tOPT_STRING('L', \"separate-git-dir\", &real_git_dir, \"gitdir\",\n+\t\t   \"separate git dir from working tree\"),\n \n \tOPT_END()\n };\n@@ -466,7 +469,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \n \tif (safe_create_leading_directories_const(git_dir) < 0)\n \t\tdie(\"could not create leading directories of '%s'\", git_dir);\n-\tset_git_dir(real_path(git_dir));\n+\n+\tset_git_dir_init(git_dir, real_git_dir, 0);\n+\tif (real_git_dir)\n+\t\tgit_dir = real_git_dir;\n \n \tif (0 <= option_verbosity)\n \t\tprintf(\"Cloning into %s%s...\\n\",\ndiff --git a/builtin/init-db.c b/builtin/init-db.c\nindex 8f5cfd7..8879399 100644\n--- a/builtin/init-db.c\n+++ b/builtin/init-db.c\n@@ -21,6 +21,7 @@\n static int init_is_bare_repository = 0;\n static int init_shared_repository = -1;\n static const char *init_db_template_dir;\n+static const char *git_link;\n \n static void safe_create_dir(const char *dir, int share)\n {\n@@ -311,11 +312,67 @@ static void create_object_directory(void)\n \tfree(path);\n }\n \n+int set_git_dir_init(const char *git_dir, const char *real_git_dir,\n+\t\t     int exist_ok)\n+{\n+\tif (real_git_dir) {\n+\t\tstruct stat st;\n+\n+\t\tif (!exist_ok && !stat(git_dir, &st))\n+\t\t\tdie(\"%s already exists\", git_dir);\n+\n+\t\tif (!exist_ok && !stat(real_git_dir, &st))\n+\t\t\tdie(\"%s already exists\", real_git_dir);\n+\n+\t\t/*\n+\t\t * make sure symlinks are resolved because we'll be\n+\t\t * moving the target repo later on in separate_git_dir()\n+\t\t */\n+\t\tgit_link = xstrdup(real_path(git_dir));\n+\t}\n+\telse {\n+\t\treal_git_dir = real_path(git_dir);\n+\t\tgit_link = NULL;\n+\t}\n+\tset_git_dir(real_path(real_git_dir));\n+\treturn 0;\n+}\n+\n+static void separate_git_dir(const char *git_dir)\n+{\n+\tstruct stat st;\n+\tFILE *fp;\n+\n+\tif (!stat(git_link, &st)) {\n+\t\tconst char *src;\n+\n+\t\tif (S_ISREG(st.st_mode))\n+\t\t\tsrc = read_gitfile_gently(git_link);\n+\t\telse if (S_ISDIR(st.st_mode))\n+\t\t\tsrc = git_link;\n+\t\telse\n+\t\t\tdie(\"unable to handle file type %d\", st.st_mode);\n+\n+\t\tif (rename(src, git_dir))\n+\t\t\tdie_errno(\"unable to move %s to %s\", src, git_dir);\n+\t}\n+\n+\tfp = fopen(git_link, \"w\");\n+\tif (!fp)\n+\t\tdie(\"Could not create git link %s\", git_link);\n+\tfprintf(fp, \"gitdir: %s\\n\", git_dir);\n+\tfclose(fp);\n+}\n+\n int init_db(const char *template_dir, unsigned int flags)\n {\n \tint reinit;\n+\tconst char *git_dir = get_git_dir();\n \n-\tsafe_create_dir(get_git_dir(), 0);\n+\tif (git_link)\n+\t\tseparate_git_dir(git_dir);\n+\n+\tsafe_create_dir(git_dir, 0);\n \n \tinit_is_bare_repository = is_bare_repository();\n \n@@ -352,7 +409,6 @@ int init_db(const char *template_dir, unsigned int flags)\n \t}\n \n \tif (!(flags & INIT_DB_QUIET)) {\n-\t\tconst char *git_dir = get_git_dir();\n \t\tint len = strlen(git_dir);\n \t\tprintf(\"%s%s Git repository in %s%s\\n\",\n \t\t       reinit ? \"Reinitialized existing\" : \"Initialized empty\",\n@@ -414,6 +470,7 @@ static const char *const 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 *real_git_dir = NULL;\n \tconst char *work_tree;\n \tconst char *template_dir = NULL;\n \tunsigned int flags = 0;\n@@ -427,11 +484,16 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \t\t\t\"specify that the git repository is to be shared amongst several users\",\n \t\t\tPARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0},\n \t\tOPT_BIT('q', \"quiet\", &flags, \"be quiet\", INIT_DB_QUIET),\n+\t\tOPT_STRING('L', \"separate-git-dir\", &real_git_dir, \"gitdir\",\n+\t\t\t   \"separate git dir from working tree\"),\n \t\tOPT_END()\n \t};\n \n \targc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0);\n \n+\tif (real_git_dir && !is_absolute_path(real_git_dir))\n+\t\treal_git_dir = xstrdup(real_path(real_git_dir));\n+\n \tif (argc == 1) {\n \t\tint mkdir_tried = 0;\n \tretry:\n@@ -522,7 +584,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \t\t\tset_git_work_tree(real_path(work_tree));\n \t}\n \n-\tset_git_dir(real_path(git_dir));\n+\tset_git_dir_init(git_dir, real_git_dir, 1);\n \n \treturn init_db(template_dir, flags);\n }\ndiff --git a/cache.h b/cache.h\nindex a99fd56..0b99487 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -436,6 +436,7 @@ extern void verify_non_filename(const char *prefix, const char *name);\n \n #define INIT_DB_QUIET 0x0001\n \n+extern int set_git_dir_init(const char *git_dir, const char *real_git_dir, int);\n extern int init_db(const char *template_dir, unsigned int flags);\n \n #define alloc_nr(x) (((x)+16)*3/2)\ndiff --git a/t/t0001-init.sh b/t/t0001-init.sh\nindex f684993..b2e6919 100755\n--- a/t/t0001-init.sh\n+++ b/t/t0001-init.sh\n@@ -374,4 +374,50 @@ test_expect_success 'init prefers command line to GIT_DIR' '\n \t! test -d otherdir/refs\n '\n \n+test_expect_success 'init with separate gitdir' '\n+\trm -rf newdir &&\n+\tgit init --separate-git-dir realgitdir newdir &&\n+\techo \"gitdir: `pwd`/realgitdir\" >expected &&\n+\ttest_cmp expected newdir/.git &&\n+\ttest -d realgitdir/refs\n+'\n+\n+test_expect_success 're-init to update git link' '\n+\t(\n+\tcd newdir &&\n+\tgit init --separate-git-dir ../surrealgitdir\n+\t) &&\n+\techo \"gitdir: `pwd`/surrealgitdir\" >expected &&\n+\ttest_cmp expected newdir/.git &&\n+\ttest -d surrealgitdir/refs &&\n+\t! test -d realgitdir/refs\n+'\n+\n+test_expect_success 're-init to move gitdir' '\n+\trm -rf newdir realgitdir surrealgitdir &&\n+\tgit init newdir &&\n+\t(\n+\tcd newdir &&\n+\tgit init --separate-git-dir ../realgitdir\n+\t) &&\n+\techo \"gitdir: `pwd`/realgitdir\" >expected &&\n+\ttest_cmp expected newdir/.git &&\n+\ttest -d realgitdir/refs\n+'\n+\n+test_expect_success 're-init to move gitdir symlink' '\n+\trm -rf newdir realgitdir &&\n+\tgit init newdir &&\n+\t(\n+\tcd newdir &&\n+\tmv .git here &&\n+\tln -s here .git &&\n+\tgit init -L ../realgitdir\n+\t) &&\n+\techo \"gitdir: `pwd`/realgitdir\" >expected &&\n+\ttest_cmp expected newdir/.git &&\n+\ttest -d realgitdir/refs &&\n+\t! test -d newdir/here\n+'\n+\n test_done\ndiff --git a/t/t5601-clone.sh b/t/t5601-clone.sh\nindex 987e0c8..c467b67 100755\n--- a/t/t5601-clone.sh\n+++ b/t/t5601-clone.sh\n@@ -192,4 +192,17 @@ test_expect_success 'do not respect url-encoding of non-url path' '\n \tgit clone x+y xy-regular\n '\n \n+test_expect_success 'clone separate gitdir' '\n+\trm -rf dst &&\n+\tgit clone --separate-git-dir realgitdir src dst &&\n+\techo \"gitdir: `pwd`/realgitdir\" >expected &&\n+\ttest_cmp expected dst/.git &&\n+\ttest -d realgitdir/refs\n+'\n+\n+test_expect_success 'clone separate gitdir where target already exists' '\n+\trm -rf dst &&\n+\ttest_must_fail git clone --separate-git-dir realgitdir src dst\n+'\n+\n test_done\n-- \n1.7.4.74.g639db\n"},{"id":"163757","messageId":"vpqbp17hzoz.fsf@bauges.imag.fr","threadId":"26791","inReplyTo":"1300547816-4768-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 1/2] git-init.txt: move description section up","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2011-03-19T15:55:56Z","receivedAt":"2011-03-19T15:55:56Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:\n\n>  - The text mentioning git-init-db is dropped. init-db is\n>    deprecated, no need to confuse new users\n\nShouldn't we add something like this then?\n\nFrom 86b8daa4bf4c7cd376335570e5f1663c6d6cde01 Mon Sep 17 00:00:00 2001\nFrom: Matthieu Moy <Matthieu.Moy@imag.fr>\nDate: Sat, 19 Mar 2011 16:54:43 +0100\nSubject: [PATCH] shorten git-init-db.txt to only point to git-init.txt\n\n---\n Documentation/git-init-db.txt |    8 +-------\n 1 files changed, 1 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt\nindex 2c4c716..b2b959e 100644\n--- a/Documentation/git-init-db.txt\n+++ b/Documentation/git-init-db.txt\n@@ -3,13 +3,7 @@ git-init-db(1)\n \n NAME\n ----\n-git-init-db - Creates an empty git repository\n-\n-\n-SYNOPSIS\n---------\n-'git init-db' [-q | --quiet] [--bare] [--template=<template_directory>] [--shared[=<permissions>]]\n-\n+git-init-db - Deprecated alias for linkgit:git-init[1]\n \n DESCRIPTION\n -----------\n-- \n1.7.4.1.293.g8414b\n\n\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"163759","messageId":"AANLkTi=DtKbpF9YdKJJij0PSpRnneDsthk7Pv5NH_x+N@mail.gmail.com","threadId":"26791","inReplyTo":"vpqbp17hzoz.fsf@bauges.imag.fr","subject":"Re: [PATCH 1/2] git-init.txt: move description section up","fromName":"Nguyen Thai Ngoc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2011-03-19T16:13:10Z","receivedAt":"2011-03-19T16:13:10Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"2011/3/19 Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>:\n> diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.txt\n> index 2c4c716..b2b959e 100644\n> --- a/Documentation/git-init-db.txt\n> +++ b/Documentation/git-init-db.txt\n> @@ -3,13 +3,7 @@ git-init-db(1)\n>\n>  NAME\n>  ----\n> -git-init-db - Creates an empty git repository\n> -\n> -\n> -SYNOPSIS\n> ---------\n> -'git init-db' [-q | --quiet] [--bare] [--template=<template_directory>] [--shared[=<permissions>]]\n> -\n> +git-init-db - Deprecated alias for linkgit:git-init[1]\n\nYou should remove DESCRIPTION section too.\n-- \nDuy\n"}]}