diff options
Diffstat (limited to 'scalar.c')
| -rw-r--r-- | scalar.c | 116 |
1 files changed, 86 insertions, 30 deletions
@@ -2,6 +2,8 @@ * The Scalar command-line interface. */ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "abspath.h" #include "gettext.h" @@ -70,6 +72,7 @@ static void setup_enlistment_directory(int argc, const char **argv, strbuf_release(&path); } +LAST_ARG_MUST_BE_NULL static int run_git(const char *arg, ...) { struct child_process cmd = CHILD_PROCESS_INIT; @@ -288,6 +291,7 @@ static int unregister_dir(void) } /* printf-style interface, expects `<key>=<value>` argument */ +__attribute__((format (printf, 1, 2))) static int set_config(const char *fmt, ...) { struct strbuf buf = STRBUF_INIT; @@ -361,16 +365,13 @@ static char *remote_default_branch(const char *url) static int delete_enlistment(struct strbuf *enlistment) { -#ifdef WIN32 struct strbuf parent = STRBUF_INIT; size_t offset; char *path_sep; -#endif if (unregister_dir()) return error(_("failed to unregister repository")); -#ifdef WIN32 /* * Change the current directory to one outside of the enlistment so * that we may delete everything underneath it. @@ -378,14 +379,13 @@ static int delete_enlistment(struct strbuf *enlistment) offset = offset_1st_component(enlistment->buf); path_sep = find_last_dir_sep(enlistment->buf + offset); strbuf_add(&parent, enlistment->buf, - path_sep ? path_sep - enlistment->buf : offset); + path_sep ? (size_t) (path_sep - enlistment->buf) : offset); if (chdir(parent.buf) < 0) { int res = error_errno(_("could not switch to '%s'"), parent.buf); strbuf_release(&parent); return res; } strbuf_release(&parent); -#endif if (have_fsmonitor_support() && stop_fsmonitor_daemon()) return error(_("failed to stop the FSMonitor daemon")); @@ -400,7 +400,8 @@ static int delete_enlistment(struct strbuf *enlistment) * Dummy implementation; Using `get_version_info()` would cause a link error * without this. */ -void load_builtin_commands(const char *prefix, struct cmdnames *cmds) +void load_builtin_commands(const char *prefix UNUSED, + struct cmdnames *cmds UNUSED) { die("not implemented"); } @@ -408,7 +409,9 @@ void load_builtin_commands(const char *prefix, struct cmdnames *cmds) static int cmd_clone(int argc, const char **argv) { const char *branch = NULL; + char *branch_to_free = NULL; int full_clone = 0, single_branch = 0, show_progress = isatty(2); + int src = 1, tags = 1; struct option clone_options[] = { OPT_STRING('b', "branch", &branch, N_("<branch>"), N_("branch to checkout after clone")), @@ -417,10 +420,15 @@ static int cmd_clone(int argc, const char **argv) OPT_BOOL(0, "single-branch", &single_branch, N_("only download metadata for the branch that will " "be checked out")), + OPT_BOOL(0, "src", &src, + N_("create repository within 'src' directory")), + OPT_BOOL(0, "tags", &tags, + N_("specify if tags should be fetched during clone")), OPT_END(), }; const char * const clone_usage[] = { - N_("scalar clone [<options>] [--] <repo> [<dir>]"), + N_("scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" + "\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]"), NULL }; const char *url; @@ -456,7 +464,10 @@ static int cmd_clone(int argc, const char **argv) if (is_directory(enlistment)) die(_("directory '%s' exists already"), enlistment); - dir = xstrfmt("%s/src", enlistment); + if (src) + dir = xstrfmt("%s/src", enlistment); + else + dir = xstrdup(enlistment); strbuf_reset(&buf); if (branch) @@ -480,7 +491,7 @@ static int cmd_clone(int argc, const char **argv) /* common-main already logs `argv` */ trace2_def_repo(the_repository); - if (!branch && !(branch = remote_default_branch(url))) { + if (!branch && !(branch = branch_to_free = remote_default_branch(url))) { res = error(_("failed to get default branch for '%s'"), url); goto cleanup; } @@ -496,6 +507,11 @@ static int cmd_clone(int argc, const char **argv) goto cleanup; } + if (!tags && set_config("remote.origin.tagOpt=--no-tags")) { + res = error(_("could not disable tags in '%s'"), dir); + goto cleanup; + } + if (!full_clone && (res = run_git("sparse-checkout", "init", "--cone", NULL))) goto cleanup; @@ -505,7 +521,9 @@ static int cmd_clone(int argc, const char **argv) if ((res = run_git("fetch", "--quiet", show_progress ? "--progress" : "--no-progress", - "origin", NULL))) { + "origin", + (tags ? NULL : "--no-tags"), + NULL))) { warning(_("partial clone failed; attempting full clone")); if (set_config("remote.origin.promisor") || @@ -535,6 +553,7 @@ static int cmd_clone(int argc, const char **argv) res = register_dir(); cleanup: + free(branch_to_free); free(enlistment); free(dir); strbuf_release(&buf); @@ -594,7 +613,9 @@ static int cmd_register(int argc, const char **argv) return register_dir(); } -static int get_scalar_repos(const char *key, const char *value, void *data) +static int get_scalar_repos(const char *key, const char *value, + const struct config_context *ctx UNUSED, + void *data) { struct string_list *list = data; @@ -635,8 +656,7 @@ static int cmd_reconfigure(int argc, const char **argv) NULL }; struct string_list scalar_repos = STRING_LIST_INIT_DUP; - int i, res = 0; - struct repository r = { NULL }; + int res = 0; struct strbuf commondir = STRBUF_INIT, gitdir = STRBUF_INIT; argc = parse_options(argc, argv, NULL, options, @@ -654,7 +674,9 @@ static int cmd_reconfigure(int argc, const char **argv) git_config(get_scalar_repos, &scalar_repos); - for (i = 0; i < scalar_repos.nr; i++) { + for (size_t i = 0; i < scalar_repos.nr; i++) { + int succeeded = 0; + struct repository *old_repo, r = { NULL }; const char *dir = scalar_repos.items[i].string; strbuf_reset(&commondir); @@ -665,30 +687,64 @@ static int cmd_reconfigure(int argc, const char **argv) if (errno != ENOENT) { warning_errno(_("could not switch to '%s'"), dir); - res = -1; - continue; + goto loop_end; } strbuf_addstr(&buf, dir); if (remove_deleted_enlistment(&buf)) - res = error(_("could not remove stale " - "scalar.repo '%s'"), dir); - else - warning(_("removing stale scalar.repo '%s'"), + error(_("could not remove stale " + "scalar.repo '%s'"), dir); + else { + warning(_("removed stale scalar.repo '%s'"), dir); + succeeded = 1; + } strbuf_release(&buf); - } else if (discover_git_directory(&commondir, &gitdir) < 0) { - warning_errno(_("git repository gone in '%s'"), dir); - res = -1; - } else { - git_config_clear(); + goto loop_end; + } - the_repository = &r; - r.commondir = commondir.buf; - r.gitdir = gitdir.buf; + switch (discover_git_directory_reason(&commondir, &gitdir)) { + case GIT_DIR_INVALID_OWNERSHIP: + warning(_("repository at '%s' has different owner"), dir); + goto loop_end; - if (set_recommended_config(1) < 0) - res = -1; + case GIT_DIR_INVALID_GITFILE: + case GIT_DIR_INVALID_FORMAT: + warning(_("repository at '%s' has a format issue"), dir); + goto loop_end; + + case GIT_DIR_DISCOVERED: + succeeded = 1; + break; + + default: + warning(_("repository not found in '%s'"), dir); + break; + } + + git_config_clear(); + + if (repo_init(&r, gitdir.buf, commondir.buf)) + goto loop_end; + + old_repo = the_repository; + the_repository = &r; + + if (set_recommended_config(1) >= 0) + succeeded = 1; + + the_repository = old_repo; + repo_clear(&r); + + if (toggle_maintenance(1) >= 0) + succeeded = 1; + +loop_end: + if (!succeeded) { + res = -1; + warning(_("to unregister this repository from Scalar, run\n" + "\tgit config --global --unset --fixed-value scalar.repo \"%s\""), + dir); } } |
