summaryrefslogtreecommitdiff
path: root/builtin/remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/remote.c')
-rw-r--r--builtin/remote.c316
1 files changed, 183 insertions, 133 deletions
diff --git a/builtin/remote.c b/builtin/remote.c
index 299c466..8412d12 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -1,6 +1,8 @@
#include "builtin.h"
#include "config.h"
+#include "gettext.h"
#include "parse-options.h"
+#include "path.h"
#include "transport.h"
#include "remote.h"
#include "string-list.h"
@@ -9,14 +11,15 @@
#include "rebase.h"
#include "refs.h"
#include "refspec.h"
-#include "object-store.h"
+#include "object-store-ll.h"
#include "strvec.h"
#include "commit-reach.h"
+#include "progress.h"
static const char * const builtin_remote_usage[] = {
- N_("git remote [-v | --verbose]"),
+ "git remote [-v | --verbose]",
N_("git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--mirror=<fetch|push>] <name> <url>"),
- N_("git remote rename <old> <new>"),
+ N_("git remote rename [--[no-]progress] <old> <new>"),
N_("git remote remove <name>"),
N_("git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"),
N_("git remote [-v | --verbose] show [-n] <name>"),
@@ -36,7 +39,7 @@ static const char * const builtin_remote_add_usage[] = {
};
static const char * const builtin_remote_rename_usage[] = {
- N_("git remote rename <old> <new>"),
+ N_("git remote rename [--[no-]progress] <old> <new>"),
NULL
};
@@ -91,13 +94,15 @@ static int verbose;
static int fetch_remote(const char *name)
{
- const char *argv[] = { "fetch", name, NULL, NULL };
- if (verbose) {
- argv[1] = "-v";
- argv[2] = name;
- }
+ struct child_process cmd = CHILD_PROCESS_INIT;
+
+ strvec_push(&cmd.args, "fetch");
+ if (verbose)
+ strvec_push(&cmd.args, "-v");
+ strvec_push(&cmd.args, name);
+ cmd.git_cmd = 1;
printf_ln(_("Updating %s"), name);
- if (run_command_v_opt(argv, RUN_GIT_CMD))
+ if (run_command(&cmd))
return error(_("Could not fetch %s"), name);
return 0;
}
@@ -145,11 +150,11 @@ static int parse_mirror_opt(const struct option *opt, const char *arg, int not)
else if (!strcmp(arg, "push"))
*mirror = MIRROR_PUSH;
else
- return error(_("unknown mirror argument: %s"), arg);
+ return error(_("unknown --mirror argument: %s"), arg);
return 0;
}
-static int add(int argc, const char **argv)
+static int add(int argc, const char **argv, const char *prefix)
{
int fetch = 0, fetch_tags = TAGS_DEFAULT;
unsigned mirror = MIRROR_NONE;
@@ -163,10 +168,9 @@ static int add(int argc, const char **argv)
struct option options[] = {
OPT_BOOL('f', "fetch", &fetch, N_("fetch the remote branches")),
OPT_SET_INT(0, "tags", &fetch_tags,
- N_("import all tags and associated objects when fetching"),
+ N_("import all tags and associated objects when fetching\n"
+ "or do not fetch any tag at all (--no-tags)"),
TAGS_SET),
- OPT_SET_INT(0, NULL, &fetch_tags,
- N_("or do not fetch any tag at all (--no-tags)"), TAGS_UNSET),
OPT_STRING_LIST('t', "track", &track, N_("branch"),
N_("branch(es) to track")),
OPT_STRING('m', "master", &master, N_("branch"), N_("master branch")),
@@ -176,8 +180,8 @@ static int add(int argc, const char **argv)
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_add_usage,
- 0);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_add_usage, 0);
if (argc != 2)
usage_with_options(builtin_remote_add_usage, options);
@@ -263,7 +267,9 @@ static const char *abbrev_ref(const char *name, const char *prefix)
}
#define abbrev_branch(name) abbrev_ref((name), "refs/heads/")
-static int config_read_branches(const char *key, const char *value, void *cb)
+static int config_read_branches(const char *key, const char *value,
+ const struct config_context *ctx UNUSED,
+ void *data UNUSED)
{
const char *orig_key = key;
char *name;
@@ -343,12 +349,13 @@ static void read_branches(void)
struct ref_states {
struct remote *remote;
- struct string_list new_refs, stale, tracked, heads, push;
+ struct string_list new_refs, skipped, stale, tracked, heads, push;
int queried;
};
#define REF_STATES_INIT { \
.new_refs = STRING_LIST_INIT_DUP, \
+ .skipped = STRING_LIST_INIT_DUP, \
.stale = STRING_LIST_INIT_DUP, \
.tracked = STRING_LIST_INIT_DUP, \
.heads = STRING_LIST_INIT_DUP, \
@@ -367,7 +374,9 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
states->remote->fetch.raw[i]);
for (ref = fetch_map; ref; ref = ref->next) {
- if (!ref->peer_ref || !ref_exists(ref->peer_ref->name))
+ if (omit_name_by_refspec(ref->name, &states->remote->fetch))
+ string_list_append(&states->skipped, abbrev_branch(ref->name));
+ else if (!ref->peer_ref || !ref_exists(ref->peer_ref->name))
string_list_append(&states->new_refs, abbrev_branch(ref->name));
else
string_list_append(&states->tracked, abbrev_branch(ref->name));
@@ -382,6 +391,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
free_refs(fetch_map);
string_list_sort(&states->new_refs);
+ string_list_sort(&states->skipped);
string_list_sort(&states->tracked);
string_list_sort(&states->stale);
@@ -435,7 +445,7 @@ static int get_push_ref_states(const struct ref *remote_refs,
info->status = PUSH_STATUS_UPTODATE;
else if (is_null_oid(&ref->old_oid))
info->status = PUSH_STATUS_CREATE;
- else if (has_object_file(&ref->old_oid) &&
+ else if (repo_has_object_file(the_repository, &ref->old_oid) &&
ref_newer(&ref->new_oid, &ref->old_oid))
info->status = PUSH_STATUS_FASTFORWARD;
else
@@ -533,7 +543,8 @@ struct branches_for_remote {
};
static int add_branch_for_removal(const char *refname,
- const struct object_id *oid, int flags, void *cb_data)
+ const struct object_id *oid UNUSED,
+ int flags UNUSED, void *cb_data)
{
struct branches_for_remote *branches = cb_data;
struct refspec_item refspec;
@@ -571,10 +582,12 @@ struct rename_info {
const char *old_name;
const char *new_name;
struct string_list *remote_branches;
+ uint32_t symrefs_nr;
};
static int read_remote_branches(const char *refname,
- const struct object_id *oid, int flags, void *cb_data)
+ const struct object_id *oid UNUSED,
+ int flags UNUSED, void *cb_data)
{
struct rename_info *rename = cb_data;
struct strbuf buf = STRBUF_INIT;
@@ -587,10 +600,12 @@ static int read_remote_branches(const char *refname,
item = string_list_append(rename->remote_branches, refname);
symref = resolve_ref_unsafe(refname, RESOLVE_REF_READING,
NULL, &flag);
- if (symref && (flag & REF_ISSYMREF))
+ if (symref && (flag & REF_ISSYMREF)) {
item->util = xstrdup(symref);
- else
+ rename->symrefs_nr++;
+ } else {
item->util = NULL;
+ }
}
strbuf_release(&buf);
@@ -631,17 +646,19 @@ struct push_default_info
};
static int config_read_push_default(const char *key, const char *value,
- void *cb)
+ const struct config_context *ctx, void *cb)
{
+ const struct key_value_info *kvi = ctx->kvi;
+
struct push_default_info* info = cb;
if (strcmp(key, "remote.pushdefault") ||
!value || strcmp(value, info->old_name))
return 0;
- info->scope = current_config_scope();
+ info->scope = kvi->scope;
strbuf_reset(&info->origin);
- strbuf_addstr(&info->origin, current_config_name());
- info->linenr = current_config_line();
+ strbuf_addstr(&info->origin, config_origin_type_name(kvi->origin_type));
+ info->linenr = kvi->linenr;
return 0;
}
@@ -672,9 +689,11 @@ static void handle_push_default(const char* old_name, const char* new_name)
}
-static int mv(int argc, const char **argv)
+static int mv(int argc, const char **argv, const char *prefix)
{
+ int show_progress = isatty(2);
struct option options[] = {
+ OPT_BOOL(0, "progress", &show_progress, N_("force progress reporting")),
OPT_END()
};
struct remote *oldremote, *newremote;
@@ -682,14 +701,19 @@ static int mv(int argc, const char **argv)
old_remote_context = STRBUF_INIT;
struct string_list remote_branches = STRING_LIST_INIT_DUP;
struct rename_info rename;
- int i, refspec_updated = 0;
+ int i, refs_renamed_nr = 0, refspec_updated = 0;
+ struct progress *progress = NULL;
- if (argc != 3)
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_rename_usage, 0);
+
+ if (argc != 2)
usage_with_options(builtin_remote_rename_usage, options);
- rename.old_name = argv[1];
- rename.new_name = argv[2];
+ rename.old_name = argv[0];
+ rename.new_name = argv[1];
rename.remote_branches = &remote_branches;
+ rename.symrefs_nr = 0;
oldremote = remote_get(rename.old_name);
if (!remote_is_configured(oldremote, 1)) {
@@ -715,29 +739,31 @@ static int mv(int argc, const char **argv)
return error(_("Could not rename config section '%s' to '%s'"),
buf.buf, buf2.buf);
- strbuf_reset(&buf);
- strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
- git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
- strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name);
- for (i = 0; i < oldremote->fetch.raw_nr; i++) {
- char *ptr;
-
- strbuf_reset(&buf2);
- strbuf_addstr(&buf2, oldremote->fetch.raw[i]);
- ptr = strstr(buf2.buf, old_remote_context.buf);
- if (ptr) {
- refspec_updated = 1;
- strbuf_splice(&buf2,
- ptr-buf2.buf + strlen(":refs/remotes/"),
- strlen(rename.old_name), rename.new_name,
- strlen(rename.new_name));
- } else
- warning(_("Not updating non-default fetch refspec\n"
- "\t%s\n"
- "\tPlease update the configuration manually if necessary."),
- buf2.buf);
-
- git_config_set_multivar(buf.buf, buf2.buf, "^$", 0);
+ if (oldremote->fetch.raw_nr) {
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
+ git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
+ strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name);
+ for (i = 0; i < oldremote->fetch.raw_nr; i++) {
+ char *ptr;
+
+ strbuf_reset(&buf2);
+ strbuf_addstr(&buf2, oldremote->fetch.raw[i]);
+ ptr = strstr(buf2.buf, old_remote_context.buf);
+ if (ptr) {
+ refspec_updated = 1;
+ strbuf_splice(&buf2,
+ ptr-buf2.buf + strlen(":refs/remotes/"),
+ strlen(rename.old_name), rename.new_name,
+ strlen(rename.new_name));
+ } else
+ warning(_("Not updating non-default fetch refspec\n"
+ "\t%s\n"
+ "\tPlease update the configuration manually if necessary."),
+ buf2.buf);
+
+ git_config_set_multivar(buf.buf, buf2.buf, "^$", 0);
+ }
}
read_branches();
@@ -764,15 +790,26 @@ static int mv(int argc, const char **argv)
* the new symrefs.
*/
for_each_ref(read_remote_branches, &rename);
+ if (show_progress) {
+ /*
+ * Count symrefs twice, since "renaming" them is done by
+ * deleting and recreating them in two separate passes.
+ */
+ progress = start_progress(_("Renaming remote references"),
+ rename.remote_branches->nr + rename.symrefs_nr);
+ }
for (i = 0; i < remote_branches.nr; i++) {
struct string_list_item *item = remote_branches.items + i;
- int flag = 0;
+ struct strbuf referent = STRBUF_INIT;
- read_ref_full(item->string, RESOLVE_REF_READING, NULL, &flag);
- if (!(flag & REF_ISSYMREF))
+ if (refs_read_symbolic_ref(get_main_ref_store(the_repository), item->string,
+ &referent))
continue;
if (delete_ref(NULL, item->string, NULL, REF_NO_DEREF))
die(_("deleting '%s' failed"), item->string);
+
+ strbuf_release(&referent);
+ display_progress(progress, ++refs_renamed_nr);
}
for (i = 0; i < remote_branches.nr; i++) {
struct string_list_item *item = remote_branches.items + i;
@@ -788,6 +825,7 @@ static int mv(int argc, const char **argv)
item->string, buf.buf);
if (rename_ref(item->string, buf.buf, buf2.buf))
die(_("renaming '%s' failed"), item->string);
+ display_progress(progress, ++refs_renamed_nr);
}
for (i = 0; i < remote_branches.nr; i++) {
struct string_list_item *item = remote_branches.items + i;
@@ -807,7 +845,9 @@ static int mv(int argc, const char **argv)
item->string, buf.buf);
if (create_symref(buf.buf, buf2.buf, buf3.buf))
die(_("creating '%s' failed"), buf.buf);
+ display_progress(progress, ++refs_renamed_nr);
}
+ stop_progress(&progress);
string_list_clear(&remote_branches, 1);
handle_push_default(rename.old_name, rename.new_name);
@@ -815,7 +855,7 @@ static int mv(int argc, const char **argv)
return 0;
}
-static int rm(int argc, const char **argv)
+static int rm(int argc, const char **argv, const char *prefix)
{
struct option options[] = {
OPT_END()
@@ -833,12 +873,14 @@ static int rm(int argc, const char **argv)
cb_data.skipped = &skipped;
cb_data.keep = &known_remotes;
- if (argc != 2)
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_rm_usage, 0);
+ if (argc != 1)
usage_with_options(builtin_remote_rm_usage, options);
- remote = remote_get(argv[1]);
+ remote = remote_get(argv[0]);
if (!remote_is_configured(remote, 1)) {
- error(_("No such remote: '%s'"), argv[1]);
+ error(_("No such remote: '%s'"), argv[0]);
exit(2);
}
@@ -906,7 +948,7 @@ static int rm(int argc, const char **argv)
return result;
}
-static void clear_push_info(void *util, const char *string)
+static void clear_push_info(void *util, const char *string UNUSED)
{
struct push_info *info = util;
free(info->dest);
@@ -916,6 +958,7 @@ static void clear_push_info(void *util, const char *string)
static void free_remote_ref_states(struct ref_states *states)
{
string_list_clear(&states->new_refs, 0);
+ string_list_clear(&states->skipped, 0);
string_list_clear(&states->stale, 1);
string_list_clear(&states->tracked, 0);
string_list_clear(&states->heads, 0);
@@ -923,7 +966,8 @@ static void free_remote_ref_states(struct ref_states *states)
}
static int append_ref_to_tracked_list(const char *refname,
- const struct object_id *oid, int flags, void *cb_data)
+ const struct object_id *oid UNUSED,
+ int flags, void *cb_data)
{
struct ref_states *states = cb_data;
struct refspec_item refspec;
@@ -1010,6 +1054,8 @@ static int show_remote_info_item(struct string_list_item *item, void *cb_data)
arg = states->remote->name;
} else if (string_list_has_string(&states->tracked, name))
arg = _(" tracked");
+ else if (string_list_has_string(&states->skipped, name))
+ arg = _(" skipped");
else if (string_list_has_string(&states->stale, name))
arg = _(" stale (use 'git remote prune' to remove)");
else
@@ -1160,14 +1206,22 @@ static int show_push_info_item(struct string_list_item *item, void *cb_data)
static int get_one_entry(struct remote *remote, void *priv)
{
struct string_list *list = priv;
- struct strbuf url_buf = STRBUF_INIT;
+ struct strbuf remote_info_buf = STRBUF_INIT;
const char **url;
int i, url_nr;
if (remote->url_nr > 0) {
- strbuf_addf(&url_buf, "%s (fetch)", remote->url[0]);
+ struct strbuf promisor_config = STRBUF_INIT;
+ const char *partial_clone_filter = NULL;
+
+ strbuf_addf(&promisor_config, "remote.%s.partialclonefilter", remote->name);
+ strbuf_addf(&remote_info_buf, "%s (fetch)", remote->url[0]);
+ if (!git_config_get_string_tmp(promisor_config.buf, &partial_clone_filter))
+ strbuf_addf(&remote_info_buf, " [%s]", partial_clone_filter);
+
+ strbuf_release(&promisor_config);
string_list_append(list, remote->name)->util =
- strbuf_detach(&url_buf, NULL);
+ strbuf_detach(&remote_info_buf, NULL);
} else
string_list_append(list, remote->name)->util = NULL;
if (remote->pushurl_nr) {
@@ -1179,9 +1233,9 @@ static int get_one_entry(struct remote *remote, void *priv)
}
for (i = 0; i < url_nr; i++)
{
- strbuf_addf(&url_buf, "%s (push)", url[i]);
+ strbuf_addf(&remote_info_buf, "%s (push)", url[i]);
string_list_append(list, remote->name)->util =
- strbuf_detach(&url_buf, NULL);
+ strbuf_detach(&remote_info_buf, NULL);
}
return 0;
@@ -1189,10 +1243,9 @@ static int get_one_entry(struct remote *remote, void *priv)
static int show_all(void)
{
- struct string_list list = STRING_LIST_INIT_NODUP;
+ struct string_list list = STRING_LIST_INIT_DUP;
int result;
- list.strdup_strings = 1;
result = for_each_remote(get_one_entry, &list);
if (!result) {
@@ -1215,7 +1268,7 @@ static int show_all(void)
return result;
}
-static int show(int argc, const char **argv)
+static int show(int argc, const char **argv, const char *prefix)
{
int no_query = 0, result = 0, query_flag = 0;
struct option options[] = {
@@ -1224,7 +1277,8 @@ static int show(int argc, const char **argv)
};
struct show_info info = SHOW_INFO_INIT;
- argc = parse_options(argc, argv, NULL, options, builtin_remote_show_usage,
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_show_usage,
0);
if (argc < 1)
@@ -1275,6 +1329,7 @@ static int show(int argc, const char **argv)
/* remote branch info */
info.width = 0;
for_each_string_list(&info.states.new_refs, add_remote_to_show_info, &info);
+ for_each_string_list(&info.states.skipped, add_remote_to_show_info, &info);
for_each_string_list(&info.states.tracked, add_remote_to_show_info, &info);
for_each_string_list(&info.states.stale, add_remote_to_show_info, &info);
if (info.list.nr)
@@ -1317,7 +1372,7 @@ static int show(int argc, const char **argv)
return result;
}
-static int set_head(int argc, const char **argv)
+static int set_head(int argc, const char **argv, const char *prefix)
{
int i, opt_a = 0, opt_d = 0, result = 0;
struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;
@@ -1330,8 +1385,8 @@ static int set_head(int argc, const char **argv)
N_("delete refs/remotes/<name>/HEAD")),
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_sethead_usage,
- 0);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_sethead_usage, 0);
if (argc)
strbuf_addf(&buf, "refs/remotes/%s/HEAD", argv[0]);
@@ -1422,7 +1477,7 @@ static int prune_remote(const char *remote, int dry_run)
return result;
}
-static int prune(int argc, const char **argv)
+static int prune(int argc, const char **argv, const char *prefix)
{
int dry_run = 0, result = 0;
struct option options[] = {
@@ -1430,8 +1485,8 @@ static int prune(int argc, const char **argv)
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_prune_usage,
- 0);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_prune_usage, 0);
if (argc < 1)
usage_with_options(builtin_remote_prune_usage, options);
@@ -1442,7 +1497,9 @@ static int prune(int argc, const char **argv)
return result;
}
-static int get_remote_default(const char *key, const char *value, void *priv)
+static int get_remote_default(const char *key, const char *value UNUSED,
+ const struct config_context *ctx UNUSED,
+ void *priv)
{
if (strcmp(key, "remotes.default") == 0) {
int *found = priv;
@@ -1451,7 +1508,7 @@ static int get_remote_default(const char *key, const char *value, void *priv)
return 0;
}
-static int update(int argc, const char **argv)
+static int update(int argc, const char **argv, const char *prefix)
{
int i, prune = -1;
struct option options[] = {
@@ -1459,36 +1516,35 @@ static int update(int argc, const char **argv)
N_("prune remotes after fetching")),
OPT_END()
};
- struct strvec fetch_argv = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
int default_defined = 0;
- int retval;
- argc = parse_options(argc, argv, NULL, options, builtin_remote_update_usage,
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_update_usage,
PARSE_OPT_KEEP_ARGV0);
- strvec_push(&fetch_argv, "fetch");
+ strvec_push(&cmd.args, "fetch");
if (prune != -1)
- strvec_push(&fetch_argv, prune ? "--prune" : "--no-prune");
+ strvec_push(&cmd.args, prune ? "--prune" : "--no-prune");
if (verbose)
- strvec_push(&fetch_argv, "-v");
- strvec_push(&fetch_argv, "--multiple");
+ strvec_push(&cmd.args, "-v");
+ strvec_push(&cmd.args, "--multiple");
if (argc < 2)
- strvec_push(&fetch_argv, "default");
+ strvec_push(&cmd.args, "default");
for (i = 1; i < argc; i++)
- strvec_push(&fetch_argv, argv[i]);
+ strvec_push(&cmd.args, argv[i]);
- if (strcmp(fetch_argv.v[fetch_argv.nr-1], "default") == 0) {
+ if (strcmp(cmd.args.v[cmd.args.nr-1], "default") == 0) {
git_config(get_remote_default, &default_defined);
if (!default_defined) {
- strvec_pop(&fetch_argv);
- strvec_push(&fetch_argv, "--all");
+ strvec_pop(&cmd.args);
+ strvec_push(&cmd.args, "--all");
}
}
- retval = run_command_v_opt(fetch_argv.v, RUN_GIT_CMD);
- strvec_clear(&fetch_argv);
- return retval;
+ cmd.git_cmd = 1;
+ return run_command(&cmd);
}
static int remove_all_fetch_refspecs(const char *key)
@@ -1534,7 +1590,7 @@ static int set_remote_branches(const char *remotename, const char **branches,
return 0;
}
-static int set_branches(int argc, const char **argv)
+static int set_branches(int argc, const char **argv, const char *prefix)
{
int add_mode = 0;
struct option options[] = {
@@ -1542,7 +1598,7 @@ static int set_branches(int argc, const char **argv)
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options,
+ argc = parse_options(argc, argv, prefix, options,
builtin_remote_setbranches_usage, 0);
if (argc == 0) {
error(_("no remote specified"));
@@ -1553,7 +1609,7 @@ static int set_branches(int argc, const char **argv)
return set_remote_branches(argv[0], argv + 1, add_mode);
}
-static int get_url(int argc, const char **argv)
+static int get_url(int argc, const char **argv, const char *prefix)
{
int i, push_mode = 0, all_mode = 0;
const char *remotename = NULL;
@@ -1567,7 +1623,8 @@ static int get_url(int argc, const char **argv)
N_("return all URLs")),
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_geturl_usage, 0);
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_geturl_usage, 0);
if (argc != 1)
usage_with_options(builtin_remote_geturl_usage, options);
@@ -1606,7 +1663,7 @@ static int get_url(int argc, const char **argv)
return 0;
}
-static int set_url(int argc, const char **argv)
+static int set_url(int argc, const char **argv, const char *prefix)
{
int i, push_mode = 0, add_mode = 0, delete_mode = 0;
int matches = 0, negative_matches = 0;
@@ -1627,7 +1684,8 @@ static int set_url(int argc, const char **argv)
N_("delete URLs")),
OPT_END()
};
- argc = parse_options(argc, argv, NULL, options, builtin_remote_seturl_usage,
+ argc = parse_options(argc, argv, prefix, options,
+ builtin_remote_seturl_usage,
PARSE_OPT_KEEP_ARGV0);
if (add_mode && delete_mode)
@@ -1698,41 +1756,33 @@ out:
int cmd_remote(int argc, const char **argv, const char *prefix)
{
+ parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
OPT__VERBOSE(&verbose, N_("be verbose; must be placed before a subcommand")),
+ OPT_SUBCOMMAND("add", &fn, add),
+ OPT_SUBCOMMAND("rename", &fn, mv),
+ OPT_SUBCOMMAND_F("rm", &fn, rm, PARSE_OPT_NOCOMPLETE),
+ OPT_SUBCOMMAND("remove", &fn, rm),
+ OPT_SUBCOMMAND("set-head", &fn, set_head),
+ OPT_SUBCOMMAND("set-branches", &fn, set_branches),
+ OPT_SUBCOMMAND("get-url", &fn, get_url),
+ OPT_SUBCOMMAND("set-url", &fn, set_url),
+ OPT_SUBCOMMAND("show", &fn, show),
+ OPT_SUBCOMMAND("prune", &fn, prune),
+ OPT_SUBCOMMAND("update", &fn, update),
OPT_END()
};
- int result;
argc = parse_options(argc, argv, prefix, options, builtin_remote_usage,
- PARSE_OPT_STOP_AT_NON_OPTION);
+ PARSE_OPT_SUBCOMMAND_OPTIONAL);
- if (argc < 1)
- result = show_all();
- else if (!strcmp(argv[0], "add"))
- result = add(argc, argv);
- else if (!strcmp(argv[0], "rename"))
- result = mv(argc, argv);
- else if (!strcmp(argv[0], "rm") || !strcmp(argv[0], "remove"))
- result = rm(argc, argv);
- else if (!strcmp(argv[0], "set-head"))
- result = set_head(argc, argv);
- else if (!strcmp(argv[0], "set-branches"))
- result = set_branches(argc, argv);
- else if (!strcmp(argv[0], "get-url"))
- result = get_url(argc, argv);
- else if (!strcmp(argv[0], "set-url"))
- result = set_url(argc, argv);
- else if (!strcmp(argv[0], "show"))
- result = show(argc, argv);
- else if (!strcmp(argv[0], "prune"))
- result = prune(argc, argv);
- else if (!strcmp(argv[0], "update"))
- result = update(argc, argv);
- else {
- error(_("Unknown subcommand: %s"), argv[0]);
- usage_with_options(builtin_remote_usage, options);
+ if (fn) {
+ return !!fn(argc, argv, prefix);
+ } else {
+ if (argc) {
+ error(_("unknown subcommand: `%s'"), argv[0]);
+ usage_with_options(builtin_remote_usage, options);
+ }
+ return !!show_all();
}
-
- return result ? 1 : 0;
}