aboutsummaryrefslogtreecommitdiff
path: root/builtin/fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/fetch.c')
-rw-r--r--builtin/fetch.c398
1 files changed, 282 insertions, 116 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c
index c7ff3480fb..a22c319467 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -47,7 +47,7 @@
static const char * const builtin_fetch_usage[] = {
N_("git fetch [<options>] [<repository> [<refspec>...]]"),
N_("git fetch [<options>] <group>"),
- N_("git fetch --multiple [<options>] [(<repository> | <group>)...]"),
+ N_("git fetch --multiple [<options>] [(<repository>|<group>)...]"),
N_("git fetch --all [<options>]"),
NULL
};
@@ -97,7 +97,6 @@ static struct strbuf default_rla = STRBUF_INIT;
static struct transport *gtransport;
static struct transport *gsecondary;
static struct refspec refmap = REFSPEC_INIT_FETCH;
-static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
static struct string_list server_options = STRING_LIST_INIT_DUP;
static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
@@ -289,13 +288,11 @@ static struct refname_hash_entry *refname_hash_add(struct hashmap *map,
return ent;
}
-static int add_one_refname(const char *refname, const char *referent UNUSED,
- const struct object_id *oid,
- int flag UNUSED, void *cbdata)
+static int add_one_refname(const struct reference *ref, void *cbdata)
{
struct hashmap *refname_map = cbdata;
- (void) refname_hash_add(refname_map, refname, oid);
+ (void) refname_hash_add(refname_map, ref->name, ref->oid);
return 0;
}
@@ -724,7 +721,7 @@ static void display_state_init(struct display_state *display_state, struct ref *
display_state->url = xstrdup("foreign");
display_state->url_len = strlen(display_state->url);
- for (i = display_state->url_len - 1; display_state->url[i] == '/' && 0 <= i; i--)
+ for (i = display_state->url_len - 1; 0 <= i && display_state->url[i] == '/'; i--)
;
display_state->url_len = i + 1;
if (4 < i && !strncmp(".git", display_state->url + i - 3, 4))
@@ -863,57 +860,147 @@ static void display_ref_update(struct display_state *display_state, char code,
fputs(display_state->buf.buf, f);
}
+struct ref_update_display_info {
+ bool failed;
+ char success_code;
+ char fail_code;
+ char *summary;
+ char *fail_detail;
+ char *success_detail;
+ char *ref;
+ char *remote;
+ struct object_id old_oid;
+ struct object_id new_oid;
+};
+
+struct ref_update_display_info_array {
+ struct ref_update_display_info *info;
+ size_t alloc, nr;
+};
+
+static struct ref_update_display_info *ref_update_display_info_append(
+ struct ref_update_display_info_array *array,
+ char success_code,
+ char fail_code,
+ const char *summary,
+ const char *success_detail,
+ const char *fail_detail,
+ const char *ref,
+ const char *remote,
+ const struct object_id *old_oid,
+ const struct object_id *new_oid)
+{
+ struct ref_update_display_info *info;
+
+ ALLOC_GROW(array->info, array->nr + 1, array->alloc);
+ info = &array->info[array->nr++];
+
+ info->failed = false;
+ info->success_code = success_code;
+ info->fail_code = fail_code;
+ info->summary = xstrdup(summary);
+ info->success_detail = xstrdup_or_null(success_detail);
+ info->fail_detail = xstrdup_or_null(fail_detail);
+ info->remote = xstrdup(remote);
+ info->ref = xstrdup(ref);
+
+ oidcpy(&info->old_oid, old_oid);
+ oidcpy(&info->new_oid, new_oid);
+
+ return info;
+}
+
+static void ref_update_display_info_set_failed(struct ref_update_display_info *info)
+{
+ info->failed = true;
+}
+
+static void ref_update_display_info_free(struct ref_update_display_info *info)
+{
+ free(info->summary);
+ free(info->success_detail);
+ free(info->fail_detail);
+ free(info->remote);
+ free(info->ref);
+}
+
+static void ref_update_display_info_display(struct ref_update_display_info *info,
+ struct display_state *display_state,
+ int summary_width)
+{
+ display_ref_update(display_state,
+ info->failed ? info->fail_code : info->success_code,
+ info->summary,
+ info->failed ? info->fail_detail : info->success_detail,
+ info->remote, info->ref, &info->old_oid,
+ &info->new_oid, summary_width);
+}
+
static int update_local_ref(struct ref *ref,
struct ref_transaction *transaction,
- struct display_state *display_state,
const struct ref *remote_ref,
- int summary_width,
- const struct fetch_config *config)
+ const struct fetch_config *config,
+ struct ref_update_display_info_array *display_array)
{
struct commit *current = NULL, *updated;
int fast_forward = 0;
if (!odb_has_object(the_repository->objects, &ref->new_oid,
- HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR))
+ ODB_HAS_OBJECT_RECHECK_PACKED | ODB_HAS_OBJECT_FETCH_PROMISOR))
die(_("object %s not found"), oid_to_hex(&ref->new_oid));
if (oideq(&ref->old_oid, &ref->new_oid)) {
if (verbosity > 0)
- display_ref_update(display_state, '=', _("[up to date]"), NULL,
- remote_ref->name, ref->name,
- &ref->old_oid, &ref->new_oid, summary_width);
+ ref_update_display_info_append(display_array, '=', '=',
+ _("[up to date]"), NULL,
+ NULL, ref->name,
+ remote_ref->name, &ref->old_oid,
+ &ref->new_oid);
return 0;
}
if (!update_head_ok &&
!is_null_oid(&ref->old_oid) &&
branch_checked_out(ref->name)) {
+ struct ref_update_display_info *info;
/*
* If this is the head, and it's not okay to update
* the head, and the old value of the head isn't empty...
*/
- display_ref_update(display_state, '!', _("[rejected]"),
- _("can't fetch into checked-out branch"),
- remote_ref->name, ref->name,
- &ref->old_oid, &ref->new_oid, summary_width);
+ info = ref_update_display_info_append(display_array, '!', '!',
+ _("[rejected]"), NULL,
+ _("can't fetch into checked-out branch"),
+ ref->name, remote_ref->name,
+ &ref->old_oid, &ref->new_oid);
+ ref_update_display_info_set_failed(info);
return 1;
}
if (!is_null_oid(&ref->old_oid) &&
starts_with(ref->name, "refs/tags/")) {
+ struct ref_update_display_info *info;
+
if (force || ref->force) {
int r;
+
r = s_update_ref("updating tag", ref, transaction, 0);
- display_ref_update(display_state, r ? '!' : 't', _("[tag update]"),
- r ? _("unable to update local ref") : NULL,
- remote_ref->name, ref->name,
- &ref->old_oid, &ref->new_oid, summary_width);
+
+ info = ref_update_display_info_append(display_array, 't', '!',
+ _("[tag update]"), NULL,
+ _("unable to update local ref"),
+ ref->name, remote_ref->name,
+ &ref->old_oid, &ref->new_oid);
+ if (r)
+ ref_update_display_info_set_failed(info);
+
return r;
} else {
- display_ref_update(display_state, '!', _("[rejected]"),
- _("would clobber existing tag"),
- remote_ref->name, ref->name,
- &ref->old_oid, &ref->new_oid, summary_width);
+ info = ref_update_display_info_append(display_array, '!', '!',
+ _("[rejected]"), NULL,
+ _("would clobber existing tag"),
+ ref->name, remote_ref->name,
+ &ref->old_oid, &ref->new_oid);
+ ref_update_display_info_set_failed(info);
return 1;
}
}
@@ -923,6 +1010,7 @@ static int update_local_ref(struct ref *ref,
updated = lookup_commit_reference_gently(the_repository,
&ref->new_oid, 1);
if (!current || !updated) {
+ struct ref_update_display_info *info;
const char *msg;
const char *what;
int r;
@@ -943,10 +1031,15 @@ static int update_local_ref(struct ref *ref,
}
r = s_update_ref(msg, ref, transaction, 0);
- display_ref_update(display_state, r ? '!' : '*', what,
- r ? _("unable to update local ref") : NULL,
- remote_ref->name, ref->name,
- &ref->old_oid, &ref->new_oid, summary_width);
+
+ info = ref_update_display_info_append(display_array, '*', '!',
+ what, NULL,
+ _("unable to update local ref"),
+ ref->name, remote_ref->name,
+ &ref->old_oid, &ref->new_oid);
+ if (r)
+ ref_update_display_info_set_failed(info);
+
return r;
}
@@ -962,6 +1055,7 @@ static int update_local_ref(struct ref *ref,
}
if (fast_forward) {
+ struct ref_update_display_info *info;
struct strbuf quickref = STRBUF_INIT;
int r;
@@ -969,29 +1063,46 @@ static int update_local_ref(struct ref *ref,
strbuf_addstr(&quickref, "..");
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
r = s_update_ref("fast-forward", ref, transaction, 1);
- display_ref_update(display_state, r ? '!' : ' ', quickref.buf,
- r ? _("unable to update local ref") : NULL,
- remote_ref->name, ref->name,
- &ref->old_oid, &ref->new_oid, summary_width);
+
+ info = ref_update_display_info_append(display_array, ' ', '!',
+ quickref.buf, NULL,
+ _("unable to update local ref"),
+ ref->name, remote_ref->name,
+ &ref->old_oid, &ref->new_oid);
+ if (r)
+ ref_update_display_info_set_failed(info);
+
strbuf_release(&quickref);
return r;
} else if (force || ref->force) {
+ struct ref_update_display_info *info;
struct strbuf quickref = STRBUF_INIT;
int r;
+
strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
strbuf_addstr(&quickref, "...");
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
r = s_update_ref("forced-update", ref, transaction, 1);
- display_ref_update(display_state, r ? '!' : '+', quickref.buf,
- r ? _("unable to update local ref") : _("forced update"),
- remote_ref->name, ref->name,
- &ref->old_oid, &ref->new_oid, summary_width);
+
+ info = ref_update_display_info_append(display_array, '+', '!',
+ quickref.buf, _("forced update"),
+ _("unable to update local ref"),
+ ref->name, remote_ref->name,
+ &ref->old_oid, &ref->new_oid);
+
+ if (r)
+ ref_update_display_info_set_failed(info);
+
strbuf_release(&quickref);
return r;
} else {
- display_ref_update(display_state, '!', _("[rejected]"), _("non-fast-forward"),
- remote_ref->name, ref->name,
- &ref->old_oid, &ref->new_oid, summary_width);
+ struct ref_update_display_info *info;
+ info = ref_update_display_info_append(display_array, '!', '!',
+ _("[rejected]"), NULL,
+ _("non-fast-forward"),
+ ref->name, remote_ref->name,
+ &ref->old_oid, &ref->new_oid);
+ ref_update_display_info_set_failed(info);
return 1;
}
}
@@ -1105,17 +1216,14 @@ static int store_updated_refs(struct display_state *display_state,
int connectivity_checked,
struct ref_transaction *transaction, struct ref *ref_map,
struct fetch_head *fetch_head,
- const struct fetch_config *config)
+ const struct fetch_config *config,
+ struct ref_update_display_info_array *display_array)
{
int rc = 0;
struct strbuf note = STRBUF_INIT;
const char *what, *kind;
struct ref *rm;
int want_status;
- int summary_width = 0;
-
- if (verbosity >= 0)
- summary_width = transport_summary_width(ref_map);
if (!connectivity_checked) {
struct check_connected_options opt = CHECK_CONNECTED_INIT;
@@ -1220,8 +1328,8 @@ static int store_updated_refs(struct display_state *display_state,
display_state->url_len);
if (ref) {
- rc |= update_local_ref(ref, transaction, display_state,
- rm, summary_width, config);
+ rc |= update_local_ref(ref, transaction, rm,
+ config, display_array);
free(ref);
} else if (write_fetch_head || dry_run) {
/*
@@ -1229,12 +1337,12 @@ static int store_updated_refs(struct display_state *display_state,
* would be written to FETCH_HEAD, if --dry-run
* is set).
*/
- display_ref_update(display_state, '*',
- *kind ? kind : "branch", NULL,
- rm->name,
- "FETCH_HEAD",
- &rm->new_oid, &rm->old_oid,
- summary_width);
+
+ ref_update_display_info_append(display_array, '*', '*',
+ *kind ? kind : "branch",
+ NULL, NULL, "FETCH_HEAD",
+ rm->name, &rm->new_oid,
+ &rm->old_oid);
}
}
}
@@ -1288,7 +1396,7 @@ static int check_exist_and_connected(struct ref *ref_map)
*/
for (r = rm; r; r = r->next) {
if (!odb_has_object(the_repository->objects, &r->old_oid,
- HAS_OBJECT_RECHECK_PACKED))
+ ODB_HAS_OBJECT_RECHECK_PACKED))
return -1;
}
@@ -1302,7 +1410,8 @@ static int fetch_and_consume_refs(struct display_state *display_state,
struct ref_transaction *transaction,
struct ref *ref_map,
struct fetch_head *fetch_head,
- const struct fetch_config *config)
+ const struct fetch_config *config,
+ struct ref_update_display_info_array *display_array)
{
int connectivity_checked = 1;
int ret;
@@ -1324,7 +1433,8 @@ static int fetch_and_consume_refs(struct display_state *display_state,
trace2_region_enter("fetch", "consume_refs", the_repository);
ret = store_updated_refs(display_state, connectivity_checked,
- transaction, ref_map, fetch_head, config);
+ transaction, ref_map, fetch_head, config,
+ display_array);
trace2_region_leave("fetch", "consume_refs", the_repository);
out:
@@ -1416,14 +1526,11 @@ static void set_option(struct transport *transport, const char *name, const char
}
-static int add_oid(const char *refname UNUSED,
- const char *referent UNUSED,
- const struct object_id *oid,
- int flags UNUSED, void *cb_data)
+static int add_oid(const struct reference *ref, void *cb_data)
{
struct oid_array *oids = cb_data;
- oid_array_append(oids, oid);
+ oid_array_append(oids, ref->oid);
return 0;
}
@@ -1434,6 +1541,9 @@ static void add_negotiation_tips(struct git_transport_options *smart_options)
for (i = 0; i < negotiation_tip.nr; i++) {
const char *s = negotiation_tip.items[i].string;
+ struct refs_for_each_ref_options opts = {
+ .pattern = s,
+ };
int old_nr;
if (!has_glob_specials(s)) {
struct object_id oid;
@@ -1445,8 +1555,8 @@ static void add_negotiation_tips(struct git_transport_options *smart_options)
continue;
}
old_nr = oids->nr;
- refs_for_each_glob_ref(get_main_ref_store(the_repository),
- add_oid, s, oids);
+ refs_for_each_ref_ext(get_main_ref_store(the_repository),
+ add_oid, oids, &opts);
if (old_nr == oids->nr)
warning("ignoring --negotiation-tip=%s because it does not match any refs",
s);
@@ -1454,7 +1564,8 @@ static void add_negotiation_tips(struct git_transport_options *smart_options)
smart_options->negotiation_tips = oids;
}
-static struct transport *prepare_transport(struct remote *remote, int deepen)
+static struct transport *prepare_transport(struct remote *remote, int deepen,
+ struct list_objects_filter_options *filter_options)
{
struct transport *transport;
@@ -1478,9 +1589,9 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
if (refetch)
set_option(transport, TRANS_OPT_REFETCH, "yes");
- if (filter_options.choice) {
+ if (filter_options->choice) {
const char *spec =
- expand_list_objects_filter_spec(&filter_options);
+ expand_list_objects_filter_spec(filter_options);
set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER, spec);
set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
}
@@ -1498,7 +1609,9 @@ static int backfill_tags(struct display_state *display_state,
struct ref_transaction *transaction,
struct ref *ref_map,
struct fetch_head *fetch_head,
- const struct fetch_config *config)
+ const struct fetch_config *config,
+ struct ref_update_display_info_array *display_array,
+ struct list_objects_filter_options *filter_options)
{
int retcode, cannot_reuse;
@@ -1512,7 +1625,7 @@ static int backfill_tags(struct display_state *display_state,
cannot_reuse = transport->cannot_reuse ||
deepen_since || deepen_not.nr;
if (cannot_reuse) {
- gsecondary = prepare_transport(transport->remote, 0);
+ gsecondary = prepare_transport(transport->remote, 0, filter_options);
transport = gsecondary;
}
@@ -1520,7 +1633,7 @@ static int backfill_tags(struct display_state *display_state,
transport_set_option(transport, TRANS_OPT_DEPTH, "0");
transport_set_option(transport, TRANS_OPT_DEEPEN_RELATIVE, NULL);
retcode = fetch_and_consume_refs(display_state, transport, transaction, ref_map,
- fetch_head, config);
+ fetch_head, config, display_array);
if (gsecondary) {
transport_disconnect(gsecondary);
@@ -1646,6 +1759,7 @@ struct ref_rejection_data {
bool conflict_msg_shown;
bool case_sensitive_msg_shown;
const char *remote_name;
+ struct strmap *rejected_refs;
};
static void ref_transaction_rejection_handler(const char *refname,
@@ -1654,6 +1768,7 @@ static void ref_transaction_rejection_handler(const char *refname,
const char *old_target UNUSED,
const char *new_target UNUSED,
enum ref_transaction_error err,
+ const char *details,
void *cb_data)
{
struct ref_rejection_data *data = cb_data;
@@ -1678,17 +1793,53 @@ static void ref_transaction_rejection_handler(const char *refname,
"branches"), data->remote_name);
data->conflict_msg_shown = true;
} else {
- const char *reason = ref_transaction_error_msg(err);
-
- error(_("fetching ref %s failed: %s"), refname, reason);
+ if (details)
+ error("%s", details);
+ else
+ error(_("fetching ref %s failed: %s"),
+ refname, ref_transaction_error_msg(err));
}
+ strmap_put(data->rejected_refs, refname, NULL);
*data->retcode = 1;
}
+/*
+ * Commit the reference transaction. If it isn't an atomic transaction, handle
+ * rejected updates as part of using batched updates.
+ */
+static int commit_ref_transaction(struct ref_transaction **transaction,
+ bool is_atomic, const char *remote_name,
+ struct strmap *rejected_refs,
+ struct strbuf *err)
+{
+ int retcode = ref_transaction_commit(*transaction, err);
+ if (retcode)
+ goto out;
+
+ if (!is_atomic) {
+ struct ref_rejection_data data = {
+ .conflict_msg_shown = 0,
+ .remote_name = remote_name,
+ .retcode = &retcode,
+ .rejected_refs = rejected_refs,
+ };
+
+ ref_transaction_for_each_rejected_update(*transaction,
+ ref_transaction_rejection_handler,
+ &data);
+ }
+
+out:
+ ref_transaction_free(*transaction);
+ *transaction = NULL;
+ return retcode;
+}
+
static int do_fetch(struct transport *transport,
struct refspec *rs,
- const struct fetch_config *config)
+ const struct fetch_config *config,
+ struct list_objects_filter_options *filter_options)
{
struct ref_transaction *transaction = NULL;
struct ref *ref_map = NULL;
@@ -1701,6 +1852,9 @@ static int do_fetch(struct transport *transport,
struct fetch_head fetch_head = { 0 };
struct strbuf err = STRBUF_INIT;
int do_set_head = 0;
+ struct ref_update_display_info_array display_array = { 0 };
+ struct strmap rejected_refs = STRMAP_INIT;
+ int summary_width = 0;
if (tags == TAGS_DEFAULT) {
if (transport->remote->fetch_tags == 2)
@@ -1825,7 +1979,7 @@ static int do_fetch(struct transport *transport,
}
if (fetch_and_consume_refs(&display_state, transport, transaction, ref_map,
- &fetch_head, config)) {
+ &fetch_head, config, &display_array)) {
retcode = 1;
goto cleanup;
}
@@ -1848,7 +2002,7 @@ static int do_fetch(struct transport *transport,
* the transaction and don't commit anything.
*/
if (backfill_tags(&display_state, transport, transaction, tags_ref_map,
- &fetch_head, config))
+ &fetch_head, config, &display_array, filter_options))
retcode = 1;
}
@@ -1858,33 +2012,18 @@ static int do_fetch(struct transport *transport,
if (retcode)
goto cleanup;
- retcode = ref_transaction_commit(transaction, &err);
- if (retcode) {
- /*
- * Explicitly handle transaction cleanup to avoid
- * aborting an already closed transaction.
- */
- ref_transaction_free(transaction);
- transaction = NULL;
- goto cleanup;
- }
-
- if (!atomic_fetch) {
- struct ref_rejection_data data = {
- .retcode = &retcode,
- .conflict_msg_shown = 0,
- .remote_name = transport->remote->name,
- };
+ if (verbosity >= 0)
+ summary_width = transport_summary_width(ref_map);
- ref_transaction_for_each_rejected_update(transaction,
- ref_transaction_rejection_handler,
- &data);
- if (retcode) {
- ref_transaction_free(transaction);
- transaction = NULL;
- goto cleanup;
- }
- }
+ retcode = commit_ref_transaction(&transaction, atomic_fetch,
+ transport->remote->name,
+ &rejected_refs, &err);
+ /*
+ * With '--atomic', bail out if the transaction fails. Without '--atomic',
+ * continue to fetch head and perform other post-fetch operations.
+ */
+ if (retcode && atomic_fetch)
+ goto cleanup;
commit_fetch_head(&fetch_head);
@@ -1950,6 +2089,24 @@ static int do_fetch(struct transport *transport,
}
cleanup:
+ /*
+ * When using batched updates, we want to commit the non-rejected
+ * updates and also handle the rejections.
+ */
+ if (retcode && !atomic_fetch && transaction)
+ commit_ref_transaction(&transaction, false,
+ transport->remote->name,
+ &rejected_refs, &err);
+
+ for (size_t i = 0; i < display_array.nr; i++) {
+ struct ref_update_display_info *info = &display_array.info[i];
+
+ if (!info->failed && strmap_contains(&rejected_refs, info->ref))
+ ref_update_display_info_set_failed(info);
+ ref_update_display_info_display(info, &display_state, summary_width);
+ ref_update_display_info_free(info);
+ }
+
if (retcode) {
if (err.len) {
error("%s", err.buf);
@@ -1963,6 +2120,9 @@ cleanup:
if (transaction)
ref_transaction_free(transaction);
+
+ free(display_array.info);
+ strmap_clear(&rejected_refs, 0);
display_state_release(&display_state);
close_fetch_head(&fetch_head);
strbuf_release(&err);
@@ -2184,20 +2344,21 @@ static int fetch_multiple(struct string_list *list, int max_children,
* Fetching from the promisor remote should use the given filter-spec
* or inherit the default filter-spec from the config.
*/
-static inline void fetch_one_setup_partial(struct remote *remote)
+static inline void fetch_one_setup_partial(struct remote *remote,
+ struct list_objects_filter_options *filter_options)
{
/*
* Explicit --no-filter argument overrides everything, regardless
* of any prior partial clones and fetches.
*/
- if (filter_options.no_filter)
+ if (filter_options->no_filter)
return;
/*
* If no prior partial clone/fetch and the current fetch DID NOT
* request a partial-fetch, do a normal fetch.
*/
- if (!repo_has_promisor_remote(the_repository) && !filter_options.choice)
+ if (!repo_has_promisor_remote(the_repository) && !filter_options->choice)
return;
/*
@@ -2206,8 +2367,8 @@ static inline void fetch_one_setup_partial(struct remote *remote)
* filter-spec as the default for subsequent fetches to this
* remote if there is currently no default filter-spec.
*/
- if (filter_options.choice) {
- partial_clone_register(remote->name, &filter_options);
+ if (filter_options->choice) {
+ partial_clone_register(remote->name, filter_options);
return;
}
@@ -2216,14 +2377,15 @@ static inline void fetch_one_setup_partial(struct remote *remote)
* explicitly given filter-spec or inherit the filter-spec from
* the config.
*/
- if (!filter_options.choice)
- partial_clone_get_default_filter_spec(&filter_options, remote->name);
+ if (!filter_options->choice)
+ partial_clone_get_default_filter_spec(filter_options, remote->name);
return;
}
static int fetch_one(struct remote *remote, int argc, const char **argv,
int prune_tags_ok, int use_stdin_refspecs,
- const struct fetch_config *config)
+ const struct fetch_config *config,
+ struct list_objects_filter_options *filter_options)
{
struct refspec rs = REFSPEC_INIT_FETCH;
int i;
@@ -2235,7 +2397,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv,
die(_("no remote repository specified; please specify either a URL or a\n"
"remote name from which new revisions should be fetched"));
- gtransport = prepare_transport(remote, 1);
+ gtransport = prepare_transport(remote, 1, filter_options);
if (prune < 0) {
/* no command line request */
@@ -2290,7 +2452,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv,
sigchain_push_common(unlock_pack_on_signal);
atexit(unlock_pack_atexit);
sigchain_push(SIGPIPE, SIG_IGN);
- exit_code = do_fetch(gtransport, &rs, config);
+ exit_code = do_fetch(gtransport, &rs, config, filter_options);
sigchain_pop(SIGPIPE);
refspec_clear(&rs);
transport_disconnect(gtransport);
@@ -2315,6 +2477,7 @@ int cmd_fetch(int argc,
const char *submodule_prefix = "";
const char *bundle_uri;
struct string_list list = STRING_LIST_INIT_DUP;
+ struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT;
struct remote *remote = NULL;
int all = -1, multiple = 0;
int result = 0;
@@ -2420,6 +2583,8 @@ int cmd_fetch(int argc,
OPT_END()
};
+ filter_options.allow_auto_filter = 1;
+
packet_trace_identity("fetch");
/* Record the command line for the reflog */
@@ -2580,7 +2745,7 @@ int cmd_fetch(int argc,
trace2_region_enter("fetch", "negotiate-only", the_repository);
if (!remote)
die(_("must supply remote when using --negotiate-only"));
- gtransport = prepare_transport(remote, 1);
+ gtransport = prepare_transport(remote, 1, &filter_options);
if (gtransport->smart_options) {
gtransport->smart_options->acked_commits = &acked_commits;
} else {
@@ -2602,12 +2767,12 @@ int cmd_fetch(int argc,
} else if (remote) {
if (filter_options.choice || repo_has_promisor_remote(the_repository)) {
trace2_region_enter("fetch", "setup-partial", the_repository);
- fetch_one_setup_partial(remote);
+ fetch_one_setup_partial(remote, &filter_options);
trace2_region_leave("fetch", "setup-partial", the_repository);
}
trace2_region_enter("fetch", "fetch-one", the_repository);
result = fetch_one(remote, argc, argv, prune_tags_ok, stdin_refspecs,
- &config);
+ &config, &filter_options);
trace2_region_leave("fetch", "fetch-one", the_repository);
} else {
int max_children = max_jobs;
@@ -2708,10 +2873,11 @@ int cmd_fetch(int argc,
if (opt_val != 0)
git_config_push_parameter("maintenance.incremental-repack.auto=-1");
}
- run_auto_maintenance(verbosity < 0);
+ run_auto_maintenance(the_repository, verbosity < 0);
}
cleanup:
string_list_clear(&list, 0);
+ list_objects_filter_release(&filter_options);
return result;
}