Instead of creating the repository at $GIT_DIR, --real-git-dir will tell git to put the repository there, then make $GIT_DIR a .git file that points to --real-git-dir. Signed-off-by: Nguyán ThÃi Ngác Duy <pclouds@xxxxxxxxx> --- This makes '.git symbolic link' (what's its official name?) more convenient to use. Previously whenever I need to create a .git link, I need to open docs to see its format. Now all I need to do is git init --real-git-dir=/where/real/git/is git clone --real-git-dir=/where/real/git/is something I intend to make 'git init --real-git-dir' move current repo to somewhere else if called on existing repo. Long term I'd like to see a init/clone hook, where I can tell git "when I ask you to create a repo/worktree at foo, put the real repo at ~/git/foo" I could use a better option name too, any suggestions? builtin/clone.c | 7 ++++++- builtin/init-db.c | 38 +++++++++++++++++++++++++++++++++++++- cache.h | 1 + 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/builtin/clone.c b/builtin/clone.c index 60d9a64..74e487a 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -42,6 +42,7 @@ static int option_local, option_no_hardlinks, option_shared, option_recursive; static char *option_template, *option_reference, *option_depth; static char *option_origin = NULL; static char *option_branch = NULL; +static const char *real_git_dir; static char *option_upload_pack = "git-upload-pack"; static int option_verbosity; static int option_progress; @@ -80,6 +81,8 @@ static struct option builtin_clone_options[] = { "path to git-upload-pack on the remote"), OPT_STRING(0, "depth", &option_depth, "depth", "create a shallow clone of that depth"), + OPT_STRING(0, "real-git-dir", &real_git_dir, "git-dir", + "directory where real repository is cloned to"), OPT_END() }; @@ -466,7 +469,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (safe_create_leading_directories_const(git_dir) < 0) die("could not create leading directories of '%s'", git_dir); - set_git_dir(make_absolute_path(git_dir)); + set_git_dir_init(git_dir, real_git_dir); + if (real_git_dir) + git_dir = real_git_dir; if (0 <= option_verbosity) printf("Cloning into %s%s...\n", diff --git a/builtin/init-db.c b/builtin/init-db.c index fbeb380..7a0fb50 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -21,6 +21,7 @@ static int init_is_bare_repository = 0; static int init_shared_repository = -1; static const char *init_db_template_dir; +static const char *git_link; static void safe_create_dir(const char *dir, int share) { @@ -311,10 +312,42 @@ static void create_object_directory(void) free(path); } +int set_git_dir_init(const char *git_dir, const char *real_git_dir) +{ + if (real_git_dir) { + struct stat st; + + if (!stat(git_dir, &st)) + die("%s already exists", git_dir); + git_link = git_dir; + } + else { + real_git_dir = git_dir; + git_link = NULL; + } + set_git_dir(make_absolute_path(real_git_dir)); + return 0; +} + int init_db(const char *template_dir, unsigned int flags) { int reinit; + if (git_link) { + struct stat st; + FILE *fp; + + /* TODO: allow --real-git-dir to move repo elsewhere */ + if (!lstat(git_link, &st)) + die("%s already exists", git_link); + + fp = fopen(git_link, "w"); + if (!fp) + die("Could not create git link %s", git_link); + fprintf(fp, "gitdir: %s\n", get_git_dir()); + fclose(fp); + } + safe_create_dir(get_git_dir(), 0); init_is_bare_repository = is_bare_repository(); @@ -414,6 +447,7 @@ static const char *const init_db_usage[] = { int cmd_init_db(int argc, const char **argv, const char *prefix) { const char *git_dir; + const char *real_git_dir = NULL; const char *work_tree; const char *template_dir = NULL; unsigned int flags = 0; @@ -427,6 +461,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) "specify that the git repository is to be shared amongst several users", PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0}, OPT_BIT('q', "quiet", &flags, "be quiet", INIT_DB_QUIET), + OPT_STRING(0, "real-git-dir", &real_git_dir, "git-dir", + "directory where real .git is initialized"), OPT_END() }; @@ -522,7 +558,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) set_git_work_tree(make_absolute_path(work_tree)); } - set_git_dir(make_absolute_path(git_dir)); + set_git_dir_init(git_dir, real_git_dir); return init_db(template_dir, flags); } diff --git a/cache.h b/cache.h index 08a9022..0b006b8 100644 --- a/cache.h +++ b/cache.h @@ -436,6 +436,7 @@ extern void verify_non_filename(const char *prefix, const char *name); #define INIT_DB_QUIET 0x0001 +extern int set_git_dir_init(const char *git_dir, const char *real_git_dir); extern int init_db(const char *template_dir, unsigned int flags); #define alloc_nr(x) (((x)+16)*3/2) -- 1.7.4.74.g639db -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html