summaryrefslogtreecommitdiff
path: root/transport.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2017-01-17 14:49:26 -0800
committerJunio C Hamano <gitster@pobox.com>2017-01-17 14:49:26 -0800
commit9da9965ba6672dc0016a5ac694271bbdd4589e15 (patch)
treea3fc3dbe012e0f974484b69942479954d94d0441 /transport.c
parent0f47d3d78ee2fc4c81950eeaf2c9a11b1a81bcad (diff)
parent250ab24ab3a35d5857855a2e00483dcd8867fdca (diff)
downloadgit-9da9965ba6672dc0016a5ac694271bbdd4589e15.tar.gz
Merge branch 'hv/submodule-not-yet-pushed-fix' into maint
The code in "git push" to compute if any commit being pushed in the superproject binds a commit in a submodule that hasn't been pushed out was overly inefficient, making it unusable even for a small project that does not have any submodule but have a reasonable number of refs. * hv/submodule-not-yet-pushed-fix: submodule_needs_pushing(): explain the behaviour when we cannot answer batch check whether submodule needs pushing into one call serialize collection of refs that contain submodule changes serialize collection of changed submodules
Diffstat (limited to 'transport.c')
-rw-r--r--transport.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/transport.c b/transport.c
index d57e8dec28..f482869057 100644
--- a/transport.c
+++ b/transport.c
@@ -949,23 +949,36 @@ int transport_push(struct transport *transport,
if ((flags & TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND) && !is_bare_repository()) {
struct ref *ref = remote_refs;
+ struct sha1_array commits = SHA1_ARRAY_INIT;
+
for (; ref; ref = ref->next)
- if (!is_null_oid(&ref->new_oid) &&
- !push_unpushed_submodules(ref->new_oid.hash,
- transport->remote->name))
- die ("Failed to push all needed submodules!");
+ if (!is_null_oid(&ref->new_oid))
+ sha1_array_append(&commits, ref->new_oid.hash);
+
+ if (!push_unpushed_submodules(&commits, transport->remote->name)) {
+ sha1_array_clear(&commits);
+ die("Failed to push all needed submodules!");
+ }
+ sha1_array_clear(&commits);
}
if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
TRANSPORT_RECURSE_SUBMODULES_CHECK)) && !is_bare_repository()) {
struct ref *ref = remote_refs;
struct string_list needs_pushing = STRING_LIST_INIT_DUP;
+ struct sha1_array commits = SHA1_ARRAY_INIT;
for (; ref; ref = ref->next)
- if (!is_null_oid(&ref->new_oid) &&
- find_unpushed_submodules(ref->new_oid.hash,
- transport->remote->name, &needs_pushing))
- die_with_unpushed_submodules(&needs_pushing);
+ if (!is_null_oid(&ref->new_oid))
+ sha1_array_append(&commits, ref->new_oid.hash);
+
+ if (find_unpushed_submodules(&commits, transport->remote->name,
+ &needs_pushing)) {
+ sha1_array_clear(&commits);
+ die_with_unpushed_submodules(&needs_pushing);
+ }
+ string_list_clear(&needs_pushing, 0);
+ sha1_array_clear(&commits);
}
push_ret = transport->push_refs(transport, remote_refs, flags);