aboutsummaryrefslogtreecommitdiff
path: root/transport.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-12-16 15:27:47 -0800
committerJunio C Hamano <gitster@pobox.com>2016-12-16 15:27:47 -0800
commitaf952dac7a6997e587ded97e4051a927e5384423 (patch)
tree517df111bbc7fd7d0c262a3c47f20f17e265f9b2 /transport.c
parenta616162909ae756c36cef17cea7466c3f500caec (diff)
parent250ab24ab3a35d5857855a2e00483dcd8867fdca (diff)
downloadgit-af952dac7a6997e587ded97e4051a927e5384423.tar.gz
git-af952dac7a6997e587ded97e4051a927e5384423.tar.xz
Merge branch 'hv/submodule-not-yet-pushed-fix'
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 d57e8dec2..f48286905 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);