Skip to content

Commit 963571a

Browse files
committed
Merge branch 'hv/submodule-not-yet-pushed-fix' (early part) into pu
* 'hv/submodule-not-yet-pushed-fix' (early part): serialize collection of refs that contain submodule changes serialize collection of changed submodules
2 parents e51cfcd + ccaa67b commit 963571a

File tree

3 files changed

+99
-29
lines changed

3 files changed

+99
-29
lines changed

submodule.c

Lines changed: 82 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -554,19 +554,38 @@ static int submodule_needs_pushing(const char *path, const unsigned char sha1[20
554554
return 0;
555555
}
556556

557+
static struct sha1_array *get_sha1s_from_list(struct string_list *submodules,
558+
const char *path)
559+
{
560+
struct string_list_item *item;
561+
struct sha1_array *hashes;
562+
563+
item = string_list_insert(submodules, path);
564+
if (item->util)
565+
return (struct sha1_array *) item->util;
566+
567+
hashes = (struct sha1_array *) xmalloc(sizeof(struct sha1_array));
568+
/* NEEDSWORK: should we add an initializer function for
569+
* sha1_array ? */
570+
memset(hashes, 0, sizeof(struct sha1_array));
571+
item->util = hashes;
572+
return hashes;
573+
}
574+
557575
static void collect_submodules_from_diff(struct diff_queue_struct *q,
558576
struct diff_options *options,
559577
void *data)
560578
{
561579
int i;
562-
struct string_list *needs_pushing = data;
580+
struct string_list *submodules = data;
563581

564582
for (i = 0; i < q->nr; i++) {
565583
struct diff_filepair *p = q->queue[i];
584+
struct sha1_array *hashes;
566585
if (!S_ISGITLINK(p->two->mode))
567586
continue;
568-
if (submodule_needs_pushing(p->two->path, p->two->oid.hash))
569-
string_list_insert(needs_pushing, p->two->path);
587+
hashes = get_sha1s_from_list(submodules, p->two->path);
588+
sha1_array_append(hashes, p->two->oid.hash);
570589
}
571590
}
572591

@@ -582,32 +601,76 @@ static void find_unpushed_submodule_commits(struct commit *commit,
582601
diff_tree_combined_merge(commit, 1, &rev);
583602
}
584603

585-
int find_unpushed_submodules(unsigned char new_sha1[20],
604+
struct collect_submodule_from_sha1s_data {
605+
char *submodule_path;
606+
struct string_list *needs_pushing;
607+
};
608+
609+
static void collect_submodules_from_sha1s(const unsigned char sha1[20],
610+
void *data)
611+
{
612+
struct collect_submodule_from_sha1s_data *me =
613+
(struct collect_submodule_from_sha1s_data *) data;
614+
615+
if (submodule_needs_pushing(me->submodule_path, sha1))
616+
string_list_insert(me->needs_pushing, me->submodule_path);
617+
}
618+
619+
static void free_submodules_sha1s(struct string_list *submodules)
620+
{
621+
int i;
622+
for (i = 0; i < submodules->nr; i++) {
623+
struct string_list_item *item = &submodules->items[i];
624+
struct sha1_array *hashes = (struct sha1_array *) item->util;
625+
sha1_array_clear(hashes);
626+
}
627+
string_list_clear(submodules, 1);
628+
}
629+
630+
static void append_hash_to_argv(const unsigned char sha1[20],
631+
void *data)
632+
{
633+
struct argv_array *argv = (struct argv_array *) data;
634+
argv_array_push(argv, sha1_to_hex(sha1));
635+
}
636+
637+
int find_unpushed_submodules(struct sha1_array *hashes,
586638
const char *remotes_name, struct string_list *needs_pushing)
587639
{
588640
struct rev_info rev;
589641
struct commit *commit;
590-
const char *argv[] = {NULL, NULL, "--not", "NULL", NULL};
591-
int argc = ARRAY_SIZE(argv) - 1;
592-
char *sha1_copy;
593-
594-
struct strbuf remotes_arg = STRBUF_INIT;
642+
int i;
643+
struct string_list submodules = STRING_LIST_INIT_DUP;
644+
struct argv_array argv = ARGV_ARRAY_INIT;
595645

596-
strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name);
597646
init_revisions(&rev, NULL);
598-
sha1_copy = xstrdup(sha1_to_hex(new_sha1));
599-
argv[1] = sha1_copy;
600-
argv[3] = remotes_arg.buf;
601-
setup_revisions(argc, argv, &rev, NULL);
647+
648+
/* argv.argv[0] will be ignored by setup_revisions */
649+
argv_array_push(&argv, "find_unpushed_submodules");
650+
sha1_array_for_each_unique(hashes, append_hash_to_argv, &argv);
651+
argv_array_push(&argv, "--not");
652+
argv_array_pushf(&argv, "--remotes=%s", remotes_name);
653+
654+
setup_revisions(argv.argc, argv.argv, &rev, NULL);
602655
if (prepare_revision_walk(&rev))
603656
die("revision walk setup failed");
604657

605658
while ((commit = get_revision(&rev)) != NULL)
606-
find_unpushed_submodule_commits(commit, needs_pushing);
659+
find_unpushed_submodule_commits(commit, &submodules);
607660

608661
reset_revision_walk();
609-
free(sha1_copy);
610-
strbuf_release(&remotes_arg);
662+
argv_array_clear(&argv);
663+
664+
for (i = 0; i < submodules.nr; i++) {
665+
struct string_list_item *item = &submodules.items[i];
666+
struct collect_submodule_from_sha1s_data data;
667+
data.submodule_path = item->string;
668+
data.needs_pushing = needs_pushing;
669+
sha1_array_for_each_unique((struct sha1_array *) item->util,
670+
collect_submodules_from_sha1s,
671+
&data);
672+
}
673+
free_submodules_sha1s(&submodules);
611674

612675
return needs_pushing->nr;
613676
}
@@ -634,12 +697,12 @@ static int push_submodule(const char *path)
634697
return 1;
635698
}
636699

