aboutsummaryrefslogtreecommitdiffstats
path: root/scalar.c
diff options
context:
space:
mode:
Diffstat (limited to 'scalar.c')
-rw-r--r--scalar.c116
1 files changed, 86 insertions, 30 deletions
diff --git a/scalar.c b/scalar.c
index 1326e1f608..da42b4be0c 100644
--- a/scalar.c
+++ b/scalar.c
@@ -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);
}
}