{"thread":{"id":"44488","subject":"[PATCH v3 0/4] Speedup finding of unpushed submodules","startedAt":"2016-11-15T14:56:59Z","lastAt":"2016-11-16T14:29:55Z","messageCount":14,"participants":["Heiko Voigt","Stefan Beller","Brandon Williams","Junio C Hamano"],"isPatch":true,"patchVersion":3,"patchTotal":4},"messages":[{"id":"305951","messageId":"cover.1479221071.git.hvoigt@hvoigt.net","threadId":"44488","inReplyTo":null,"subject":"[PATCH v3 0/4] Speedup finding of unpushed submodules","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2016-11-15T14:56:13Z","receivedAt":"2016-11-15T14:56:59Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"You can find the second iteration of this series here:\n\nhttp://public-inbox.org/git/cover.1475851621.git.hvoigt@hvoigt.net/\n\nAll mentioned issues should be fixed. I put the NEEDSWORK comment in a\nseperate patch since it seemed to me as if we did not fully agree on\nthat. So in case we decide against it we can just drop that patch.\n\nCheers Heiko\n\nHeiko Voigt (4):\n  serialize collection of changed submodules\n  serialize collection of refs that contain submodule changes\n  batch check whether submodule needs pushing into one call\n  submodule_needs_pushing() NEEDSWORK when we can not answer this\n    question\n\n submodule.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++-------------\n submodule.h |   5 ++-\n transport.c |  29 +++++++++++----\n 3 files changed, 118 insertions(+), 36 deletions(-)\n\n-- \n2.10.1.386.gc503e45\n\n"},{"id":"305952","messageId":"0f1aaa07e151f6be87eb61b434f8c9448f8dad75.1479221071.git.hvoigt@hvoigt.net","threadId":"44488","inReplyTo":"cover.1479221071.git.hvoigt@hvoigt.net","subject":"[PATCH v3 3/4] batch check whether submodule needs pushing into one call","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2016-11-15T14:56:16Z","receivedAt":"2016-11-15T14:57:22Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"We run a command for each sha1 change in a submodule. This is\nunnecessary since we can simply batch all sha1's we want to check into\none command. Lets do it so we can speedup the check when many submodule\nchanges are in need of checking.\n\nSigned-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n---\n submodule.c | 63 ++++++++++++++++++++++++++++++++-----------------------------\n 1 file changed, 33 insertions(+), 30 deletions(-)\n\ndiff --git a/submodule.c b/submodule.c\nindex 769d666..e1196fd 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -507,27 +507,49 @@ static int append_sha1_to_argv(const unsigned char sha1[20], void *data)\n \treturn 0;\n }\n \n-static int submodule_needs_pushing(const char *path, const unsigned char sha1[20])\n+static int check_has_commit(const unsigned char sha1[20], void *data)\n {\n-\tif (add_submodule_odb(path) || !lookup_commit_reference(sha1))\n+\tint *has_commit = (int *) data;\n+\n+\tif (!lookup_commit_reference(sha1))\n+\t\t*has_commit = 0;\n+\n+\treturn 0;\n+}\n+\n+static int submodule_has_commits(const char *path, struct sha1_array *commits)\n+{\n+\tint has_commit = 1;\n+\n+\tif (add_submodule_odb(path))\n+\t\treturn 0;\n+\n+\tsha1_array_for_each_unique(commits, check_has_commit, &has_commit);\n+\treturn has_commit;\n+}\n+\n+static int submodule_needs_pushing(const char *path, struct sha1_array *commits)\n+{\n+\tif (!submodule_has_commits(path, commits))\n \t\treturn 0;\n \n \tif (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {\n \t\tstruct child_process cp = CHILD_PROCESS_INIT;\n-\t\tconst char *argv[] = {\"rev-list\", NULL, \"--not\", \"--remotes\", \"-n\", \"1\" , NULL};\n \t\tstruct strbuf buf = STRBUF_INIT;\n \t\tint needs_pushing = 0;\n \n-\t\targv[1] = sha1_to_hex(sha1);\n-\t\tcp.argv = argv;\n+\t\targv_array_push(&cp.args, \"rev-list\");\n+\t\tsha1_array_for_each_unique(commits, append_sha1_to_argv, &cp.args);\n+\t\targv_array_pushl(&cp.args, \"--not\", \"--remotes\", \"-n\", \"1\" , NULL);\n+\n \t\tprepare_submodule_repo_env(&cp.env_array);\n \t\tcp.git_cmd = 1;\n \t\tcp.no_stdin = 1;\n \t\tcp.out = -1;\n \t\tcp.dir = path;\n \t\tif (start_command(&cp))\n-\t\t\tdie(\"Could not run 'git rev-list %s --not --remotes -n 1' command in submodule %s\",\n-\t\t\t\tsha1_to_hex(sha1), path);\n+\t\t\tdie(\"Could not run 'git rev-list <commits> --not --remotes -n 1' command in submodule %s\",\n+\t\t\t\t\tpath);\n \t\tif (strbuf_read(&buf, cp.out, 41))\n \t\t\tneeds_pushing = 1;\n \t\tfinish_command(&cp);\n@@ -582,23 +604,6 @@ static void find_unpushed_submodule_commits(struct commit *commit,\n \tdiff_tree_combined_merge(commit, 1, &rev);\n }\n \n-struct collect_submodule_from_sha1s_data {\n-\tchar *submodule_path;\n-\tstruct string_list *needs_pushing;\n-};\n-\n-static int collect_submodules_from_sha1s(const unsigned char sha1[20],\n-\t\tvoid *data)\n-{\n-\tstruct collect_submodule_from_sha1s_data *me =\n-\t\t(struct collect_submodule_from_sha1s_data *) data;\n-\n-\tif (submodule_needs_pushing(me->submodule_path, sha1))\n-\t\tstring_list_insert(me->needs_pushing, me->submodule_path);\n-\n-\treturn 0;\n-}\n-\n static void free_submodules_sha1s(struct string_list *submodules)\n {\n \tstruct string_list_item *item;\n@@ -635,12 +640,10 @@ int find_unpushed_submodules(struct sha1_array *commits,\n \targv_array_clear(&argv);\n \n \tfor_each_string_list_item(submodule, &submodules) {\n-\t\tstruct collect_submodule_from_sha1s_data data;\n-\t\tdata.submodule_path = submodule->string;\n-\t\tdata.needs_pushing = needs_pushing;\n-\t\tsha1_array_for_each_unique((struct sha1_array *) submodule->util,\n-\t\t\t\tcollect_submodules_from_sha1s,\n-\t\t\t\t&data);\n+\t\tstruct sha1_array *commits = (struct sha1_array *) submodule->util;\n+\n+\t\tif (submodule_needs_pushing(submodule->string, commits))\n+\t\t\tstring_list_insert(needs_pushing, submodule->string);\n \t}\n \tfree_submodules_sha1s(&submodules);\n \n-- \n2.10.1.386.gc503e45\n\n"},{"id":"305953","messageId":"616038c9b59cfcccce180de480c2a168921b9a63.1479221071.git.hvoigt@hvoigt.net","threadId":"44488","inReplyTo":"cover.1479221071.git.hvoigt@hvoigt.net","subject":"[PATCH v3 2/4] serialize collection of refs that contain submodule changes","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2016-11-15T14:56:15Z","receivedAt":"2016-11-15T14:57:27Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"We are iterating over each pushed ref and want to check whether it\ncontains changes to submodules. Instead of immediately checking each ref\nlets first collect them and then do the check for all of them in one\nrevision walk.\n\nSigned-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n---\n submodule.c | 35 ++++++++++++++++++++---------------\n submodule.h |  5 +++--\n transport.c | 29 +++++++++++++++++++++--------\n 3 files changed, 44 insertions(+), 25 deletions(-)\n\ndiff --git a/submodule.c b/submodule.c\nindex b91585e..769d666 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -500,6 +500,13 @@ static int has_remote(const char *refname, const struct object_id *oid,\n \treturn 1;\n }\n \n+static int append_sha1_to_argv(const unsigned char sha1[20], void *data)\n+{\n+\tstruct argv_array *argv = (struct argv_array *) data;\n+\targv_array_push(argv, sha1_to_hex(sha1));\n+\treturn 0;\n+}\n+\n static int submodule_needs_pushing(const char *path, const unsigned char sha1[20])\n {\n \tif (add_submodule_odb(path) || !lookup_commit_reference(sha1))\n@@ -600,25 +607,24 @@ static void free_submodules_sha1s(struct string_list *submodules)\n \tstring_list_clear(submodules, 1);\n }\n \n-int find_unpushed_submodules(unsigned char new_sha1[20],\n+int find_unpushed_submodules(struct sha1_array *commits,\n \t\tconst char *remotes_name, struct string_list *needs_pushing)\n {\n \tstruct rev_info rev;\n \tstruct commit *commit;\n-\tconst char *argv[] = {NULL, NULL, \"--not\", \"NULL\", NULL};\n-\tint argc = ARRAY_SIZE(argv) - 1;\n-\tchar *sha1_copy;\n \tstruct string_list submodules = STRING_LIST_INIT_DUP;\n \tstruct string_list_item *submodule;\n+\tstruct argv_array argv = ARGV_ARRAY_INIT;\n \n-\tstruct strbuf remotes_arg = STRBUF_INIT;\n-\n-\tstrbuf_addf(&remotes_arg, \"--remotes=%s\", remotes_name);\n \tinit_revisions(&rev, NULL);\n-\tsha1_copy = xstrdup(sha1_to_hex(new_sha1));\n-\targv[1] = sha1_copy;\n-\targv[3] = remotes_arg.buf;\n-\tsetup_revisions(argc, argv, &rev, NULL);\n+\n+\t/* argv.argv[0] will be ignored by setup_revisions */\n+\targv_array_push(&argv, \"find_unpushed_submodules\");\n+\tsha1_array_for_each_unique(commits, append_sha1_to_argv, &argv);\n+\targv_array_push(&argv, \"--not\");\n+\targv_array_pushf(&argv, \"--remotes=%s\", remotes_name);\n+\n+\tsetup_revisions(argv.argc, argv.argv, &rev, NULL);\n \tif (prepare_revision_walk(&rev))\n \t\tdie(\"revision walk setup failed\");\n \n@@ -626,8 +632,7 @@ int find_unpushed_submodules(unsigned char new_sha1[20],\n \t\tfind_unpushed_submodule_commits(commit, &submodules);\n \n \treset_revision_walk();\n-\tfree(sha1_copy);\n-\tstrbuf_release(&remotes_arg);\n+\targv_array_clear(&argv);\n \n \tfor_each_string_list_item(submodule, &submodules) {\n \t\tstruct collect_submodule_from_sha1s_data data;\n@@ -664,12 +669,12 @@ static int push_submodule(const char *path)\n \treturn 1;\n }\n \n-int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name)\n+int push_unpushed_submodules(struct sha1_array *commits, const char *remotes_name)\n {\n \tint i, ret = 1;\n \tstruct string_list needs_pushing = STRING_LIST_INIT_DUP;\n \n-\tif (!find_unpushed_submodules(new_sha1, remotes_name, &needs_pushing))\n+\tif (!find_unpushed_submodules(commits, remotes_name, &needs_pushing))\n \t\treturn 1;\n \n \tfor (i = 0; i < needs_pushing.nr; i++) {\ndiff --git a/submodule.h b/submodule.h\nindex d9e197a..9454806 100644\n--- a/submodule.h\n+++ b/submodule.h\n@@ -3,6 +3,7 @@\n \n struct diff_options;\n struct argv_array;\n+struct sha1_array;\n \n enum {\n \tRECURSE_SUBMODULES_CHECK = -4,\n@@ -62,9 +63,9 @@ int submodule_uses_gitfile(const char *path);\n int ok_to_remove_submodule(const char *path);\n int merge_submodule(unsigned char result[20], const char *path, const unsigned char base[20],\n \t\t    const unsigned char a[20], const unsigned char b[20], int search);\n-int find_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name,\n+int find_unpushed_submodules(struct sha1_array *commits, const char *remotes_name,\n \t\tstruct string_list *needs_pushing);\n-int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_name);\n+int push_unpushed_submodules(struct sha1_array *commits, const char *remotes_name);\n void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir);\n int parallel_submodules(void);\n \ndiff --git a/transport.c b/transport.c\nindex d57e8de..f482869 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -949,23 +949,36 @@ int transport_push(struct transport *transport,\n \n \t\tif ((flags & TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND) && !is_bare_repository()) {\n \t\t\tstruct ref *ref = remote_refs;\n+\t\t\tstruct sha1_array commits = SHA1_ARRAY_INIT;\n+\n \t\t\tfor (; ref; ref = ref->next)\n-\t\t\t\tif (!is_null_oid(&ref->new_oid) &&\n-\t\t\t\t    !push_unpushed_submodules(ref->new_oid.hash,\n-\t\t\t\t\t    transport->remote->name))\n-\t\t\t\t    die (\"Failed to push all needed submodules!\");\n+\t\t\t\tif (!is_null_oid(&ref->new_oid))\n+\t\t\t\t\tsha1_array_append(&commits, ref->new_oid.hash);\n+\n+\t\t\tif (!push_unpushed_submodules(&commits, transport->remote->name)) {\n+\t\t\t\tsha1_array_clear(&commits);\n+\t\t\t\tdie(\"Failed to push all needed submodules!\");\n+\t\t\t}\n+\t\t\tsha1_array_clear(&commits);\n \t\t}\n \n \t\tif ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND |\n \t\t\t      TRANSPORT_RECURSE_SUBMODULES_CHECK)) && !is_bare_repository()) {\n \t\t\tstruct ref *ref = remote_refs;\n \t\t\tstruct string_list needs_pushing = STRING_LIST_INIT_DUP;\n+\t\t\tstruct sha1_array commits = SHA1_ARRAY_INIT;\n \n \t\t\tfor (; ref; ref = ref->next)\n-\t\t\t\tif (!is_null_oid(&ref->new_oid) &&\n-\t\t\t\t    find_unpushed_submodules(ref->new_oid.hash,\n-\t\t\t\t\t    transport->remote->name, &needs_pushing))\n-\t\t\t\t\tdie_with_unpushed_submodules(&needs_pushing);\n+\t\t\t\tif (!is_null_oid(&ref->new_oid))\n+\t\t\t\t\tsha1_array_append(&commits, ref->new_oid.hash);\n+\n+\t\t\tif (find_unpushed_submodules(&commits, transport->remote->name,\n+\t\t\t\t\t\t&needs_pushing)) {\n+\t\t\t\tsha1_array_clear(&commits);\n+\t\t\t\tdie_with_unpushed_submodules(&needs_pushing);\n+\t\t\t}\n+\t\t\tstring_list_clear(&needs_pushing, 0);\n+\t\t\tsha1_array_clear(&commits);\n \t\t}\n \n \t\tpush_ret = transport->push_refs(transport, remote_refs, flags);\n-- \n2.10.1.386.gc503e45\n\n"},{"id":"305954","messageId":"67e11474d4fd8ada2652809cf14f6c4d96be55ff.1479221071.git.hvoigt@hvoigt.net","threadId":"44488","inReplyTo":"cover.1479221071.git.hvoigt@hvoigt.net","subject":"[PATCH v3 1/4] serialize collection of changed submodules","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2016-11-15T14:56:14Z","receivedAt":"2016-11-15T14:57:30Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"To check whether a submodule needs to be pushed we need to collect all\nchanged submodules. Lets collect them first and then execute the\npossibly expensive test whether certain revisions are already pushed\nonly once per submodule.\n\nThere is further potential for optimization since we can assemble one\ncommand and only issued that instead of one call for each remote ref in\nthe submodule.\n\nSigned-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n---\n submodule.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----\n 1 file changed, 56 insertions(+), 4 deletions(-)\n\ndiff --git a/submodule.c b/submodule.c\nindex 6f7d883..b91585e 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -532,19 +532,34 @@ static int submodule_needs_pushing(const char *path, const unsigned char sha1[20\n \treturn 0;\n }\n \n+static struct sha1_array *submodule_commits(struct string_list *submodules,\n+\t\t\t\t\t    const char *path)\n+{\n+\tstruct string_list_item *item;\n+\n+\titem = string_list_insert(submodules, path);\n+\tif (item->util)\n+\t\treturn (struct sha1_array *) item->util;\n+\n+\t/* NEEDSWORK: should we have sha1_array_init()? */\n+\titem->util = xcalloc(1, sizeof(struct sha1_array));\n+\treturn (struct sha1_array *) item->util;\n+}\n+\n static void collect_submodules_from_diff(struct diff_queue_struct *q,\n \t\t\t\t\t struct diff_options *options,\n \t\t\t\t\t void *data)\n {\n \tint i;\n-\tstruct string_list *needs_pushing = data;\n+\tstruct string_list *submodules = data;\n \n \tfor (i = 0; i < q->nr; i++) {\n \t\tstruct diff_filepair *p = q->queue[i];\n+\t\tstruct sha1_array *commits;\n \t\tif (!S_ISGITLINK(p->two->mode))\n \t\t\tcontinue;\n-\t\tif (submodule_needs_pushing(p->two->path, p->two->oid.hash))\n-\t\t\tstring_list_insert(needs_pushing, p->two->path);\n+\t\tcommits = submodule_commits(submodules, p->two->path);\n+\t\tsha1_array_append(commits, p->two->oid.hash);\n \t}\n }\n \n@@ -560,6 +575,31 @@ static void find_unpushed_submodule_commits(struct commit *commit,\n \tdiff_tree_combined_merge(commit, 1, &rev);\n }\n \n+struct collect_submodule_from_sha1s_data {\n+\tchar *submodule_path;\n+\tstruct string_list *needs_pushing;\n+};\n+\n+static int collect_submodules_from_sha1s(const unsigned char sha1[20],\n+\t\tvoid *data)\n+{\n+\tstruct collect_submodule_from_sha1s_data *me =\n+\t\t(struct collect_submodule_from_sha1s_data *) data;\n+\n+\tif (submodule_needs_pushing(me->submodule_path, sha1))\n+\t\tstring_list_insert(me->needs_pushing, me->submodule_path);\n+\n+\treturn 0;\n+}\n+\n+static void free_submodules_sha1s(struct string_list *submodules)\n+{\n+\tstruct string_list_item *item;\n+\tfor_each_string_list_item(item, submodules)\n+\t\tsha1_array_clear((struct sha1_array *) item->util);\n+\tstring_list_clear(submodules, 1);\n+}\n+\n int find_unpushed_submodules(unsigned char new_sha1[20],\n \t\tconst char *remotes_name, struct string_list *needs_pushing)\n {\n@@ -568,6 +608,8 @@ int find_unpushed_submodules(unsigned char new_sha1[20],\n \tconst char *argv[] = {NULL, NULL, \"--not\", \"NULL\", NULL};\n \tint argc = ARRAY_SIZE(argv) - 1;\n \tchar *sha1_copy;\n+\tstruct string_list submodules = STRING_LIST_INIT_DUP;\n+\tstruct string_list_item *submodule;\n \n \tstruct strbuf remotes_arg = STRBUF_INIT;\n \n@@ -581,12 +623,22 @@ int find_unpushed_submodules(unsigned char new_sha1[20],\n \t\tdie(\"revision walk setup failed\");\n \n \twhile ((commit = get_revision(&rev)) != NULL)\n-\t\tfind_unpushed_submodule_commits(commit, needs_pushing);\n+\t\tfind_unpushed_submodule_commits(commit, &submodules);\n \n \treset_revision_walk();\n \tfree(sha1_copy);\n \tstrbuf_release(&remotes_arg);\n \n+\tfor_each_string_list_item(submodule, &submodules) {\n+\t\tstruct collect_submodule_from_sha1s_data data;\n+\t\tdata.submodule_path = submodule->string;\n+\t\tdata.needs_pushing = needs_pushing;\n+\t\tsha1_array_for_each_unique((struct sha1_array *) submodule->util,\n+\t\t\t\tcollect_submodules_from_sha1s,\n+\t\t\t\t&data);\n+\t}\n+\tfree_submodules_sha1s(&submodules);\n+\n \treturn needs_pushing->nr;\n }\n \n-- \n2.10.1.386.gc503e45\n\n"},{"id":"305955","messageId":"1d87628994df89751afdcc7e180ebcdc29dde722.1479221071.git.hvoigt@hvoigt.net","threadId":"44488","inReplyTo":"cover.1479221071.git.hvoigt@hvoigt.net","subject":"[PATCH v3 4/4] submodule_needs_pushing() NEEDSWORK when we can not answer this question","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2016-11-15T14:56:17Z","receivedAt":"2016-11-15T14:57:33Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n---\n submodule.c | 8 ++++++++\n 1 file changed, 8 insertions(+)\n\ndiff --git a/submodule.c b/submodule.c\nindex e1196fd..29efee9 100644\n--- a/submodule.c\n+++ b/submodule.c\n@@ -531,6 +531,14 @@ static int submodule_has_commits(const char *path, struct sha1_array *commits)\n static int submodule_needs_pushing(const char *path, struct sha1_array *commits)\n {\n \tif (!submodule_has_commits(path, commits))\n+\t\t/* NEEDSWORK: The correct answer here is \"We do not\n+\t\t * know\" instead of \"No push needed\". We currently\n+\t\t * proceed pushing here as if the submodules commits are\n+\t\t * available on a remote. Since we can not check the\n+\t\t * remote availability for this submodule we should\n+\t\t * consider changing this behavior to: Stop here and\n+\t\t * tell the user how to skip this check if wanted.\n+\t\t */\n \t\treturn 0;\n \n \tif (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {\n-- \n2.10.1.386.gc503e45\n\n"},{"id":"305969","messageId":"CAGZ79kawQOO98GFYZBnUhN_A8jKDVopTDHMjsM=rrG_5ekyidQ@mail.gmail.com","threadId":"44488","inReplyTo":"cover.1479221071.git.hvoigt@hvoigt.net","subject":"Re: [PATCH v3 0/4] Speedup finding of unpushed submodules","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-15T17:43:27Z","receivedAt":"2016-11-15T17:43:49Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Nov 15, 2016 at 6:56 AM, Heiko Voigt <hvoigt@hvoigt.net> wrote:\n> You can find the second iteration of this series here:\n>\n> http://public-inbox.org/git/cover.1475851621.git.hvoigt@hvoigt.net/\n>\n> All mentioned issues should be fixed. I put the NEEDSWORK comment in a\n> seperate patch since it seemed to me as if we did not fully agree on\n> that. So in case we decide against it we can just drop that patch.\n>\n> Cheers Heiko\n>\n\n+cc Brandon who started building a series on top of yours.\n"},{"id":"305970","messageId":"20161115175231.GB66382@google.com","threadId":"44488","inReplyTo":"CAGZ79kawQOO98GFYZBnUhN_A8jKDVopTDHMjsM=rrG_5ekyidQ@mail.gmail.com","subject":"Re: [PATCH v3 0/4] Speedup finding of unpushed submodules","fromName":"Brandon Williams","fromEmail":"bmwill@google.com","sentAt":"2016-11-15T17:52:31Z","receivedAt":"2016-11-15T17:52:39Z","isPatch":true,"sender":{"key":"bwilliams.eng@gmail.com","avatar":null},"body":"On 11/15, Stefan Beller wrote:\n> On Tue, Nov 15, 2016 at 6:56 AM, Heiko Voigt <hvoigt@hvoigt.net> wrote:\n> > You can find the second iteration of this series here:\n> >\n> > http://public-inbox.org/git/cover.1475851621.git.hvoigt@hvoigt.net/\n> >\n> > All mentioned issues should be fixed. I put the NEEDSWORK comment in a\n> > seperate patch since it seemed to me as if we did not fully agree on\n> > that. So in case we decide against it we can just drop that patch.\n> >\n> > Cheers Heiko\n> >\n> \n> +cc Brandon who started building a series on top of yours.\n\nI don't think there should be too much I'll have to change with my\nseries, I'll just rebase against these changes once Junio updates his\nbranch.\n\nIf you want to take a look at my series its here:\nhttps://public-inbox.org/git/1479172735-698-1-git-send-email-bmwill@google.com/\n\nThanks for the heads up Stefan.\n\n-- \nBrandon Williams\n"},{"id":"305989","messageId":"CAGZ79kYBf_B4ZQ7CoTt62ZR-qXhHNBEWem5K-r1eOPrUPYufrw@mail.gmail.com","threadId":"44488","inReplyTo":"67e11474d4fd8ada2652809cf14f6c4d96be55ff.1479221071.git.hvoigt@hvoigt.net","subject":"Re: [PATCH v3 1/4] serialize collection of changed submodules","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-15T22:15:31Z","receivedAt":"2016-11-15T22:15:38Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Nov 15, 2016 at 6:56 AM, Heiko Voigt <hvoigt@hvoigt.net> wrote:\n\n> @@ -560,6 +575,31 @@ static void find_unpushed_submodule_commits(struct commit *commit,\n>         diff_tree_combined_merge(commit, 1, &rev);\n>  }\n>\n> +struct collect_submodule_from_sha1s_data {\n> +       char *submodule_path;\n> +       struct string_list *needs_pushing;\n> +};\n> +\n> +static int collect_submodules_from_sha1s(const unsigned char sha1[20],\n> +               void *data)\n> +{\n> +       struct collect_submodule_from_sha1s_data *me =\n> +               (struct collect_submodule_from_sha1s_data *) data;\n\nnit: no explicit cast needed when coming from void* ?\n"},{"id":"305990","messageId":"CAGZ79kY4aA-vx+qfiACd9NOtao4q02PxZgw-Yq+JMuAz_cqLvw@mail.gmail.com","threadId":"44488","inReplyTo":"616038c9b59cfcccce180de480c2a168921b9a63.1479221071.git.hvoigt@hvoigt.net","subject":"Re: [PATCH v3 2/4] serialize collection of refs that contain submodule changes","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-15T22:20:39Z","receivedAt":"2016-11-15T22:20:44Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Nov 15, 2016 at 6:56 AM, Heiko Voigt <hvoigt@hvoigt.net> wrote:\n\n> +++ b/submodule.c\n> @@ -500,6 +500,13 @@ static int has_remote(const char *refname, const struct object_id *oid,\n>         return 1;\n>  }\n>\n> +static int append_sha1_to_argv(const unsigned char sha1[20], void *data)\n> +{\n> +       struct argv_array *argv = (struct argv_array *) data;\n\nnit: no explicit cast needed when coming from a void pointer.\n"},{"id":"305991","messageId":"CAGZ79kZtQG5pE-6N-1yZKA95VRmrDRB3PnSd1gtqBM9fxD48Cg@mail.gmail.com","threadId":"44488","inReplyTo":"0f1aaa07e151f6be87eb61b434f8c9448f8dad75.1479221071.git.hvoigt@hvoigt.net","subject":"Re: [PATCH v3 3/4] batch check whether submodule needs pushing into one call","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-15T22:28:31Z","receivedAt":"2016-11-15T22:28:38Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Nov 15, 2016 at 6:56 AM, Heiko Voigt <hvoigt@hvoigt.net> wrote:\n\n> -static int submodule_needs_pushing(const char *path, const unsigned char sha1[20])\n> +static int check_has_commit(const unsigned char sha1[20], void *data)\n>  {\n> -       if (add_submodule_odb(path) || !lookup_commit_reference(sha1))\n> +       int *has_commit = (int *) data;\n\nnit: just as prior patches ;) void* can be cast implicitly.\n"},{"id":"305992","messageId":"CAGZ79kYyyjP7W7gWq6WomVSkhRtMbZZMKYQPFszko4_f9oprgg@mail.gmail.com","threadId":"44488","inReplyTo":"1d87628994df89751afdcc7e180ebcdc29dde722.1479221071.git.hvoigt@hvoigt.net","subject":"Re: [PATCH v3 4/4] submodule_needs_pushing() NEEDSWORK when we can not answer this question","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-15T22:39:10Z","receivedAt":"2016-11-15T22:39:35Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Nov 15, 2016 at 6:56 AM, Heiko Voigt <hvoigt@hvoigt.net> wrote:\n> Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n> ---\n>  submodule.c | 8 ++++++++\n>  1 file changed, 8 insertions(+)\n>\n> diff --git a/submodule.c b/submodule.c\n> index e1196fd..29efee9 100644\n> --- a/submodule.c\n> +++ b/submodule.c\n> @@ -531,6 +531,14 @@ static int submodule_has_commits(const char *path, struct sha1_array *commits)\n>  static int submodule_needs_pushing(const char *path, struct sha1_array *commits)\n>  {\n>         if (!submodule_has_commits(path, commits))\n> +               /* NEEDSWORK: The correct answer here is \"We do not\n\nstyle nit:\n/*\n * Usually we prefer comments with both the first and last line of the\ncomment \"empty\".\n */\n/* or just a one liner */\n\nAFAICT these are the only two modes that we prefer in Git.\nFor a discussion of all the other style, enjoy Linus' guidance. ;)\nhttp://lkml.iu.edu/hypermail/linux/kernel/1607.1/00627.html\n\n\n> \"We do not know\" ...\n\n... because there is no way to check for us as we don't have the\nsubmodule commits.\n\n    \" We do consider it safe as no one in their sane mind would\n    have changed the submodule pointers without having the\n    submodule around. If a user did however change the submodules\n    without having the submodule commits around, this indicates an\n    expert who knows what they were doing.\"\n\n\n\n\n>   We currently\n> +                * proceed pushing here as if the submodules commits are\n> +                * available on a remote. Since we can not check the\n> +                * remote availability for this submodule we should\n> +                * consider changing this behavior to: Stop here and\n> +                * tell the user how to skip this check if wanted.\n> +                */\n>                 return 0;\n\nThanks for adding the NEEDSWORK, I just wrote the above lines\nto clarify my thought process, not as a suggestion for change.\n\nOverall the series looks good to me; the nits are minor IMHO.\n\nThanks,\nStefan\n"},{"id":"306021","messageId":"xmqqtwb8s2m8.fsf@gitster.mtv.corp.google.com","threadId":"44488","inReplyTo":"CAGZ79kYyyjP7W7gWq6WomVSkhRtMbZZMKYQPFszko4_f9oprgg@mail.gmail.com","subject":"Re: [PATCH v3 4/4] submodule_needs_pushing() NEEDSWORK when we can not answer this question","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-11-16T00:13:51Z","receivedAt":"2016-11-16T00:14:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n>> \"We do not know\" ...\n>\n> ... because there is no way to check for us as we don't have the\n> submodule commits.\n>\n>     \" We do consider it safe as no one in their sane mind would\n>     have changed the submodule pointers without having the\n>     submodule around. If a user did however change the submodules\n>     without having the submodule commits around, this indicates an\n>     expert who knows what they were doing.\"\n\nI didn't think it through myself to arrive at such a conclusion, but\nto me the above sounds like a sensible reasoning [*1*].\n\n>>   We currently\n>> +                * proceed pushing here as if the submodules commits are\n>> +                * available on a remote. Since we can not check the\n>> +                * remote availability for this submodule we should\n>> +                * consider changing this behavior to: Stop here and\n>> +                * tell the user how to skip this check if wanted.\n>> +                */\n>>                 return 0;\n>\n> Thanks for adding the NEEDSWORK, I just wrote the above lines\n> to clarify my thought process, not as a suggestion for change.\n\nOne thing I would suggest would be \"Stop here, explain the situation\nand then tell the user how to skip\".  I am not convinced that it\nwould _help_ users and make it _safer_ if we stopped here, though.\n\n> Overall the series looks good to me; the nits are minor IMHO.\n\nDitto.\n\n\n[Footnote]\n\n*1* My version was more like \"we do not know if they would get into\n    a situation where they do not have enough submodule commits if\n    we pushed our superproject, but more importantly, we DO KNOW\n    that it would not help an iota if we pushed our submodule to\n    them, so there is no point stopping the push of superproject\n    saying 'no, no, no, you must push the submodule first'\".\n"},{"id":"306046","messageId":"20161116142649.GA32087@book.hvoigt.net","threadId":"44488","inReplyTo":"xmqqtwb8s2m8.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v3 4/4] submodule_needs_pushing() NEEDSWORK when we can not answer this question","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2016-11-16T14:26:49Z","receivedAt":"2016-11-16T14:27:05Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Tue, Nov 15, 2016 at 04:13:51PM -0800, Junio C Hamano wrote:\n> Stefan Beller <sbeller@google.com> writes:\n> \n> >> \"We do not know\" ...\n> >\n> > ... because there is no way to check for us as we don't have the\n> > submodule commits.\n> >\n> >     \" We do consider it safe as no one in their sane mind would\n> >     have changed the submodule pointers without having the\n> >     submodule around. If a user did however change the submodules\n> >     without having the submodule commits around, this indicates an\n> >     expert who knows what they were doing.\"\n> \n> I didn't think it through myself to arrive at such a conclusion, but\n> to me the above sounds like a sensible reasoning [*1*].\n\nI think you have a point here. If I rephrase it like this: \"We do\nconsider it safe as no one in their sane mind *could* have changed the\nsubmodule pointers without having the submodule around...\"\n\nSince its actually hard to create such a situation without the submodule\ncommit around I agree here.\n\n> *1* My version was more like \"we do not know if they would get into\n>     a situation where they do not have enough submodule commits if\n>     we pushed our superproject, but more importantly, we DO KNOW\n>     that it would not help an iota if we pushed our submodule to\n>     them, so there is no point stopping the push of superproject\n>     saying 'no, no, no, you must push the submodule first'\".\n\nYes saying that would be wrong. I was rather suggesting that we tell the\nuser that we could not find the submodule commits to and that if he\nwants to proceed he should either pass --recurse-submodules=no or\ninitialize the submodule.\n\nBut I think the above reasoning obsoletes my suggestion. I would adjust\nthe comment accordingly but still keep the patch so we have\ndocumentation that this behavior is on purpose.\n\nCheers Heiko\n"},{"id":"306047","messageId":"20161116142930.GB32087@book.hvoigt.net","threadId":"44488","inReplyTo":"CAGZ79kZtQG5pE-6N-1yZKA95VRmrDRB3PnSd1gtqBM9fxD48Cg@mail.gmail.com","subject":"Re: [PATCH v3 3/4] batch check whether submodule needs pushing into one call","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2016-11-16T14:29:30Z","receivedAt":"2016-11-16T14:29:55Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"On Tue, Nov 15, 2016 at 02:28:31PM -0800, Stefan Beller wrote:\n> On Tue, Nov 15, 2016 at 6:56 AM, Heiko Voigt <hvoigt@hvoigt.net> wrote:\n> \n> > -static int submodule_needs_pushing(const char *path, const unsigned char sha1[20])\n> > +static int check_has_commit(const unsigned char sha1[20], void *data)\n> >  {\n> > -       if (add_submodule_odb(path) || !lookup_commit_reference(sha1))\n> > +       int *has_commit = (int *) data;\n> \n> nit: just as prior patches ;) void* can be cast implicitly.\n\nEven though its just a nit: Will remove all the void casts. :)\n\nCheers Heiko\n"}]}