static const char * const builtin_fetch_usage[] = {
"git fetch [options] [<repository> <refspec>...]",
"git fetch [options] <group>",
+ "git fetch --multiple [options] [<repository> | <group>]...",
"git fetch --all [options]",
NULL
};
TAGS_SET = 2
};
-static int all, append, force, keep, update_head_ok, verbosity;
+static int all, append, force, keep, multiple, prune, update_head_ok, verbosity;
static int tags = TAGS_DEFAULT;
static const char *depth;
static const char *upload_pack;
"path to upload pack on remote end"),
OPT_BOOLEAN('f', "force", &force,
"force overwrite of local branch"),
+ OPT_BOOLEAN('m', "multiple", &multiple,
+ "fetch from multiple remotes"),
OPT_SET_INT('t', "tags", &tags,
"fetch all tags and associated objects", TAGS_SET),
OPT_SET_INT('n', NULL, &tags,
"do not fetch all tags (--no-tags)", TAGS_UNSET),
+ OPT_BOOLEAN('p', "prune", &prune,
+ "prune tracking branches no longer on remote"),
OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"),
OPT_BOOLEAN('u', "update-head-ok", &update_head_ok,
"allow updating of HEAD ref"),
return ret;
}
+static int prune_refs(struct transport *transport, struct ref *ref_map)
+{
+ int result = 0;
+ struct ref *ref, *stale_refs = get_stale_heads(transport->remote, ref_map);
+ const char *dangling_msg = dry_run
+ ? " (%s will become dangling)\n"
+ : " (%s has become dangling)\n";
+
+ for (ref = stale_refs; ref; ref = ref->next) {
+ if (!dry_run)
+ result |= delete_ref(ref->name, NULL, 0);
+ if (verbosity >= 0) {
+ fprintf(stderr, " x %-*s %-*s -> %s\n",
+ SUMMARY_WIDTH, "[deleted]",
+ REFCOL_WIDTH, "(none)", prettify_refname(ref->name));
+ warn_dangling_symref(stderr, dangling_msg, ref->name);
+ }
+ }
+ free_refs(stale_refs);
+ return result;
+}
+
static int add_existing(const char *refname, const unsigned char *sha1,
int flag, void *cbdata)
{
free_refs(ref_map);
return 1;
}
+ if (prune)
+ prune_refs(transport, ref_map);
free_refs(ref_map);
/* if neither --no-tags nor --tags was specified, do automated tag
static int get_one_remote_for_fetch(struct remote *remote, void *priv)
{
struct string_list *list = priv;
- string_list_append(remote->name, list);
+ if (!remote->skip_default_update)
+ string_list_append(remote->name, list);
return 0;
}
static int fetch_multiple(struct string_list *list)
{
int i, result = 0;
- const char *argv[] = { "fetch", NULL, NULL, NULL, NULL };
+ const char *argv[] = { "fetch", NULL, NULL, NULL, NULL, NULL };
int argc = 1;
+ if (prune)
+ argv[argc++] = "--prune";
if (verbosity >= 2)
argv[argc++] = "-v";
if (verbosity >= 1)
/* No arguments -- use default remote */
remote = remote_get(NULL);
result = fetch_one(remote, argc, argv);
+ } else if (multiple) {
+ /* All arguments are assumed to be remotes or groups */
+ for (i = 0; i < argc; i++)
+ if (!add_remote_or_group(argv[i], &list))
+ die("No such remote or remote group: %s", argv[i]);
+ result = fetch_multiple(&list);
} else {
/* Single remote or group */
(void) add_remote_or_group(argv[0], &list);