"git init --split-repo abc" will create abc/.git file with the content
gitsuper: `git rev-parse --git-dir` gitdir: abc and a new directory in current .git/repos/abc with a valid HEAD. This is enough to start checking out and do stuff. We should probably take a branch name and check that branch out though. If that's the case, this feature may better be parked in "git checkout" instead of here.. So far it's not any better than git-new-workdir, except that info from all worktrees created this way is centralized in the super repo's .git/repos, which makes it possible to ensure what worktree does not step on one another. In particular: - If a worktree updates a ref, we could check if any other worktrees are also checking out that ref. Detach those worktrees. - prune/gc should be taught about the extra HEADs in .git/repos. fsck on the super repo should be taught about extra indexes in .git/repos - ... Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com> --- builtin/init-db.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/builtin/init-db.c b/builtin/init-db.c index 78aa387..9c7139a 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -426,6 +426,38 @@ int init_db(const char *template_dir, unsigned int flags) return 0; } +static int create_new_worktree(const char *path) +{ + struct strbuf sb = STRBUF_INIT; + const char *name; + unsigned char sha1[20]; + FILE *fp; + + for (name = path + strlen(path) - 1; name > path; name--) + if (is_dir_sep(*name)) { + name++; + break; + } + + strbuf_addf(&sb, "%s/.git", path); + safe_create_leading_directories_const(sb.buf); + fp = fopen(sb.buf, "w"); + fprintf(fp, "gitsuper: %s\ngitdir: %s\n", + real_path(get_git_dir()), name); + fclose(fp); + safe_create_leading_directories_const(git_path("repos/%s/HEAD", + name)); + fp = fopen(git_path("repos/%s/HEAD", name), "w"); + get_sha1("HEAD", sha1); + fprintf(fp, "%s\n", sha1_to_hex(sha1)); + fclose(fp); +#if 0 + chdir(path); + system("git reset --hard"); +#endif + return 0; +} + static int guess_repository_type(const char *git_dir) { char cwd[PATH_MAX]; @@ -481,6 +513,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) const char *work_tree; const char *template_dir = NULL; unsigned int flags = 0; + int split_repo = 0; const struct option init_db_options[] = { OPT_STRING(0, "template", &template_dir, N_("template-directory"), N_("directory from which templates will be used")), @@ -491,6 +524,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) N_("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, N_("be quiet"), INIT_DB_QUIET), + OPT_BOOL(0, "split-repo", &split_repo, N_("git-new-workdir")), OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), N_("separate git dir from working tree")), OPT_END() @@ -498,6 +532,14 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0); + if (split_repo) { + if (real_git_dir) + die(_("--split-repo and --separate-git-dir are incompatible")); + if (!argv[0]) + die(_("--split-repo requires a path")); + return create_new_worktree(argv[0]); + } + if (real_git_dir && !is_absolute_path(real_git_dir)) real_git_dir = xstrdup(real_path(real_git_dir)); -- 1.8.5.1.77.g42c48fa -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html