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;
strbuf_init(&buf, 0);
strbuf_init(&buf2, 0);
+ strbuf_addf(&buf2, "refs/heads/test:refs/remotes/%s/test", name);
+ if (!valid_fetch_refspec(buf2.buf))
+ die("'%s' is not a valid remote name", name);
+
strbuf_addf(&buf, "remote.%s.url", name);
if (git_config_set(buf.buf, url))
return 1;
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "remote.%s.fetch", name);
+
if (track.nr == 0)
path_list_append("*", &track);
for (i = 0; i < track.nr; i++) {
struct path_list_item *item = track.items + i;
- strbuf_reset(&buf);
- strbuf_addf(&buf, "remote.%s.fetch", name);
-
strbuf_reset(&buf2);
if (mirror)
strbuf_addf(&buf2, "refs/%s:refs/%s",
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;
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);
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);
if (prune) {
struct strbuf buf;
+ int prefix_len;
strbuf_init(&buf, 0);
+ if (states.remote->fetch_refspec_nr == 1 &&
+ states.remote->fetch->pattern &&
+ !strcmp(states.remote->fetch->src,
+ states.remote->fetch->dst))
+ /* handle --mirror remote */
+ strbuf_addstr(&buf, "refs/heads/");
+ else
+ strbuf_addf(&buf, "refs/remotes/%s/", *argv);
+ prefix_len = buf.len;
+
for (i = 0; i < states.stale.nr; i++) {
- strbuf_reset(&buf);
- strbuf_addf(&buf, "refs/remotes/%s/%s", *argv,
- states.stale.items[i].path);
+ strbuf_setlen(&buf, prefix_len);
+ strbuf_addstr(&buf, states.stale.items[i].path);
result |= delete_ref(buf.buf, NULL);
}
spec->dst ? ":" : "",
skip_prefix(spec->dst, "refs/heads/"));
}
+ printf("\n");
}
cleanup_states:
/* NEEDSWORK: free remote */
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)