summaryrefslogtreecommitdiff
path: root/builtin/fetch.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/fetch.c')
-rw-r--r--builtin/fetch.c123
1 files changed, 57 insertions, 66 deletions
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 95fd0018b9..40a0e8d244 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -14,7 +14,7 @@
#include "refs.h"
#include "refspec.h"
#include "object-name.h"
-#include "object-store-ll.h"
+#include "object-store.h"
#include "oidset.h"
#include "oid-array.h"
#include "commit.h"
@@ -337,7 +337,6 @@ static void find_non_local_tags(const struct ref *refs,
struct string_list_item *remote_ref_item;
const struct ref *ref;
struct refname_hash_entry *item = NULL;
- const int quick_flags = OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT;
refname_hash_init(&existing_refs);
refname_hash_init(&remote_refs);
@@ -367,9 +366,9 @@ static void find_non_local_tags(const struct ref *refs,
*/
if (ends_with(ref->name, "^{}")) {
if (item &&
- !repo_has_object_file_with_flags(the_repository, &ref->old_oid, quick_flags) &&
+ !has_object(the_repository, &ref->old_oid, 0) &&
!oidset_contains(&fetch_oids, &ref->old_oid) &&
- !repo_has_object_file_with_flags(the_repository, &item->oid, quick_flags) &&
+ !has_object(the_repository, &item->oid, 0) &&
!oidset_contains(&fetch_oids, &item->oid))
clear_item(item);
item = NULL;
@@ -383,7 +382,7 @@ static void find_non_local_tags(const struct ref *refs,
* fetch.
*/
if (item &&
- !repo_has_object_file_with_flags(the_repository, &item->oid, quick_flags) &&
+ !has_object(the_repository, &item->oid, 0) &&
!oidset_contains(&fetch_oids, &item->oid))
clear_item(item);
@@ -404,7 +403,7 @@ static void find_non_local_tags(const struct ref *refs,
* checked to see if it needs fetching.
*/
if (item &&
- !repo_has_object_file_with_flags(the_repository, &item->oid, quick_flags) &&
+ !has_object(the_repository, &item->oid, 0) &&
!oidset_contains(&fetch_oids, &item->oid))
clear_item(item);
@@ -586,7 +585,7 @@ static struct ref *get_ref_map(struct remote *remote,
struct refspec_item tag_refspec;
/* also fetch all tags */
- refspec_item_init(&tag_refspec, TAG_REFSPEC, 0);
+ refspec_item_init_push(&tag_refspec, TAG_REFSPEC);
get_fetch_map(remote_refs, &tag_refspec, &tail, 0);
refspec_item_clear(&tag_refspec);
} else if (tags == TAGS_DEFAULT && *autotags) {
@@ -687,7 +686,7 @@ static int s_update_ref(const char *action,
switch (ref_transaction_commit(our_transaction, &err)) {
case 0:
break;
- case TRANSACTION_NAME_CONFLICT:
+ case REF_TRANSACTION_ERROR_NAME_CONFLICT:
ret = STORE_REF_ERROR_DF_CONFLICT;
goto out;
default:
@@ -911,7 +910,8 @@ static int update_local_ref(struct ref *ref,
struct commit *current = NULL, *updated;
int fast_forward = 0;
- if (!repo_has_object_file(the_repository, &ref->new_oid))
+ if (!has_object(the_repository, &ref->new_oid,
+ HAS_OBJECT_RECHECK_PACKED | HAS_OBJECT_FETCH_PROMISOR))
die(_("object %s not found"), oid_to_hex(&ref->new_oid));
if (oideq(&ref->old_oid, &ref->new_oid)) {
@@ -1330,8 +1330,7 @@ static int check_exist_and_connected(struct ref *ref_map)
* we need all direct targets to exist.
*/
for (r = rm; r; r = r->next) {
- if (!repo_has_object_file_with_flags(the_repository, &r->old_oid,
- OBJECT_INFO_SKIP_FETCH_OBJECT))
+ if (!has_object(the_repository, &r->old_oid, HAS_OBJECT_RECHECK_PACKED))
return -1;
}
@@ -1638,14 +1637,11 @@ static int set_head(const struct ref *remote_refs, struct remote *remote)
get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);
matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"),
- fetch_map, 1);
+ fetch_map, REMOTE_GUESS_HEAD_ALL);
for (ref = matches; ref; ref = ref->next) {
string_list_append(&heads, strip_refshead(ref->name));
}
- if (follow_remote_head == FOLLOW_REMOTE_NEVER)
- goto cleanup;
-
if (!heads.nr)
result = 1;
else if (heads.nr > 1)
@@ -1691,21 +1687,6 @@ cleanup:
return result;
}
-static int uses_remote_tracking(struct transport *transport, struct refspec *rs)
-{
- if (!remote_is_configured(transport->remote, 0))
- return 0;
-
- if (!rs->nr)
- rs = &transport->remote->fetch;
-
- for (int i = 0; i < rs->nr; i++)
- if (rs->items[i].dst)
- return 1;
-
- return 0;
-}
-
static int do_fetch(struct transport *transport,
struct refspec *rs,
const struct fetch_config *config)
@@ -1718,9 +1699,9 @@ static int do_fetch(struct transport *transport,
const struct ref *remote_refs;
struct transport_ls_refs_options transport_ls_refs_options =
TRANSPORT_LS_REFS_OPTIONS_INIT;
- int must_list_refs = 1;
struct fetch_head fetch_head = { 0 };
struct strbuf err = STRBUF_INIT;
+ int do_set_head = 0;
if (tags == TAGS_DEFAULT) {
if (transport->remote->fetch_tags == 2)
@@ -1737,28 +1718,17 @@ static int do_fetch(struct transport *transport,
}
if (rs->nr) {
- int i;
-
refspec_ref_prefixes(rs, &transport_ls_refs_options.ref_prefixes);
-
- /*
- * We can avoid listing refs if all of them are exact
- * OIDs
- */
- must_list_refs = 0;
- for (i = 0; i < rs->nr; i++) {
- if (!rs->items[i].exact_sha1) {
- must_list_refs = 1;
- break;
- }
- }
} else {
struct branch *branch = branch_get(NULL);
- if (transport->remote->fetch.nr)
+ if (transport->remote->fetch.nr) {
refspec_ref_prefixes(&transport->remote->fetch,
&transport_ls_refs_options.ref_prefixes);
- if (branch_has_merge_config(branch) &&
+ if (transport->remote->follow_remote_head != FOLLOW_REMOTE_NEVER)
+ do_set_head = 1;
+ }
+ if (branch && branch_has_merge_config(branch) &&
!strcmp(branch->remote_name, transport->remote->name)) {
int i;
for (i = 0; i < branch->merge_nr; i++) {
@@ -1766,23 +1736,29 @@ static int do_fetch(struct transport *transport,
branch->merge[i]->src);
}
}
- }
- if (tags == TAGS_SET || tags == TAGS_DEFAULT) {
- must_list_refs = 1;
- if (transport_ls_refs_options.ref_prefixes.nr)
- strvec_push(&transport_ls_refs_options.ref_prefixes,
- "refs/tags/");
- }
-
- if (uses_remote_tracking(transport, rs)) {
- must_list_refs = 1;
- if (transport_ls_refs_options.ref_prefixes.nr)
+ /*
+ * If there are no refs specified to fetch, then we just
+ * fetch HEAD; mention that to narrow the advertisement.
+ */
+ if (!transport_ls_refs_options.ref_prefixes.nr)
strvec_push(&transport_ls_refs_options.ref_prefixes,
"HEAD");
}
- if (must_list_refs) {
+ if (tags == TAGS_SET || tags == TAGS_DEFAULT)
+ strvec_push(&transport_ls_refs_options.ref_prefixes,
+ "refs/tags/");
+
+ if (do_set_head)
+ strvec_push(&transport_ls_refs_options.ref_prefixes,
+ "HEAD");
+
+ /*
+ * Only initiate ref listing if we have at least one ref we want to
+ * know about.
+ */
+ if (transport_ls_refs_options.ref_prefixes.nr) {
trace2_region_enter("fetch", "remote_refs", the_repository);
remote_refs = transport_get_remote_refs(transport,
&transport_ls_refs_options);
@@ -1867,8 +1843,15 @@ static int do_fetch(struct transport *transport,
goto cleanup;
retcode = ref_transaction_commit(transaction, &err);
- if (retcode)
+ if (retcode) {
+ /*
+ * Explicitly handle transaction cleanup to avoid
+ * aborting an already closed transaction.
+ */
+ ref_transaction_free(transaction);
+ transaction = NULL;
goto cleanup;
+ }
}
commit_fetch_head(&fetch_head);
@@ -1926,12 +1909,13 @@ static int do_fetch(struct transport *transport,
"you need to specify exactly one branch with the --set-upstream option"));
}
}
- if (set_head(remote_refs, transport->remote))
- ;
+ if (do_set_head) {
/*
- * Way too many cases where this can go wrong
- * so let's just fail silently for now.
+ * Way too many cases where this can go wrong so let's just
+ * ignore errors and fail silently for now.
*/
+ set_head(remote_refs, transport->remote);
+ }
cleanup:
if (retcode) {
@@ -2367,8 +2351,14 @@ int cmd_fetch(int argc,
OPT_SET_INT_F(0, "refetch", &refetch,
N_("re-fetch without negotiating common commits"),
1, PARSE_OPT_NONEG),
- { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
- N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
+ {
+ .type = OPTION_STRING,
+ .long_name = "submodule-prefix",
+ .value = &submodule_prefix,
+ .argh = N_("dir"),
+ .help = N_("prepend this to submodule path output"),
+ .flags = PARSE_OPT_HIDDEN,
+ },
OPT_CALLBACK_F(0, "recurse-submodules-default",
&recurse_submodules_default, N_("on-demand"),
N_("default for recursive fetching of submodules "
@@ -2570,6 +2560,7 @@ int cmd_fetch(int argc,
if (server_options.nr)
gtransport->server_options = &server_options;
result = transport_fetch_refs(gtransport, NULL);
+ gtransport->smart_options->acked_commits = NULL;
oidset_iter_init(&acked_commits, &iter);
while ((oid = oidset_iter_next(&iter)))