Skip to content

Commit ccaa67b

Browse files
hvoigtgitster
authored andcommitted
serialize collection of refs that contain submodule changes
We are iterating over each pushed ref and want to check whether it contains changes to submodules. Instead of immediately checking each ref lets first collect them and then do the check for all of them in one revision walk. Signed-off-by: Heiko Voigt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7cc85e4 commit ccaa67b

File tree

3 files changed

+38
-25
lines changed

3 files changed

+38
-25
lines changed

submodule.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -507,33 +507,39 @@ static void free_submodules_sha1s(struct string_list *submodules)
507507
string_list_clear(submodules, 1);
508508
}
509509

510-
int find_unpushed_submodules(unsigned char new_sha1[20],
510+
static void append_hash_to_argv(const unsigned char sha1[20],
511+
void *data)
512+
{
513+
struct argv_array *argv = (struct argv_array *) data;
514+
argv_array_push(argv, sha1_to_hex(sha1));
515+
}
516+
517+
int find_unpushed_submodules(struct sha1_array *hashes,
511518
const char *remotes_name, struct string_list *needs_pushing)
512519
{
513520
struct rev_info rev;
514521
struct commit *commit;
515-
const char *argv[] = {NULL, NULL, "--not", "NULL", NULL};
516-
int argc = ARRAY_SIZE(argv) - 1, i;
517-
char *sha1_copy;
522+
int i;
518523
struct string_list submodules = STRING_LIST_INIT_DUP;
524+
struct argv_array argv = ARGV_ARRAY_INIT;
519525

520-
struct strbuf remotes_arg = STRBUF_INIT;
521-
522-
strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name);
523526
init_revisions(&rev, NULL);
524-
sha1_copy = xstrdup(sha1_to_hex(new_sha1));
525-
argv[1] = sha1_copy;
526-
argv[3] = remotes_arg.buf;
527-
setup_revisions(argc, argv, &rev, NULL);
527+
528+
/* argv.argv[0] will be ignored by setup_revisions */
529+
argv_array_push(&argv, "find_unpushed_submodules");
530+
sha1_array_for_each_unique(hashes, append_hash_to_argv, &argv);
531+
argv_array_push(&argv, "--not");
532+
argv_array_pushf(&argv, "--remotes=%s", remotes_name);
533+
534+
setup_revisions(argv.argc, argv.argv, &rev, NULL);
528535
if (prepare_revision_walk(&rev))
529536
die("revision walk setup failed");
530537

531538
while ((commit = get_revision(&rev)) != NULL)
532539
find_unpushed_submodule_commits(commit, &submodules);
533540

534541
reset_revision_walk();
535-
free(sha1_copy);
536-
strbuf_release(&remotes_arg);
542+
argv_array_clear(&argv);
537543

538544
for (i = 0; i < submodules.nr; i++) {
539545
struct string_list_item *item = &submodules.items[i];
@@ -571,12 +577,12 @@ static int push_submodule(const char *path)
571577
return 1;
572578
}
573579

574-
int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name)
580+
int push_unpushed_submodules(struct sha1_array *hashes, const char *remotes_name)
575581
{
576582
int i, ret = 1;
577583
struct string_list needs_pushing = STRING_LIST_INIT_DUP;
578584

579-
if (!find_unpushed_submodules(new_sha1, remotes_name, &needs_pushing))
585+
if (!find_unpushed_submodules(hashes, remotes_name, &needs_pushing))
580586
return 1;
581587

582588
for (i = 0; i < needs_pushing.nr; i++) {

submodule.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
struct diff_options;
55
struct argv_array;
6+
struct sha1_array;
67

78
enum {
89
RECURSE_SUBMODULES_CHECK = -4,
@@ -56,9 +57,9 @@ int submodule_uses_gitfile(const char *path);
5657
int ok_to_remove_submodule(const char *path);
5758
int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
5859
const unsigned char a[20], const unsigned char b[20], int search);
59-
int find_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name,
60+
int find_unpushed_submodules(struct sha1_array *hashes, const char *remotes_name,
6061
struct string_list *needs_pushing);
61-
int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name);
62+
int push_unpushed_submodules(struct sha1_array *hashes, const char *remotes_name);
6263
void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir);
6364
int parallel_submodules(void);
6465

transport.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -903,23 +903,29 @@ int transport_push(struct transport *transport,
903903

904904
if ((flags & TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND) && !is_bare_repository()) {
905905
struct ref *ref = remote_refs;
906+
struct sha1_array hashes = SHA1_ARRAY_INIT;
907+
906908
for (; ref; ref = ref->next)
907-
if (!is_null_oid(&ref->new_oid) &&
908-
!push_unpushed_submodules(ref->new_oid.hash,
909-
transport->remote->name))
910-
die ("Failed to push all needed submodules!");
909+
if (!is_null_oid(&ref->new_oid))
910+
sha1_array_append(&hashes, ref->new_oid.hash);
911+
912+
if (!push_unpushed_submodules(&hashes, transport->remote->name))
913+
die ("Failed to push all needed submodules!");
911914
}
912915

913916
if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
914917
TRANSPORT_RECURSE_SUBMODULES_CHECK)) && !is_bare_repository()) {
915918
struct ref *ref = remote_refs;
916919
struct string_list needs_pushing = STRING_LIST_INIT_DUP;
920+
struct sha1_array hashes = SHA1_ARRAY_INIT;
917921

918922
for (; ref; ref = ref->next)
919-
if (!is_null_oid(&ref->new_oid) &&
920-
find_unpushed_submodules(ref->new_oid.hash,
921-
transport->remote->name, &needs_pushing))
922-
die_with_unpushed_submodules(&needs_pushing);
923+
if (!is_null_oid(&ref->new_oid))
924+
sha1_array_append(&hashes, ref->new_oid.hash);
925+
926+
if (find_unpushed_submodules(&hashes, transport->remote->name,
927+
&needs_pushing))
928+
die_with_unpushed_submodules(&needs_pushing);
923929
}
924930

925931
push_ret = transport->push_refs(transport, remote_refs, flags);

0 commit comments

Comments
 (0)