637-
int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name)
700+
int push_unpushed_submodules(struct sha1_array *hashes, const char *remotes_name)
638701
{
639702
int i, ret = 1;
640703
struct string_list needs_pushing = STRING_LIST_INIT_DUP;
641704

642-
if (!find_unpushed_submodules(new_sha1, remotes_name, &needs_pushing))
705+
if (!find_unpushed_submodules(hashes, remotes_name, &needs_pushing))
643706
return 1;
644707

645708
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,
@@ -62,9 +63,9 @@ int submodule_uses_gitfile(const char *path);
6263
int ok_to_remove_submodule(const char *path);
6364
int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
6465
const unsigned char a[20], const unsigned char b[20], int search);
65-
int find_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name,
66+
int find_unpushed_submodules(struct sha1_array *hashes, const char *remotes_name,
6667
struct string_list *needs_pushing);
67-
int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name);
68+
int push_unpushed_submodules(struct sha1_array *hashes, const char *remotes_name);
6869
void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir);
6970
int parallel_submodules(void);
7071

transport.c

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

918918
if ((flags & TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND) && !is_bare_repository()) {
919919
struct ref *ref = remote_refs;
920+
struct sha1_array hashes = SHA1_ARRAY_INIT;
921+
920922
for (; ref; ref = ref->next)
921-
if (!is_null_oid(&ref->new_oid) &&
922-
!push_unpushed_submodules(ref->new_oid.hash,
923-
transport->remote->name))
924-
die ("Failed to push all needed submodules!");
923+
if (!is_null_oid(&ref->new_oid))
924+
sha1_array_append(&hashes, ref->new_oid.hash);
925+
926+
if (!push_unpushed_submodules(&hashes, transport->remote->name))
927+
die ("Failed to push all needed submodules!");
925928
}
926929

927930
if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |
928931
TRANSPORT_RECURSE_SUBMODULES_CHECK)) && !is_bare_repository()) {
929932
struct ref *ref = remote_refs;
930933
struct string_list needs_pushing = STRING_LIST_INIT_DUP;
934+
struct sha1_array hashes = SHA1_ARRAY_INIT;
931935

932936
for (; ref; ref = ref->next)
933-
if (!is_null_oid(&ref->new_oid) &&
934-
find_unpushed_submodules(ref->new_oid.hash,
935-
transport->remote->name, &needs_pushing))
936-
die_with_unpushed_submodules(&needs_pushing);
937+
if (!is_null_oid(&ref->new_oid))
938+
sha1_array_append(&hashes, ref->new_oid.hash);
939+
940+
if (find_unpushed_submodules(&hashes, transport->remote->name,
941+
&needs_pushing))
942+
die_with_unpushed_submodules(&needs_pushing);
937943
}
938944

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

0 commit comments

Comments
 (0)