MALLOC_CHECK: various clean-ups
[gitweb.git] / transport.c
index 2dfac700b630aabb2d1014c51a08889b3a3bae82..1811b500d92b1120a01d0ac09f86c0218f3d163b 100644 (file)
@@ -11,6 +11,7 @@
 #include "branch.h"
 #include "url.h"
 #include "submodule.h"
+#include "string-list.h"
 
 /* rsync support */
 
@@ -1013,6 +1014,25 @@ void transport_set_verbosity(struct transport *transport, int verbosity,
                transport->progress = verbosity >= 0 && isatty(2);
 }
 
+static void die_with_unpushed_submodules(struct string_list *needs_pushing)
+{
+       int i;
+
+       fprintf(stderr, "The following submodule paths contain changes that can\n"
+                       "not be found on any remote:\n");
+       for (i = 0; i < needs_pushing->nr; i++)
+               printf("  %s\n", needs_pushing->items[i].string);
+       fprintf(stderr, "\nPlease try\n\n"
+                       "       git push --recurse-submodules=on-demand\n\n"
+                       "or cd to the path and use\n\n"
+                       "       git push\n\n"
+                       "to push them to a remote.\n\n");
+
+       string_list_clear(needs_pushing, 0);
+
+       die("Aborting.");
+}
+
 int transport_push(struct transport *transport,
                   int refspec_nr, const char **refspec, int flags,
                   int *nonfastforward)
@@ -1053,12 +1073,27 @@ int transport_push(struct transport *transport,
                        flags & TRANSPORT_PUSH_MIRROR,
                        flags & TRANSPORT_PUSH_FORCE);
 
-               if ((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) && !is_bare_repository()) {
+               if ((flags & TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND) && !is_bare_repository()) {
                        struct ref *ref = remote_refs;
                        for (; ref; ref = ref->next)
                                if (!is_null_sha1(ref->new_sha1) &&
-                                   check_submodule_needs_pushing(ref->new_sha1,transport->remote->name))
-                                       die("There are unpushed submodules, aborting.");
+                                   !push_unpushed_submodules(ref->new_sha1,
+                                           transport->remote->name))
+                                   die ("Failed to push all needed submodules!");
+               }
+
+               if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
+                             TRANSPORT_RECURSE_SUBMODULES_CHECK)) && !is_bare_repository()) {
+                       struct ref *ref = remote_refs;
+                       struct string_list needs_pushing;
+
+                       memset(&needs_pushing, 0, sizeof(struct string_list));
+                       needs_pushing.strdup_strings = 1;
+                       for (; ref; ref = ref->next)
+                               if (!is_null_sha1(ref->new_sha1) &&
+                                   find_unpushed_submodules(ref->new_sha1,
+                                           transport->remote->name, &needs_pushing))
+                                       die_with_unpushed_submodules(&needs_pushing);
                }
 
                push_ret = transport->push_refs(transport, remote_refs, flags);