log: teach "terminator" vs "separator" mode to "--pretty=format"
[gitweb.git] / builtin-remote.c
index d0c07c7a0b7e31aeb61b4c8d94b1dac3c381598b..d77f10a0eaa64466b919bcede37ad8c67b70b3fc 100644 (file)
@@ -46,6 +46,7 @@ static int opt_parse_track(const struct option *opt, const char *arg, int not)
 static int fetch_remote(const char *name)
 {
        const char *argv[] = { "fetch", name, NULL };
+       printf("Updating %s\n", name);
        if (run_command_v_opt(argv, RUN_GIT_CMD))
                return error("Could not fetch %s", name);
        return 0;
@@ -206,7 +207,10 @@ static int handle_one_branch(const char *refname,
        if (!remote_find_tracking(states->remote, &refspec)) {
                struct path_list_item *item;
                const char *name = skip_prefix(refspec.src, "refs/heads/");
-               if (unsorted_path_list_has_path(&states->tracked, name) ||
+               /* symbolic refs pointing nowhere were handled already */
+               if ((flags & REF_ISSYMREF) ||
+                               unsorted_path_list_has_path(&states->tracked,
+                                       name) ||
                                unsorted_path_list_has_path(&states->new,
                                        name))
                        return 0;
@@ -264,6 +268,11 @@ static int add_branch_for_removal(const char *refname,
 
        if (!prefixcmp(refname, branches->prefix)) {
                struct path_list_item *item;
+
+               /* make sure that symrefs are deleted */
+               if (flags & REF_ISSYMREF)
+                       return unlink(git_path(refname));
+
                item = path_list_append(refname, branches->branches);
                item->util = xmalloc(20);
                hashcpy(item->util, sha1);
@@ -387,6 +396,7 @@ static int show_or_prune(int argc, const char **argv, int prune)
                transport = transport_get(NULL, states.remote->url_nr > 0 ?
                        states.remote->url[0] : NULL);
                ref = transport_get_remote_refs(transport);
+               transport_disconnect(transport);
 
                read_branches();
                got_states = get_ref_states(ref, &states);
@@ -462,6 +472,7 @@ static int show_or_prune(int argc, const char **argv, int prune)
                                        spec->dst ? ":" : "",
                                        skip_prefix(spec->dst, "refs/heads/"));
                        }
+                       printf("\n");
                }
 cleanup_states:
                /* NEEDSWORK: free remote */
@@ -473,24 +484,65 @@ static int show_or_prune(int argc, const char **argv, int prune)
        return result;
 }
 
-static int update_one(struct remote *remote, void *priv)
+static int get_one_remote_for_update(struct remote *remote, void *priv)
 {
+       struct path_list *list = priv;
        if (!remote->skip_default_update)
-               return fetch_remote(remote->name);
+               path_list_append(xstrdup(remote->name), list);
+       return 0;
+}
+
+struct remote_group {
+       const char *name;
+       struct path_list *list;
+} remote_group;
+
+static int get_remote_group(const char *key, const char *value)
+{
+       if (!prefixcmp(key, "remotes.") &&
+                       !strcmp(key + 8, remote_group.name)) {
+               /* split list by white space */
+               int space = strcspn(value, " \t\n");
+               while (*value) {
+                       if (space > 1)
+                               path_list_append(xstrndup(value, space),
+                                               remote_group.list);
+                       value += space + (value[space] != '\0');
+                       space = strcspn(value, " \t\n");
+               }
+       }
+
        return 0;
 }
 
 static int update(int argc, const char **argv)
 {
-       int i;
+       int i, result = 0;
+       struct path_list list = { NULL, 0, 0, 0 };
+       static const char *default_argv[] = { NULL, "default", NULL };
 
-       if (argc < 2)
-               return for_each_remote(update_one, NULL);
+       if (argc < 2) {
+               argc = 2;
+               argv = default_argv;
+       }
 
-       for (i = 1; i < argc; i++)
-               if (fetch_remote(argv[i]))
-                       return 1;
-       return 0;
+       remote_group.list = &list;
+       for (i = 1; i < argc; i++) {
+               remote_group.name = argv[i];
+               result = git_config(get_remote_group);
+       }
+
+       if (!result && !list.nr  && argc == 2 && !strcmp(argv[1], "default"))
+               result = for_each_remote(get_one_remote_for_update, &list);
+
+       for (i = 0; i < list.nr; i++)
+               result |= fetch_remote(list.items[i].path);
+
+       /* all names were strdup()ed or strndup()ed */
+       list.strdup_paths = 1;
+       path_list_clear(&list, 0);
+
+       return result;
 }
 
 static int get_one_entry(struct remote *remote, void *priv)