]> git.ipfire.org Git - thirdparty/git.git/blobdiff - transport.c
clone: fix colliding file detection on APFS
[thirdparty/git.git] / transport.c
index a32da30dee6f4e38433b68d7c9f7e9404aa58858..fdd813f684f766fe22169537468402677b0eaa71 100644 (file)
@@ -151,7 +151,8 @@ static struct ref *get_refs_from_bundle(struct transport *transport,
 }
 
 static int fetch_refs_from_bundle(struct transport *transport,
-                              int nr_heads, struct ref **to_fetch)
+                              int nr_heads, struct ref **to_fetch,
+                              struct ref **fetched_refs)
 {
        struct bundle_transport_data *data = transport->data;
        return unbundle(&data->header, data->fd,
@@ -287,7 +288,8 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus
 }
 
 static int fetch_refs_via_pack(struct transport *transport,
-                              int nr_heads, struct ref **to_fetch)
+                              int nr_heads, struct ref **to_fetch,
+                              struct ref **fetched_refs)
 {
        int ret = 0;
        struct git_transport_data *data = transport->data;
@@ -348,14 +350,19 @@ static int fetch_refs_via_pack(struct transport *transport,
        data->got_remote_heads = 0;
        data->options.self_contained_and_connected =
                args.self_contained_and_connected;
+       data->options.connectivity_checked = args.connectivity_checked;
 
        if (refs == NULL)
                ret = -1;
        if (report_unmatched_refs(to_fetch, nr_heads))
                ret = -1;
 
+       if (fetched_refs)
+               *fetched_refs = refs;
+       else
+               free_refs(refs);
+
        free_refs(refs_tmp);
-       free_refs(refs);
        free(dest);
        return ret;
 }
@@ -1215,19 +1222,31 @@ const struct ref *transport_get_remote_refs(struct transport *transport,
        return transport->remote_refs;
 }
 
-int transport_fetch_refs(struct transport *transport, struct ref *refs)
+int transport_fetch_refs(struct transport *transport, struct ref *refs,
+                        struct ref **fetched_refs)
 {
        int rc;
        int nr_heads = 0, nr_alloc = 0, nr_refs = 0;
        struct ref **heads = NULL;
+       struct ref *nop_head = NULL, **nop_tail = &nop_head;
        struct ref *rm;
 
        for (rm = refs; rm; rm = rm->next) {
                nr_refs++;
                if (rm->peer_ref &&
                    !is_null_oid(&rm->old_oid) &&
-                   !oidcmp(&rm->peer_ref->old_oid, &rm->old_oid))
+                   !oidcmp(&rm->peer_ref->old_oid, &rm->old_oid)) {
+                       /*
+                        * These need to be reported as fetched, but we don't
+                        * actually need to fetch them.
+                        */
+                       if (fetched_refs) {
+                               struct ref *nop_ref = copy_ref(rm);
+                               *nop_tail = nop_ref;
+                               nop_tail = &nop_ref->next;
+                       }
                        continue;
+               }
                ALLOC_GROW(heads, nr_heads + 1, nr_alloc);
                heads[nr_heads++] = rm;
        }
@@ -1245,7 +1264,11 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
                        heads[nr_heads++] = rm;
        }
 
-       rc = transport->vtable->fetch(transport, nr_heads, heads);
+       rc = transport->vtable->fetch(transport, nr_heads, heads, fetched_refs);
+       if (fetched_refs && nop_head) {
+               *nop_tail = *fetched_refs;
+               *fetched_refs = nop_head;
+       }
 
        free(heads);
        return rc;