Refactor submodule push check to use string list instead of integer
This allows us to tell the user which submodules have not been pushed. Additionally this is helpful when we want to automatically try to push submodules that have not been pushed. Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Heiko Voigt committed
Mar 29, 2012 at 09:21 UTC
a762e51ef2a39b0c326a1529dbe7f4cb303960db
3 files changed
+35
-15
submodule.c
+11
-12
@@ -357,21 +357,19 @@ static void collect_submodules_from_diff(struct diff_queue_struct *q,
357
void *data)
358
{
359
int i;
360
- int *needs_pushing = data;
360
+ struct string_list *needs_pushing = data;
361
362
for (i = 0; i < q->nr; i++) {
363
struct diff_filepair *p = q->queue[i];
364
if (!S_ISGITLINK(p->two->mode))
365
continue;
366
- if (submodule_needs_pushing(p->two->path, p->two->sha1)) {
367
- *needs_pushing = 1;
368
- break;
369
- }
366
+ if (submodule_needs_pushing(p->two->path, p->two->sha1))
367
+ string_list_insert(needs_pushing, p->two->path);
368
}
369
}
370
373
-
374
-static void commit_need_pushing(struct commit *commit, int *needs_pushing)
371
+static void find_unpushed_submodule_commits(struct commit *commit,
372
+ struct string_list *needs_pushing)
373
{
374
struct rev_info rev;
375
@@ -382,14 +380,15 @@ static void commit_need_pushing(struct commit *commit, int *needs_pushing)
380
diff_tree_combined_merge(commit, 1, &rev);
381
}
382
385
-int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name)
383
+int find_unpushed_submodules(unsigned char new_sha1[20],
384
+ const char *remotes_name, struct string_list *needs_pushing)
385
{
386
struct rev_info rev;
387
struct commit *commit;
388
const char *argv[] = {NULL, NULL, "--not", "NULL", NULL};
389
int argc = ARRAY_SIZE(argv) - 1;
390
char *sha1_copy;
392
- int needs_pushing = 0;
391
+
392
struct strbuf remotes_arg = STRBUF_INIT;
393
394
strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name);
@@ -401,14 +400,14 @@ int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remote
400
if (prepare_revision_walk(&rev))
401
die("revision walk setup failed");
402
404
- while ((commit = get_revision(&rev)) && !needs_pushing)
405
- commit_need_pushing(commit, &needs_pushing);
403
+ while ((commit = get_revision(&rev)) != NULL)
404
+ find_unpushed_submodule_commits(commit, needs_pushing);
405
406
reset_revision_walk();
407
free(sha1_copy);
408
strbuf_release(&remotes_arg);
409
411
- return needs_pushing;
410
+ return needs_pushing->nr;
411
}
412
413
static int is_submodule_commit_present(const char *path, unsigned char sha1[20])
submodule.h
+2
-1
@@ -29,6 +29,7 @@ int fetch_populated_submodules(int num_options, const char **options,
29
unsigned is_submodule_modified(const char *path, int ignore_untracked);
30
int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],
31
const unsigned char a[20], const unsigned char b[20], int search);
32
-int check_submodule_needs_pushing(unsigned char new_sha1[20], const char *remotes_name);
32
+int find_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name,
33
+ struct string_list *needs_pushing);
34
35
#endif
transport.c
+22
-2
@@ -11,6 +11,7 @@
11
#include "branch.h"
12
#include "url.h"
13
#include "submodule.h"
14
+#include "string-list.h"
15
16
/* rsync support */
17
@@ -1000,6 +1001,20 @@ void transport_set_verbosity(struct transport *transport, int verbosity,
1001
transport->progress = force_progress || (verbosity >= 0 && isatty(2));
1002
}
1003
1004
+static void die_with_unpushed_submodules(struct string_list *needs_pushing)
1005
+{
1006
+ int i;
1007
+
1008
+ fprintf(stderr, "The following submodule paths contain changes that can\n"
1009
+ "not be found on any remote:\n");
1010
+ for (i = 0; i < needs_pushing->nr; i++)
1011
+ printf(" %s\n", needs_pushing->items[i].string);
1012
+
1013
+ string_list_clear(needs_pushing, 0);
1014
+
1015
+ die("Aborting.");
1016
+}
1017
+
1018
int transport_push(struct transport *transport,
1019
int refspec_nr, const char **refspec, int flags,
1020
int *nonfastforward)
@@ -1040,10 +1055,15 @@ int transport_push(struct transport *transport,
1055
1056
if ((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) && !is_bare_repository()) {
1057
struct ref *ref = remote_refs;
1058
+ struct string_list needs_pushing;
1059
+
1060
+ memset(&needs_pushing, 0, sizeof(struct string_list));
1061
+ needs_pushing.strdup_strings = 1;
1062
for (; ref; ref = ref->next)
1063
if (!is_null_sha1(ref->new_sha1) &&
1045
- check_submodule_needs_pushing(ref->new_sha1,transport->remote->name))
1046
- die("There are unpushed submodules, aborting.");
1064
+ find_unpushed_submodules(ref->new_sha1,
1065
+ transport->remote->name, &needs_pushing))
1066
+ die_with_unpushed_submodules(&needs_pushing);
1067
}
1068
1069
push_ret = transport->push_refs(transport, remote_refs, flags);