diff options
author | Junio C Hamano <gitster@pobox.com> | 2017-01-17 14:49:26 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-01-17 14:49:26 -0800 |
commit | 9da9965ba6672dc0016a5ac694271bbdd4589e15 (patch) | |
tree | a3fc3dbe012e0f974484b69942479954d94d0441 /transport.c | |
parent | 0f47d3d78ee2fc4c81950eeaf2c9a11b1a81bcad (diff) | |
parent | 250ab24ab3a35d5857855a2e00483dcd8867fdca (diff) | |
download | git-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.c | 29 |
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); |