diff options
Diffstat (limited to 'builtin/fetch.c')
| -rw-r--r-- | builtin/fetch.c | 362 | 
1 files changed, 249 insertions, 113 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c index f9512652cf..acd0cf1755 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -11,9 +11,11 @@  #include "run-command.h"  #include "parse-options.h"  #include "sigchain.h" +#include "submodule-config.h"  #include "submodule.h"  #include "connected.h"  #include "argv-array.h" +#include "utf8.h"  static const char * const builtin_fetch_usage[] = {  	N_("git fetch [<options>] [<repository> [<refspec>...]]"), @@ -36,6 +38,8 @@ static int prune = -1; /* unspecified */  static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;  static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;  static int tags = TAGS_DEFAULT, unshallow, update_shallow; +static int max_children = -1; +static enum transport_family family;  static const char *depth;  static const char *upload_pack;  static struct strbuf default_rla = STRBUF_INIT; @@ -98,6 +102,8 @@ static struct option builtin_fetch_options[] = {  		    N_("fetch all tags and associated objects"), TAGS_SET),  	OPT_SET_INT('n', NULL, &tags,  		    N_("do not fetch all tags (--no-tags)"), TAGS_UNSET), +	OPT_INTEGER('j', "jobs", &max_children, +		    N_("number of submodules fetched in parallel")),  	OPT_BOOL('p', "prune", &prune,  		 N_("prune remote-tracking branches no longer on remote")),  	{ OPTION_CALLBACK, 0, "recurse-submodules", NULL, N_("on-demand"), @@ -123,6 +129,10 @@ static struct option builtin_fetch_options[] = {  		 N_("accept refs that update .git/shallow")),  	{ OPTION_CALLBACK, 0, "refmap", NULL, N_("refmap"),  	  N_("specify fetch refmap"), PARSE_OPT_NONEG, parse_refmap_arg }, +	OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"), +			TRANSPORT_FAMILY_IPV4), +	OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"), +			TRANSPORT_FAMILY_IPV6),  	OPT_END()  }; @@ -179,13 +189,15 @@ static void add_merge_config(struct ref **head,  	}  } -static int add_existing(const char *refname, const unsigned char *sha1, +static int add_existing(const char *refname, const struct object_id *oid,  			int flag, void *cbdata)  {  	struct string_list *list = (struct string_list *)cbdata;  	struct string_list_item *item = string_list_insert(list, refname); -	item->util = xmalloc(20); -	hashcpy(item->util, sha1); +	struct object_id *old_oid = xmalloc(sizeof(*old_oid)); + +	oidcpy(old_oid, oid); +	item->util = old_oid;  	return 0;  } @@ -193,7 +205,7 @@ static int will_fetch(struct ref **head, const unsigned char *sha1)  {  	struct ref *rm = *head;  	while (rm) { -		if (!hashcmp(rm->old_sha1, sha1)) +		if (!hashcmp(rm->old_oid.hash, sha1))  			return 1;  		rm = rm->next;  	} @@ -221,8 +233,8 @@ static void find_non_local_tags(struct transport *transport,  		 * as one to ignore by setting util to NULL.  		 */  		if (ends_with(ref->name, "^{}")) { -			if (item && !has_sha1_file(ref->old_sha1) && -			    !will_fetch(head, ref->old_sha1) && +			if (item && !has_object_file(&ref->old_oid) && +			    !will_fetch(head, ref->old_oid.hash) &&  			    !has_sha1_file(item->util) &&  			    !will_fetch(head, item->util))  				item->util = NULL; @@ -248,7 +260,7 @@ static void find_non_local_tags(struct transport *transport,  			continue;  		item = string_list_insert(&remote_refs, ref->name); -		item->util = (void *)ref->old_sha1; +		item->util = (void *)&ref->old_oid;  	}  	string_list_clear(&existing_refs, 1); @@ -270,7 +282,7 @@ static void find_non_local_tags(struct transport *transport,  		{  			struct ref *rm = alloc_ref(item->string);  			rm->peer_ref = alloc_ref(item->string); -			hashcpy(rm->old_sha1, item->util); +			oidcpy(&rm->old_oid, item->util);  			**tail = rm;  			*tail = &rm->next;  		} @@ -416,8 +428,8 @@ static int s_update_ref(const char *action,  	transaction = ref_transaction_begin(&err);  	if (!transaction ||  	    ref_transaction_update(transaction, ref->name, -				   ref->new_sha1, -				   check_old ? ref->old_sha1 : NULL, +				   ref->new_oid.hash, +				   check_old ? ref->old_oid.hash : NULL,  				   0, msg, &err))  		goto fail; @@ -438,7 +450,132 @@ fail:  			   : STORE_REF_ERROR_OTHER;  } -#define REFCOL_WIDTH  10 +static int refcol_width = 10; +static int compact_format; + +static void adjust_refcol_width(const struct ref *ref) +{ +	int max, rlen, llen, len; + +	/* uptodate lines are only shown on high verbosity level */ +	if (!verbosity && !oidcmp(&ref->peer_ref->old_oid, &ref->old_oid)) +		return; + +	max    = term_columns(); +	rlen   = utf8_strwidth(prettify_refname(ref->name)); + +	llen   = utf8_strwidth(prettify_refname(ref->peer_ref->name)); + +	/* +	 * rough estimation to see if the output line is too long and +	 * should not be counted (we can't do precise calculation +	 * anyway because we don't know if the error explanation part +	 * will be printed in update_local_ref) +	 */ +	if (compact_format) { +		llen = 0; +		max = max * 2 / 3; +	} +	len = 21 /* flag and summary */ + rlen + 4 /* -> */ + llen; +	if (len >= max) +		return; + +	/* +	 * Not precise calculation for compact mode because '*' can +	 * appear on the left hand side of '->' and shrink the column +	 * back. +	 */ +	if (refcol_width < rlen) +		refcol_width = rlen; +} + +static void prepare_format_display(struct ref *ref_map) +{ +	struct ref *rm; +	const char *format = "full"; + +	git_config_get_string_const("fetch.output", &format); +	if (!strcasecmp(format, "full")) +		compact_format = 0; +	else if (!strcasecmp(format, "compact")) +		compact_format = 1; +	else +		die(_("configuration fetch.output contains invalid value %s"), +		    format); + +	for (rm = ref_map; rm; rm = rm->next) { +		if (rm->status == REF_STATUS_REJECT_SHALLOW || +		    !rm->peer_ref || +		    !strcmp(rm->name, "HEAD")) +			continue; + +		adjust_refcol_width(rm); +	} +} + +static void print_remote_to_local(struct strbuf *display, +				  const char *remote, const char *local) +{ +	strbuf_addf(display, "%-*s -> %s", refcol_width, remote, local); +} + +static int find_and_replace(struct strbuf *haystack, +			    const char *needle, +			    const char *placeholder) +{ +	const char *p = strstr(haystack->buf, needle); +	int plen, nlen; + +	if (!p) +		return 0; + +	if (p > haystack->buf && p[-1] != '/') +		return 0; + +	plen = strlen(p); +	nlen = strlen(needle); +	if (plen > nlen && p[nlen] != '/') +		return 0; + +	strbuf_splice(haystack, p - haystack->buf, nlen, +		      placeholder, strlen(placeholder)); +	return 1; +} + +static void print_compact(struct strbuf *display, +			  const char *remote, const char *local) +{ +	struct strbuf r = STRBUF_INIT; +	struct strbuf l = STRBUF_INIT; + +	if (!strcmp(remote, local)) { +		strbuf_addf(display, "%-*s -> *", refcol_width, remote); +		return; +	} + +	strbuf_addstr(&r, remote); +	strbuf_addstr(&l, local); + +	if (!find_and_replace(&r, local, "*")) +		find_and_replace(&l, remote, "*"); +	print_remote_to_local(display, r.buf, l.buf); + +	strbuf_release(&r); +	strbuf_release(&l); +} + +static void format_display(struct strbuf *display, char code, +			   const char *summary, const char *error, +			   const char *remote, const char *local) +{ +	strbuf_addf(display, "%c %-*s ", code, TRANSPORT_SUMMARY(summary)); +	if (!compact_format) +		print_remote_to_local(display, remote, local); +	else +		print_compact(display, remote, local); +	if (error) +		strbuf_addf(display, "  (%s)", error); +}  static int update_local_ref(struct ref *ref,  			    const char *remote, @@ -450,47 +587,43 @@ static int update_local_ref(struct ref *ref,  	struct branch *current_branch = branch_get(NULL);  	const char *pretty_ref = prettify_refname(ref->name); -	type = sha1_object_info(ref->new_sha1, NULL); +	type = sha1_object_info(ref->new_oid.hash, NULL);  	if (type < 0) -		die(_("object %s not found"), sha1_to_hex(ref->new_sha1)); +		die(_("object %s not found"), oid_to_hex(&ref->new_oid)); -	if (!hashcmp(ref->old_sha1, ref->new_sha1)) { +	if (!oidcmp(&ref->old_oid, &ref->new_oid)) {  		if (verbosity > 0) -			strbuf_addf(display, "= %-*s %-*s -> %s", -				    TRANSPORT_SUMMARY(_("[up to date]")), -				    REFCOL_WIDTH, remote, pretty_ref); +			format_display(display, '=', _("[up to date]"), NULL, +				       remote, pretty_ref);  		return 0;  	}  	if (current_branch &&  	    !strcmp(ref->name, current_branch->name) &&  	    !(update_head_ok || is_bare_repository()) && -	    !is_null_sha1(ref->old_sha1)) { +	    !is_null_oid(&ref->old_oid)) {  		/*  		 * If this is the head, and it's not okay to update  		 * the head, and the old value of the head isn't empty...  		 */ -		strbuf_addf(display, -			    _("! %-*s %-*s -> %s  (can't fetch in current branch)"), -			    TRANSPORT_SUMMARY(_("[rejected]")), -			    REFCOL_WIDTH, remote, pretty_ref); +		format_display(display, '!', _("[rejected]"), +			       _("can't fetch in current branch"), +			       remote, pretty_ref);  		return 1;  	} -	if (!is_null_sha1(ref->old_sha1) && +	if (!is_null_oid(&ref->old_oid) &&  	    starts_with(ref->name, "refs/tags/")) {  		int r;  		r = s_update_ref("updating tag", ref, 0); -		strbuf_addf(display, "%c %-*s %-*s -> %s%s", -			    r ? '!' : '-', -			    TRANSPORT_SUMMARY(_("[tag update]")), -			    REFCOL_WIDTH, remote, pretty_ref, -			    r ? _("  (unable to update local ref)") : ""); +		format_display(display, r ? '!' : 't', _("[tag update]"), +			       r ? _("unable to update local ref") : NULL, +			       remote, pretty_ref);  		return r;  	} -	current = lookup_commit_reference_gently(ref->old_sha1, 1); -	updated = lookup_commit_reference_gently(ref->new_sha1, 1); +	current = lookup_commit_reference_gently(ref->old_oid.hash, 1); +	updated = lookup_commit_reference_gently(ref->new_oid.hash, 1);  	if (!current || !updated) {  		const char *msg;  		const char *what; @@ -514,53 +647,47 @@ static int update_local_ref(struct ref *ref,  		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&  		    (recurse_submodules != RECURSE_SUBMODULES_ON)) -			check_for_new_submodule_commits(ref->new_sha1); +			check_for_new_submodule_commits(ref->new_oid.hash);  		r = s_update_ref(msg, ref, 0); -		strbuf_addf(display, "%c %-*s %-*s -> %s%s", -			    r ? '!' : '*', -			    TRANSPORT_SUMMARY(what), -			    REFCOL_WIDTH, remote, pretty_ref, -			    r ? _("  (unable to update local ref)") : ""); +		format_display(display, r ? '!' : '*', what, +			       r ? _("unable to update local ref") : NULL, +			       remote, pretty_ref);  		return r;  	}  	if (in_merge_bases(current, updated)) { -		char quickref[83]; +		struct strbuf quickref = STRBUF_INIT;  		int r; -		strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV)); -		strcat(quickref, ".."); -		strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV)); +		strbuf_add_unique_abbrev(&quickref, current->object.oid.hash, DEFAULT_ABBREV); +		strbuf_addstr(&quickref, ".."); +		strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV);  		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&  		    (recurse_submodules != RECURSE_SUBMODULES_ON)) -			check_for_new_submodule_commits(ref->new_sha1); +			check_for_new_submodule_commits(ref->new_oid.hash);  		r = s_update_ref("fast-forward", ref, 1); -		strbuf_addf(display, "%c %-*s %-*s -> %s%s", -			    r ? '!' : ' ', -			    TRANSPORT_SUMMARY_WIDTH, quickref, -			    REFCOL_WIDTH, remote, pretty_ref, -			    r ? _("  (unable to update local ref)") : ""); +		format_display(display, r ? '!' : ' ', quickref.buf, +			       r ? _("unable to update local ref") : NULL, +			       remote, pretty_ref); +		strbuf_release(&quickref);  		return r;  	} else if (force || ref->force) { -		char quickref[84]; +		struct strbuf quickref = STRBUF_INIT;  		int r; -		strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV)); -		strcat(quickref, "..."); -		strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV)); +		strbuf_add_unique_abbrev(&quickref, current->object.oid.hash, DEFAULT_ABBREV); +		strbuf_addstr(&quickref, "..."); +		strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV);  		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&  		    (recurse_submodules != RECURSE_SUBMODULES_ON)) -			check_for_new_submodule_commits(ref->new_sha1); +			check_for_new_submodule_commits(ref->new_oid.hash);  		r = s_update_ref("forced-update", ref, 1); -		strbuf_addf(display, "%c %-*s %-*s -> %s  (%s)", -			    r ? '!' : '+', -			    TRANSPORT_SUMMARY_WIDTH, quickref, -			    REFCOL_WIDTH, remote, pretty_ref, -			    r ? _("unable to update local ref") : _("forced update")); +		format_display(display, r ? '!' : '+', quickref.buf, +			       r ? _("unable to update local ref") : _("forced update"), +			       remote, pretty_ref); +		strbuf_release(&quickref);  		return r;  	} else { -		strbuf_addf(display, "! %-*s %-*s -> %s  %s", -			    TRANSPORT_SUMMARY(_("[rejected]")), -			    REFCOL_WIDTH, remote, pretty_ref, -			    _("(non-fast-forward)")); +		format_display(display, '!', _("[rejected]"), _("non-fast-forward"), +			       remote, pretty_ref);  		return 1;  	}  } @@ -575,7 +702,7 @@ static int iterate_ref_map(void *cb_data, unsigned char sha1[20])  	if (!ref)  		return -1; /* end of the list */  	*rm = ref->next; -	hashcpy(sha1, ref->old_sha1); +	hashcpy(sha1, ref->old_oid.hash);  	return 0;  } @@ -588,12 +715,13 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,  	struct strbuf note = STRBUF_INIT;  	const char *what, *kind;  	struct ref *rm; -	char *url, *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD"); +	char *url; +	const char *filename = dry_run ? "/dev/null" : git_path_fetch_head();  	int want_status;  	fp = fopen(filename, "a");  	if (!fp) -		return error(_("cannot open %s: %s\n"), filename, strerror(errno)); +		return error_errno(_("cannot open %s"), filename);  	if (raw_url)  		url = transport_anonymize_url(raw_url); @@ -606,6 +734,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,  		goto abort;  	} +	prepare_format_display(ref_map); +  	/*  	 * We do a pass for each fetch_head_status type in their enum order, so  	 * merged entries are written before not-for-merge. That lets readers @@ -625,7 +755,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,  				continue;  			} -			commit = lookup_commit_reference_gently(rm->old_sha1, 1); +			commit = lookup_commit_reference_gently(rm->old_oid.hash, 1);  			if (!commit)  				rm->fetch_head_status = FETCH_HEAD_NOT_FOR_MERGE; @@ -633,10 +763,9 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,  				continue;  			if (rm->peer_ref) { -				ref = xcalloc(1, sizeof(*ref) + strlen(rm->peer_ref->name) + 1); -				strcpy(ref->name, rm->peer_ref->name); -				hashcpy(ref->old_sha1, rm->peer_ref->old_sha1); -				hashcpy(ref->new_sha1, rm->old_sha1); +				ref = alloc_ref(rm->peer_ref->name); +				oidcpy(&ref->old_oid, &rm->peer_ref->old_oid); +				oidcpy(&ref->new_oid, &rm->old_oid);  				ref->force = rm->peer_ref->force;  			} @@ -681,7 +810,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,  				/* fall-through */  			case FETCH_HEAD_MERGE:  				fprintf(fp, "%s\t%s\t%s", -					sha1_to_hex(rm->old_sha1), +					oid_to_hex(&rm->old_oid),  					merge_status_marker,  					note.buf);  				for (i = 0; i < url_len; ++i) @@ -701,11 +830,10 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,  				rc |= update_local_ref(ref, what, rm, ¬e);  				free(ref);  			} else -				strbuf_addf(¬e, "* %-*s %-*s -> FETCH_HEAD", -					    TRANSPORT_SUMMARY_WIDTH, -					    *kind ? kind : "branch", -					    REFCOL_WIDTH, -					    *what ? what : "HEAD"); +				format_display(¬e, '*', +					       *kind ? kind : "branch", NULL, +					       *what ? what : "HEAD", +					       "FETCH_HEAD");  			if (note.len) {  				if (verbosity >= 0 && !shown_url) {  					fprintf(stderr, _("From %.*s\n"), @@ -787,20 +915,31 @@ static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,  	if (4 < i && !strncmp(".git", url + i - 3, 4))  		url_len = i - 3; -	for (ref = stale_refs; ref; ref = ref->next) { -		if (!dry_run) -			result |= delete_ref(ref->name, NULL, 0); -		if (verbosity >= 0 && !shown_url) { -			fprintf(stderr, _("From %.*s\n"), url_len, url); -			shown_url = 1; -		} -		if (verbosity >= 0) { -			fprintf(stderr, " x %-*s %-*s -> %s\n", -				TRANSPORT_SUMMARY(_("[deleted]")), -				REFCOL_WIDTH, _("(none)"), prettify_refname(ref->name)); +	if (!dry_run) { +		struct string_list refnames = STRING_LIST_INIT_NODUP; + +		for (ref = stale_refs; ref; ref = ref->next) +			string_list_append(&refnames, ref->name); + +		result = delete_refs(&refnames, 0); +		string_list_clear(&refnames, 0); +	} + +	if (verbosity >= 0) { +		for (ref = stale_refs; ref; ref = ref->next) { +			struct strbuf sb = STRBUF_INIT; +			if (!shown_url) { +				fprintf(stderr, _("From %.*s\n"), url_len, url); +				shown_url = 1; +			} +			format_display(&sb, '-', _("[deleted]"), NULL, +				       _("(none)"), prettify_refname(ref->name)); +			fprintf(stderr, " %s\n",sb.buf); +			strbuf_release(&sb);  			warn_dangling_symref(stderr, dangling_msg, ref->name);  		}  	} +  	free(url);  	free_refs(stale_refs);  	return result; @@ -822,11 +961,11 @@ static void check_not_current_branch(struct ref *ref_map)  static int truncate_fetch_head(void)  { -	char *filename = git_path("FETCH_HEAD"); -	FILE *fp = fopen(filename, "w"); +	const char *filename = git_path_fetch_head(); +	FILE *fp = fopen_for_writing(filename);  	if (!fp) -		return error(_("cannot open %s: %s\n"), filename, strerror(errno)); +		return error_errno(_("cannot open %s"), filename);  	fclose(fp);  	return 0;  } @@ -847,6 +986,7 @@ static struct transport *prepare_transport(struct remote *remote)  	struct transport *transport;  	transport = transport_get(remote, NULL);  	transport_set_verbosity(transport, verbosity, progress); +	transport->family = family;  	if (upload_pack)  		set_option(transport, TRANS_OPT_UPLOADPACK, upload_pack);  	if (keep) @@ -912,9 +1052,10 @@ static int do_fetch(struct transport *transport,  			struct string_list_item *peer_item =  				string_list_lookup(&existing_refs,  						   rm->peer_ref->name); -			if (peer_item) -				hashcpy(rm->peer_ref->old_sha1, -					peer_item->util); +			if (peer_item) { +				struct object_id *old_oid = peer_item->util; +				oidcpy(&rm->peer_ref->old_oid, old_oid); +			}  		}  	} @@ -975,17 +1116,15 @@ static int get_remote_group(const char *key, const char *value, void *priv)  {  	struct remote_group_data *g = priv; -	if (starts_with(key, "remotes.") && -			!strcmp(key + 8, g->name)) { +	if (skip_prefix(key, "remotes.", &key) && !strcmp(key, g->name)) {  		/* split list by white space */ -		int space = strcspn(value, " \t\n");  		while (*value) { -			if (space > 1) { -				string_list_append(g->list, -						   xstrndup(value, space)); -			} -			value += space + (value[space] != '\0'); -			space = strcspn(value, " \t\n"); +			size_t wordlen = strcspn(value, " \t\n"); + +			if (wordlen >= 1) +				string_list_append_nodup(g->list, +						   xstrndup(value, wordlen)); +			value += wordlen + (value[wordlen] != '\0');  		}  	} @@ -1000,10 +1139,9 @@ static int add_remote_or_group(const char *name, struct string_list *list)  	git_config(get_remote_group, &g);  	if (list->nr == prev_nr) { -		struct remote *remote; -		if (!remote_is_configured(name)) +		struct remote *remote = remote_get(name); +		if (!remote_is_configured(remote))  			return 0; -		remote = remote_get(name);  		string_list_append(list, remote->name);  	}  	return 1; @@ -1094,7 +1232,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)  	if (argc > 0) {  		int j = 0;  		int i; -		refs = xcalloc(argc + 1, sizeof(const char *)); +		refs = xcalloc(st_add(argc, 1), sizeof(const char *));  		for (i = 0; i < argc; i++) {  			if (!strcmp(argv[i], "tag")) {  				i++; @@ -1122,7 +1260,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)  int cmd_fetch(int argc, const char **argv, const char *prefix)  {  	int i; -	struct string_list list = STRING_LIST_INIT_NODUP; +	struct string_list list = STRING_LIST_INIT_DUP;  	struct remote *remote;  	int result = 0;  	struct argv_array argv_gc_auto = ARGV_ARRAY_INIT; @@ -1144,11 +1282,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)  			die(_("--depth and --unshallow cannot be used together"));  		else if (!is_repository_shallow())  			die(_("--unshallow on a complete repository does not make sense")); -		else { -			static char inf_depth[12]; -			sprintf(inf_depth, "%d", INFINITE_DEPTH); -			depth = inf_depth; -		} +		else +			depth = xstrfmt("%d", INFINITE_DEPTH);  	}  	/* no need to be strict, transport_set_option() will validate it again */ @@ -1203,14 +1338,15 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)  		result = fetch_populated_submodules(&options,  						    submodule_prefix,  						    recurse_submodules, -						    verbosity < 0); +						    verbosity < 0, +						    max_children);  		argv_array_clear(&options);  	} -	/* All names were strdup()ed or strndup()ed */ -	list.strdup_strings = 1;  	string_list_clear(&list, 0); +	close_all_packs(); +  	argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL);  	if (verbosity < 0)  		argv_array_push(&argv_gc_auto, "--quiet");  | 
