Merge branch 'jk/submodule-fsck-loose-fixup'
[gitweb.git] / builtin / remote.c
index 8708e584e9e8793f3a5e44861d9fb9f049027fa3..1a82d850a22c3bfc3176eeda3f8b061b6feb7dc4 100644 (file)
@@ -7,6 +7,7 @@
 #include "strbuf.h"
 #include "run-command.h"
 #include "refs.h"
+#include "refspec.h"
 #include "argv-array.h"
 
 static const char * const builtin_remote_usage[] = {
@@ -245,7 +246,9 @@ static int add(int argc, const char **argv)
 struct branch_info {
        char *remote_name;
        struct string_list merge;
-       enum { NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE } rebase;
+       enum {
+               NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE, REBASE_MERGES
+       } rebase;
 };
 
 static struct string_list branch_list = STRING_LIST_INIT_NODUP;
@@ -306,6 +309,8 @@ static int config_read_branches(const char *key, const char *value, void *cb)
                                info->rebase = v;
                        else if (!strcmp(value, "preserve"))
                                info->rebase = NORMAL_REBASE;
+                       else if (!strcmp(value, "merges"))
+                               info->rebase = REBASE_MERGES;
                        else if (!strcmp(value, "interactive"))
                                info->rebase = INTERACTIVE_REBASE;
                }
@@ -332,10 +337,10 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
        struct ref *ref, *stale_refs;
        int i;
 
-       for (i = 0; i < states->remote->fetch_refspec_nr; i++)
-               if (get_fetch_map(remote_refs, states->remote->fetch + i, &tail, 1))
+       for (i = 0; i < states->remote->fetch.nr; i++)
+               if (get_fetch_map(remote_refs, &states->remote->fetch.items[i], &tail, 1))
                        die(_("Could not get fetch map for refspec %s"),
-                               states->remote->fetch_refspec[i]);
+                               states->remote->fetch.raw[i]);
 
        states->new_refs.strdup_strings = 1;
        states->tracked.strdup_strings = 1;
@@ -346,8 +351,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
                else
                        string_list_append(&states->tracked, abbrev_branch(ref->name));
        }
-       stale_refs = get_stale_heads(states->remote->fetch,
-                                    states->remote->fetch_refspec_nr, fetch_map);
+       stale_refs = get_stale_heads(&states->remote->fetch, fetch_map);
        for (ref = stale_refs; ref; ref = ref->next) {
                struct string_list_item *item =
                        string_list_append(&states->stale, abbrev_branch(ref->name));
@@ -387,8 +391,7 @@ static int get_push_ref_states(const struct ref *remote_refs,
        local_refs = get_local_heads();
        push_map = copy_ref_list(remote_refs);
 
-       match_push_refs(local_refs, &push_map, remote->push_refspec_nr,
-                       remote->push_refspec, MATCH_REFS_NONE);
+       match_push_refs(local_refs, &push_map, &remote->push, MATCH_REFS_NONE);
 
        states->push.strdup_strings = 1;
        for (ref = push_map; ref; ref = ref->next) {
@@ -434,14 +437,14 @@ static int get_push_ref_states_noquery(struct ref_states *states)
                return 0;
 
        states->push.strdup_strings = 1;
-       if (!remote->push_refspec_nr) {
+       if (!remote->push.nr) {
                item = string_list_append(&states->push, _("(matching)"));
                info = item->util = xcalloc(1, sizeof(struct push_info));
                info->status = PUSH_STATUS_NOTQUERIED;
                info->dest = xstrdup(item->string);
        }
-       for (i = 0; i < remote->push_refspec_nr; i++) {
-               struct refspec *spec = remote->push + i;
+       for (i = 0; i < remote->push.nr; i++) {
+               const struct refspec_item *spec = &remote->push.items[i];
                if (spec->matching)
                        item = string_list_append(&states->push, _("(matching)"));
                else if (strlen(spec->src))
@@ -461,7 +464,7 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat
 {
        struct ref *ref, *matches;
        struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map;
-       struct refspec refspec;
+       struct refspec_item refspec;
 
        refspec.force = 0;
        refspec.pattern = 1;
@@ -514,7 +517,7 @@ static int add_branch_for_removal(const char *refname,
        const struct object_id *oid, int flags, void *cb_data)
 {
        struct branches_for_remote *branches = cb_data;
-       struct refspec refspec;
+       struct refspec_item refspec;
        struct known_remote *kr;
 
        memset(&refspec, 0, sizeof(refspec));
@@ -585,12 +588,12 @@ static int migrate_file(struct remote *remote)
                git_config_set_multivar(buf.buf, remote->url[i], "^$", 0);
        strbuf_reset(&buf);
        strbuf_addf(&buf, "remote.%s.push", remote->name);
-       for (i = 0; i < remote->push_refspec_nr; i++)
-               git_config_set_multivar(buf.buf, remote->push_refspec[i], "^$", 0);
+       for (i = 0; i < remote->push.raw_nr; i++)
+               git_config_set_multivar(buf.buf, remote->push.raw[i], "^$", 0);
        strbuf_reset(&buf);
        strbuf_addf(&buf, "remote.%s.fetch", remote->name);
-       for (i = 0; i < remote->fetch_refspec_nr; i++)
-               git_config_set_multivar(buf.buf, remote->fetch_refspec[i], "^$", 0);
+       for (i = 0; i < remote->fetch.raw_nr; i++)
+               git_config_set_multivar(buf.buf, remote->fetch.raw[i], "^$", 0);
        if (remote->origin == REMOTE_REMOTES)
                unlink_or_warn(git_path("remotes/%s", remote->name));
        else if (remote->origin == REMOTE_BRANCHES)
@@ -645,11 +648,11 @@ static int mv(int argc, const char **argv)
        strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
        git_config_set_multivar(buf.buf, NULL, NULL, 1);
        strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name);
-       for (i = 0; i < oldremote->fetch_refspec_nr; i++) {
+       for (i = 0; i < oldremote->fetch.raw_nr; i++) {
                char *ptr;
 
                strbuf_reset(&buf2);
-               strbuf_addstr(&buf2, oldremote->fetch_refspec[i]);
+               strbuf_addstr(&buf2, oldremote->fetch.raw[i]);
                ptr = strstr(buf2.buf, old_remote_context.buf);
                if (ptr) {
                        refspec_updated = 1;
@@ -833,7 +836,7 @@ static int append_ref_to_tracked_list(const char *refname,
        const struct object_id *oid, int flags, void *cb_data)
 {
        struct ref_states *states = cb_data;
-       struct refspec refspec;
+       struct refspec_item refspec;
 
        if (flags & REF_ISSYMREF)
                return 0;
@@ -963,9 +966,15 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data)
 
        printf("    %-*s ", show_info->width, item->string);
        if (branch_info->rebase) {
-               printf_ln(branch_info->rebase == INTERACTIVE_REBASE
-                         ? _("rebases interactively onto remote %s")
-                         : _("rebases onto remote %s"), merge->items[0].string);
+               const char *msg;
+               if (branch_info->rebase == INTERACTIVE_REBASE)
+                       msg = _("rebases interactively onto remote %s");
+               else if (branch_info->rebase == REBASE_MERGES)
+                       msg = _("rebases interactively (with merges) onto "
+                               "remote %s");
+               else
+                       msg = _("rebases onto remote %s");
+               printf_ln(msg, merge->items[0].string);
                return 0;
        } else if (show_info->any_rebase) {
                printf_ln(_(" merges with remote %s"), merge->items[0].string);