git@vger.kernel.org mailing list mirror (one of many)
 help / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
						download: 
* [PATCH 4/7] builtin/submodule--helper: store update_clone information in a struct
      [irrelevant] <20180803222322.261813-1-sbeller@google.com>
@ 2018-08-03 22:23 ` Stefan Beller
  2018-08-03 22:23 ` [PATCH 5/7] builtin/submodule--helper: factor out method to update a single submodule Stefan Beller
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-03 22:23 UTC (permalink / raw)
  To: git; +Cc: gitster, Stefan Beller

The information that is printed for update_submodules in
'submodule--helper update-clone' and consumed by 'git submodule update'
is stored as a string per submodule. This made sense at the time of
48308681b07 (git submodule update: have a dedicated helper for cloning,
2016-02-29), but as we want to migrate the rest of the submodule update
into C, we're better off having access to the raw information in a helper
struct.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/submodule--helper.c | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 32f00ca6f87..40b94dd622e 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1446,6 +1446,12 @@ static int module_clone(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+struct update_clone_data {
+	const struct submodule *sub;
+	struct object_id oid;
+	unsigned just_cloned;
+};
+
 struct submodule_update_clone {
 	/* index into 'list', the list of submodules to look into for cloning */
 	int current;
@@ -1465,8 +1471,9 @@ struct submodule_update_clone {
 	const char *recursive_prefix;
 	const char *prefix;
 
-	/* Machine-readable status lines to be consumed by git-submodule.sh */
-	struct string_list projectlines;
+	/* to be consumed by git-submodule.sh */
+	struct update_clone_data *update_clone;
+	int update_clone_nr; int update_clone_alloc;
 
 	/* If we want to stop as fast as possible and return an error */
 	unsigned quickstop : 1;
@@ -1480,7 +1487,7 @@ struct submodule_update_clone {
 #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
 	SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
 	NULL, NULL, NULL, \
-	STRING_LIST_INIT_DUP, 0, NULL, 0, 0}
+	NULL, 0, 0, 0, NULL, 0, 0, 0}
 
 
 static void next_submodule_warn_missing(struct submodule_update_clone *suc,
@@ -1574,10 +1581,12 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	strbuf_addf(&sb, "%s/.git", ce->name);
 	needs_cloning = !file_exists(sb.buf);
 
-	strbuf_reset(&sb);
-	strbuf_addf(&sb, "dummy %s %d\t%s\n",
-		    oid_to_hex(&ce->oid), needs_cloning, ce->name);
-	string_list_append(&suc->projectlines, sb.buf);
+	ALLOC_GROW(suc->update_clone, suc->update_clone_nr + 1,
+		   suc->update_clone_alloc);
+	oidcpy(&suc->update_clone[suc->update_clone_nr].oid, &ce->oid);
+	suc->update_clone[suc->update_clone_nr].just_cloned = needs_cloning;
+	suc->update_clone[suc->update_clone_nr].sub = sub;
+	suc->update_clone_nr++;
 
 	if (!needs_cloning)
 		goto cleanup;
@@ -1720,7 +1729,8 @@ static int git_update_clone_config(const char *var, const char *value,
 
 static int update_submodules(struct submodule_update_clone *suc)
 {
-	struct string_list_item *item;
+	int i;
+	struct strbuf sb = STRBUF_INIT;
 
 	run_processes_parallel(suc->max_jobs,
 			       update_clone_get_next_task,
@@ -1739,9 +1749,16 @@ static int update_submodules(struct submodule_update_clone *suc)
 	if (suc->quickstop)
 		return 1;
 
-	for_each_string_list_item(item, &suc->projectlines)
-		fprintf(stdout, "%s", item->string);
+	for (i = 0; i < suc->update_clone_nr; i++) {
+		strbuf_addf(&sb, "dummy %s %d\t%s\n",
+			oid_to_hex(&suc->update_clone[i].oid),
+			suc->update_clone[i].just_cloned,
+			suc->update_clone[i].sub->path);
+		fprintf(stdout, "%s", sb.buf);
+		strbuf_reset(&sb);
+	}
 
+	strbuf_release(&sb);
 	return 0;
 }
 
-- 
2.18.0.132.g195c49a2227


^ permalink raw reply	[relevance 20%]

* [PATCH 5/7] builtin/submodule--helper: factor out method to update a single submodule
      [irrelevant] <20180803222322.261813-1-sbeller@google.com>
  2018-08-03 22:23 ` [PATCH 4/7] builtin/submodule--helper: store update_clone information in a struct Stefan Beller
@ 2018-08-03 22:23 ` Stefan Beller
  2018-08-03 22:23 ` [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree Stefan Beller
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-03 22:23 UTC (permalink / raw)
  To: git; +Cc: gitster, Stefan Beller

In a later patch we'll find this method handy.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/submodule--helper.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 40b94dd622e..8b1088ab58a 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1727,10 +1727,17 @@ static int git_update_clone_config(const char *var, const char *value,
 	return 0;
 }
 
+static void update_submodule(struct update_clone_data *ucd)
+{
+	fprintf(stdout, "dummy %s %d\t%s\n",
+		oid_to_hex(&ucd->oid),
+		ucd->just_cloned,
+		ucd->sub->path);
+}
+
 static int update_submodules(struct submodule_update_clone *suc)
 {
 	int i;
-	struct strbuf sb = STRBUF_INIT;
 
 	run_processes_parallel(suc->max_jobs,
 			       update_clone_get_next_task,
@@ -1749,16 +1756,9 @@ static int update_submodules(struct submodule_update_clone *suc)
 	if (suc->quickstop)
 		return 1;
 
-	for (i = 0; i < suc->update_clone_nr; i++) {
-		strbuf_addf(&sb, "dummy %s %d\t%s\n",
-			oid_to_hex(&suc->update_clone[i].oid),
-			suc->update_clone[i].just_cloned,
-			suc->update_clone[i].sub->path);
-		fprintf(stdout, "%s", sb.buf);
-		strbuf_reset(&sb);
-	}
+	for (i = 0; i < suc->update_clone_nr; i++)
+		update_submodule(&suc->update_clone[i]);
 
-	strbuf_release(&sb);
 	return 0;
 }
 
-- 
2.18.0.132.g195c49a2227


^ permalink raw reply	[relevance 13%]

* [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
      [irrelevant] <20180803222322.261813-1-sbeller@google.com>
  2018-08-03 22:23 ` [PATCH 4/7] builtin/submodule--helper: store update_clone information in a struct Stefan Beller
  2018-08-03 22:23 ` [PATCH 5/7] builtin/submodule--helper: factor out method to update a single submodule Stefan Beller
@ 2018-08-03 22:23 ` Stefan Beller
  2018-08-10 21:47   ` Brandon Williams
  2018-08-03 22:23 ` [PATCH 7/7] submodule--helper: introduce new update-module-mode helper Stefan Beller
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-03 22:23 UTC (permalink / raw)
  To: git; +Cc: gitster, Stefan Beller

e98317508c0 (submodule: ensure core.worktree is set after update,
2018-06-18) was overly aggressive in calling connect_work_tree_and_git_dir
as that ensures both the 'core.worktree' configuration is set as well as
setting up correct gitlink file pointing at the git directory.

We do not need to check for the gitlink in this part of the cmd_update
in git-submodule.sh, as the initial call to update-clone will have ensured
that. So we can reduce the work to only (check and potentially) set the
'core.worktree' setting.

While at it move the check from shell to C as that proves to be useful in
a follow up patch, as we do not need the 'name' in shell now.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 64 +++++++++++++++++++++++--------------
 git-submodule.sh            |  7 ++--
 2 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 8b1088ab58a..e7635d5d9ab 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1964,6 +1964,45 @@ static int push_check(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
+{
+	const struct submodule *sub;
+	const char *path;
+	char *cw;
+	struct repository subrepo;
+
+	if (argc != 2)
+		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
+
+	path = argv[1];
+
+	sub = submodule_from_path(the_repository, &null_oid, path);
+	if (!sub)
+		BUG("We could get the submodule handle before?");
+
+	if (repo_submodule_init(&subrepo, the_repository, path))
+		die(_("could not get a repository handle for submodule '%s'"), path);
+
+	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
+		char *cfg_file, *abs_path;
+		const char *rel_path;
+		struct strbuf sb = STRBUF_INIT;
+
+		cfg_file = xstrfmt("%s/config", subrepo.gitdir);
+
+		abs_path = absolute_pathdup(path);
+		rel_path = relative_path(abs_path, subrepo.gitdir, &sb);
+
+		git_config_set_in_file(cfg_file, "core.worktree", rel_path);
+
+		free(cfg_file);
+		free(abs_path);
+		strbuf_release(&sb);
+	}
+
+	return 0;
+}
+
 static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
 {
 	int i;
@@ -2029,29 +2068,6 @@ static int check_name(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
-static int connect_gitdir_workingtree(int argc, const char **argv, const char *prefix)
-{
-	struct strbuf sb = STRBUF_INIT;
-	const char *name, *path;
-	char *sm_gitdir;
-
-	if (argc != 3)
-		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
-
-	name = argv[1];
-	path = argv[2];
-
-	strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
-	sm_gitdir = absolute_pathdup(sb.buf);
-
-	connect_work_tree_and_git_dir(path, sm_gitdir, 0);
-
-	strbuf_release(&sb);
-	free(sm_gitdir);
-
-	return 0;
-}
-
 #define SUPPORT_SUPER_PREFIX (1<<0)
 
 struct cmd_struct {
@@ -2065,7 +2081,7 @@ static struct cmd_struct commands[] = {
 	{"name", module_name, 0},
 	{"clone", module_clone, 0},
 	{"update-clone", update_clone, 0},
-	{"connect-gitdir-workingtree", connect_gitdir_workingtree, 0},
+	{"ensure-core-worktree", ensure_core_worktree, 0},
 	{"relative-path", resolve_relative_path, 0},
 	{"resolve-relative-url", resolve_relative_url, 0},
 	{"resolve-relative-url-test", resolve_relative_url_test, 0},
diff --git a/git-submodule.sh b/git-submodule.sh
index 8caaf274e25..19d010eac06 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -535,6 +535,8 @@ cmd_update()
 	do
 		die_if_unmatched "$quickabort" "$sha1"
 
+		git submodule--helper ensure-core-worktree "$sm_path"
+
 		name=$(git submodule--helper name "$sm_path") || exit
 		if ! test -z "$update"
 		then
@@ -577,11 +579,6 @@ cmd_update()
 			die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
 		fi
 
-		if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
-		then
-			git submodule--helper connect-gitdir-workingtree "$name" "$sm_path"
-		fi
-
 		if test "$subsha1" != "$sha1" || test -n "$force"
 		then
 			subforce=$force
-- 
2.18.0.132.g195c49a2227


^ permalink raw reply	[relevance 23%]

* [PATCH 7/7] submodule--helper: introduce new update-module-mode helper
      [irrelevant] <20180803222322.261813-1-sbeller@google.com>
                   ` (2 preceding siblings ...)
  2018-08-03 22:23 ` [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree Stefan Beller
@ 2018-08-03 22:23 ` Stefan Beller
  2018-08-03 22:36 ` [PATCH 0/7] Resend of sb/submodule-update-in-c Junio C Hamano
  2018-08-13 22:42 ` Stefan Beller
  5 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-03 22:23 UTC (permalink / raw)
  To: git; +Cc: gitster, Stefan Beller

This chews off a bit of the shell part of the update command in
git-submodule.sh. When writing the C code, keep in mind that the
submodule--helper part will go away eventually and we want to have
a C function that is able to determine the submodule update strategy,
it as a nicety, make determine_submodule_update_strategy accessible
for arbitrary repositories.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/submodule--helper.c | 61 +++++++++++++++++++++++++++++++++++++
 git-submodule.sh            | 16 +---------
 2 files changed, 62 insertions(+), 15 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index e7635d5d9ab..e72157664f5 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1446,6 +1446,66 @@ static int module_clone(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+static void determine_submodule_update_strategy(struct repository *r,
+						int just_cloned,
+						const char *path,
+						const char *update,
+						struct submodule_update_strategy *out)
+{
+	const struct submodule *sub = submodule_from_path(r, &null_oid, path);
+	char *key;
+	const char *val;
+
+	key = xstrfmt("submodule.%s.update", sub->name);
+
+	if (update) {
+		trace_printf("parsing update");
+		if (parse_submodule_update_strategy(update, out) < 0)
+			die(_("Invalid update mode '%s' for submodule path '%s'"),
+				update, path);
+	} else if (!repo_config_get_string_const(r, key, &val)) {
+		if (parse_submodule_update_strategy(val, out) < 0)
+			die(_("Invalid update mode '%s' configured for submodule path '%s'"),
+				val, path);
+	} else if (sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
+		trace_printf("loaded thing");
+		out->type = sub->update_strategy.type;
+		out->command = sub->update_strategy.command;
+	} else
+		out->type = SM_UPDATE_CHECKOUT;
+
+	if (just_cloned &&
+	    (out->type == SM_UPDATE_MERGE ||
+	     out->type == SM_UPDATE_REBASE ||
+	     out->type == SM_UPDATE_NONE))
+		out->type = SM_UPDATE_CHECKOUT;
+
+	free(key);
+}
+
+static int module_update_module_mode(int argc, const char **argv, const char *prefix)
+{
+	const char *path, *update = NULL;
+	int just_cloned;
+	struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT };
+
+	if (argc < 3 || argc > 4)
+		die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]");
+
+	just_cloned = git_config_int("just_cloned", argv[1]);
+	path = argv[2];
+
+	if (argc == 4)
+		update = argv[3];
+
+	determine_submodule_update_strategy(the_repository,
+					    just_cloned, path, update,
+					    &update_strategy);
+	fputs(submodule_strategy_to_string(&update_strategy), stdout);
+
+	return 0;
+}
+
 struct update_clone_data {
 	const struct submodule *sub;
 	struct object_id oid;
@@ -2080,6 +2140,7 @@ static struct cmd_struct commands[] = {
 	{"list", module_list, 0},
 	{"name", module_name, 0},
 	{"clone", module_clone, 0},
+	{"update-module-mode", module_update_module_mode, 0},
 	{"update-clone", update_clone, 0},
 	{"ensure-core-worktree", ensure_core_worktree, 0},
 	{"relative-path", resolve_relative_path, 0},
diff --git a/git-submodule.sh b/git-submodule.sh
index 19d010eac06..19c9f1215e1 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -537,27 +537,13 @@ cmd_update()
 
 		git submodule--helper ensure-core-worktree "$sm_path"
 
-		name=$(git submodule--helper name "$sm_path") || exit
-		if ! test -z "$update"
-		then
-			update_module=$update
-		else
-			update_module=$(git config submodule."$name".update)
-			if test -z "$update_module"
-			then
-				update_module="checkout"
-			fi
-		fi
+		update_module=$(git submodule--helper update-module-mode $just_cloned "$sm_path" $update)
 
 		displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
 
 		if test $just_cloned -eq 1
 		then
 			subsha1=
-			case "$update_module" in
-			merge | rebase | none)
-				update_module=checkout ;;
-			esac
 		else
 			subsha1=$(sanitize_submodule_env; cd "$sm_path" &&
 				git rev-parse --verify HEAD) ||
-- 
2.18.0.132.g195c49a2227


^ permalink raw reply	[relevance 24%]

* Re: [PATCH 0/7] Resend of sb/submodule-update-in-c
      [irrelevant] <20180803222322.261813-1-sbeller@google.com>
                   ` (3 preceding siblings ...)
  2018-08-03 22:23 ` [PATCH 7/7] submodule--helper: introduce new update-module-mode helper Stefan Beller
@ 2018-08-03 22:36 ` Junio C Hamano
  2018-08-13 22:42 ` Stefan Beller
  5 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-08-03 22:36 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> * Introduce new patch
>   "submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree"
>   that resolves the conflict with earlier versions of this series with
>   sb/submodule-core-worktree
> * This series is based on master, which already contains 
>   sb/submodule-core-worktree

Thanks; as this is not a bugfix but a new way of implementing the
thing, it is good to base it on 'master'.

Will queue.

^ permalink raw reply	[relevance 5%]

* Re: [RFC PATCH v2 06/12] submodule--helper: add a '--stage' option to the 'config' sub command
      [irrelevant]         ` <20180806125828.66fc99ef0b118e26e0b3e60d@ao2.it>
@ 2018-08-06 18:19           ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-06 18:19 UTC (permalink / raw)
  To: Antonio Ospite
  Cc: Junio C Hamano, git, Brandon Williams, Daniel Graña,
	Jonathan Nieder, Richard Hartmann

> The consistency I was referring to is merely in the mechanism used to
> deal with .gitmodules: by always using "submodule--helper config".
>
> As a side argument: in some previous discussion Stefan mentioned the
> possibility that, in the future, he may be interested to explore
> different locations for submodules configuration, like a special ref,
> to prevent .gitmodules from being in the working tree at all, not even
> for writing submodule configuration.
>
> Having an opaque "stage submodule configuration" operation would
> prepare for that too, but as I said this is not my immediate goal.
>

Thanks for demonstrating that this will be easy to achieve in the future!

> Having said that I can drop patches 06/07 if this can help moving things
> forward; or if I had some success in convincing you I can improve the
> user interface (any advice?) and the commit message.
>

I think dropping the patches would be a good idea,
given that this is not your immediate goal.

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* [PATCH 0/3] Resending sb/config-write-fix
@ 2018-08-08 19:50 Stefan Beller
  2018-08-08 19:50 ` [PATCH 2/3] config: fix case sensitive subsection names on writing Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-08 19:50 UTC (permalink / raw)
  To: gitster; +Cc: git, Stefan Beller

This is a resend of sb/config-write-fix, with a slightly
better commit message and a renamed variable.

Thanks,
Stefan


Stefan Beller (3):
  t1300: document current behavior of setting options
  config: fix case sensitive subsection names on writing
  git-config: document accidental multi-line setting in deprecated
    syntax

 Documentation/git-config.txt | 21 +++++++++
 config.c                     | 12 ++++-
 t/t1300-config.sh            | 87 ++++++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+), 1 deletion(-)

./git-range-diff origin/sb/config-write-fix...HEAD >>0000-cover-letter.patch 
2.18.0.597.ga71716f1ad-goog

1:  999d9026272 ! 1:  e40f57f3da1 t1300: document current behavior of setting options
    @@ -7,7 +7,6 @@
         for the follow up that will fix some issues with the current behavior.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/t/t1300-config.sh b/t/t1300-config.sh
      --- a/t/t1300-config.sh
2:  c667e555066 ! 2:  f01cb1d9dae config: fix case sensitive subsection names on writing
    @@ -2,8 +2,8 @@
     
         config: fix case sensitive subsection names on writing
     
    -    A use reported a submodule issue regarding strange case indentation
    -    issues, but it could be boiled down to the following test case:
    +    A user reported a submodule issue regarding a section mix-up,
    +    but it could be boiled down to the following test case:
     
           $ git init test  && cd test
           $ git config foo."Bar".key test
    @@ -32,7 +32,6 @@
     
         Reported-by: JP Sugarbroad <jpsugar@google.com>
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/config.c b/config.c
      --- a/config.c
    @@ -41,7 +40,7 @@
      	int eof;
      	struct strbuf value;
      	struct strbuf var;
    -+	unsigned section_name_old_dot_style : 1;
    ++	unsigned subsection_case_sensitive : 1;
      
      	int (*do_fgetc)(struct config_source *c);
      	int (*do_ungetc)(int c, struct config_source *conf);
    @@ -49,7 +48,7 @@
      
      static int get_extended_base_var(struct strbuf *name, int c)
      {
    -+	cf->section_name_old_dot_style = 0;
    ++	cf->subsection_case_sensitive = 0;
      	do {
      		if (c == '\n')
      			goto error_incomplete_line;
    @@ -57,7 +56,7 @@
      
      static int get_base_var(struct strbuf *name)
      {
    -+	cf->section_name_old_dot_style = 1;
    ++	cf->subsection_case_sensitive = 1;
      	for (;;) {
      		int c = get_next_char();
      		if (cf->eof)
    @@ -70,7 +69,7 @@
      		if (cf->var.len < 2 || cf->var.buf[cf->var.len - 1] != '.')
      			return error("invalid section name '%s'", cf->var.buf);
      
    -+		if (cf->section_name_old_dot_style)
    ++		if (cf->subsection_case_sensitive)
     +			cmpfn = strncasecmp;
     +		else
     +			cmpfn = strncmp;
3:  6749bb283a8 ! 3:  6b5ad773490 git-config: document accidental multi-line setting in deprecated syntax
    @@ -29,7 +29,6 @@
         spend time on fixing the behavior and just document it instead.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
      --- a/Documentation/git-config.txt

^ permalink raw reply	[relevance 8%]

* [PATCH 2/3] config: fix case sensitive subsection names on writing
  2018-08-08 19:50 [PATCH 0/3] Resending sb/config-write-fix Stefan Beller
@ 2018-08-08 19:50 ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-08 19:50 UTC (permalink / raw)
  To: gitster; +Cc: git, Stefan Beller

A user reported a submodule issue regarding a section mix-up,
but it could be boiled down to the following test case:

  $ git init test  && cd test
  $ git config foo."Bar".key test
  $ git config foo."bar".key test
  $ tail -n 3 .git/config
  [foo "Bar"]
        key = test
        key = test

Sub sections are case sensitive and we have a test for correctly reading
them. However we do not have a test for writing out config correctly with
case sensitive subsection names, which is why this went unnoticed in
6ae996f2acf (git_config_set: make use of the config parser's event
stream, 2018-04-09)

Unfortunately we have to make a distinction between old style configuration
that looks like

  [foo.Bar]
        key = test

and the new quoted style as seen above. The old style is documented as
case-agnostic, hence we need to keep 'strncasecmp'; although the
resulting setting for the old style config differs from the configuration.
That will be fixed in a follow up patch.

Reported-by: JP Sugarbroad <jpsugar@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 config.c          | 12 +++++++++++-
 t/t1300-config.sh |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/config.c b/config.c
index 02050529788..27e800c7ce8 100644
--- a/config.c
+++ b/config.c
@@ -35,6 +35,7 @@ struct config_source {
 	int eof;
 	struct strbuf value;
 	struct strbuf var;
+	unsigned subsection_case_sensitive : 1;
 
 	int (*do_fgetc)(struct config_source *c);
 	int (*do_ungetc)(int c, struct config_source *conf);
@@ -603,6 +604,7 @@ static int get_value(config_fn_t fn, void *data, struct strbuf *name)
 
 static int get_extended_base_var(struct strbuf *name, int c)
 {
+	cf->subsection_case_sensitive = 0;
 	do {
 		if (c == '\n')
 			goto error_incomplete_line;
@@ -639,6 +641,7 @@ static int get_extended_base_var(struct strbuf *name, int c)
 
 static int get_base_var(struct strbuf *name)
 {
+	cf->subsection_case_sensitive = 1;
 	for (;;) {
 		int c = get_next_char();
 		if (cf->eof)
@@ -2328,14 +2331,21 @@ static int store_aux_event(enum config_event_t type,
 	store->parsed[store->parsed_nr].type = type;
 
 	if (type == CONFIG_EVENT_SECTION) {
+		int (*cmpfn)(const char *, const char *, size_t);
+
 		if (cf->var.len < 2 || cf->var.buf[cf->var.len - 1] != '.')
 			return error("invalid section name '%s'", cf->var.buf);
 
+		if (cf->subsection_case_sensitive)
+			cmpfn = strncasecmp;
+		else
+			cmpfn = strncmp;
+
 		/* Is this the section we were looking for? */
 		store->is_keys_section =
 			store->parsed[store->parsed_nr].is_keys_section =
 			cf->var.len - 1 == store->baselen &&
-			!strncasecmp(cf->var.buf, store->key, store->baselen);
+			!cmpfn(cf->var.buf, store->key, store->baselen);
 		if (store->is_keys_section) {
 			store->section_seen = 1;
 			ALLOC_GROW(store->seen, store->seen_nr + 1,
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index c15c19bf78d..77c5899d000 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -1260,6 +1260,7 @@ test_expect_success 'setting different case sensitive subsections ' '
 		Qc = v2
 		[d "e"]
 		f = v1
+		[d "E"]
 		Qf = v2
 	EOF
 	# exact match
-- 
2.18.0.597.ga71716f1ad-goog


^ permalink raw reply	[relevance 5%]

* [RFC PATCH 00/10] fetch: make sure submodule oids are fetched
@ 2018-08-08 22:17 Stefan Beller
  2018-08-08 22:17 ` [PATCH 04/10] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
                   ` (6 more replies)
  0 siblings, 7 replies; 200+ results
From: Stefan Beller @ 2018-08-08 22:17 UTC (permalink / raw)
  To: git; +Cc: hvoigt, Stefan Beller

Currently when git-fetch is asked to recurse into submodules, it dispatches
a plain "git-fetch -C <submodule-dir>" (and some submodule related options
such as prefix and recusing strategy, but) without any information of the
remote or the tip that should be fetched.

This works surprisingly well in some workflows, not so well in others,
which this series aims to fix.

The first patches provide new basic functionality and do some refactoring;
the interesting part is in the two last patches.

Thanks,
Stefan

Stefan Beller (10):
  string_list: print_string_list to use trace_printf
  string-list.h: add string_list_pop function.
  sha1-array: provide oid_array_remove_if
  submodule.c: convert submodule_move_head new argument to object id
  submodule.c: fix indentation
  submodule.c: sort changed_submodule_names before searching it
  submodule: move global changed_submodule_names into fetch submodule
    struct
  submodule.c: do not copy around submodule list
  submodule: fetch in submodules git directory instead of in worktree
  fetch: retry fetching submodules if sha1 were not fetched

 builtin/fetch.c             |   9 +-
 entry.c                     |   6 +-
 sha1-array.c                |  39 ++++++++
 sha1-array.h                |   3 +
 string-list.c               |  12 ++-
 string-list.h               |   6 ++
 submodule.c                 | 194 +++++++++++++++++++++++++++---------
 submodule.h                 |   2 +-
 t/t5526-fetch-submodules.sh |  23 ++++-
 unpack-trees.c              |  13 +--
 10 files changed, 241 insertions(+), 66 deletions(-)

-- 
2.18.0.597.ga71716f1ad-goog


^ permalink raw reply	[relevance 10%]

* [PATCH 04/10] submodule.c: convert submodule_move_head new argument to object id
  2018-08-08 22:17 [RFC PATCH 00/10] fetch: make sure submodule oids are fetched Stefan Beller
@ 2018-08-08 22:17 ` Stefan Beller
  2018-08-09 22:00   ` Junio C Hamano
  2018-08-08 22:17 ` [PATCH 05/10] submodule.c: fix indentation Stefan Beller
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-08 22:17 UTC (permalink / raw)
  To: git; +Cc: hvoigt, Stefan Beller

All callers use oid_to_hex to convert the desired oid to a string before
calling submodule_move_head. Defer the conversion to the
submodule_move_head as it will turn out to be useful in a bit.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 entry.c        |  6 +++---
 submodule.c    | 12 ++++++------
 submodule.h    |  2 +-
 unpack-trees.c | 13 +++++--------
 4 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/entry.c b/entry.c
index b5d1d3cf231..4b34dfd30df 100644
--- a/entry.c
+++ b/entry.c
@@ -358,7 +358,7 @@ static int write_entry(struct cache_entry *ce,
 		sub = submodule_from_ce(ce);
 		if (sub)
 			return submodule_move_head(ce->name,
-				NULL, oid_to_hex(&ce->oid),
+				NULL, &ce->oid,
 				state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
 		break;
 
@@ -438,10 +438,10 @@ int checkout_entry(struct cache_entry *ce,
 					unlink_or_warn(ce->name);
 
 				return submodule_move_head(ce->name,
-					NULL, oid_to_hex(&ce->oid), 0);
+					NULL, &ce->oid, 0);
 			} else
 				return submodule_move_head(ce->name,
-					"HEAD", oid_to_hex(&ce->oid),
+					"HEAD", &ce->oid,
 					state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
 		}
 
diff --git a/submodule.c b/submodule.c
index 6e14547e9e0..5b4e5227d90 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1597,9 +1597,9 @@ static void submodule_reset_index(const char *path)
  * pass NULL for old or new respectively.
  */
 int submodule_move_head(const char *path,
-			 const char *old_head,
-			 const char *new_head,
-			 unsigned flags)
+			const char *old_head,
+			const struct object_id *new_oid,
+			unsigned flags)
 {
 	int ret = 0;
 	struct child_process cp = CHILD_PROCESS_INIT;
@@ -1679,7 +1679,7 @@ int submodule_move_head(const char *path,
 	if (!(flags & SUBMODULE_MOVE_HEAD_FORCE))
 		argv_array_push(&cp.args, old_head ? old_head : empty_tree_oid_hex());
 
-	argv_array_push(&cp.args, new_head ? new_head : empty_tree_oid_hex());
+	argv_array_push(&cp.args, new_oid ? oid_to_hex(new_oid) : empty_tree_oid_hex());
 
 	if (run_command(&cp)) {
 		ret = error(_("Submodule '%s' could not be updated."), path);
@@ -1687,7 +1687,7 @@ int submodule_move_head(const char *path,
 	}
 
 	if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
-		if (new_head) {
+		if (new_oid) {
 			child_process_init(&cp);
 			/* also set the HEAD accordingly */
 			cp.git_cmd = 1;
@@ -1696,7 +1696,7 @@ int submodule_move_head(const char *path,
 
 			prepare_submodule_repo_env(&cp.env_array);
 			argv_array_pushl(&cp.args, "update-ref", "HEAD",
-					 "--no-deref", new_head, NULL);
+					 "--no-deref", oid_to_hex(new_oid), NULL);
 
 			if (run_command(&cp)) {
 				ret = -1;
diff --git a/submodule.h b/submodule.h
index 4644683e6cb..d1cceabb9b7 100644
--- a/submodule.h
+++ b/submodule.h
@@ -118,7 +118,7 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule);
 #define SUBMODULE_MOVE_HEAD_FORCE   (1<<1)
 extern int submodule_move_head(const char *path,
 			       const char *old,
-			       const char *new_head,
+			       const struct object_id *new_oid,
 			       unsigned flags);
 
 void submodule_unset_core_worktree(const struct submodule *sub);
diff --git a/unpack-trees.c b/unpack-trees.c
index f9efee0836a..6c76bd6162a 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -256,7 +256,7 @@ static void display_error_msgs(struct unpack_trees_options *o)
 
 static int check_submodule_move_head(const struct cache_entry *ce,
 				     const char *old_id,
-				     const char *new_id,
+				     const struct object_id *new_id,
 				     struct unpack_trees_options *o)
 {
 	unsigned flags = SUBMODULE_MOVE_HEAD_DRY_RUN;
@@ -1513,7 +1513,7 @@ static int verify_uptodate_1(const struct cache_entry *ce,
 
 		if (submodule_from_ce(ce)) {
 			int r = check_submodule_move_head(ce,
-				"HEAD", oid_to_hex(&ce->oid), o);
+				"HEAD", &ce->oid, o);
 			if (r)
 				return o->gently ? -1 :
 					add_rejected_path(o, error_type, ce->name);
@@ -1576,8 +1576,7 @@ static int verify_clean_submodule(const char *old_sha1,
 	if (!submodule_from_ce(ce))
 		return 0;
 
-	return check_submodule_move_head(ce, old_sha1,
-					 oid_to_hex(&ce->oid), o);
+	return check_submodule_move_head(ce, old_sha1, &ce->oid, o);
 }
 
 static int verify_clean_subdirectory(const struct cache_entry *ce,
@@ -1821,8 +1820,7 @@ static int merged_entry(const struct cache_entry *ce,
 
 		if (submodule_from_ce(ce)) {
 			int ret = check_submodule_move_head(ce, NULL,
-							    oid_to_hex(&ce->oid),
-							    o);
+							    &ce->oid, o);
 			if (ret)
 				return ret;
 		}
@@ -1850,8 +1848,7 @@ static int merged_entry(const struct cache_entry *ce,
 
 		if (submodule_from_ce(ce)) {
 			int ret = check_submodule_move_head(ce, oid_to_hex(&old->oid),
-							    oid_to_hex(&ce->oid),
-							    o);
+							    &ce->oid, o);
 			if (ret)
 				return ret;
 		}
-- 
2.18.0.597.ga71716f1ad-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 05/10] submodule.c: fix indentation
  2018-08-08 22:17 [RFC PATCH 00/10] fetch: make sure submodule oids are fetched Stefan Beller
  2018-08-08 22:17 ` [PATCH 04/10] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
@ 2018-08-08 22:17 ` Stefan Beller
  2018-08-08 22:17 ` [PATCH 06/10] submodule.c: sort changed_submodule_names before searching it Stefan Beller
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-08 22:17 UTC (permalink / raw)
  To: git; +Cc: hvoigt, Stefan Beller

The submodule subsystem is really bad at staying within 80 characters.
Fix it while we are here.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index 5b4e5227d90..bceeba13217 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1244,7 +1244,8 @@ static int get_next_submodule(struct child_process *cp,
 		if (!submodule) {
 			const char *name = default_name_or_path(ce->name);
 			if (name) {
-				default_submodule.path = default_submodule.name = name;
+				default_submodule.path = name;
+				default_submodule.name = name;
 				submodule = &default_submodule;
 			}
 		}
@@ -1254,8 +1255,9 @@ static int get_next_submodule(struct child_process *cp,
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule || !unsorted_string_list_lookup(&changed_submodule_names,
-							 submodule->name))
+			if (!submodule || !unsorted_string_list_lookup(
+					&changed_submodule_names,
+					submodule->name))
 				continue;
 			default_argv = "on-demand";
 			break;
-- 
2.18.0.597.ga71716f1ad-goog


^ permalink raw reply	[relevance 26%]

* [PATCH 06/10] submodule.c: sort changed_submodule_names before searching it
  2018-08-08 22:17 [RFC PATCH 00/10] fetch: make sure submodule oids are fetched Stefan Beller
  2018-08-08 22:17 ` [PATCH 04/10] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
  2018-08-08 22:17 ` [PATCH 05/10] submodule.c: fix indentation Stefan Beller
@ 2018-08-08 22:17 ` Stefan Beller
  2018-08-08 22:17 ` [PATCH 07/10] submodule: move global changed_submodule_names into fetch submodule struct Stefan Beller
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-08 22:17 UTC (permalink / raw)
  To: git; +Cc: hvoigt, Stefan Beller

Instead of sorting it after we created an unsorted list, we could insert
correctly into the list.  As the unsorted append is in order of cache entry
names, this is already sorted if names were equal to paths for submodules.

As submodule names are often the same as their path, the input is sorted
pretty well already, so let's just do the sort afterwards.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/submodule.c b/submodule.c
index bceeba13217..89a46b8af50 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1255,7 +1255,7 @@ static int get_next_submodule(struct child_process *cp,
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule || !unsorted_string_list_lookup(
+			if (!submodule || !string_list_lookup(
 					&changed_submodule_names,
 					submodule->name))
 				continue;
@@ -1349,6 +1349,7 @@ int fetch_populated_submodules(struct repository *r,
 	/* default value, "--submodule-prefix" and its value are added later */
 
 	calculate_changed_submodule_paths();
+	string_list_sort(&changed_submodule_names);
 	run_processes_parallel(max_parallel_jobs,
 			       get_next_submodule,
 			       fetch_start_failure,
-- 
2.18.0.597.ga71716f1ad-goog


^ permalink raw reply	[relevance 24%]

* [PATCH 07/10] submodule: move global changed_submodule_names into fetch submodule struct
  2018-08-08 22:17 [RFC PATCH 00/10] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (2 preceding siblings ...)
  2018-08-08 22:17 ` [PATCH 06/10] submodule.c: sort changed_submodule_names before searching it Stefan Beller
@ 2018-08-08 22:17 ` Stefan Beller
  2018-08-08 22:17 ` [PATCH 08/10] submodule.c: do not copy around submodule list Stefan Beller
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-08 22:17 UTC (permalink / raw)
  To: git; +Cc: hvoigt, Stefan Beller

The `changed_submodule_names` are only used for fetching, so let's make it
part of the struct that is passed around for fetching submodules.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/submodule.c b/submodule.c
index 89a46b8af50..92988239f6b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -24,7 +24,7 @@
 #include "object-store.h"
 
 static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
-static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
+
 static int initialized_fetch_ref_tips;
 static struct oid_array ref_tips_before_fetch;
 static struct oid_array ref_tips_after_fetch;
@@ -1110,7 +1110,22 @@ void check_for_new_submodule_commits(struct object_id *oid)
 	oid_array_append(&ref_tips_after_fetch, oid);
 }
 
-static void calculate_changed_submodule_paths(void)
+struct submodule_parallel_fetch {
+	int count;
+	struct argv_array args;
+	struct repository *r;
+	const char *prefix;
+	int command_line_option;
+	int default_option;
+	int quiet;
+	int result;
+
+	struct string_list changed_submodule_names;
+};
+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
+
+static void calculate_changed_submodule_paths(
+	struct submodule_parallel_fetch *spf)
 {
 	struct argv_array argv = ARGV_ARRAY_INIT;
 	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
@@ -1148,7 +1163,8 @@ static void calculate_changed_submodule_paths(void)
 			continue;
 
 		if (!submodule_has_commits(path, commits))
-			string_list_append(&changed_submodule_names, name->string);
+			string_list_append(&spf->changed_submodule_names,
+					   name->string);
 	}
 
 	free_submodules_oids(&changed_submodules);
@@ -1185,18 +1201,6 @@ int submodule_touches_in_range(struct object_id *excl_oid,
 	return ret;
 }
 
-struct submodule_parallel_fetch {
-	int count;
-	struct argv_array args;
-	struct repository *r;
-	const char *prefix;
-	int command_line_option;
-	int default_option;
-	int quiet;
-	int result;
-};
-#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0}
-
 static int get_fetch_recurse_config(const struct submodule *submodule,
 				    struct submodule_parallel_fetch *spf)
 {
@@ -1256,7 +1260,7 @@ static int get_next_submodule(struct child_process *cp,
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
 			if (!submodule || !string_list_lookup(
-					&changed_submodule_names,
+					&spf->changed_submodule_names,
 					submodule->name))
 				continue;
 			default_argv = "on-demand";
@@ -1348,8 +1352,8 @@ int fetch_populated_submodules(struct repository *r,
 	argv_array_push(&spf.args, "--recurse-submodules-default");
 	/* default value, "--submodule-prefix" and its value are added later */
 
-	calculate_changed_submodule_paths();
-	string_list_sort(&changed_submodule_names);
+	calculate_changed_submodule_paths(&spf);
+	string_list_sort(&spf.changed_submodule_names);
 	run_processes_parallel(max_parallel_jobs,
 			       get_next_submodule,
 			       fetch_start_failure,
@@ -1358,7 +1362,7 @@ int fetch_populated_submodules(struct repository *r,
 
 	argv_array_clear(&spf.args);
 out:
-	string_list_clear(&changed_submodule_names, 1);
+	string_list_clear(&spf.changed_submodule_names, 1);
 	return spf.result;
 }
 
-- 
2.18.0.597.ga71716f1ad-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 08/10] submodule.c: do not copy around submodule list
  2018-08-08 22:17 [RFC PATCH 00/10] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (3 preceding siblings ...)
  2018-08-08 22:17 ` [PATCH 07/10] submodule: move global changed_submodule_names into fetch submodule struct Stefan Beller
@ 2018-08-08 22:17 ` Stefan Beller
  2018-08-08 22:17 ` [PATCH 09/10] submodule: fetch in submodules git directory instead of in worktree Stefan Beller
  2018-08-08 22:17 ` [PATCH 10/10] fetch: retry fetching submodules if sha1 were not fetched Stefan Beller
  6 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-08 22:17 UTC (permalink / raw)
  To: git; +Cc: hvoigt, Stefan Beller

'calculate_changed_submodule_paths' uses a local list to compute the
changed submodules, and then produces the result by copying appropriate
items into the result list.

Instead use the result list directly and prune items afterwards
using string_list_remove_empty_items.

As a side effect, we'll have access to the util pointer for longer that
contains the commits that we need to fetch.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/submodule.c b/submodule.c
index 92988239f6b..21757e32908 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1128,8 +1128,7 @@ static void calculate_changed_submodule_paths(
 	struct submodule_parallel_fetch *spf)
 {
 	struct argv_array argv = ARGV_ARRAY_INIT;
-	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
-	const struct string_list_item *name;
+	struct string_list_item *name;
 
 	/* No need to check if there are no submodules configured */
 	if (!submodule_from_path(the_repository, NULL, NULL))
@@ -1146,9 +1145,9 @@ static void calculate_changed_submodule_paths(
 	 * Collect all submodules (whether checked out or not) for which new
 	 * commits have been recorded upstream in "changed_submodule_names".
 	 */
-	collect_changed_submodules(&changed_submodules, &argv);
+	collect_changed_submodules(&spf->changed_submodule_names, &argv);
 
-	for_each_string_list_item(name, &changed_submodules) {
+	for_each_string_list_item(name, &spf->changed_submodule_names) {
 		struct oid_array *commits = name->util;
 		const struct submodule *submodule;
 		const char *path = NULL;
@@ -1162,12 +1161,14 @@ static void calculate_changed_submodule_paths(
 		if (!path)
 			continue;
 
-		if (!submodule_has_commits(path, commits))
-			string_list_append(&spf->changed_submodule_names,
-					   name->string);
+		if (submodule_has_commits(path, commits)) {
+			oid_array_clear(commits);
+			*name->string = '\0';
+		}
 	}
 
-	free_submodules_oids(&changed_submodules);
+	string_list_remove_empty_items(&spf->changed_submodule_names, 1);
+
 	argv_array_clear(&argv);
 	oid_array_clear(&ref_tips_before_fetch);
 	oid_array_clear(&ref_tips_after_fetch);
@@ -1362,7 +1363,7 @@ int fetch_populated_submodules(struct repository *r,
 
 	argv_array_clear(&spf.args);
 out:
-	string_list_clear(&spf.changed_submodule_names, 1);
+	free_submodules_oids(&spf.changed_submodule_names);
 	return spf.result;
 }
 
-- 
2.18.0.597.ga71716f1ad-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 09/10] submodule: fetch in submodules git directory instead of in worktree
  2018-08-08 22:17 [RFC PATCH 00/10] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (4 preceding siblings ...)
  2018-08-08 22:17 ` [PATCH 08/10] submodule.c: do not copy around submodule list Stefan Beller
@ 2018-08-08 22:17 ` Stefan Beller
  2018-08-08 22:17 ` [PATCH 10/10] fetch: retry fetching submodules if sha1 were not fetched Stefan Beller
  6 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-08 22:17 UTC (permalink / raw)
  To: git; +Cc: hvoigt, Stefan Beller

This patch started as a refactoring to make 'get_next_submodule' more
readable, but upon doing so, I realized that git-fetch actually doesn't
need to be run in the worktree. So let's run it in the git dir instead.

That should pave the way towards fetching submodules that are currently
not checked out.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c                 | 43 ++++++++++++++++++++++++++-----------
 t/t5526-fetch-submodules.sh |  7 +++++-
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/submodule.c b/submodule.c
index 21757e32908..ec7ea6f8c2d 100644
--- a/submodule.c
+++ b/submodule.c
@@ -481,6 +481,12 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
+static void prepare_submodule_repo_env_in_gitdir(struct argv_array *out)
+{
+	prepare_submodule_repo_env_no_git_dir(out);
+	argv_array_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT);
+}
+
 /* Helper function to display the submodule header line prior to the full
  * summary output. If it can locate the submodule objects directory it will
  * attempt to lookup both the left and right commits and put them into the
@@ -1227,6 +1233,27 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+static const char *get_submodule_git_dir(struct repository *r, const char *path)
+{
+	struct repository subrepo;
+	const char *ret;
+
+	if (repo_submodule_init(&subrepo, r, path)) {
+		/* no entry in .gitmodules? */
+		struct strbuf gitdir = STRBUF_INIT;
+		strbuf_repo_worktree_path(&gitdir, r, "%s/.git", path);
+		if (repo_init(&subrepo, gitdir.buf, NULL)) {
+			strbuf_release(&gitdir);
+			return NULL;
+		}
+	}
+
+	ret = xstrdup(subrepo.gitdir);
+	repo_clear(&subrepo);
+
+	return ret;
+}
+
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
@@ -1234,8 +1261,6 @@ static int get_next_submodule(struct child_process *cp,
 	struct submodule_parallel_fetch *spf = data;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
-		struct strbuf submodule_path = STRBUF_INIT;
-		struct strbuf submodule_git_dir = STRBUF_INIT;
 		struct strbuf submodule_prefix = STRBUF_INIT;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *git_dir, *default_argv;
@@ -1273,16 +1298,12 @@ static int get_next_submodule(struct child_process *cp,
 			continue;
 		}
 
-		strbuf_repo_worktree_path(&submodule_path, spf->r, "%s", ce->name);
-		strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
 		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
-		git_dir = read_gitfile(submodule_git_dir.buf);
-		if (!git_dir)
-			git_dir = submodule_git_dir.buf;
-		if (is_directory(git_dir)) {
+		git_dir = get_submodule_git_dir(spf->r, ce->name);
+		if (git_dir) {
 			child_process_init(cp);
-			cp->dir = strbuf_detach(&submodule_path, NULL);
-			prepare_submodule_repo_env(&cp->env_array);
+			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+			cp->dir = git_dir;
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
@@ -1294,8 +1315,6 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_push(&cp->args, submodule_prefix.buf);
 			ret = 1;
 		}
-		strbuf_release(&submodule_path);
-		strbuf_release(&submodule_git_dir);
 		strbuf_release(&submodule_prefix);
 		if (ret) {
 			spf->count++;
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 0f730d77815..4437cb17698 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -567,7 +567,12 @@ test_expect_success 'fetching submodule into a broken repository' '
 
 	test_must_fail git -C dst status &&
 	test_must_fail git -C dst diff &&
-	test_must_fail git -C dst fetch --recurse-submodules
+
+	# git-fetch cannot find the git directory of the submodule,
+	# so it will do nothing, successfully, as it cannot distinguish between
+	# this broken submodule and a submodule that was just set active but
+	# not cloned yet
+	git -C dst fetch --recurse-submodules
 '
 
 test_expect_success "fetch new commits when submodule got renamed" '
-- 
2.18.0.597.ga71716f1ad-goog


^ permalink raw reply	[relevance 28%]

* [PATCH 10/10] fetch: retry fetching submodules if sha1 were not fetched
  2018-08-08 22:17 [RFC PATCH 00/10] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (5 preceding siblings ...)
  2018-08-08 22:17 ` [PATCH 09/10] submodule: fetch in submodules git directory instead of in worktree Stefan Beller
@ 2018-08-08 22:17 ` Stefan Beller
  2018-08-09  7:50   ` Martin Ågren
  6 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-08 22:17 UTC (permalink / raw)
  To: git; +Cc: hvoigt, Stefan Beller

Currently when git-fetch is asked to recurse into submodules, it dispatches
a plain "git-fetch -C <submodule-dir>" (and some submodule related options
such as prefix and recusing strategy, but) without any information of the
remote or the tip that should be fetched.

This works surprisingly well in some workflows (such as using submodules
as a third party library), while not so well in other scenarios, such
as in a Gerrit topic-based workflow, that can tie together changes
(potentially across repositories) on the server side. One of the parts
of such a Gerrit workflow is to download a change when wanting to examine
it, and you'd want to have its submodule changes that are in the same
topic downloaded as well. However these submodule changes reside in their
own repository in their on ref (refs/changes/<int>).

Retry fetching a submodule if the object id that the superproject points
to, cannot be found.

Note: This is an RFC and doesn't support fetching to FETCH_HEAD yet, but
only into a local branch. To make fetching into FETCH_HEAD work, we need
some refactoring in builtin/fetch.c to adjust the calls to
'check_for_new_submodule_commits'.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/fetch.c             |  9 ++---
 submodule.c                 | 79 ++++++++++++++++++++++++++++++++++++-
 t/t5526-fetch-submodules.sh | 16 ++++++++
 3 files changed, 97 insertions(+), 7 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 34d2bd123b3..9396e6a44c6 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -700,8 +700,7 @@ static int update_local_ref(struct ref *ref,
 			what = _("[new ref]");
 		}
 
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
+		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
 			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref(msg, ref, 0);
 		format_display(display, r ? '!' : '*', what,
@@ -716,8 +715,7 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "..");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
+		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
 			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("fast-forward", ref, 1);
 		format_display(display, r ? '!' : ' ', quickref.buf,
@@ -731,8 +729,7 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "...");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
+		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
 			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("forced-update", ref, 1);
 		format_display(display, r ? '!' : '+', quickref.buf,
diff --git a/submodule.c b/submodule.c
index ec7ea6f8c2d..6cbd0b1a470 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1127,6 +1127,7 @@ struct submodule_parallel_fetch {
 	int result;
 
 	struct string_list changed_submodule_names;
+	struct string_list retry;
 };
 #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
 
@@ -1259,8 +1260,10 @@ static int get_next_submodule(struct child_process *cp,
 {
 	int ret = 0;
 	struct submodule_parallel_fetch *spf = data;
+	struct string_list_item *retry_it;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
+		int recurse_config;
 		struct strbuf submodule_prefix = STRBUF_INIT;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *git_dir, *default_argv;
@@ -1280,7 +1283,9 @@ static int get_next_submodule(struct child_process *cp,
 			}
 		}
 
-		switch (get_fetch_recurse_config(submodule, spf))
+		recurse_config = get_fetch_recurse_config(submodule, spf);
+
+		switch (recurse_config)
 		{
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
@@ -1318,9 +1323,46 @@ static int get_next_submodule(struct child_process *cp,
 		strbuf_release(&submodule_prefix);
 		if (ret) {
 			spf->count++;
+			if (submodule != &default_submodule)
+				/* discard const-ness: */
+				*task_cb = (void*)submodule;
 			return 1;
 		}
 	}
+
+retry_next:
+	retry_it = string_list_pop(&spf->retry);
+	if (retry_it) {
+		struct strbuf submodule_prefix = STRBUF_INIT;
+		const struct submodule *sub =
+				submodule_from_name(spf->r,
+						    &null_oid,
+						    retry_it->string);
+
+		child_process_init(cp);
+		cp->dir = get_submodule_git_dir(spf->r, sub->path);
+		if (!cp->dir)
+			goto retry_next;
+		prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+		cp->git_cmd = 1;
+
+		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, sub->path);
+		argv_array_init(&cp->args);
+		argv_array_pushv(&cp->args, spf->args.argv);
+		argv_array_push(&cp->args, "on-demand");
+		argv_array_push(&cp->args, "--submodule-prefix");
+		argv_array_push(&cp->args, submodule_prefix.buf);
+
+		/* NEEDSWORK: have get_default_remote from s--h */
+		argv_array_push(&cp->args, "origin");
+		oid_array_for_each_unique(retry_it->util,
+					  append_oid_to_argv, &cp->args);
+
+		*task_cb = NULL; /* make sure we do not recurse forever */
+		strbuf_release(&submodule_prefix);
+		return 1;
+	}
+
 	return 0;
 }
 
@@ -1334,14 +1376,49 @@ static int fetch_start_failure(struct strbuf *err,
 	return 0;
 }
 
+static int commit_exists_in_sub(const struct object_id *oid, void *data)
+{
+	struct repository *subrepo = data;
+
+	enum object_type type = oid_object_info(subrepo, oid, NULL);
+
+	return type == OBJ_COMMIT;
+}
+
 static int fetch_finish(int retvalue, struct strbuf *err,
 			void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
+	struct submodule *sub = task_cb;
+	struct repository subrepo;
 
 	if (retvalue)
 		spf->result = 1;
 
+	if (!sub)
+		return 0;
+
+	if (repo_submodule_init(&subrepo, spf->r, sub->path) < 0)
+		warning(_("Could not get submodule repository for submodule '%s' in repository '%s'"),
+			  sub->path, spf->r->worktree);
+	else {
+		struct string_list_item *it;
+		struct oid_array *commits;
+
+		it = string_list_lookup(&spf->changed_submodule_names, sub->name);
+		if (!it)
+			return 0;
+
+		commits = it->util;
+		oid_array_remove_if(commits,
+				    commit_exists_in_sub,
+				    &subrepo);
+
+		if (commits->nr)
+			string_list_append(&spf->retry, sub->name)
+				->util = commits;
+	}
+
 	return 0;
 }
 
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 4437cb17698..ade4bf6d0bc 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -606,4 +606,20 @@ test_expect_success "fetch new commits when submodule got renamed" '
 	test_cmp expect actual
 '
 
+test_expect_success "fetch new commits on-demand when they are not reachable" '
+	git checkout --detach &&
+	C=$(git -C submodule commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/1 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	git commit -m "updated submodule outside of refs/heads" &&
+	D=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/2 $D &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules --recurse-submodules-default on-demand origin refs/changes/2:refs/heads/my_branch &&
+		git -C submodule cat-file -t $C &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
 test_done
-- 
2.18.0.597.ga71716f1ad-goog


^ permalink raw reply	[relevance 20%]

* Re: [PATCH 1/2] submodule: create helper to build paths to submodule gitdirs
      [irrelevant]   ` <20180808223323.79989-2-bmwill@google.com>
@ 2018-08-08 23:21     ` Stefan Beller
  2018-08-09  0:45       ` Brandon Williams
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-08 23:21 UTC (permalink / raw)
  To: Brandon Williams; +Cc: git

On Wed, Aug 8, 2018 at 3:33 PM Brandon Williams <bmwill@google.com> wrote:
>
> Introduce a helper function "submodule_name_to_gitdir()" (and the
> submodule--helper subcommand "gitdir") which constructs a path to a
> submodule's gitdir, located in the provided repository's "modules"
> directory.

Makes sense.

>
> This consolidates the logic needed to build up a path into a
> repository's "modules" directory, abstracting away the fact that
> submodule git directories are stored in a repository's common gitdir.
> This makes it easier to adjust how submodules gitdir are stored in the
> "modules" directory in a future patch.

and yet, all places that we touch were and still are broken for old-style
submodules that have their git directory inside the working tree?
Do we need to pay attention to those, too?


> diff --git a/git-submodule.sh b/git-submodule.sh
> index 8b5ad59bde..053747d290 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh

> @@ -577,7 +578,7 @@ cmd_update()
>                         die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
>                 fi
>
> -               if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
> +               if ! $(git config -f "$(git submodule--helper gitdir "$name")/config" core.worktree) 2>/dev/null

This will collide with origin/sb/submodule-update-in-c specifically
1c866b9831d (submodule--helper: replace connect-gitdir-workingtree
by ensure-core-worktree, 2018-08-03), but as that removes these lines,
it should be easy to resolve the conflict.

^ permalink raw reply	[relevance 9%]

* Re: [PATCH 1/2] submodule: create helper to build paths to submodule gitdirs
  2018-08-08 23:21     ` [PATCH 1/2] submodule: create helper to build paths to submodule gitdirs Stefan Beller
@ 2018-08-09  0:45       ` Brandon Williams
  0 siblings, 0 replies; 200+ results
From: Brandon Williams @ 2018-08-09  0:45 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

On 08/08, Stefan Beller wrote:
> On Wed, Aug 8, 2018 at 3:33 PM Brandon Williams <bmwill@google.com> wrote:
> >
> > Introduce a helper function "submodule_name_to_gitdir()" (and the
> > submodule--helper subcommand "gitdir") which constructs a path to a
> > submodule's gitdir, located in the provided repository's "modules"
> > directory.
> 
> Makes sense.
> 
> >
> > This consolidates the logic needed to build up a path into a
> > repository's "modules" directory, abstracting away the fact that
> > submodule git directories are stored in a repository's common gitdir.
> > This makes it easier to adjust how submodules gitdir are stored in the
> > "modules" directory in a future patch.
> 
> and yet, all places that we touch were and still are broken for old-style
> submodules that have their git directory inside the working tree?
> Do we need to pay attention to those, too?

This series only tries to address the issues with submodules stored in
$GITDIR/modules/ and places in our codebase that explicitly reference
submodules stored there.

For those old-old-style submodules, wouldn't the absorb submodule
functions handle that migration?

> 
> 
> > diff --git a/git-submodule.sh b/git-submodule.sh
> > index 8b5ad59bde..053747d290 100755
> > --- a/git-submodule.sh
> > +++ b/git-submodule.sh
> 
> > @@ -577,7 +578,7 @@ cmd_update()
> >                         die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
> >                 fi
> >
> > -               if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
> > +               if ! $(git config -f "$(git submodule--helper gitdir "$name")/config" core.worktree) 2>/dev/null
> 
> This will collide with origin/sb/submodule-update-in-c specifically
> 1c866b9831d (submodule--helper: replace connect-gitdir-workingtree
> by ensure-core-worktree, 2018-08-03), but as that removes these lines,
> it should be easy to resolve the conflict.

-- 
Brandon Williams

^ permalink raw reply	[relevance 9%]

* Re: [PATCH 10/10] fetch: retry fetching submodules if sha1 were not fetched
  2018-08-08 22:17 ` [PATCH 10/10] fetch: retry fetching submodules if sha1 were not fetched Stefan Beller
@ 2018-08-09  7:50   ` Martin Ågren
  2018-08-09 17:42     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Martin Ågren @ 2018-08-09  7:50 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Git Mailing List, hvoigt

On 9 August 2018 at 00:17, Stefan Beller <sbeller@google.com> wrote:
> Currently when git-fetch is asked to recurse into submodules, it dispatches
> a plain "git-fetch -C <submodule-dir>" (and some submodule related options
> such as prefix and recusing strategy, but) without any information of the
> remote or the tip that should be fetched.
>
> This works surprisingly well in some workflows (such as using submodules
> as a third party library), while not so well in other scenarios, such
> as in a Gerrit topic-based workflow, that can tie together changes
> (potentially across repositories) on the server side. One of the parts
> of such a Gerrit workflow is to download a change when wanting to examine
> it, and you'd want to have its submodule changes that are in the same
> topic downloaded as well. However these submodule changes reside in their
> own repository in their on ref (refs/changes/<int>).

s/on/own/

> Retry fetching a submodule if the object id that the superproject points
> to, cannot be found.
>
> Note: This is an RFC and doesn't support fetching to FETCH_HEAD yet, but
> only into a local branch. To make fetching into FETCH_HEAD work, we need
> some refactoring in builtin/fetch.c to adjust the calls to
> 'check_for_new_submodule_commits'.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---

> diff --git a/submodule.c b/submodule.c
> index ec7ea6f8c2d..6cbd0b1a470 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1127,6 +1127,7 @@ struct submodule_parallel_fetch {
>         int result;
>
>         struct string_list changed_submodule_names;
> +       struct string_list retry;
>  };
>  #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }

`retry` will effectively be `STRING_LIST_INIT_NODUP`, but making that
explicit would be better and the next addition to the struct would be
easier to get right.

> +retry_next:
> +       retry_it = string_list_pop(&spf->retry);
> +       if (retry_it) {
> +               struct strbuf submodule_prefix = STRBUF_INIT;
> +               const struct submodule *sub =
> +                               submodule_from_name(spf->r,
> +                                                   &null_oid,
> +                                                   retry_it->string);
> +
> +               child_process_init(cp);
> +               cp->dir = get_submodule_git_dir(spf->r, sub->path);
> +               if (!cp->dir)
> +                       goto retry_next;

So here you just drop the string list item. Since it's NODUP, and since
the `util` pointers are owned elsewhere(?), this seems fine. Other uses
of `string_list_pop()` might not be so straightforward.

Just a thought, but rather than pop+if+goto, maybe

while ((retry_it = )) {
        ...
        if (!cp->dir) continue;
        ...
        return 1;
}

I haven't commented on any of the submodule stuff, which is probably
where you'd be most interested in comments. I don't use submodules, nor
do I know the code that runs them.. I guess my comments are more "if
those who know something about submodules find this series worthwhile,
you might want to consider my comments as well".

Martin

^ permalink raw reply	[relevance 7%]

* Re: [RFC PATCH v2 10/12] t7416: add new test about HEAD:.gitmodules and not existing .gitmodules
      [irrelevant]   ` <CAGZ79kbQ0DsAXZrvpp3_2CrMU6Jburf6UdjTxNSd72JqQCczWQ@mail.gmail.com>
@ 2018-08-09  9:14     ` Antonio Ospite
  0 siblings, 0 replies; 200+ results
From: Antonio Ospite @ 2018-08-09  9:14 UTC (permalink / raw)
  To: Stefan Beller
  Cc: git, Brandon Williams, Daniel Graña, Jonathan Nieder,
	Richard Hartmann

On Thu, 2 Aug 2018 13:43:05 -0700
Stefan Beller <sbeller@google.com> wrote:

> On Thu, Aug 2, 2018 at 6:47 AM Antonio Ospite <ao2@ao2.it> wrote:
> >
> > git submodule commands can now access .gitmodules from the current
> > branch even when it's not in the working tree, add some tests for that
> > scenario.
> >
> > Signed-off-by: Antonio Ospite <ao2@ao2.it>
> > ---

[...]
> > +NOTE: "git mv" and "git rm" are still supposed to work even without
> > +a .gitmodules file, as stated in the t3600-rm.sh and t7001-mv.sh tests.
> 
> "supposed to work" != "tested that it works" ?

"git mv submod new_submod" and "git rm submod" are actually expected to
work without the .gitmodules file, and there are tests about that in
t3600-rm.sh and t7001-mv.sh:

t3600-rm.sh:
  'rm does not complain when no .gitmodules file is found'

t7001-mv.sh:
  'git mv moves a submodule with a .git directory and no .gitmodules'  
  'mv does not complain when no .gitmodules file is found'

> I am not sure what the NOTE wants to tell me? (Should I review those
> tests to double check them now? or do we just want to tell future readers
> of this test there are other tangent tests to this?)
>

Admittedly the NOTE is not useful without any context: during the
development of "submodule--helper config --stage" I initially assumed
that "git mv" and "git rm" should fail if .gitmodules was not available,
because these commands modify .gitmodules and I added code for that in
stage_updated_gitmodules().

But then later I found out that my assumption was wrong and that git has
tests to verify that these operations on submodules succeed even when
.gitmodules does not exist, which was a little of a surprise to me.

So I removed all my code that was conflicting with git assumptions, and
added the NOTE. However I guess that was primarily a note to myself, and
it should have not slipped in the public patches.

I think I will remove the note, it can be confusing and does not really
add anything, and even less considering that "submodule--helper config
--stage" is going to be dropped.

[...]
> > +test_expect_success 'not adding submodules when the gitmodules config is not checked out' '
> > +       (cd super &&
> > +               test_must_fail git submodule add ../new_submodule
> > +       )
> > +'
> > +
> > +# "git add" in the test above fails as expected, however it still leaves the
> > +# cloned tree in there and adds a config entry to .git/config. This is because
> > +# no cleanup is done by cmd_add in git-submodule.sh when "git
> > +# submodule--helper config" fails to add a new config setting.
> > +#
> > +# If we added the following commands to the test above:
> > +#
> > +#   rm -rf .git/modules/new_submodule &&
> > +#   git reset HEAD new_submodule &&
> > +#   rm -rf new_submodule
> 
> Alternatively we could check for the existence of .gitmodules
> before starting all these things?
>

You mean in cmd_add(), before doing anything?

The following would anticipates the same check which makes "git submodule
add" fail:

diff --git a/git-submodule.sh b/git-submodule.sh
index ff258e2e8c..b261175143 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -159,6 +159,11 @@ cmd_add()
                shift
        done

+       if test ! -e .gitmodules && git cat-file -e HEAD:.gitmodules
+       then
+                die "$(eval_gettext "please make sure that the .gitmodules file in the current branch is checked out")"
+       fi
+
        if test -n "$reference_path"
        then
                is_absolute_path "$reference_path" ||

This refers to .gitmodules explicitly but we said that we do not care
about that for now, if opaque access was ever needed in the future,
something like "submodule--helper config --is-writeable" could be added.

> I think it is okay to not clean up if we check all "regular" or rather expected
> things such as a non-writable .gitmodules file before actually doing it.
> (This is similar to 'checkout' that walks the whole tree and checks if the
> checkout is possible given the dirtyness of the tree, to either abort early
> or pull through completely. In catastrophic problems such as a full disk
> we'd still die in the middle of work)
> 
> > +#
> > +# then the repository would be in a clean state and the test below would pass.
> > +#
> > +# Maybe cmd_add should do the cleanup from above itself when failing to add
> > +# a submodule.
> > +test_expect_failure 'init submodule after adding failed when the gitmodules config is not checked out' '
> 
> So this comment and test is about explaining why we can fail mid way through,
> which we could not before unless we had the catastrophic event.
> 
> I think we should check for a "writable" .gitmodules file at the beginning,
> which is if (G || (!G && !H)) [using the notation from the cover letter]?
> 
> > +       (cd super &&
> > +               git submodule init

With the change from above this last test passes.

BTW the check I am using here and in the code of submodule--helper,
corresponds indeed to the boolean expression you mentioned, but
simplified and negated.

Thanks,
   Antonio

-- 
Antonio Ospite
https://ao2.it
https://twitter.com/ao2it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?

^ permalink raw reply	[relevance 7%]

* Re: [RFC PATCH v2 01/12] submodule: add a print_config_from_gitmodules() helper
      [irrelevant]   ` <CAGZ79ka-rbOiwWrwbW2vJW9ZOgSas23LkfmzBRLfK=g_cW=MhA@mail.gmail.com>
@ 2018-08-09 10:17     ` Antonio Ospite
  0 siblings, 0 replies; 200+ results
From: Antonio Ospite @ 2018-08-09 10:17 UTC (permalink / raw)
  To: Stefan Beller
  Cc: git, Brandon Williams, Daniel Graña, Jonathan Nieder,
	Richard Hartmann

On Thu, 2 Aug 2018 11:05:02 -0700
Stefan Beller <sbeller@google.com> wrote:

> On Thu, Aug 2, 2018 at 6:47 AM Antonio Ospite <ao2@ao2.it> wrote:
> >
[...]
> > +extern int print_config_from_gitmodules(const char *key);
> 
> The only real pushback for this patch I'd have is lack of documentation
> in public functions, though this is pretty self explanatory; so I'd be fine
> for lacking the docs here.
> 
> In case a resend is needed, please drop the extern keyword here.
> 

I'll drop the extern keyword also for the public function added in
patch 02 then.

Thanks,
   Antonio

-- 
Antonio Ospite
https://ao2.it
https://twitter.com/ao2it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?

^ permalink raw reply	[relevance 5%]

* Re: [RFC PATCH v2 03/12] t7411: be nicer to future tests and really clean things up
      [irrelevant]     ` <CAGZ79kYn8hCV3z7wLhG+-nOooie-PwHN7n1SrEJdka8bSHc+3w@mail.gmail.com>
@ 2018-08-09 13:59       ` Antonio Ospite
  0 siblings, 0 replies; 200+ results
From: Antonio Ospite @ 2018-08-09 13:59 UTC (permalink / raw)
  To: Stefan Beller
  Cc: SZEDER Gábor, git, Brandon Williams, Daniel Graña,
	Jonathan Nieder, Richard Hartmann

On Thu, 2 Aug 2018 11:15:03 -0700
Stefan Beller <sbeller@google.com> wrote:

> On Thu, Aug 2, 2018 at 9:41 AM SZEDER Gábor <szeder.dev@gmail.com> wrote:
> >
[...]
> > >
> > > Note that test_when_finished is not used here, both to keep the current style
> > > and also because it does not work in sub-shells.
> >
> > That's true, but I think that this:
> >
> >   test_when_finished git -C super reset --hard HEAD~2
> >
> > at the very beginning of the test should work.
> 
> Yeah that is a better way to do it.
> Even better would be to have 2 of these for both tests 5 and 8,
> such that each of them could be skipped individually and any following
> tests still work fine.
>

Test 6 also relies on the error introduced in test 5.

So the options would be either to remove one commit at the time in
test 6 and 8 (with a comment in test 6 to note that the commit is from
the previous test), or to remove both the commits in test 8. I am going
to go with the former, using test_when_finished.

> > >  t/t7411-submodule-config.sh | 4 +++-
> > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh
> > > index 0bde5850ac..248da0bc4f 100755
> > > --- a/t/t7411-submodule-config.sh
> > > +++ b/t/t7411-submodule-config.sh
> > > @@ -135,7 +135,9 @@ test_expect_success 'error in history in fetchrecursesubmodule lets continue' '
> > >                       HEAD submodule \
> > >                               >actual &&
> > >               test_cmp expect_error actual  &&
> > > -             git reset --hard HEAD^
> > > +             # Remove both the commits which add errors to .gitmodules,
> > > +             # the one from this test and the one from a previous test.
> > > +             git reset --hard HEAD~2
> 
> I am a bit hesitant to removing the commits though, as it is expected to have
> potentially broken history and submodules still working.
>

The commits which are removed only affected .gitmoudles, no "submodule
init" nor "submoudle update" is ever called after they are added, so I
don't know what problems there could be.

Would a revert be any different?

> The config --unset already fixes the gitmodules file,
> so I think we can rather do
> 
>     git commit -a -m 'now the .gitmodules file is fixed at HEAD \
>         but has a messy history'
> 
> But as I have only read up to here, not knowing what the future tests will
> bring this is all speculation at this point.

IIUC the "config --unset" is used to cause the error, not to fix it, I
am not sure I understand this point.

Thanks,
   Antonio

-- 
Antonio Ospite
https://ao2.it
https://twitter.com/ao2it

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 10/10] fetch: retry fetching submodules if sha1 were not fetched
  2018-08-09  7:50   ` Martin Ågren
@ 2018-08-09 17:42     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-09 17:42 UTC (permalink / raw)
  To: Martin Ågren; +Cc: git, Heiko Voigt

On Thu, Aug 9, 2018 at 12:50 AM Martin Ågren <martin.agren@gmail.com> wrote:
>
> On 9 August 2018 at 00:17, Stefan Beller <sbeller@google.com> wrote:
> > Currently when git-fetch is asked to recurse into submodules, it dispatches
> > a plain "git-fetch -C <submodule-dir>" (and some submodule related options
> > such as prefix and recusing strategy, but) without any information of the
> > remote or the tip that should be fetched.
> >
> > This works surprisingly well in some workflows (such as using submodules
> > as a third party library), while not so well in other scenarios, such
> > as in a Gerrit topic-based workflow, that can tie together changes
> > (potentially across repositories) on the server side. One of the parts
> > of such a Gerrit workflow is to download a change when wanting to examine
> > it, and you'd want to have its submodule changes that are in the same
> > topic downloaded as well. However these submodule changes reside in their
> > own repository in their on ref (refs/changes/<int>).
>
> s/on/own/
>
> > Retry fetching a submodule if the object id that the superproject points
> > to, cannot be found.
> >
> > Note: This is an RFC and doesn't support fetching to FETCH_HEAD yet, but
> > only into a local branch. To make fetching into FETCH_HEAD work, we need
> > some refactoring in builtin/fetch.c to adjust the calls to
> > 'check_for_new_submodule_commits'.
> >
> > Signed-off-by: Stefan Beller <sbeller@google.com>
> > ---
>
> > diff --git a/submodule.c b/submodule.c
> > index ec7ea6f8c2d..6cbd0b1a470 100644
> > --- a/submodule.c
> > +++ b/submodule.c
> > @@ -1127,6 +1127,7 @@ struct submodule_parallel_fetch {
> >         int result;
> >
> >         struct string_list changed_submodule_names;
> > +       struct string_list retry;
> >  };
> >  #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
>
> `retry` will effectively be `STRING_LIST_INIT_NODUP`, but making that
> explicit would be better and the next addition to the struct would be
> easier to get right.
>
> > +retry_next:
> > +       retry_it = string_list_pop(&spf->retry);
> > +       if (retry_it) {
> > +               struct strbuf submodule_prefix = STRBUF_INIT;
> > +               const struct submodule *sub =
> > +                               submodule_from_name(spf->r,
> > +                                                   &null_oid,
> > +                                                   retry_it->string);
> > +
> > +               child_process_init(cp);
> > +               cp->dir = get_submodule_git_dir(spf->r, sub->path);
> > +               if (!cp->dir)
> > +                       goto retry_next;
>
> So here you just drop the string list item. Since it's NODUP, and since
> the `util` pointers are owned elsewhere(?), this seems fine. Other uses
> of `string_list_pop()` might not be so straightforward.
>
> Just a thought, but rather than pop+if+goto, maybe
>
> while ((retry_it = )) {
>         ...
>         if (!cp->dir) continue;
>         ...
>         return 1;
> }

I really want to keep the retry list short and pruned, as this
function is called O(n) times with n the number of submodules
and the retry list will also be up to n.
And with that we'd run O(n^2) times into "if (!..) continue;".

When we use the 'pop-no-work items' logic, then we're still in O(n).

> I haven't commented on any of the submodule stuff, which is probably
> where you'd be most interested in comments. I don't use submodules, nor
> do I know the code that runs them.. I guess my comments are more "if
> those who know something about submodules find this series worthwhile,
> you might want to consider my comments as well".

Thanks for your comments! I'll try to think of another way to
represent this more easily in code.

Thanks,
Stefan

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 04/10] submodule.c: convert submodule_move_head new argument to object id
  2018-08-08 22:17 ` [PATCH 04/10] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
@ 2018-08-09 22:00   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-08-09 22:00 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, hvoigt

Stefan Beller <sbeller@google.com> writes:

> All callers use oid_to_hex to convert the desired oid to a string before
> calling submodule_move_head. Defer the conversion to the
> submodule_move_head as it will turn out to be useful in a bit.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  entry.c        |  6 +++---
>  submodule.c    | 12 ++++++------
>  submodule.h    |  2 +-
>  unpack-trees.c | 13 +++++--------
>  4 files changed, 15 insertions(+), 18 deletions(-)
>
> diff --git a/entry.c b/entry.c
> index b5d1d3cf231..4b34dfd30df 100644
> --- a/entry.c
> +++ b/entry.c
> @@ -358,7 +358,7 @@ static int write_entry(struct cache_entry *ce,
>  		sub = submodule_from_ce(ce);
>  		if (sub)
>  			return submodule_move_head(ce->name,
> -				NULL, oid_to_hex(&ce->oid),
> +				NULL, &ce->oid,
>  				state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
>  		break;

Nice.


^ permalink raw reply	[relevance 5%]

* Re: [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
  2018-08-03 22:23 ` [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree Stefan Beller
@ 2018-08-10 21:47   ` Brandon Williams
  2018-08-10 21:52     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Brandon Williams @ 2018-08-10 21:47 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, gitster

On 08/03, Stefan Beller wrote:
> e98317508c0 (submodule: ensure core.worktree is set after update,
> 2018-06-18) was overly aggressive in calling connect_work_tree_and_git_dir
> as that ensures both the 'core.worktree' configuration is set as well as
> setting up correct gitlink file pointing at the git directory.
> 
> We do not need to check for the gitlink in this part of the cmd_update
> in git-submodule.sh, as the initial call to update-clone will have ensured
> that. So we can reduce the work to only (check and potentially) set the
> 'core.worktree' setting.
> 
> While at it move the check from shell to C as that proves to be useful in
> a follow up patch, as we do not need the 'name' in shell now.
> 
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  builtin/submodule--helper.c | 64 +++++++++++++++++++++++--------------
>  git-submodule.sh            |  7 ++--
>  2 files changed, 42 insertions(+), 29 deletions(-)
> 
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index 8b1088ab58a..e7635d5d9ab 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -1964,6 +1964,45 @@ static int push_check(int argc, const char **argv, const char *prefix)
>  	return 0;
>  }
>  
> +static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
> +{
> +	const struct submodule *sub;
> +	const char *path;
> +	char *cw;
> +	struct repository subrepo;
> +
> +	if (argc != 2)
> +		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
> +
> +	path = argv[1];
> +
> +	sub = submodule_from_path(the_repository, &null_oid, path);
> +	if (!sub)
> +		BUG("We could get the submodule handle before?");
> +
> +	if (repo_submodule_init(&subrepo, the_repository, path))
> +		die(_("could not get a repository handle for submodule '%s'"), path);
> +
> +	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
> +		char *cfg_file, *abs_path;
> +		const char *rel_path;
> +		struct strbuf sb = STRBUF_INIT;
> +
> +		cfg_file = xstrfmt("%s/config", subrepo.gitdir);

As I mentioned here:
https://public-inbox.org/git/20180807230637.247200-1-bmwill@google.com/T/#t

This lines should probably be more like:

  cfg_file = repo_git_path(&subrepo, "config");

> +
> +		abs_path = absolute_pathdup(path);
> +		rel_path = relative_path(abs_path, subrepo.gitdir, &sb);
> +
> +		git_config_set_in_file(cfg_file, "core.worktree", rel_path);
> +
> +		free(cfg_file);
> +		free(abs_path);
> +		strbuf_release(&sb);
> +	}
> +
> +	return 0;
> +}
> +
>  static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
>  {
>  	int i;
> @@ -2029,29 +2068,6 @@ static int check_name(int argc, const char **argv, const char *prefix)
>  	return 0;
>  }
>  
> -static int connect_gitdir_workingtree(int argc, const char **argv, const char *prefix)
> -{
> -	struct strbuf sb = STRBUF_INIT;
> -	const char *name, *path;
> -	char *sm_gitdir;
> -
> -	if (argc != 3)
> -		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
> -
> -	name = argv[1];
> -	path = argv[2];
> -
> -	strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
> -	sm_gitdir = absolute_pathdup(sb.buf);
> -
> -	connect_work_tree_and_git_dir(path, sm_gitdir, 0);
> -
> -	strbuf_release(&sb);
> -	free(sm_gitdir);
> -
> -	return 0;
> -}
> -
>  #define SUPPORT_SUPER_PREFIX (1<<0)
>  
>  struct cmd_struct {
> @@ -2065,7 +2081,7 @@ static struct cmd_struct commands[] = {
>  	{"name", module_name, 0},
>  	{"clone", module_clone, 0},
>  	{"update-clone", update_clone, 0},
> -	{"connect-gitdir-workingtree", connect_gitdir_workingtree, 0},
> +	{"ensure-core-worktree", ensure_core_worktree, 0},
>  	{"relative-path", resolve_relative_path, 0},
>  	{"resolve-relative-url", resolve_relative_url, 0},
>  	{"resolve-relative-url-test", resolve_relative_url_test, 0},
> diff --git a/git-submodule.sh b/git-submodule.sh
> index 8caaf274e25..19d010eac06 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -535,6 +535,8 @@ cmd_update()
>  	do
>  		die_if_unmatched "$quickabort" "$sha1"
>  
> +		git submodule--helper ensure-core-worktree "$sm_path"
> +
>  		name=$(git submodule--helper name "$sm_path") || exit
>  		if ! test -z "$update"
>  		then
> @@ -577,11 +579,6 @@ cmd_update()
>  			die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
>  		fi
>  
> -		if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
> -		then
> -			git submodule--helper connect-gitdir-workingtree "$name" "$sm_path"
> -		fi
> -
>  		if test "$subsha1" != "$sha1" || test -n "$force"
>  		then
>  			subforce=$force
> -- 
> 2.18.0.132.g195c49a2227
> 

-- 
Brandon Williams

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
  2018-08-10 21:47   ` Brandon Williams
@ 2018-08-10 21:52     ` Stefan Beller
  2018-08-10 22:02       ` Brandon Williams
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-10 21:52 UTC (permalink / raw)
  To: Brandon Williams; +Cc: git, Junio C Hamano

> > +             cfg_file = xstrfmt("%s/config", subrepo.gitdir);
>
> As I mentioned here:
> https://public-inbox.org/git/20180807230637.247200-1-bmwill@google.com/T/#t
>
> This lines should probably be more like:
>
>   cfg_file = repo_git_path(&subrepo, "config");
>

Why? You did not mention the benefits for writing it this way
here or on the reference. Care to elaborate?

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
  2018-08-10 21:52     ` Stefan Beller
@ 2018-08-10 22:02       ` Brandon Williams
  0 siblings, 0 replies; 200+ results
From: Brandon Williams @ 2018-08-10 22:02 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, Junio C Hamano

On 08/10, Stefan Beller wrote:
> > > +             cfg_file = xstrfmt("%s/config", subrepo.gitdir);
> >
> > As I mentioned here:
> > https://public-inbox.org/git/20180807230637.247200-1-bmwill@google.com/T/#t
> >
> > This lines should probably be more like:
> >
> >   cfg_file = repo_git_path(&subrepo, "config");
> >
> 
> Why? You did not mention the benefits for writing it this way
> here or on the reference. Care to elaborate?

Its more future proof especially because we have the difference bettwen
commondir and gitdir for worktrees.  Using the "repo_git_path" function
handles path rewritting when using worktrees.  Here (when working with
worktrees) "subrepo.gitdir" refers to the worktree specific gitdir while
"subrepo.commondir" refers to the global common gitdir where the
repository config actually lives.

-- 
Brandon Williams

^ permalink raw reply	[relevance 5%]

* [PATCH 0/7] Resend of sb/submodule-update-in-c
      [irrelevant] <20180803222322.261813-1-sbeller@google.com>
                   ` (4 preceding siblings ...)
  2018-08-03 22:36 ` [PATCH 0/7] Resend of sb/submodule-update-in-c Junio C Hamano
@ 2018-08-13 22:42 ` Stefan Beller
  2018-08-13 22:42   ` [PATCH 1/7] git-submodule.sh: align error reporting for update mode to use path Stefan Beller
                     ` (7 more replies)
  5 siblings, 8 replies; 200+ results
From: Stefan Beller @ 2018-08-13 22:42 UTC (permalink / raw)
  To: gitster, bmwill; +Cc: git, Stefan Beller

Thanks Brandon for pointing out to use repo_git_path instead of
manually constructing the path.

That is the only change in this resend.

Thanks,
Stefan

Stefan Beller (7):
  git-submodule.sh: align error reporting for update mode to use path
  git-submodule.sh: rename unused variables
  builtin/submodule--helper: factor out submodule updating
  builtin/submodule--helper: store update_clone information in a struct
  builtin/submodule--helper: factor out method to update a single
    submodule
  submodule--helper: replace connect-gitdir-workingtree by
    ensure-core-worktree
  submodule--helper: introduce new update-module-mode helper

 builtin/submodule--helper.c | 216 ++++++++++++++++++++++++++----------
 git-submodule.sh            |  29 +----
 2 files changed, 164 insertions(+), 81 deletions(-)

(I am not yet using format-patches internal range diff version,
but  the paste below is manually crafted; the patch numbers are off, as
the fix was done in the second to last patch)

./git-range-diff origin/sb/submodule-update-in-c...

1:  1c866b9831d ! 1:  7bb6249dea9 submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
    @@ -49,7 +49,7 @@
     +		const char *rel_path;
     +		struct strbuf sb = STRBUF_INIT;
     +
    -+		cfg_file = xstrfmt("%s/config", subrepo.gitdir);
    ++		cfg_file = repo_git_path(&subrepo, "config");
     +
     +		abs_path = absolute_pathdup(path);
     +		rel_path = relative_path(abs_path, subrepo.gitdir, &sb);
2:  5a3587e9c25 = 2:  23dc45cee2d submodule--helper: introduce new update-module-mode helper

^ permalink raw reply	[relevance 10%]

* [PATCH 1/7] git-submodule.sh: align error reporting for update mode to use path
  2018-08-13 22:42 ` Stefan Beller
@ 2018-08-13 22:42   ` Stefan Beller
  2018-08-13 22:42   ` [PATCH 2/7] git-submodule.sh: rename unused variables Stefan Beller
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-13 22:42 UTC (permalink / raw)
  To: gitster, bmwill; +Cc: git, Stefan Beller

All other error messages in cmd_update are reporting the submodule based
on its path, so let's do that for invalid update modes, too.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 git-submodule.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/git-submodule.sh b/git-submodule.sh
index 8b5ad59bdee..5a58812645d 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -632,7 +632,7 @@ cmd_update()
 				must_die_on_failure=yes
 				;;
 			*)
-				die "$(eval_gettext "Invalid update mode '$update_module' for submodule '$name'")"
+				die "$(eval_gettext "Invalid update mode '$update_module' for submodule path '$path'")"
 			esac
 
 			if (sanitize_submodule_env; cd "$sm_path" && $command "$sha1")
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply	[relevance 21%]

* [PATCH 2/7] git-submodule.sh: rename unused variables
  2018-08-13 22:42 ` Stefan Beller
  2018-08-13 22:42   ` [PATCH 1/7] git-submodule.sh: align error reporting for update mode to use path Stefan Beller
@ 2018-08-13 22:42   ` Stefan Beller
  2018-08-13 22:42   ` [PATCH 3/7] builtin/submodule--helper: factor out submodule updating Stefan Beller
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-13 22:42 UTC (permalink / raw)
  To: gitster, bmwill; +Cc: git, Stefan Beller

The 'mode' variable is not used in cmd_update for its original purpose,
rename it to 'dummy' as it only serves the purpose to abort quickly
documenting this knowledge.

The variable 'stage' is also not used any more in cmd_update, so remove it.

This went unnoticed as first each function used the commonly used
submodule listing, which was converted in 74703a1e4df (submodule: rewrite
`module_list` shell function in C, 2015-09-02). When cmd_update was
using its own function starting in 48308681b07 (git submodule update:
have a dedicated helper for cloning, 2016-02-29), its removal was missed.

A later patch in this series also touches the communication between
the submodule helper and git-submodule.sh, but let's have this as
a preparatory patch, as it eases the next patch, which stores the
raw data instead of the line printed for this communication.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/submodule--helper.c | 5 ++---
 git-submodule.sh            | 4 ++--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index a3c4564c6c8..da700c88963 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1573,9 +1573,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	needs_cloning = !file_exists(sb.buf);
 
 	strbuf_reset(&sb);
-	strbuf_addf(&sb, "%06o %s %d %d\t%s\n", ce->ce_mode,
-			oid_to_hex(&ce->oid), ce_stage(ce),
-			needs_cloning, ce->name);
+	strbuf_addf(&sb, "dummy %s %d\t%s\n",
+		    oid_to_hex(&ce->oid), needs_cloning, ce->name);
 	string_list_append(&suc->projectlines, sb.buf);
 
 	if (!needs_cloning)
diff --git a/git-submodule.sh b/git-submodule.sh
index 5a58812645d..8caaf274e25 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -531,9 +531,9 @@ cmd_update()
 		"$@" || echo "#unmatched" $?
 	} | {
 	err=
-	while read -r mode sha1 stage just_cloned sm_path
+	while read -r quickabort sha1 just_cloned sm_path
 	do
-		die_if_unmatched "$mode" "$sha1"
+		die_if_unmatched "$quickabort" "$sha1"
 
 		name=$(git submodule--helper name "$sm_path") || exit
 		if ! test -z "$update"
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply	[relevance 16%]

* [PATCH 3/7] builtin/submodule--helper: factor out submodule updating
  2018-08-13 22:42 ` Stefan Beller
  2018-08-13 22:42   ` [PATCH 1/7] git-submodule.sh: align error reporting for update mode to use path Stefan Beller
  2018-08-13 22:42   ` [PATCH 2/7] git-submodule.sh: rename unused variables Stefan Beller
@ 2018-08-13 22:42   ` Stefan Beller
  2018-08-13 22:42   ` [PATCH 4/7] builtin/submodule--helper: store update_clone information in a struct Stefan Beller
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-13 22:42 UTC (permalink / raw)
  To: gitster, bmwill; +Cc: git, Stefan Beller

Separate the command line parsing from the actual execution of the command
within the repository. For now there is not a lot of execution as
most of it is still in git-submodule.sh.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/submodule--helper.c | 59 +++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 26 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index da700c88963..32f00ca6f87 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1474,6 +1474,8 @@ struct submodule_update_clone {
 	/* failed clones to be retried again */
 	const struct cache_entry **failed_clones;
 	int failed_clones_nr, failed_clones_alloc;
+
+	int max_jobs;
 };
 #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
 	SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
@@ -1716,11 +1718,36 @@ static int git_update_clone_config(const char *var, const char *value,
 	return 0;
 }
 
+static int update_submodules(struct submodule_update_clone *suc)
+{
+	struct string_list_item *item;
+
+	run_processes_parallel(suc->max_jobs,
+			       update_clone_get_next_task,
+			       update_clone_start_failure,
+			       update_clone_task_finished,
+			       suc);
+
+	/*
+	 * We saved the output and put it out all at once now.
+	 * That means:
+	 * - the listener does not have to interleave their (checkout)
+	 *   work with our fetching.  The writes involved in a
+	 *   checkout involve more straightforward sequential I/O.
+	 * - the listener can avoid doing any work if fetching failed.
+	 */
+	if (suc->quickstop)
+		return 1;
+
+	for_each_string_list_item(item, &suc->projectlines)
+		fprintf(stdout, "%s", item->string);
+
+	return 0;
+}
+
 static int update_clone(int argc, const char **argv, const char *prefix)
 {
 	const char *update = NULL;
-	int max_jobs = 1;
-	struct string_list_item *item;
 	struct pathspec pathspec;
 	struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT;
 
@@ -1742,7 +1769,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
 		OPT_STRING(0, "depth", &suc.depth, "<depth>",
 			   N_("Create a shallow clone truncated to the "
 			      "specified number of revisions")),
-		OPT_INTEGER('j', "jobs", &max_jobs,
+		OPT_INTEGER('j', "jobs", &suc.max_jobs,
 			    N_("parallel jobs")),
 		OPT_BOOL(0, "recommend-shallow", &suc.recommend_shallow,
 			    N_("whether the initial clone should follow the shallow recommendation")),
@@ -1758,8 +1785,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)
 	};
 	suc.prefix = prefix;
 
-	update_clone_config_from_gitmodules(&max_jobs);
-	git_config(git_update_clone_config, &max_jobs);
+	update_clone_config_from_gitmodules(&suc.max_jobs);
+	git_config(git_update_clone_config, &suc.max_jobs);
 
 	argc = parse_options(argc, argv, prefix, module_update_clone_options,
 			     git_submodule_helper_usage, 0);
@@ -1774,27 +1801,7 @@ static int update_clone(int argc, const char **argv, const char *prefix)
 	if (pathspec.nr)
 		suc.warn_if_uninitialized = 1;
 
-	run_processes_parallel(max_jobs,
-			       update_clone_get_next_task,
-			       update_clone_start_failure,
-			       update_clone_task_finished,
-			       &suc);
-
-	/*
-	 * We saved the output and put it out all at once now.
-	 * That means:
-	 * - the listener does not have to interleave their (checkout)
-	 *   work with our fetching.  The writes involved in a
-	 *   checkout involve more straightforward sequential I/O.
-	 * - the listener can avoid doing any work if fetching failed.
-	 */
-	if (suc.quickstop)
-		return 1;
-
-	for_each_string_list_item(item, &suc.projectlines)
-		fprintf(stdout, "%s", item->string);
-
-	return 0;
+	return update_submodules(&suc);
 }
 
 static int resolve_relative_path(int argc, const char **argv, const char *prefix)
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply	[relevance 11%]

* [PATCH 4/7] builtin/submodule--helper: store update_clone information in a struct
  2018-08-13 22:42 ` Stefan Beller
                     ` (2 preceding siblings ...)
  2018-08-13 22:42   ` [PATCH 3/7] builtin/submodule--helper: factor out submodule updating Stefan Beller
@ 2018-08-13 22:42   ` Stefan Beller
  2018-08-13 22:42   ` [PATCH 5/7] builtin/submodule--helper: factor out method to update a single submodule Stefan Beller
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-13 22:42 UTC (permalink / raw)
  To: gitster, bmwill; +Cc: git, Stefan Beller

The information that is printed for update_submodules in
'submodule--helper update-clone' and consumed by 'git submodule update'
is stored as a string per submodule. This made sense at the time of
48308681b07 (git submodule update: have a dedicated helper for cloning,
2016-02-29), but as we want to migrate the rest of the submodule update
into C, we're better off having access to the raw information in a helper
struct.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/submodule--helper.c | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 32f00ca6f87..40b94dd622e 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1446,6 +1446,12 @@ static int module_clone(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+struct update_clone_data {
+	const struct submodule *sub;
+	struct object_id oid;
+	unsigned just_cloned;
+};
+
 struct submodule_update_clone {
 	/* index into 'list', the list of submodules to look into for cloning */
 	int current;
@@ -1465,8 +1471,9 @@ struct submodule_update_clone {
 	const char *recursive_prefix;
 	const char *prefix;
 
-	/* Machine-readable status lines to be consumed by git-submodule.sh */
-	struct string_list projectlines;
+	/* to be consumed by git-submodule.sh */
+	struct update_clone_data *update_clone;
+	int update_clone_nr; int update_clone_alloc;
 
 	/* If we want to stop as fast as possible and return an error */
 	unsigned quickstop : 1;
@@ -1480,7 +1487,7 @@ struct submodule_update_clone {
 #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
 	SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
 	NULL, NULL, NULL, \
-	STRING_LIST_INIT_DUP, 0, NULL, 0, 0}
+	NULL, 0, 0, 0, NULL, 0, 0, 0}
 
 
 static void next_submodule_warn_missing(struct submodule_update_clone *suc,
@@ -1574,10 +1581,12 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	strbuf_addf(&sb, "%s/.git", ce->name);
 	needs_cloning = !file_exists(sb.buf);
 
-	strbuf_reset(&sb);
-	strbuf_addf(&sb, "dummy %s %d\t%s\n",
-		    oid_to_hex(&ce->oid), needs_cloning, ce->name);
-	string_list_append(&suc->projectlines, sb.buf);
+	ALLOC_GROW(suc->update_clone, suc->update_clone_nr + 1,
+		   suc->update_clone_alloc);
+	oidcpy(&suc->update_clone[suc->update_clone_nr].oid, &ce->oid);
+	suc->update_clone[suc->update_clone_nr].just_cloned = needs_cloning;
+	suc->update_clone[suc->update_clone_nr].sub = sub;
+	suc->update_clone_nr++;
 
 	if (!needs_cloning)
 		goto cleanup;
@@ -1720,7 +1729,8 @@ static int git_update_clone_config(const char *var, const char *value,
 
 static int update_submodules(struct submodule_update_clone *suc)
 {
-	struct string_list_item *item;
+	int i;
+	struct strbuf sb = STRBUF_INIT;
 
 	run_processes_parallel(suc->max_jobs,
 			       update_clone_get_next_task,
@@ -1739,9 +1749,16 @@ static int update_submodules(struct submodule_update_clone *suc)
 	if (suc->quickstop)
 		return 1;
 
-	for_each_string_list_item(item, &suc->projectlines)
-		fprintf(stdout, "%s", item->string);
+	for (i = 0; i < suc->update_clone_nr; i++) {
+		strbuf_addf(&sb, "dummy %s %d\t%s\n",
+			oid_to_hex(&suc->update_clone[i].oid),
+			suc->update_clone[i].just_cloned,
+			suc->update_clone[i].sub->path);
+		fprintf(stdout, "%s", sb.buf);
+		strbuf_reset(&sb);
+	}
 
+	strbuf_release(&sb);
 	return 0;
 }
 
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply	[relevance 20%]

* [PATCH 5/7] builtin/submodule--helper: factor out method to update a single submodule
  2018-08-13 22:42 ` Stefan Beller
                     ` (3 preceding siblings ...)
  2018-08-13 22:42   ` [PATCH 4/7] builtin/submodule--helper: store update_clone information in a struct Stefan Beller
@ 2018-08-13 22:42   ` Stefan Beller
  2018-08-13 22:42   ` [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree Stefan Beller
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-13 22:42 UTC (permalink / raw)
  To: gitster, bmwill; +Cc: git, Stefan Beller

In a later patch we'll find this method handy.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/submodule--helper.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 40b94dd622e..8b1088ab58a 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1727,10 +1727,17 @@ static int git_update_clone_config(const char *var, const char *value,
 	return 0;
 }
 
+static void update_submodule(struct update_clone_data *ucd)
+{
+	fprintf(stdout, "dummy %s %d\t%s\n",
+		oid_to_hex(&ucd->oid),
+		ucd->just_cloned,
+		ucd->sub->path);
+}
+
 static int update_submodules(struct submodule_update_clone *suc)
 {
 	int i;
-	struct strbuf sb = STRBUF_INIT;
 
 	run_processes_parallel(suc->max_jobs,
 			       update_clone_get_next_task,
@@ -1749,16 +1756,9 @@ static int update_submodules(struct submodule_update_clone *suc)
 	if (suc->quickstop)
 		return 1;
 
-	for (i = 0; i < suc->update_clone_nr; i++) {
-		strbuf_addf(&sb, "dummy %s %d\t%s\n",
-			oid_to_hex(&suc->update_clone[i].oid),
-			suc->update_clone[i].just_cloned,
-			suc->update_clone[i].sub->path);
-		fprintf(stdout, "%s", sb.buf);
-		strbuf_reset(&sb);
-	}
+	for (i = 0; i < suc->update_clone_nr; i++)
+		update_submodule(&suc->update_clone[i]);
 
-	strbuf_release(&sb);
 	return 0;
 }
 
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply	[relevance 13%]

* [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree
  2018-08-13 22:42 ` Stefan Beller
                     ` (4 preceding siblings ...)
  2018-08-13 22:42   ` [PATCH 5/7] builtin/submodule--helper: factor out method to update a single submodule Stefan Beller
@ 2018-08-13 22:42   ` Stefan Beller
  2018-08-13 22:42   ` [PATCH 7/7] submodule--helper: introduce new update-module-mode helper Stefan Beller
  2018-08-14 21:01   ` [PATCH 0/7] Resend of sb/submodule-update-in-c Junio C Hamano
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-13 22:42 UTC (permalink / raw)
  To: gitster, bmwill; +Cc: git, Stefan Beller

e98317508c0 (submodule: ensure core.worktree is set after update,
2018-06-18) was overly aggressive in calling connect_work_tree_and_git_dir
as that ensures both the 'core.worktree' configuration is set as well as
setting up correct gitlink file pointing at the git directory.

We do not need to check for the gitlink in this part of the cmd_update
in git-submodule.sh, as the initial call to update-clone will have ensured
that. So we can reduce the work to only (check and potentially) set the
'core.worktree' setting.

While at it move the check from shell to C as that proves to be useful in
a follow up patch, as we do not need the 'name' in shell now.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/submodule--helper.c | 64 +++++++++++++++++++++++--------------
 git-submodule.sh            |  7 ++--
 2 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 8b1088ab58a..648e1330c15 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1964,6 +1964,45 @@ static int push_check(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
+{
+	const struct submodule *sub;
+	const char *path;
+	char *cw;
+	struct repository subrepo;
+
+	if (argc != 2)
+		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
+
+	path = argv[1];
+
+	sub = submodule_from_path(the_repository, &null_oid, path);
+	if (!sub)
+		BUG("We could get the submodule handle before?");
+
+	if (repo_submodule_init(&subrepo, the_repository, path))
+		die(_("could not get a repository handle for submodule '%s'"), path);
+
+	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
+		char *cfg_file, *abs_path;
+		const char *rel_path;
+		struct strbuf sb = STRBUF_INIT;
+
+		cfg_file = repo_git_path(&subrepo, "config");
+
+		abs_path = absolute_pathdup(path);
+		rel_path = relative_path(abs_path, subrepo.gitdir, &sb);
+
+		git_config_set_in_file(cfg_file, "core.worktree", rel_path);
+
+		free(cfg_file);
+		free(abs_path);
+		strbuf_release(&sb);
+	}
+
+	return 0;
+}
+
 static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
 {
 	int i;
@@ -2029,29 +2068,6 @@ static int check_name(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
-static int connect_gitdir_workingtree(int argc, const char **argv, const char *prefix)
-{
-	struct strbuf sb = STRBUF_INIT;
-	const char *name, *path;
-	char *sm_gitdir;
-
-	if (argc != 3)
-		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
-
-	name = argv[1];
-	path = argv[2];
-
-	strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
-	sm_gitdir = absolute_pathdup(sb.buf);
-
-	connect_work_tree_and_git_dir(path, sm_gitdir, 0);
-
-	strbuf_release(&sb);
-	free(sm_gitdir);
-
-	return 0;
-}
-
 #define SUPPORT_SUPER_PREFIX (1<<0)
 
 struct cmd_struct {
@@ -2065,7 +2081,7 @@ static struct cmd_struct commands[] = {
 	{"name", module_name, 0},
 	{"clone", module_clone, 0},
 	{"update-clone", update_clone, 0},
-	{"connect-gitdir-workingtree", connect_gitdir_workingtree, 0},
+	{"ensure-core-worktree", ensure_core_worktree, 0},
 	{"relative-path", resolve_relative_path, 0},
 	{"resolve-relative-url", resolve_relative_url, 0},
 	{"resolve-relative-url-test", resolve_relative_url_test, 0},
diff --git a/git-submodule.sh b/git-submodule.sh
index 8caaf274e25..19d010eac06 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -535,6 +535,8 @@ cmd_update()
 	do
 		die_if_unmatched "$quickabort" "$sha1"
 
+		git submodule--helper ensure-core-worktree "$sm_path"
+
 		name=$(git submodule--helper name "$sm_path") || exit
 		if ! test -z "$update"
 		then
@@ -577,11 +579,6 @@ cmd_update()
 			die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
 		fi
 
-		if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
-		then
-			git submodule--helper connect-gitdir-workingtree "$name" "$sm_path"
-		fi
-
 		if test "$subsha1" != "$sha1" || test -n "$force"
 		then
 			subforce=$force
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply	[relevance 23%]

* [PATCH 7/7] submodule--helper: introduce new update-module-mode helper
  2018-08-13 22:42 ` Stefan Beller
                     ` (5 preceding siblings ...)
  2018-08-13 22:42   ` [PATCH 6/7] submodule--helper: replace connect-gitdir-workingtree by ensure-core-worktree Stefan Beller
@ 2018-08-13 22:42   ` Stefan Beller
  2018-08-18 16:10     ` Duy Nguyen
  2018-08-14 21:01   ` [PATCH 0/7] Resend of sb/submodule-update-in-c Junio C Hamano
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-13 22:42 UTC (permalink / raw)
  To: gitster, bmwill; +Cc: git, Stefan Beller

This chews off a bit of the shell part of the update command in
git-submodule.sh. When writing the C code, keep in mind that the
submodule--helper part will go away eventually and we want to have
a C function that is able to determine the submodule update strategy,
it as a nicety, make determine_submodule_update_strategy accessible
for arbitrary repositories.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/submodule--helper.c | 61 +++++++++++++++++++++++++++++++++++++
 git-submodule.sh            | 16 +---------
 2 files changed, 62 insertions(+), 15 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 648e1330c15..5c9d1fb496d 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1446,6 +1446,66 @@ static int module_clone(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+static void determine_submodule_update_strategy(struct repository *r,
+						int just_cloned,
+						const char *path,
+						const char *update,
+						struct submodule_update_strategy *out)
+{
+	const struct submodule *sub = submodule_from_path(r, &null_oid, path);
+	char *key;
+	const char *val;
+
+	key = xstrfmt("submodule.%s.update", sub->name);
+
+	if (update) {
+		trace_printf("parsing update");
+		if (parse_submodule_update_strategy(update, out) < 0)
+			die(_("Invalid update mode '%s' for submodule path '%s'"),
+				update, path);
+	} else if (!repo_config_get_string_const(r, key, &val)) {
+		if (parse_submodule_update_strategy(val, out) < 0)
+			die(_("Invalid update mode '%s' configured for submodule path '%s'"),
+				val, path);
+	} else if (sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
+		trace_printf("loaded thing");
+		out->type = sub->update_strategy.type;
+		out->command = sub->update_strategy.command;
+	} else
+		out->type = SM_UPDATE_CHECKOUT;
+
+	if (just_cloned &&
+	    (out->type == SM_UPDATE_MERGE ||
+	     out->type == SM_UPDATE_REBASE ||
+	     out->type == SM_UPDATE_NONE))
+		out->type = SM_UPDATE_CHECKOUT;
+
+	free(key);
+}
+
+static int module_update_module_mode(int argc, const char **argv, const char *prefix)
+{
+	const char *path, *update = NULL;
+	int just_cloned;
+	struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT };
+
+	if (argc < 3 || argc > 4)
+		die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]");
+
+	just_cloned = git_config_int("just_cloned", argv[1]);
+	path = argv[2];
+
+	if (argc == 4)
+		update = argv[3];
+
+	determine_submodule_update_strategy(the_repository,
+					    just_cloned, path, update,
+					    &update_strategy);
+	fputs(submodule_strategy_to_string(&update_strategy), stdout);
+
+	return 0;
+}
+
 struct update_clone_data {
 	const struct submodule *sub;
 	struct object_id oid;
@@ -2080,6 +2140,7 @@ static struct cmd_struct commands[] = {
 	{"list", module_list, 0},
 	{"name", module_name, 0},
 	{"clone", module_clone, 0},
+	{"update-module-mode", module_update_module_mode, 0},
 	{"update-clone", update_clone, 0},
 	{"ensure-core-worktree", ensure_core_worktree, 0},
 	{"relative-path", resolve_relative_path, 0},
diff --git a/git-submodule.sh b/git-submodule.sh
index 19d010eac06..19c9f1215e1 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -537,27 +537,13 @@ cmd_update()
 
 		git submodule--helper ensure-core-worktree "$sm_path"
 
-		name=$(git submodule--helper name "$sm_path") || exit
-		if ! test -z "$update"
-		then
-			update_module=$update
-		else
-			update_module=$(git config submodule."$name".update)
-			if test -z "$update_module"
-			then
-				update_module="checkout"
-			fi
-		fi
+		update_module=$(git submodule--helper update-module-mode $just_cloned "$sm_path" $update)
 
 		displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
 
 		if test $just_cloned -eq 1
 		then
 			subsha1=
-			case "$update_module" in
-			merge | rebase | none)
-				update_module=checkout ;;
-			esac
 		else
 			subsha1=$(sanitize_submodule_env; cd "$sm_path" &&
 				git rev-parse --verify HEAD) ||
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply	[relevance 24%]

* [PATCH] git-submodule.sh: accept verbose flag in cmd_update to be non-quiet
      [irrelevant] <929572FA-6B1D-4EC7-825B-93B96053A82C@gmx.de>
@ 2018-08-14 18:22 ` Stefan Beller
  2018-08-14 18:28   ` Jonathan Nieder
  2018-08-15  6:27   ` Aw: " Jochen Kühner
  0 siblings, 2 replies; 200+ results
From: Stefan Beller @ 2018-08-14 18:22 UTC (permalink / raw)
  To: jochen.kuehner; +Cc: git, Stefan Beller

In a56771a668d (builtin/pull: respect verbosity settings in submodules,
2018-01-25), we made sure to pass on both quiet and verbose flag from
builtin/pull.c to the submodule shell script. However git-submodule doesn't
understand a verbose flag, which results in a bug when invoking

  git pull --recurse-submodules -v [...]

There are a few different approaches to fix this bug:

1) rewrite 'argv_push_verbosity' or its caller in builtin/pull.c to
   cap opt_verbosity at 0. Then 'argv_push_verbosity' would only add
   '-q' if any.

2) Have a flag in 'argv_push_verbosity' that specifies if we allow adding
  -q or -v (or both).

3) Add -v to git-submodule.sh and make it a no-op

(1) seems like a maintenance burden: What if we add code after
the submodule operations or move submodule operations higher up,
then we have altered the opt_verbosity setting further down the line
in builtin/pull.c.

(2) seems like it could work reasonably well without more regressions

(3) seems easiest to implement as well as actually is a feature with the
    last-one-wins rule of passing flags to Git commands.

Signed-off-by: Stefan Beller <sbeller@google.com>
---

On Tue, Aug 14, 2018 at 10:54 AM Jochen Kühner <jochen.kuehner@gmx.de> wrote:
>
> If I set 
> git config --global submodule.recurse true
> and run git via:
> git pull --progress -v --no-rebase "origin"
> The command will fail with following output (Errorlevel is 1)
> Fetching submodule submodules/tstemplates
> From http://10.0.102.194:7990/scm/mcc/tstemplates
> = [up to date]      feature/robin -> origin/feature/robin
> = [up to date]      master        -> origin/master
> Already up to date.
> usage: git submodule [--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
>    or: git submodule [--quiet] status [--cached] [--recursive] [--] [<path>...]
>    or: git submodule [--quiet] init [--] [<path>...]
>    or: git submodule [--quiet] deinit [-f|--force] (--all| [--] <path>...)
>    or: git submodule [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--] [<path>...]
>    or: git submodule [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
>    or: git submodule [--quiet] foreach [--recursive] <command>
>    or: git submodule [--quiet] sync [--recursive] [--] [<path>...]
>    or: git submodule [--quiet] absorbgitdirs [--] [<path>...]
>
> seams that the “verbose” parameter “-v” is also sent to “git submodules” wich does not support it.
>
> If I remove “-v” it will work.
>
> Problem is, I use TortoiseGit, wich will automatically create this command!

 git-submodule.sh | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/git-submodule.sh b/git-submodule.sh
index 8b5ad59bdee..f7fd80345cd 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -438,6 +438,9 @@ cmd_update()
 		-q|--quiet)
 			GIT_QUIET=1
 			;;
+		-v)
+			GIT_QUIET=0
+			;;
 		--progress)
 			progress=1
 			;;
-- 
2.18.0.265.g16de1b435c9.dirty


^ permalink raw reply	[relevance 14%]

* Re: [PATCH] git-submodule.sh: accept verbose flag in cmd_update to be non-quiet
  2018-08-14 18:22 ` [PATCH] git-submodule.sh: accept verbose flag in cmd_update to be non-quiet Stefan Beller
@ 2018-08-14 18:28   ` Jonathan Nieder
  2018-08-15  6:27   ` Aw: " Jochen Kühner
  1 sibling, 0 replies; 200+ results
From: Jonathan Nieder @ 2018-08-14 18:28 UTC (permalink / raw)
  To: Stefan Beller; +Cc: jochen.kuehner, git

Stefan Beller wrote:

>  git-submodule.sh | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/git-submodule.sh b/git-submodule.sh
> index 8b5ad59bdee..f7fd80345cd 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -438,6 +438,9 @@ cmd_update()
>  		-q|--quiet)
>  			GIT_QUIET=1
>  			;;
> +		-v)
> +			GIT_QUIET=0
> +			;;

Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>

Thanks.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH] submodule: add more exhaustive up-path testing
      [irrelevant] <20180814185906.2680-1-avarab@gmail.com>
@ 2018-08-14 19:10 ` Stefan Beller
  2018-08-14 19:54   ` Junio C Hamano
  2018-08-14 21:05   ` Ævar Arnfjörð Bjarmason
  0 siblings, 2 replies; 200+ results
From: Stefan Beller @ 2018-08-14 19:10 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Brandon Williams

On Tue, Aug 14, 2018 at 11:59 AM Ævar Arnfjörð Bjarmason
<avarab@gmail.com> wrote:
>
> The tests added in 63e95beb08 ("submodule: port resolve_relative_url
> from shell to C", 2016-04-15) didn't do a good job of testing various
> up-path invocations where the up-path would bring us beyond even the
> URL in question without emitting an error.
>
> These results look nonsensical, but it's worth exhaustively testing
> them before fixing any of this code, so we can see which of these
> cases were changed.

Yeah. Please look at the comment in builtin/submodule--helper.c
in that commit, where I described my expectations.

I should have put them into tests instead with the expectations
spelled out there.

Thanks for this patch!
Stefan

>
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---


> So I think these tests are worthwihle in themselves,

The reason I put it in the comment instead of tests was the
ease of spelling out both the status quo and expectations.

> but would like
> some advice on how to proceed with that from someone more familiar
> with submodules.

So ideally we'd also error out as soon as the host name is touched?

^ permalink raw reply	[relevance 7%]

* Re: [PATCH] submodule: add more exhaustive up-path testing
  2018-08-14 19:10 ` [PATCH] submodule: add more exhaustive up-path testing Stefan Beller
@ 2018-08-14 19:54   ` Junio C Hamano
  2018-08-14 21:05   ` Ævar Arnfjörð Bjarmason
  1 sibling, 0 replies; 200+ results
From: Junio C Hamano @ 2018-08-14 19:54 UTC (permalink / raw)
  To: Stefan Beller
  Cc: Ævar Arnfjörð Bjarmason, git, Brandon Williams

Stefan Beller <sbeller@google.com> writes:

> Thanks for this patch!
> Stefan

Thanks, I'd take it as your Acked-by: (please holler if it isn't
before the patch hits 'next').

^ permalink raw reply	[relevance 5%]

* Re: Syncing HEAD
      [irrelevant] <CAP8UFD0_jpKdcDvNx5CYnmyDMagE_O-E7cef5VthaT_w-=4xsA@mail.gmail.com>
@ 2018-08-14 20:58 ` Stefan Beller
  2018-08-14 21:08   ` Brandon Williams
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-14 20:58 UTC (permalink / raw)
  To: Christian Couder, Brandon Williams; +Cc: git

On Tue, Aug 14, 2018 at 1:09 PM Christian Couder
<christian.couder@gmail.com> wrote:
>
> Hi,
>
> When cloning with --mirror, the clone gets its HEAD initialized with
> the value HEAD has in its origin remote. After that if HEAD changes in
> origin there is no simple way to sync HEAD at the same time as the
> refs are synced.
>
> It looks like the simplest way to sync HEAD is:
>
> 1) git remote show origin
> 2) parse "HEAD branch: XXX" from the output of the above command
> 3) git symbolic-ref HEAD refs/heads/XXX
>
> It looks like it would be quite easy to add an option to `fetch` to
> sync HEAD at the same time as regular refs are synced because every
> fetch from an origin that uses a recent Git contains something like:
>
> 19:55:39.304976 pkt-line.c:80           packet:          git< YYYYYYYY
> HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow
> deepen-since deepen-not deepen-relative no-progress include-tag
> multi_ack_detailed no-done symref=HEAD:refs/heads/test-1
> agent=git/2.18.0
>
> which in this example shows that HEAD is a symref to refs/heads/test-1
> in origin.
>
> Is there a reason why no such option already exists? Would it makes
> sense to add one? Is there any reason why it's not a good idea? Or am
> I missing something?

I think it is a great idea to add that. IIRC there was some talk when
designing protocol v2 on how fetching of symrefs could be added later
on in the protocol, which is why I cc'd Brandon who did the work there.

> I am asking because GitLab uses HEAD in the bare repos it manages to
> store the default branch against which the Merge Requests (same thing
> as Pull Requests on GitHub) are created.
>
> So when people want to keep 2 GitLab hosted repos in sync, GitLab
> needs to sync HEADs too, not just the refs.
>
> I think this could be useful to other setups than GitLab though.

As said, I can see how that is useful; I recently came across some
HEAD bug related to submodules, and there we'd also have the application.

    git clone --recurse-submodules file://...

might clone the submodules that are in detached HEAD, which is totally
not a long term viable good HEAD, so a subsequent fetch might want
to change the detached HEAD in submodules or re-affix it to branches.

Unrelated/extended: I think it would be cool to mirror a repository even
more, e.g. it would be cool to be able to fetch (if configured as allowed)
the remote reflog, (not to be confused with you local reflog of the remote).
I think that work would be enabled once reftables are available, which you
have an eye on?

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 0/7] Resend of sb/submodule-update-in-c
  2018-08-13 22:42 ` Stefan Beller
                     ` (6 preceding siblings ...)
  2018-08-13 22:42   ` [PATCH 7/7] submodule--helper: introduce new update-module-mode helper Stefan Beller
@ 2018-08-14 21:01   ` Junio C Hamano
  2018-08-14 21:24     ` Stefan Beller
  7 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-08-14 21:01 UTC (permalink / raw)
  To: Stefan Beller; +Cc: bmwill, git

Stefan Beller <sbeller@google.com> writes:

> Thanks Brandon for pointing out to use repo_git_path instead of
> manually constructing the path.
>
> That is the only change in this resend.

Rcpt.  Hopefully this is now ready for 'next'?

^ permalink raw reply	[relevance 5%]

* Re: [PATCH] submodule: add more exhaustive up-path testing
  2018-08-14 19:10 ` [PATCH] submodule: add more exhaustive up-path testing Stefan Beller
  2018-08-14 19:54   ` Junio C Hamano
@ 2018-08-14 21:05   ` Ævar Arnfjörð Bjarmason
  2018-08-14 21:10     ` Stefan Beller
  1 sibling, 1 reply; 200+ results
From: Ævar Arnfjörð Bjarmason @ 2018-08-14 21:05 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, Junio C Hamano, Brandon Williams


On Tue, Aug 14 2018, Stefan Beller wrote:

> On Tue, Aug 14, 2018 at 11:59 AM Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>>
>> The tests added in 63e95beb08 ("submodule: port resolve_relative_url
>> from shell to C", 2016-04-15) didn't do a good job of testing various
>> up-path invocations where the up-path would bring us beyond even the
>> URL in question without emitting an error.
>>
>> These results look nonsensical, but it's worth exhaustively testing
>> them before fixing any of this code, so we can see which of these
>> cases were changed.
>
> Yeah. Please look at the comment in builtin/submodule--helper.c
> in that commit, where I described my expectations.
>
> I should have put them into tests instead with the expectations
> spelled out there.

I'll check that out thanks. I saw that comment, but have been skimming
most of this code...

> Thanks for this patch!
> Stefan
>
>>
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> ---
>
>
>> So I think these tests are worthwihle in themselves,
>
> The reason I put it in the comment instead of tests was the
> ease of spelling out both the status quo and expectations.
>
>> but would like
>> some advice on how to proceed with that from someone more familiar
>> with submodules.
>
> So ideally we'd also error out as soon as the host name is touched?

Do we have some utility function that'll take whatever we have in
remote.<name>.url and spew out the username / host / path? We must,
since the clone protocol needs it, but I haven't found it.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
      [irrelevant]         ` <20180814185743.GE142615@aiede.svl.corp.google.com>
@ 2018-08-14 21:08           ` Stefan Beller
  2018-08-14 21:12             ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-14 21:08 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Brandon Williams, Jeff King, git

On Tue, Aug 14, 2018 at 11:57 AM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> Hi,
>
> Brandon Williams wrote:
> > On 08/09, Jeff King wrote:
>
> >> One interesting thing about url-encoding is that it's not one-to-one.
> >> This case could also be %2F, which is a different file (on a
> >> case-sensitive filesystem). I think "%20" and "+" are similarly
> >> interchangeable.
> >>
> >> If we were decoding the filenames, that's fine. The round-trip is
> >> lossless.
> >>
> >> But that's not quite how the new code behaves. We encode the input and
> >> then check to see if it matches an encoding we previously performed. So
> >> if our urlencode routines ever change, this will subtly break.
> >>
> >> I don't know how much it's worth caring about. We're not that likely to
> >> change the routines ourself (though certainly a third-party
> >> implementation would need to know our exact url-encoding decisions).
> >
> > This is exactly the reason why I wanted to get some opinions on what the
> > best thing to do here would be.  I _think_ the best thing would probably
> > be to write a specific routine to do the conversion, and it wouldn't
> > even have to be all that complex.  Basically I'm just interested in
> > converting '/' characters so that things no longer behave like
> > nested directories.
>
> First of all, I think the behavior with this patch is already much
> better than the previous status quo.  I'm using the patch now and am
> very happy with it.
>
> Second, what if we store the pathname in config?  We already store the
> URL there:
>
>         [submodule "plugins/hooks"]
>                 url = https://gerrit.googlesource.com/plugins/hooks
>
> So we could (as a followup patch) do something like
>
>         [submodule "plugins/hooks"]
>                 url = https://gerrit.googlesource.com/plugins/hooks
>                 gitdirname = plugins%2fhooks
>
> and use that for lookups instead of regenerating the directory name.
> What do you think?

As I just looked at worktree code, this sounds intriguing for the wrong
reason (again), as a user may want to point the gitdirname to a repository
that they have already on disk outside the actual superproject. They
would be reinventing worktrees in the submodule space. ;-)

This would open up the security hole that we just had, again.
So we'd have to make sure that the gitdirname (instead of the
now meaningless subsection name) is proof to ../ attacks.

I feel uneasy about this as then the user might come in
and move submodules and repoint the gitdirname...
to a not url encoded path. Exposing this knob just
asks for trouble, no?

On the other hand, the only requirement for the "name" is
now uniqueness, and that is implied with subsections,
so I guess it looks elegant.

What would happen if gitdirname is changed as part of
history? (The same problem we have now with changing
the subsection name)

The more I think about it the less appealing this is, but it looks
elegant.

Stefan

^ permalink raw reply	[relevance 8%]

* Re: Syncing HEAD
  2018-08-14 20:58 ` Syncing HEAD Stefan Beller
@ 2018-08-14 21:08   ` Brandon Williams
  0 siblings, 0 replies; 200+ results
From: Brandon Williams @ 2018-08-14 21:08 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Christian Couder, git

On 08/14, Stefan Beller wrote:
> On Tue, Aug 14, 2018 at 1:09 PM Christian Couder
> <christian.couder@gmail.com> wrote:
> >
> > Hi,
> >
> > When cloning with --mirror, the clone gets its HEAD initialized with
> > the value HEAD has in its origin remote. After that if HEAD changes in
> > origin there is no simple way to sync HEAD at the same time as the
> > refs are synced.
> >
> > It looks like the simplest way to sync HEAD is:
> >
> > 1) git remote show origin
> > 2) parse "HEAD branch: XXX" from the output of the above command
> > 3) git symbolic-ref HEAD refs/heads/XXX
> >
> > It looks like it would be quite easy to add an option to `fetch` to
> > sync HEAD at the same time as regular refs are synced because every
> > fetch from an origin that uses a recent Git contains something like:
> >
> > 19:55:39.304976 pkt-line.c:80           packet:          git< YYYYYYYY
> > HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow
> > deepen-since deepen-not deepen-relative no-progress include-tag
> > multi_ack_detailed no-done symref=HEAD:refs/heads/test-1
> > agent=git/2.18.0
> >
> > which in this example shows that HEAD is a symref to refs/heads/test-1
> > in origin.
> >
> > Is there a reason why no such option already exists? Would it makes
> > sense to add one? Is there any reason why it's not a good idea? Or am
> > I missing something?
> 
> I think it is a great idea to add that. IIRC there was some talk when
> designing protocol v2 on how fetching of symrefs could be added later
> on in the protocol, which is why I cc'd Brandon who did the work there.

Actually the functionality for fetching symrefs already exists (when
using protocol v2 of course).  Despite this functionality existing its
not being used right now.

When performing a v2 fetch the first thing that a client does is request
the list of refs (by doing an ls-refs request).  The output from ls-refs
(if asked) will included information about each ref including if they
are a symref and what ref they resolve to.  So really we just need to
plumb that information through fetch to actually update HEAD, or even
update other symrefs which exist on the server.

> 
> > I am asking because GitLab uses HEAD in the bare repos it manages to
> > store the default branch against which the Merge Requests (same thing
> > as Pull Requests on GitHub) are created.
> >
> > So when people want to keep 2 GitLab hosted repos in sync, GitLab
> > needs to sync HEADs too, not just the refs.
> >
> > I think this could be useful to other setups than GitLab though.
> 
> As said, I can see how that is useful; I recently came across some
> HEAD bug related to submodules, and there we'd also have the application.
> 
>     git clone --recurse-submodules file://...
> 
> might clone the submodules that are in detached HEAD, which is totally
> not a long term viable good HEAD, so a subsequent fetch might want
> to change the detached HEAD in submodules or re-affix it to branches.
> 
> Unrelated/extended: I think it would be cool to mirror a repository even
> more, e.g. it would be cool to be able to fetch (if configured as allowed)
> the remote reflog, (not to be confused with you local reflog of the remote).
> I think that work would be enabled once reftables are available, which you
> have an eye on?

-- 
Brandon Williams

^ permalink raw reply	[relevance 2%]

* Re: [PATCH] submodule: add more exhaustive up-path testing
  2018-08-14 21:05   ` Ævar Arnfjörð Bjarmason
@ 2018-08-14 21:10     ` Stefan Beller
  2018-08-14 21:16       ` Ævar Arnfjörð Bjarmason
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-14 21:10 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Brandon Williams

On Tue, Aug 14, 2018 at 2:05 PM Ævar Arnfjörð Bjarmason
<avarab@gmail.com> wrote:

> > So ideally we'd also error out as soon as the host name is touched?
>
> Do we have some utility function that'll take whatever we have in
> remote.<name>.url and spew out the username / host / path? We must,
> since the clone protocol needs it, but I haven't found it.

Nope. Welcome to the wonderful world of submodules.
As submodules are in the transition state towards "in C",
we could do some refactorings that would allow for easy access to
these properties, but the transition is done via faithful conversion from
shell to C, which did not have these functions either, but could just
do some string hackery. And that is how we ended up with this
function in the first place.

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-14 21:08           ` [PATCH 2/2] submodule: munge paths to submodule git directories Stefan Beller
@ 2018-08-14 21:12             ` Jonathan Nieder
  2018-08-14 22:34               ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-08-14 21:12 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Brandon Williams, Jeff King, git

Hi,

Stefan Beller wrote:
> On Tue, Aug 14, 2018 at 11:57 AM Jonathan Nieder <jrnieder@gmail.com> wrote:

>> Second, what if we store the pathname in config?  We already store the
>> URL there:
>>
>>         [submodule "plugins/hooks"]
>>                 url = https://gerrit.googlesource.com/plugins/hooks
>>
>> So we could (as a followup patch) do something like
>>
>>         [submodule "plugins/hooks"]
>>                 url = https://gerrit.googlesource.com/plugins/hooks
>>                 gitdirname = plugins%2fhooks
>>
>> and use that for lookups instead of regenerating the directory name.
>> What do you think?
>
> As I just looked at worktree code, this sounds intriguing for the wrong
> reason (again), as a user may want to point the gitdirname to a repository
> that they have already on disk outside the actual superproject. They
> would be reinventing worktrees in the submodule space. ;-)
>
> This would open up the security hole that we just had, again.
> So we'd have to make sure that the gitdirname (instead of the
> now meaningless subsection name) is proof to ../ attacks.
>
> I feel uneasy about this as then the user might come in
> and move submodules and repoint the gitdirname...
> to a not url encoded path. Exposing this knob just
> asks for trouble, no?

What if we forbid directory separator characters in the gitdirname?

[...]
> What would happen if gitdirname is changed as part of
> history? (The same problem we have now with changing
> the subsection name)

In this proposal, it would only be read from config, not from
.gitmodules.

Thanks,
Jonathan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH] submodule: add more exhaustive up-path testing
  2018-08-14 21:10     ` Stefan Beller
@ 2018-08-14 21:16       ` Ævar Arnfjörð Bjarmason
  2018-08-14 21:32         ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Ævar Arnfjörð Bjarmason @ 2018-08-14 21:16 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, Junio C Hamano, Brandon Williams


On Tue, Aug 14 2018, Stefan Beller wrote:

> On Tue, Aug 14, 2018 at 2:05 PM Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>
>> > So ideally we'd also error out as soon as the host name is touched?
>>
>> Do we have some utility function that'll take whatever we have in
>> remote.<name>.url and spew out the username / host / path? We must,
>> since the clone protocol needs it, but I haven't found it.
>
> Nope. Welcome to the wonderful world of submodules.
> As submodules are in the transition state towards "in C",
> we could do some refactorings that would allow for easy access to
> these properties, but the transition is done via faithful conversion from
> shell to C, which did not have these functions either, but could just
> do some string hackery. And that is how we ended up with this
> function in the first place.

The remote/clone machinery is in C and so is the resolve-relative-url
helper. What's the missing bridge here?

Maybe we don't have that function yet, but we can presumably expose it,
and this seems unrelated to some other bits of submodules being in
shellscript.

No?

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 0/7] Resend of sb/submodule-update-in-c
  2018-08-14 21:01   ` [PATCH 0/7] Resend of sb/submodule-update-in-c Junio C Hamano
@ 2018-08-14 21:24     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-14 21:24 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Brandon Williams, git

gist
On Tue, Aug 14, 2018 at 2:01 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > Thanks Brandon for pointing out to use repo_git_path instead of
> > manually constructing the path.
> >
> > That is the only change in this resend.
>
> Rcpt.  Hopefully this is now ready for 'next'?

I don't know any reasons opposing its progression.

So, Yes, I think it is.

Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH] submodule: add more exhaustive up-path testing
  2018-08-14 21:16       ` Ævar Arnfjörð Bjarmason
@ 2018-08-14 21:32         ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-14 21:32 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: git, Junio C Hamano, Brandon Williams

On Tue, Aug 14, 2018 at 2:16 PM Ævar Arnfjörð Bjarmason
<avarab@gmail.com> wrote:
>
>
> On Tue, Aug 14 2018, Stefan Beller wrote:
>
> > On Tue, Aug 14, 2018 at 2:05 PM Ævar Arnfjörð Bjarmason
> > <avarab@gmail.com> wrote:
> >
> >> > So ideally we'd also error out as soon as the host name is touched?
> >>
> >> Do we have some utility function that'll take whatever we have in
> >> remote.<name>.url and spew out the username / host / path? We must,
> >> since the clone protocol needs it, but I haven't found it.
> >
> > Nope. Welcome to the wonderful world of submodules.
> > As submodules are in the transition state towards "in C",
> > we could do some refactorings that would allow for easy access to
> > these properties, but the transition is done via faithful conversion from
> > shell to C, which did not have these functions either, but could just
> > do some string hackery. And that is how we ended up with this
> > function in the first place.
>
> The remote/clone machinery is in C and so is the resolve-relative-url
> helper. What's the missing bridge here?
>
> Maybe we don't have that function yet, but we can presumably expose it,
> and this seems unrelated to some other bits of submodules being in
> shellscript.
>
> No?

Gah, I misread your original question. Sorry about that.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-14 21:12             ` Jonathan Nieder
@ 2018-08-14 22:34               ` Stefan Beller
  2018-08-16  2:34                 ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-14 22:34 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Brandon Williams, Jeff King, git

On Tue, Aug 14, 2018 at 2:12 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> Hi,
>
> Stefan Beller wrote:
> > On Tue, Aug 14, 2018 at 11:57 AM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> >> Second, what if we store the pathname in config?  We already store the
> >> URL there:
> >>
> >>         [submodule "plugins/hooks"]
> >>                 url = https://gerrit.googlesource.com/plugins/hooks
> >>
> >> So we could (as a followup patch) do something like
> >>
> >>         [submodule "plugins/hooks"]
> >>                 url = https://gerrit.googlesource.com/plugins/hooks
> >>                 gitdirname = plugins%2fhooks
> >>
> >> and use that for lookups instead of regenerating the directory name.
> >> What do you think?
> >
> > As I just looked at worktree code, this sounds intriguing for the wrong
> > reason (again), as a user may want to point the gitdirname to a repository
> > that they have already on disk outside the actual superproject. They
> > would be reinventing worktrees in the submodule space. ;-)
> >
> > This would open up the security hole that we just had, again.
> > So we'd have to make sure that the gitdirname (instead of the
> > now meaningless subsection name) is proof to ../ attacks.
> >
> > I feel uneasy about this as then the user might come in
> > and move submodules and repoint the gitdirname...
> > to a not url encoded path. Exposing this knob just
> > asks for trouble, no?
>
> What if we forbid directory separator characters in the gitdirname?

Fine with me, but ideally we'd want to allow sharding the
submodules. When you have 1000 submodules
we'd want them not all inside the toplevel "modules/" ?
Up to now we could just wave hands and claim the user
(who is clearly experienced with submodules as they
use so many of them) would shard it properly.

With this scheme we loose the ability to shard.

> [...]
> > What would happen if gitdirname is changed as part of
> > history? (The same problem we have now with changing
> > the subsection name)
>
> In this proposal, it would only be read from config, not from
> .gitmodules.

Ah good point. That makes sense.

Stepping back a bit regarding the config:
When I clone gerrit (or any repo using submodules)

$ git clone --recurse-submodules \
  https://gerrit.googlesource.com/gerrit g2
[...]
$ cat g2/.git/config
[submodule]
    active = .
[submodule "plugins/codemirror-editor"]
    url = https://gerrit.googlesource.com/plugins/codemirror-editor
[... more urls to follow...]

Originally we have had the url in the config, (a) that we can change
the URLs after the "git submodule init" and "git submodule update"
step that actually clones the submodule if not present and much more
importantly (b) to know which submodule "was initialized/active".

Now that we have the submodule.active or even
submodule.<name>.active flags, we do not need (b) any more.
So the URL turns into a useless piece of cruft that just is unneeded
and might confuse the user.

So maybe I'd want to propose a patch that removes
submodule.<name>.url from the config once it is cloned.
(I just read up on "submodule sync" again, but that might not
even need special care for this new world)

And with all that said, I think if we can avoid having the submodules
gitdir in the config, the config would look much cleaner, too.

But maybe that is the wrong thing to optimize for. ;-)
It just demonstrates that we'd have a submodule specific
thing again in the config.

So my preference would be to do a similar thing as
url-encoding as that solves the issue of slashes and
potentially of case sensitivity (e.g. encode upper case A
as lower case with underscore _a)

However the transition worries me, as it transitions
within the same namespace. Back then when we
transferred from the .git dir inside the submodules
working tree to the embedded version in the superprojects
.git dir, there was no overlap, and any potential directory
in .git/modules/ that was already there, was highly
unusual, so asking the user for help is the reasonable
thing to do.
But now we might run into issues that has overlap between
old(name as is) and new (urlencoded) world.

So maybe we also want to transition from

    modules/<name>

to

    submodules/<urlencoded(<name>)>

Thanks,
Stefan

^ permalink raw reply	[relevance 8%]

* [PATCH 1/2] store submodule in common dir
      [irrelevant] <95e4f9df528a40bf3f3e648318904500343abf9a.camel@infinera.com>
@ 2018-08-14 22:38 ` Stefan Beller
  2018-08-14 23:04   ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-14 22:38 UTC (permalink / raw)
  To: joakim.tjernlund; +Cc: git, bmwill, pclouds, Stefan Beller

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 path.c | 1 +
 1 file changed, 1 insertion(+)
 
On Tue, Aug 14, 2018 at 3:27 PM Joakim Tjernlund <Joakim.Tjernlund@infinera.com> wrote:
>
> I am trying to create 3 submodules from the same git repo, each pointing to a different branch.
> Since the repo is somewhat large, I don't want the 3 submodules to clone the same repo 3
> times, I want one clone and then have the 3 submodules to point to different commits.
>
> Is this possible? If not, could it be added?

yup.

According to recent discussions, it would be just this patch.
(plus some unspecified amount of work, TBD).

I thought about proposing something proper later, but here is the WIP patch.

Thanks,
Stefan 

diff --git a/path.c b/path.c
index 34f0f98349a..64c9821b834 100644
--- a/path.c
+++ b/path.c
@@ -115,6 +115,7 @@ static struct common_dir common_list[] = {
 	{ 1, 1, 1, "logs/HEAD" },
 	{ 0, 1, 1, "logs/refs/bisect" },
 	{ 0, 1, 0, "lost-found" },
+	{ 0, 1, 0, "modules" },
 	{ 0, 1, 0, "objects" },
 	{ 0, 1, 0, "refs" },
 	{ 0, 1, 1, "refs/bisect" },
-- 
2.18.0.865.gffc8e1a3cd6-goog


^ permalink raw reply	[relevance 7%]

* Re: [PATCH 1/2] store submodule in common dir
  2018-08-14 22:38 ` [PATCH 1/2] store submodule in common dir Stefan Beller
@ 2018-08-14 23:04   ` Junio C Hamano
  2018-08-14 23:23     ` Stefan Beller
      [irrelevant]     ` <xmqqk1osy1qo.fsf@gitster-ct.c.googlers.com>
  0 siblings, 2 replies; 200+ results
From: Junio C Hamano @ 2018-08-14 23:04 UTC (permalink / raw)
  To: Stefan Beller; +Cc: joakim.tjernlund, git, bmwill, pclouds

Stefan Beller <sbeller@google.com> writes:

> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  path.c | 1 +
>  1 file changed, 1 insertion(+)
>  
> On Tue, Aug 14, 2018 at 3:27 PM Joakim Tjernlund <Joakim.Tjernlund@infinera.com> wrote:
>>
>> I am trying to create 3 submodules from the same git repo, each pointing to a different branch.
>> Since the repo is somewhat large, I don't want the 3 submodules to clone the same repo 3
>> times, I want one clone and then have the 3 submodules to point to different commits.
>>
>> Is this possible? If not, could it be added?
>
> yup.
>
> According to recent discussions, it would be just this patch.
> (plus some unspecified amount of work, TBD).
>
> I thought about proposing something proper later, but here is the WIP patch.
>
> Thanks,
> Stefan 

My understanding of what Joakim wants to do is to have a top-level
project that has three subdirectories, e.g. kernel/v2.2, kernel/v2.4
and kernel/v2.6, each of which is a submodule that houses these
versions of Linux kernel source, but only clone Linus's repository
(as the up-to-late tree has all the necessary history to check out
these past development tracks).  And that should be doable with
just the main checkout, without any additional worktree (it's just
the matter of having .git/modules/kernel%2fv2.6/ directory pointed
by two symlinks from .git/modules/kernel%2fv2.[24], or something
like that).

Isn't "common_dir" stuff used to decide if each of separate
"worktree" instance (of the superproject) shares ".git/$stuff"
with each other?

Unless I am grossly misinterpreting the original question, I fail to
see how changing .git/modules to be shared across worktrees possibly
affects anything.  I am puzzled...

>
> diff --git a/path.c b/path.c
> index 34f0f98349a..64c9821b834 100644
> --- a/path.c
> +++ b/path.c
> @@ -115,6 +115,7 @@ static struct common_dir common_list[] = {
>  	{ 1, 1, 1, "logs/HEAD" },
>  	{ 0, 1, 1, "logs/refs/bisect" },
>  	{ 0, 1, 0, "lost-found" },
> +	{ 0, 1, 0, "modules" },
>  	{ 0, 1, 0, "objects" },
>  	{ 0, 1, 0, "refs" },
>  	{ 0, 1, 1, "refs/bisect" },

^ permalink raw reply	[relevance 6%]

* Re: [PATCH 1/2] store submodule in common dir
  2018-08-14 23:04   ` Junio C Hamano
@ 2018-08-14 23:23     ` Stefan Beller
      [irrelevant]     ` <xmqqk1osy1qo.fsf@gitster-ct.c.googlers.com>
  1 sibling, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-14 23:23 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: joakim.tjernlund, git, Brandon Williams, Duy Nguyen

On Tue, Aug 14, 2018 at 4:04 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > Signed-off-by: Stefan Beller <sbeller@google.com>
> > ---
> >  path.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > On Tue, Aug 14, 2018 at 3:27 PM Joakim Tjernlund <Joakim.Tjernlund@infinera.com> wrote:
> >>
> >> I am trying to create 3 submodules from the same git repo, each pointing to a different branch.
> >> Since the repo is somewhat large, I don't want the 3 submodules to clone the same repo 3
> >> times, I want one clone and then have the 3 submodules to point to different commits.
> >>
> >> Is this possible? If not, could it be added?
> >
> > yup.
> >
> > According to recent discussions, it would be just this patch.
> > (plus some unspecified amount of work, TBD).
> >
> > I thought about proposing something proper later, but here is the WIP patch.
> >
> > Thanks,
> > Stefan
>
> My understanding of what Joakim wants to do is to have a top-level
> project that has three subdirectories, e.g. kernel/v2.2, kernel/v2.4
> and kernel/v2.6, each of which is a submodule that houses these
> versions of Linux kernel source, but only clone Linus's repository
> (as the up-to-late tree has all the necessary history to check out
> these past development tracks).  And that should be doable with
> just the main checkout, without any additional worktree (it's just
> the matter of having .git/modules/kernel%2fv2.6/ directory pointed
> by two symlinks from .git/modules/kernel%2fv2.[24], or something
> like that).

Ah! I misunderstood due to fast reading.

For that I think you are interested in the feature added in d92a39590d1
(Add --reference option to git submodule., 2009-05-04), i.e.
both the update and add command take the --reference flag
that can be pointed at another repository such as an outside
clone of these three submodules, so some deduplication will
be performed.

> Isn't "common_dir" stuff used to decide if each of separate
> "worktree" instance (of the superproject) shares ".git/$stuff"
> with each other?
>
> Unless I am grossly misinterpreting the original question, I fail to
> see how changing .git/modules to be shared across worktrees possibly
> affects anything.  I am puzzled...

I did misunderstand grossly.

Stefan

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 1/2] store submodule in common dir
      [irrelevant]     ` <xmqqk1osy1qo.fsf@gitster-ct.c.googlers.com>
@ 2018-08-14 23:30       ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-14 23:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: joakim.tjernlund, git, Brandon Williams, Duy Nguyen

On Tue, Aug 14, 2018 at 4:20 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Junio C Hamano <gitster@pobox.com> writes:
>
> > My understanding of what Joakim wants to do is to have a top-level
> > project that has three subdirectories, e.g. kernel/v2.2, kernel/v2.4
> > and kernel/v2.6, each of which is a submodule that houses these
> > versions of Linux kernel source, but only clone Linus's repository
> > (as the up-to-late tree has all the necessary history to check out
> > these past development tracks).  And that should be doable with
> > just the main checkout, without any additional worktree (it's just
> > the matter of having .git/modules/kernel%2fv2.6/ directory pointed
> > by two symlinks from .git/modules/kernel%2fv2.[24], or something
> > like that).
>
> Actually I take the last part of that back.  When thought naively
> about, it may appear that it should be doable, but because each of
> the modules/* directory in the top-level project has to serve as the
> $GIT_DIR for each submodule checkout, and the desire is to have
> these three directories to have checkout of three different
> branches, a single directory under modules/. that is shared among
> three submodules would *not* work---they must have separate index,
> HEAD, etc.
>
> Theoretically we should be able to make modules/kernel%2fv2.[24]
> additional "worktree"s of modules/kernel%2fv2.6, but given that
> these are all "bare" repositories without an attached working tree,
> I am not sure how that would supposed to work.  Thinking about
> having multiple worktrees on a single bare repository makes me head
> spin and ache X-<;-)

Well the worktree feature would do all this in a safe manner, but the existing
feature of just cloning the submodules with a reference pointer to another
repository at least dedupes some of the object store, although warnings
need to be read carefully.

Regarding the worktree, I would think we'd want to have

  git worktree --recurse-submodules [list, add, etc]

that would do a sensible thing for each action on the worktrees,
but you seem to propose to have one of the three submodules
the main worktree and the other two would be just worktrees of
the first.

  I guess you could just

* init/update one of the submodules
* add their worktrees manually pointed to where
  the 2nd and 3rd submodule would go.
* make a symbolic link from
  ln -s .git/modules/<1st>/worktrees/<2nd> .git/modules/<2nd>
  ln -s .git/modules/<1st>/worktrees/<3rd> .git/modules/<3rd>

as then submodule operations should "just work" and by having the
worktrees in-place where the submodules are, we'd also have
all the protection against overzealous garbage collection, too.

Stefan

^ permalink raw reply	[relevance 8%]

* Aw: [PATCH] git-submodule.sh: accept verbose flag in cmd_update to be non-quiet
  2018-08-14 18:22 ` [PATCH] git-submodule.sh: accept verbose flag in cmd_update to be non-quiet Stefan Beller
  2018-08-14 18:28   ` Jonathan Nieder
@ 2018-08-15  6:27   ` " Jochen Kühner
  2018-08-15 22:52     ` Stefan Beller
  1 sibling, 1 reply; 200+ results
From: Jochen Kühner @ 2018-08-15  6:27 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, Stefan Beller


 

We use git for windows, there I cannot fin the git-submodule.sh! How can I fix it there?
 

Gesendet: Dienstag, 14. August 2018 um 20:22 Uhr
Von: "Stefan Beller" <sbeller@google.com>
An: jochen.kuehner@gmx.de
Cc: git@vger.kernel.org, "Stefan Beller" <sbeller@google.com>
Betreff: [PATCH] git-submodule.sh: accept verbose flag in cmd_update to be non-quiet
In a56771a668d (builtin/pull: respect verbosity settings in submodules,
2018-01-25), we made sure to pass on both quiet and verbose flag from
builtin/pull.c to the submodule shell script. However git-submodule doesn't
understand a verbose flag, which results in a bug when invoking

git pull --recurse-submodules -v [...]

There are a few different approaches to fix this bug:

1) rewrite 'argv_push_verbosity' or its caller in builtin/pull.c to
cap opt_verbosity at 0. Then 'argv_push_verbosity' would only add
'-q' if any.

2) Have a flag in 'argv_push_verbosity' that specifies if we allow adding
-q or -v (or both).

3) Add -v to git-submodule.sh and make it a no-op

(1) seems like a maintenance burden: What if we add code after
the submodule operations or move submodule operations higher up,
then we have altered the opt_verbosity setting further down the line
in builtin/pull.c.

(2) seems like it could work reasonably well without more regressions

(3) seems easiest to implement as well as actually is a feature with the
last-one-wins rule of passing flags to Git commands.

Signed-off-by: Stefan Beller <sbeller@google.com>
---

On Tue, Aug 14, 2018 at 10:54 AM Jochen Kühner <jochen.kuehner@gmx.de> wrote:
>
> If I set
> git config --global submodule.recurse true
> and run git via:
> git pull --progress -v --no-rebase "origin"
> The command will fail with following output (Errorlevel is 1)
> Fetching submodule submodules/tstemplates
> From http://10.0.102.194:7990/scm/mcc/tstemplates
> = [up to date] feature/robin -> origin/feature/robin
> = [up to date] master -> origin/master
> Already up to date.
> usage: git submodule [--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
> or: git submodule [--quiet] status [--cached] [--recursive] [--] [<path>...]
> or: git submodule [--quiet] init [--] [<path>...]
> or: git submodule [--quiet] deinit [-f|--force] (--all| [--] <path>...)
> or: git submodule [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--] [<path>...]
> or: git submodule [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
> or: git submodule [--quiet] foreach [--recursive] <command>
> or: git submodule [--quiet] sync [--recursive] [--] [<path>...]
> or: git submodule [--quiet] absorbgitdirs [--] [<path>...]
>
> seams that the “verbose” parameter “-v” is also sent to “git submodules” wich does not support it.
>
> If I remove “-v” it will work.
>
> Problem is, I use TortoiseGit, wich will automatically create this command!

git-submodule.sh | 3 +++
1 file changed, 3 insertions(+)

diff --git a/git-submodule.sh b/git-submodule.sh
index 8b5ad59bdee..f7fd80345cd 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -438,6 +438,9 @@ cmd_update()
-q|--quiet)
GIT_QUIET=1
;;
+ -v)
+ GIT_QUIET=0
+ ;;
--progress)
progress=1
;;
--
2.18.0.265.g16de1b435c9.dirty
 

^ permalink raw reply	[relevance 11%]

* Re: [PATCH] git-submodule.sh: accept verbose flag in cmd_update to be non-quiet
  2018-08-15  6:27   ` Aw: " Jochen Kühner
@ 2018-08-15 22:52     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-15 22:52 UTC (permalink / raw)
  To: jochen.kuehner; +Cc: git

On Tue, Aug 14, 2018 at 11:27 PM "Jochen Kühner" <jochen.kuehner@gmx.de> wrote:
>
>
>
>
> We use git for windows, there I cannot fin the git-submodule.sh! How can I fix it there?
>
>

It probably doesn't have the .sh extension. I don't know where all git
executables are located in GfW.

Maybe "dir /s git.exe" can give you a starting point to look for the
executables of Git.
(courtesy stackoverflow, I am no expert on Windows)

As git-submodule is a shell script and doesn't need compilation, you
can just edit
this in to see if it fixes the problem; mind to use a text editor that
doesn't put CRLF,
but LF line endings only in that file ... shell script is not the most portable.

^ permalink raw reply	[relevance 7%]

* [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed
@ 2018-08-16  2:30 Stefan Beller
  2018-08-16  2:30 ` [PATCH 1/7] t7410: update to new style Stefan Beller
                   ` (7 more replies)
  0 siblings, 8 replies; 200+ results
From: Stefan Beller @ 2018-08-16  2:30 UTC (permalink / raw)
  To: git; +Cc: bmwill, jrnieder, Stefan Beller

This is available as

  git fetch //github.com/stefanbeller/git unsetsubmoduleurl
  
and was hinted at in
https://public-inbox.org/git/CAGZ79kYfoK9hfXM2-VMAZLPpqBOFQYKtyYuYJb8twzz6Oz5ymQ@mail.gmail.com/

  Originally we have had the url in the config, (a) that we can change
  the URLs after the "git submodule init" and "git submodule update"
  step that actually clones the submodule if not present and much more
  importantly (b) to know which submodule "was initialized/active".
  
  Now that we have the submodule.active or even
  submodule.<name>.active flags, we do not need (b) any more.
  So the URL turns into a useless piece of cruft that just is unneeded
  and might confuse the user.

Opinions?

Thanks,
Stefan

Stefan Beller (7):
  t7410: update to new style
  builtin/submodule--helper: remove stray new line
  submodule: is_submodule_active to differentiate between new and old
    mode
  submodule sync: omit setting submodule URL in config if possible
  submodule--helper: factor out allocation of callback cookie
  submodule--helper, update_clone: store index to update_clone instead
    of ce
  builtin/submodule--helper: unset submodule url if possible

 builtin/submodule--helper.c      | 82 ++++++++++++++++++--------
 submodule.c                      |  5 +-
 submodule.h                      |  6 ++
 t/t5526-fetch-submodules.sh      |  2 +-
 t/t7406-submodule-update.sh      |  8 +++
 t/t7410-submodule-checkout-to.sh | 99 +++++++++++++++++++-------------
 6 files changed, 131 insertions(+), 71 deletions(-)

-- 
2.18.0.265.g16de1b435c9.dirty


^ permalink raw reply	[relevance 10%]

* [PATCH 1/7] t7410: update to new style
  2018-08-16  2:30 [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Stefan Beller
@ 2018-08-16  2:30 ` Stefan Beller
  2018-08-16 17:06   ` Junio C Hamano
  2018-08-16  2:30 ` [PATCH 2/7] builtin/submodule--helper: remove stray new line Stefan Beller
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-16  2:30 UTC (permalink / raw)
  To: git; +Cc: bmwill, jrnieder, Stefan Beller

While at it fix a typo (s/independed/independent) and
make sure git is not in a chain of pipes.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 t/t7410-submodule-checkout-to.sh | 99 +++++++++++++++++++-------------
 1 file changed, 58 insertions(+), 41 deletions(-)

diff --git a/t/t7410-submodule-checkout-to.sh b/t/t7410-submodule-checkout-to.sh
index 1acef32647a..f1b492ebc46 100755
--- a/t/t7410-submodule-checkout-to.sh
+++ b/t/t7410-submodule-checkout-to.sh
@@ -6,55 +6,72 @@ test_description='Combination of submodules and multiple workdirs'
 
 base_path=$(pwd -P)
 
-test_expect_success 'setup: make origin' \
-    'mkdir -p origin/sub && ( cd origin/sub && git init &&
-	echo file1 >file1 &&
-	git add file1 &&
-	git commit -m file1 ) &&
-    mkdir -p origin/main && ( cd origin/main && git init &&
-	git submodule add ../sub &&
-	git commit -m "add sub" ) &&
-    ( cd origin/sub &&
-	echo file1updated >file1 &&
-	git add file1 &&
-	git commit -m "file1 updated" ) &&
-    ( cd origin/main/sub && git pull ) &&
-    ( cd origin/main &&
-	git add sub &&
-	git commit -m "sub updated" )'
-
-test_expect_success 'setup: clone' \
-    'mkdir clone && ( cd clone &&
-	git clone --recursive "$base_path/origin/main")'
+test_expect_success 'setup: make origin'  '
+	mkdir -p origin/sub &&
+	(
+		cd origin/sub && git init &&
+		echo file1 >file1 &&
+		git add file1 &&
+		git commit -m file1
+	) &&
+	mkdir -p origin/main &&
+	(
+		cd origin/main && git init &&
+		git submodule add ../sub &&
+		git commit -m "add sub"
+	) &&
+	(
+		cd origin/sub &&
+		echo file1updated >file1 &&
+		git add file1 &&
+		git commit -m "file1 updated"
+	) &&
+	git -C origin/main/sub pull &&
+	(
+		cd origin/main &&
+		git add sub &&
+		git commit -m "sub updated"
+	)
+'
+
+test_expect_success 'setup: clone' '
+	mkdir clone &&
+	git -C clone clone --recursive "$base_path/origin/main"
+'
 
 rev1_hash_main=$(git --git-dir=origin/main/.git show --pretty=format:%h -q "HEAD~1")
 rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q "HEAD~1")
 
-test_expect_success 'checkout main' \
-    'mkdir default_checkout &&
-    (cd clone/main &&
-	git worktree add "$base_path/default_checkout/main" "$rev1_hash_main")'
+test_expect_success 'checkout main' '
+	mkdir default_checkout &&
+	git -C clone/main worktree add "$base_path/default_checkout/main" "$rev1_hash_main"
+'
 
-test_expect_failure 'can see submodule diffs just after checkout' \
-    '(cd default_checkout/main && git diff --submodule master"^!" | grep "file1 updated")'
+test_expect_failure 'can see submodule diffs just after checkout' '
+	git -C default_checkout/main diff --submodule master"^!" >out &&
+	grep "file1 updated" out
+'
 
-test_expect_success 'checkout main and initialize independed clones' \
-    'mkdir fully_cloned_submodule &&
-    (cd clone/main &&
-	git worktree add "$base_path/fully_cloned_submodule/main" "$rev1_hash_main") &&
-    (cd fully_cloned_submodule/main && git submodule update)'
+test_expect_success 'checkout main and initialize independent clones' '
+	mkdir fully_cloned_submodule &&
+	git -C clone/main worktree add "$base_path/fully_cloned_submodule/main" "$rev1_hash_main" &&
+	git -C fully_cloned_submodule/main submodule update
+'
 
-test_expect_success 'can see submodule diffs after independed cloning' \
-    '(cd fully_cloned_submodule/main && git diff --submodule master"^!" | grep "file1 updated")'
+test_expect_success 'can see submodule diffs after independent cloning' '
+	git -C fully_cloned_submodule/main diff --submodule master"^!" >out &&
+	grep "file1 updated" out
+'
 
-test_expect_success 'checkout sub manually' \
-    'mkdir linked_submodule &&
-    (cd clone/main &&
-	git worktree add "$base_path/linked_submodule/main" "$rev1_hash_main") &&
-    (cd clone/main/sub &&
-	git worktree add "$base_path/linked_submodule/main/sub" "$rev1_hash_sub")'
+test_expect_success 'checkout sub manually' '
+	mkdir linked_submodule &&
+	git -C clone/main worktree add "$base_path/linked_submodule/main" "$rev1_hash_main" &&
+	git -C clone/main/sub worktree add "$base_path/linked_submodule/main/sub" "$rev1_hash_sub"
+'
 
-test_expect_success 'can see submodule diffs after manual checkout of linked submodule' \
-    '(cd linked_submodule/main && git diff --submodule master"^!" | grep "file1 updated")'
+test_expect_success 'can see submodule diffs after manual checkout of linked submodule' '
+	git -C linked_submodule/main diff --submodule master"^!" >out &&
+	grep "file1 updated" out
+'
 
 test_done
-- 
2.18.0.265.g16de1b435c9.dirty


^ permalink raw reply	[relevance 20%]

* [PATCH 2/7] builtin/submodule--helper: remove stray new line
  2018-08-16  2:30 [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Stefan Beller
  2018-08-16  2:30 ` [PATCH 1/7] t7410: update to new style Stefan Beller
@ 2018-08-16  2:30 ` Stefan Beller
  2018-08-16  2:30 ` [PATCH 3/7] submodule: is_submodule_active to differentiate between new and old mode Stefan Beller
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-16  2:30 UTC (permalink / raw)
  To: git; +Cc: bmwill, jrnieder, Stefan Beller

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 5c9d1fb496d..2f20bd4abdc 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1024,7 +1024,6 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data
 {
 	struct sync_cb *info = cb_data;
 	sync_submodule(list_item->name, info->prefix, info->flags);
-
 }
 
 static int module_sync(int argc, const char **argv, const char *prefix)
-- 
2.18.0.265.g16de1b435c9.dirty


^ permalink raw reply	[relevance 13%]

* [PATCH 3/7] submodule: is_submodule_active to differentiate between new and old mode
  2018-08-16  2:30 [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Stefan Beller
  2018-08-16  2:30 ` [PATCH 1/7] t7410: update to new style Stefan Beller
  2018-08-16  2:30 ` [PATCH 2/7] builtin/submodule--helper: remove stray new line Stefan Beller
@ 2018-08-16  2:30 ` Stefan Beller
  2018-08-16 17:37   ` Junio C Hamano
  2018-08-16  2:30 ` [PATCH 4/7] submodule sync: omit setting submodule URL in config if possible Stefan Beller
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-16  2:30 UTC (permalink / raw)
  To: git; +Cc: bmwill, jrnieder, Stefan Beller

The change a086f921a72 (submodule: decouple url and submodule interest,
2017-03-17) enables us to do more than originally thought.
As the url setting was used both to actually set the url where to
obtain the submodule from, as well as used as a boolean flag later
to see if it was active, we would need to keep the url around.

Now that submodules can be activated using the submodule.[<name>.]active
setting, we could remove the url if the submodule is activated via that
setting.

In preparation to do so, pave the way by providing an easy way to see
if a submodule is considered active via the new .active setting or via
the old .url setting.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 5 +----
 submodule.h | 6 ++++++
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/submodule.c b/submodule.c
index 6e14547e9e0..d56350ed094 100644
--- a/submodule.c
+++ b/submodule.c
@@ -221,9 +221,6 @@ int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
 	return 0;
 }
 
-/*
- * Determine if a submodule has been initialized at a given 'path'
- */
 int is_submodule_active(struct repository *repo, const char *path)
 {
 	int ret = 0;
@@ -267,7 +264,7 @@ int is_submodule_active(struct repository *repo, const char *path)
 
 	/* fallback to checking if the URL is set */
 	key = xstrfmt("submodule.%s.url", module->name);
-	ret = !repo_config_get_string(repo, key, &value);
+	ret = !repo_config_get_string(repo, key, &value) ? 2 : 0;
 
 	free(value);
 	free(key);
diff --git a/submodule.h b/submodule.h
index 4644683e6cb..bfc070e4629 100644
--- a/submodule.h
+++ b/submodule.h
@@ -45,6 +45,12 @@ extern int git_default_submodule_config(const char *var, const char *value, void
 struct option;
 int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
 						     const char *arg, int unset);
+/*
+ * Determine if a submodule has been initialized at a given 'path'.
+ * Returns 1 if it is considered active via the submodule.[<name>.]active
+ * setting, or return 2 if it is active via the older submodule.url setting.
+ */
+#define SUBMODULE_ACTIVE_VIA_URL 2
 extern int is_submodule_active(struct repository *repo, const char *path);
 /*
  * Determine if a submodule has been populated at a given 'path' by checking if
-- 
2.18.0.265.g16de1b435c9.dirty


^ permalink raw reply	[relevance 24%]

* [PATCH 4/7] submodule sync: omit setting submodule URL in config if possible
  2018-08-16  2:30 [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Stefan Beller
                   ` (2 preceding siblings ...)
  2018-08-16  2:30 ` [PATCH 3/7] submodule: is_submodule_active to differentiate between new and old mode Stefan Beller
@ 2018-08-16  2:30 ` Stefan Beller
  2018-08-16  2:30 ` [PATCH 5/7] submodule--helper: factor out allocation of callback cookie Stefan Beller
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-16  2:30 UTC (permalink / raw)
  To: git; +Cc: bmwill, jrnieder, Stefan Beller

We do not need to update the submodule url in the superprojects config
if the url is not used to keep the submodule active.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 2f20bd4abdc..639d0bb20a1 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -922,8 +922,10 @@ static void sync_submodule(const char *path, const char *prefix,
 	struct strbuf sb = STRBUF_INIT;
 	struct child_process cp = CHILD_PROCESS_INIT;
 	char *sub_config_path = NULL;
+	int active, r;
 
-	if (!is_submodule_active(the_repository, path))
+	active = is_submodule_active(the_repository, path);
+	if (!active)
 		return;
 
 	sub = submodule_from_path(the_repository, &null_oid, path);
@@ -983,13 +985,15 @@ static void sync_submodule(const char *path, const char *prefix,
 	strbuf_strip_suffix(&sb, "\n");
 	remote_key = xstrfmt("remote.%s.url", sb.buf);
 
+	if (active == SUBMODULE_ACTIVE_VIA_URL)
+		FREE_AND_NULL(sub_origin_url);
 	strbuf_reset(&sb);
 	submodule_to_gitdir(&sb, path);
 	strbuf_addstr(&sb, "/config");
-
-	if (git_config_set_in_file_gently(sb.buf, remote_key, sub_origin_url))
-		die(_("failed to update remote for submodule '%s'"),
-		      path);
+	if ((r = git_config_set_in_file_gently(sb.buf, remote_key, sub_origin_url)))
+		if (sub_origin_url || r != CONFIG_NOTHING_SET)
+			die(_("failed to update remote for submodule '%s'"),
+			      path);
 
 	if (flags & OPT_RECURSIVE) {
 		struct child_process cpr = CHILD_PROCESS_INIT;
-- 
2.18.0.265.g16de1b435c9.dirty


^ permalink raw reply	[relevance 20%]

* [PATCH 5/7] submodule--helper: factor out allocation of callback cookie
  2018-08-16  2:30 [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Stefan Beller
                   ` (3 preceding siblings ...)
  2018-08-16  2:30 ` [PATCH 4/7] submodule sync: omit setting submodule URL in config if possible Stefan Beller
@ 2018-08-16  2:30 ` Stefan Beller
  2018-08-16  2:30 ` [PATCH 6/7] submodule--helper, update_clone: store index to update_clone instead of ce Stefan Beller
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-16  2:30 UTC (permalink / raw)
  To: git; +Cc: bmwill, jrnieder, Stefan Beller

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 639d0bb20a1..1c9a12781fd 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1688,6 +1688,13 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	return needs_cloning;
 }
 
+static void *update_clone_alloc_cb(int i)
+{
+	int *p = xmalloc(sizeof(*p));
+	*p = i;
+	return p;
+}
+
 static int update_clone_get_next_task(struct child_process *child,
 				      struct strbuf *err,
 				      void *suc_cb,
@@ -1700,9 +1707,7 @@ static int update_clone_get_next_task(struct child_process *child,
 	for (; suc->current < suc->list.nr; suc->current++) {
 		ce = suc->list.entries[suc->current];
 		if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
-			int *p = xmalloc(sizeof(*p));
-			*p = suc->current;
-			*idx_task_cb = p;
+			*idx_task_cb = update_clone_alloc_cb(suc->current);
 			suc->current++;
 			return 1;
 		}
@@ -1715,7 +1720,6 @@ static int update_clone_get_next_task(struct child_process *child,
 	 */
 	index = suc->current - suc->list.nr;
 	if (index < suc->failed_clones_nr) {
-		int *p;
 		ce = suc->failed_clones[index];
 		if (!prepare_to_clone_next_submodule(ce, child, suc, err)) {
 			suc->current ++;
@@ -1724,9 +1728,7 @@ static int update_clone_get_next_task(struct child_process *child,
 					   "any more?\n");
 			return 0;
 		}
-		p = xmalloc(sizeof(*p));
-		*p = suc->current;
-		*idx_task_cb = p;
+		*idx_task_cb = update_clone_alloc_cb(suc->current);
 		suc->current ++;
 		return 1;
 	}
-- 
2.18.0.265.g16de1b435c9.dirty


^ permalink raw reply	[relevance 12%]

* [PATCH 6/7] submodule--helper, update_clone: store index to update_clone instead of ce
  2018-08-16  2:30 [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Stefan Beller
                   ` (4 preceding siblings ...)
  2018-08-16  2:30 ` [PATCH 5/7] submodule--helper: factor out allocation of callback cookie Stefan Beller
@ 2018-08-16  2:30 ` Stefan Beller
  2018-08-16  2:31 ` [PATCH 7/7] builtin/submodule--helper: unset submodule url if possible Stefan Beller
  2018-08-16 15:12 ` [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Junio C Hamano
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-16  2:30 UTC (permalink / raw)
  To: git; +Cc: bmwill, jrnieder, Stefan Beller

In update_submodules, we use the run_processes_parallel(get_task, finished)
API, which allows to pass around a task specific callback cookie from the
get_next function to the finish function. That finish function in turn may
alter generic callback cookie to have the next call of get_task come up
with another new task.

Up to now we passed around the index into a list of cache entries,
which was stored in the generic callback cookie which is a struct
submodule_update_clone.

Change this to an index into 'update_clone' array, which is the potential
output of this helper. This will allow for a future change to make
use of the data the update_clone_data struct.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 1c9a12781fd..36de64902ec 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1511,8 +1511,10 @@ static int module_update_module_mode(int argc, const char **argv, const char *pr
 
 struct update_clone_data {
 	const struct submodule *sub;
+	const struct cache_entry *ce;
 	struct object_id oid;
 	unsigned just_cloned;
+	unsigned retried;
 };
 
 struct submodule_update_clone {
@@ -1541,8 +1543,8 @@ struct submodule_update_clone {
 	/* If we want to stop as fast as possible and return an error */
 	unsigned quickstop : 1;
 
-	/* failed clones to be retried again */
-	const struct cache_entry **failed_clones;
+	/* failed clones to be retried again, indexes into update_clone */
+	int *failed_clones;
 	int failed_clones_nr, failed_clones_alloc;
 
 	int max_jobs;
@@ -1649,6 +1651,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	oidcpy(&suc->update_clone[suc->update_clone_nr].oid, &ce->oid);
 	suc->update_clone[suc->update_clone_nr].just_cloned = needs_cloning;
 	suc->update_clone[suc->update_clone_nr].sub = sub;
+	suc->update_clone[suc->update_clone_nr].retried = 0;
+	suc->update_clone[suc->update_clone_nr].ce = ce;
 	suc->update_clone_nr++;
 
 	if (!needs_cloning)
@@ -1707,7 +1711,8 @@ static int update_clone_get_next_task(struct child_process *child,
 	for (; suc->current < suc->list.nr; suc->current++) {
 		ce = suc->list.entries[suc->current];
 		if (prepare_to_clone_next_submodule(ce, child, suc, err)) {
-			*idx_task_cb = update_clone_alloc_cb(suc->current);
+			*idx_task_cb = update_clone_alloc_cb(
+				suc->update_clone_nr - 1);
 			suc->current++;
 			return 1;
 		}
@@ -1720,7 +1725,9 @@ static int update_clone_get_next_task(struct child_process *child,
 	 */
 	index = suc->current - suc->list.nr;
 	if (index < suc->failed_clones_nr) {
-		ce = suc->failed_clones[index];
+		int ucd_index = suc->failed_clones[index];
+		struct update_clone_data *ucd = &suc->update_clone[ucd_index];
+		ce = ucd->ce;
 		if (!prepare_to_clone_next_submodule(ce, child, suc, err)) {
 			suc->current ++;
 			strbuf_addstr(err, "BUG: submodule considered for "
@@ -1728,7 +1735,7 @@ static int update_clone_get_next_task(struct child_process *child,
 					   "any more?\n");
 			return 0;
 		}
-		*idx_task_cb = update_clone_alloc_cb(suc->current);
+		*idx_task_cb = update_clone_alloc_cb(ucd_index);
 		suc->current ++;
 		return 1;
 	}
@@ -1750,31 +1757,31 @@ static int update_clone_task_finished(int result,
 				      void *suc_cb,
 				      void *idx_task_cb)
 {
-	const struct cache_entry *ce;
 	struct submodule_update_clone *suc = suc_cb;
+	struct update_clone_data *ucd;
 
 	int *idxP = idx_task_cb;
 	int idx = *idxP;
+	ucd = &suc->update_clone[idx];
 	free(idxP);
 
 	if (!result)
 		return 0;
 
-	if (idx < suc->list.nr) {
-		ce  = suc->list.entries[idx];
+	if (!ucd->retried) {
+		ucd->retried = 1;
 		strbuf_addf(err, _("Failed to clone '%s'. Retry scheduled"),
-			    ce->name);
+			    ucd->ce->name);
 		strbuf_addch(err, '\n');
 		ALLOC_GROW(suc->failed_clones,
 			   suc->failed_clones_nr + 1,
 			   suc->failed_clones_alloc);
-		suc->failed_clones[suc->failed_clones_nr++] = ce;
+		suc->failed_clones[suc->failed_clones_nr++] = idx;
 		return 0;
 	} else {
 		idx -= suc->list.nr;
-		ce  = suc->failed_clones[idx];
 		strbuf_addf(err, _("Failed to clone '%s' a second time, aborting"),
-			    ce->name);
+			    ucd->ce->name);
 		strbuf_addch(err, '\n');
 		suc->quickstop = 1;
 		return 1;
-- 
2.18.0.265.g16de1b435c9.dirty


^ permalink raw reply	[relevance 12%]

* [PATCH 7/7] builtin/submodule--helper: unset submodule url if possible
  2018-08-16  2:30 [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Stefan Beller
                   ` (5 preceding siblings ...)
  2018-08-16  2:30 ` [PATCH 6/7] submodule--helper, update_clone: store index to update_clone instead of ce Stefan Beller
@ 2018-08-16  2:31 ` Stefan Beller
  2018-08-16 15:12 ` [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Junio C Hamano
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-16  2:31 UTC (permalink / raw)
  To: git; +Cc: bmwill, jrnieder, Stefan Beller

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c      | 24 ++++++++++++++++++++++--
 t/t5526-fetch-submodules.sh      |  2 +-
 t/t7406-submodule-update.sh      |  8 ++++++++
 t/t7410-submodule-checkout-to.sh |  2 +-
 4 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 36de64902ec..3aa385bce5c 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1515,6 +1515,7 @@ struct update_clone_data {
 	struct object_id oid;
 	unsigned just_cloned;
 	unsigned retried;
+	unsigned cleanup_url;
 };
 
 struct submodule_update_clone {
@@ -1590,7 +1591,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	struct strbuf displaypath_sb = STRBUF_INIT;
 	struct strbuf sb = STRBUF_INIT;
 	const char *displaypath = NULL;
-	int needs_cloning = 0;
+	int needs_cloning = 0, active;
 
 	if (ce_stage(ce)) {
 		if (suc->recursive_prefix)
@@ -1632,7 +1633,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	}
 
 	/* Check if the submodule has been initialized. */
-	if (!is_submodule_active(the_repository, ce->name)) {
+	active = is_submodule_active(the_repository, ce->name);
+	if (!active) {
 		next_submodule_warn_missing(suc, out, displaypath);
 		goto cleanup;
 	}
@@ -1653,6 +1655,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	suc->update_clone[suc->update_clone_nr].sub = sub;
 	suc->update_clone[suc->update_clone_nr].retried = 0;
 	suc->update_clone[suc->update_clone_nr].ce = ce;
+	suc->update_clone[suc->update_clone_nr].cleanup_url =
+		(active != SUBMODULE_ACTIVE_VIA_URL);
 	suc->update_clone_nr++;
 
 	if (!needs_cloning)
@@ -1801,6 +1805,22 @@ static int git_update_clone_config(const char *var, const char *value,
 
 static void update_submodule(struct update_clone_data *ucd)
 {
+	if (ucd->cleanup_url) {
+		struct strbuf cfg = STRBUF_INIT;
+		struct strbuf submodule_url = STRBUF_INIT;
+		int r;
+
+		strbuf_addf(&submodule_url, "submodule.%s.url", ucd->sub->name);
+		strbuf_repo_git_path(&cfg, the_repository, "config");
+
+		r = git_config_set_in_file_gently(cfg.buf, submodule_url.buf, NULL);
+		if (r && r != CONFIG_NOTHING_SET)
+			die(_("failed to remove '%s'"), submodule_url.buf);
+
+		strbuf_release(&cfg);
+		strbuf_release(&submodule_url);
+	}
+
 	fprintf(stdout, "dummy %s %d\t%s\n",
 		oid_to_hex(&ucd->oid),
 		ucd->just_cloned,
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 0f730d77815..cd1bd131b59 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -508,7 +508,7 @@ test_expect_success "'fetch.recurseSubmodules=on-demand' works also without .git
 		git config -f .gitmodules submodule.fake.path fake &&
 		git config -f .gitmodules submodule.fake.url fakeurl &&
 		git add .gitmodules &&
-		git config --unset submodule.submodule.url &&
+		test_might_fail git config --unset submodule.submodule.url &&
 		git fetch >../actual.out 2>../actual.err &&
 		# cleanup
 		git config --unset fetch.recurseSubmodules &&
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index f604ef7a729..f581fea28e0 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -84,6 +84,14 @@ test_expect_success 'submodule update detaching the HEAD ' '
 	)
 '
 
+test_expect_success 'active submodule leaves no URL config in superproject' '
+	# relies on previous test
+	(
+		cd super &&
+		test_must_fail git config -f .git/config submodule.submodule.url
+	)
+'
+
 test_expect_success 'submodule update from subdirectory' '
 	(cd super/submodule &&
 	 git reset --hard HEAD~1
diff --git a/t/t7410-submodule-checkout-to.sh b/t/t7410-submodule-checkout-to.sh
index f1b492ebc46..683e957934b 100755
--- a/t/t7410-submodule-checkout-to.sh
+++ b/t/t7410-submodule-checkout-to.sh
@@ -55,7 +55,7 @@ test_expect_failure 'can see submodule diffs just after checkout' '
 test_expect_success 'checkout main and initialize independent clones' '
 	mkdir fully_cloned_submodule &&
 	git -C clone/main worktree add "$base_path/fully_cloned_submodule/main" "$rev1_hash_main" &&
-	git -C fully_cloned_submodule/main submodule update
+	git -C fully_cloned_submodule/main submodule update --init
 '
 
 test_expect_success 'can see submodule diffs after independent cloning' '
-- 
2.18.0.265.g16de1b435c9.dirty


^ permalink raw reply	[relevance 31%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-14 22:34               ` Stefan Beller
@ 2018-08-16  2:34                 ` Jonathan Nieder
  2018-08-16  2:39                   ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-08-16  2:34 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Brandon Williams, Jeff King, git

Hi again,

Stefan Beller wrote:
> On Tue, Aug 14, 2018 at 2:12 PM Jonathan Nieder <jrnieder@gmail.com> wrote:

>> What if we forbid directory separator characters in the gitdirname?
>
> Fine with me, but ideally we'd want to allow sharding the
> submodules. When you have 1000 submodules
> we'd want them not all inside the toplevel "modules/" ?

That's a good reason to permit slashes in the gitdirname.

If I understood the rest of your reply correctly, your worry was about
dangerous gitdirname values in .gitmodules.  I never had any wish to
read them from there anyway, so this worry hopefully goes away.

[...]
>> In this proposal, it would only be read from config, not from
>> .gitmodules.
>
> Ah good point. That makes sense.
>
> Stepping back a bit regarding the config:
[...]
> Now that we have the submodule.active or even
> submodule.<name>.active flags, we do not need (b) any more.
> So the URL turns into a useless piece of cruft that just is unneeded
> and might confuse the user.
>
> So maybe I'd want to propose a patch that removes
> submodule.<name>.url from the config once it is cloned.
> (I just read up on "submodule sync" again, but that might not
> even need special care for this new world)
>
> And with all that said, I think if we can avoid having the submodules
> gitdir in the config, the config would look much cleaner, too.

Yes, I understand and agree with this.

I should further spell out my motivation with this gitdirname
suggestion.  The issue that some people have mentioned in this thread
is that urlencoding might not be perfect --- it's pretty close to
perfect, but it's likely we'll come up with some unanticipated needs
later (like sharding) that it doesn't solve.  Solving those all right
now would not necessarily be wise, since the thing about unanticipated
needs is that you never know in advance what they will be. ;-)

So it would be nice, for future-proofing, if we can change the naming
scheme later.

As a bonus, that would also make interoperability with other
implementations easier.  For example, suppose we mess up in JGit and
urlencode a different set of characters than Git does.  Then a mixed
Git + JGit installation would have this subtle bug of the submodule
.git directory not being reused when I switch to and from and branch
not containing that submodule, in some circumstances.  That sounds
difficult to support.

Whereas if we have a gitdirname configuration variable, then JGit and
libgit2 and go-git do not have to match the naming scheme Git chooses.
They can try, but if one gets it subtly wrong then that is okay
because the submodule's directory name is right there and easy to look
up.

All at the cost of recording a little configuration somewhere.  If we
want to decrease the configuration, we can avoid recording it there in
the easy cases (e.g. when name == gitdirname).  That's "just" an
optimization.

And then we have the ability later to handle all the edge cases we
haven't handled yet today:

- sharding when the number of submodules is too large
- case-insensitive filesystems
- path name length limits
- different sets of filesystem-special characters

Sane?

Thanks,
Jonathan

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-16  2:34                 ` Jonathan Nieder
@ 2018-08-16  2:39                   ` Stefan Beller
  2018-08-16  2:47                     ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-16  2:39 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Brandon Williams, Jeff King, git

> [...]

all good reasons; ship it :-)

> All at the cost of recording a little configuration somewhere.  If we
> want to decrease the configuration, we can avoid recording it there in
> the easy cases (e.g. when name == gitdirname).  That's "just" an
> optimization.

Sounds good, but gerrit for example would not take advantage of such
optimisation as they have slashes in their submodules. :-(
I wonder if we can optimize further and keep slashes if there is
no conflict (as then name == gitdirname, so it can be optimized).

> And then we have the ability later to handle all the edge cases we
> haven't handled yet today:
>
> - sharding when the number of submodules is too large
> - case-insensitive filesystems
> - path name length limits
> - different sets of filesystem-special characters
>
> Sane?

I'll keep thinking about it.

FYI: the reduction in configuration was just sent out.

Thanks,
Stefan

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-16  2:39                   ` Stefan Beller
@ 2018-08-16  2:47                     ` Jonathan Nieder
  2018-08-16 17:34                       ` Brandon Williams
  0 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-08-16  2:47 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Brandon Williams, Jeff King, git

Stefan Beller wrote:
> Jonathan Nieder wrote:

>> All at the cost of recording a little configuration somewhere.  If we
>> want to decrease the configuration, we can avoid recording it there in
>> the easy cases (e.g. when name == gitdirname).  That's "just" an
>> optimization.
>
> Sounds good, but gerrit for example would not take advantage of such
> optimisation as they have slashes in their submodules. :-(
> I wonder if we can optimize further and keep slashes if there is
> no conflict (as then name == gitdirname, so it can be optimized).

One possibility would be to treat gsub("/", "%2f") as another of the
easy cases.

[...]
>> And then we have the ability later to handle all the edge cases we
>> haven't handled yet today:
>>
>> - sharding when the number of submodules is too large
>> - case-insensitive filesystems
>> - path name length limits
>> - different sets of filesystem-special characters
>>
>> Sane?
>
> I'll keep thinking about it.

Thanks.

> FYI: the reduction in configuration was just sent out.

https://public-inbox.org/git/20180816023100.161626-1-sbeller@google.com/
for those following along.

Ciao,
Jonathan

^ permalink raw reply	[relevance 5%]

* Re: submodules : switching to an older commit/Tag in project with submodules
      [irrelevant] <bc9762aaf57e441e95f9eed4e64799b7@EX13.visionmap.co.il>
@ 2018-08-16 14:56 ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-16 14:56 UTC (permalink / raw)
  To: Shani.Fridman; +Cc: git

On Thu, Aug 16, 2018 at 4:55 AM Shani Fridman
<Shani.Fridman@visionmap.com> wrote:
>
>
> Hi everybody,
>
> I've got a question regarding submodules -
>
> I'm working on a git project with submodules connected to it, and pulling changes from them every month (more or less).
> Sometimes I need to checkout older versions of the project (tags or specific commits), that needs the older versions of the submodules as they were when I defined the tag. The problem is, that the checkout only changes the superProject directories, and not the submodules... I have to checkout the relevant submodules commit manually.
>
> Have you came across the same problem? Any idea what can I do?

git checkout learned about the --recurse-submodules flag some time
ago. If that is what you need, just set 'git config submodule.recurse
true' so you don't have to pass that flag every time.

Hope that helps,
Stefan

^ permalink raw reply	[relevance 8%]

* Re: [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed
  2018-08-16  2:30 [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Stefan Beller
                   ` (6 preceding siblings ...)
  2018-08-16  2:31 ` [PATCH 7/7] builtin/submodule--helper: unset submodule url if possible Stefan Beller
@ 2018-08-16 15:12 ` Junio C Hamano
  2018-08-16 15:45   ` Stefan Beller
  7 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-08-16 15:12 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, bmwill, jrnieder

Stefan Beller <sbeller@google.com> writes:

>   Originally we have had the url in the config, (a) that we can change
>   the URLs after the "git submodule init" and "git submodule update"
>   step that actually clones the submodule if not present and much more
>   importantly (b) to know which submodule "was initialized/active".
>   
>   Now that we have the submodule.active or even
>   submodule.<name>.active flags, we do not need (b) any more.

Up to that point the description is sane.

>   So the URL turns into a useless piece of cruft that just is unneeded
>   and might confuse the user.
>
> Opinions?

You spelled out why you do not need for (b) but not for (a) and
worse it is is unclear if you never need it for (a) or under what
condition you need it for (a).  So there isn't enough information to
form an opinion in the above.  Sorry--readers need to go to the real
patches.


^ permalink raw reply	[relevance 5%]

* Re: [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed
  2018-08-16 15:12 ` [RFC PATCH 0/7] Unset the submodule URL in the superproject when no longer needed Junio C Hamano
@ 2018-08-16 15:45   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-16 15:45 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Brandon Williams, Jonathan Nieder

On Thu, Aug 16, 2018 at 8:12 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> >   Originally we have had the url in the config, (a) that we can change
> >   the URLs after the "git submodule init" and "git submodule update"
> >   step that actually clones the submodule if not present and much more
> >   importantly (b) to know which submodule "was initialized/active".
> >
> >   Now that we have the submodule.active or even
> >   submodule.<name>.active flags, we do not need (b) any more.
>
> Up to that point the description is sane.
>
> >   So the URL turns into a useless piece of cruft that just is unneeded
> >   and might confuse the user.
> >
> > Opinions?
>
> You spelled out why you do not need for (b) but not for (a) and
> worse it is is unclear if you never need it for (a) or under what
> condition you need it for (a).  So there isn't enough information to
> form an opinion in the above.  Sorry--readers need to go to the real
> patches.

Regarding (a): Once the submodule is cloned, you either need
to change the remote in the submodule or you can use "git submodule sync"
which can bypass the superproject config, too (that copies the URL from
.gitmodules to the submodules config/remote)

I don't think (a) is needed after the clone of a submodule is done.

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 1/7] t7410: update to new style
  2018-08-16  2:30 ` [PATCH 1/7] t7410: update to new style Stefan Beller
@ 2018-08-16 17:06   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-08-16 17:06 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, bmwill, jrnieder

Stefan Beller <sbeller@google.com> writes:

> While at it fix a typo (s/independed/independent) and
> make sure git is not in a chain of pipes.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  t/t7410-submodule-checkout-to.sh | 99 +++++++++++++++++++-------------
>  1 file changed, 58 insertions(+), 41 deletions(-)

Makes sense and the result does read easier.

> diff --git a/t/t7410-submodule-checkout-to.sh b/t/t7410-submodule-checkout-to.sh
> index 1acef32647a..f1b492ebc46 100755
> --- a/t/t7410-submodule-checkout-to.sh
> +++ b/t/t7410-submodule-checkout-to.sh
> @@ -6,55 +6,72 @@ test_description='Combination of submodules and multiple workdirs'
>  
>  base_path=$(pwd -P)
>  
> -test_expect_success 'setup: make origin' \
> -    'mkdir -p origin/sub && ( cd origin/sub && git init &&
> -	echo file1 >file1 &&
> -	git add file1 &&
> -	git commit -m file1 ) &&
> -    mkdir -p origin/main && ( cd origin/main && git init &&
> -	git submodule add ../sub &&
> -	git commit -m "add sub" ) &&
> -    ( cd origin/sub &&
> -	echo file1updated >file1 &&
> -	git add file1 &&
> -	git commit -m "file1 updated" ) &&
> -    ( cd origin/main/sub && git pull ) &&
> -    ( cd origin/main &&
> -	git add sub &&
> -	git commit -m "sub updated" )'
> -
> -test_expect_success 'setup: clone' \
> -    'mkdir clone && ( cd clone &&
> -	git clone --recursive "$base_path/origin/main")'
> +test_expect_success 'setup: make origin'  '
> +	mkdir -p origin/sub &&
> +	(
> +		cd origin/sub && git init &&
> +		echo file1 >file1 &&
> +		git add file1 &&
> +		git commit -m file1
> +	) &&
> +	mkdir -p origin/main &&
> +	(
> +		cd origin/main && git init &&
> +		git submodule add ../sub &&
> +		git commit -m "add sub"
> +	) &&
> +	(
> +		cd origin/sub &&
> +		echo file1updated >file1 &&
> +		git add file1 &&
> +		git commit -m "file1 updated"
> +	) &&
> +	git -C origin/main/sub pull &&
> +	(
> +		cd origin/main &&
> +		git add sub &&
> +		git commit -m "sub updated"
> +	)
> +'
> +
> +test_expect_success 'setup: clone' '
> +	mkdir clone &&
> +	git -C clone clone --recursive "$base_path/origin/main"
> +'
>  
>  rev1_hash_main=$(git --git-dir=origin/main/.git show --pretty=format:%h -q "HEAD~1")
>  rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q "HEAD~1")
>  
> -test_expect_success 'checkout main' \
> -    'mkdir default_checkout &&
> -    (cd clone/main &&
> -	git worktree add "$base_path/default_checkout/main" "$rev1_hash_main")'
> +test_expect_success 'checkout main' '
> +	mkdir default_checkout &&
> +	git -C clone/main worktree add "$base_path/default_checkout/main" "$rev1_hash_main"
> +'
>  
> -test_expect_failure 'can see submodule diffs just after checkout' \
> -    '(cd default_checkout/main && git diff --submodule master"^!" | grep "file1 updated")'
> +test_expect_failure 'can see submodule diffs just after checkout' '
> +	git -C default_checkout/main diff --submodule master"^!" >out &&
> +	grep "file1 updated" out
> +'
>  
> -test_expect_success 'checkout main and initialize independed clones' \
> -    'mkdir fully_cloned_submodule &&
> -    (cd clone/main &&
> -	git worktree add "$base_path/fully_cloned_submodule/main" "$rev1_hash_main") &&
> -    (cd fully_cloned_submodule/main && git submodule update)'
> +test_expect_success 'checkout main and initialize independent clones' '
> +	mkdir fully_cloned_submodule &&
> +	git -C clone/main worktree add "$base_path/fully_cloned_submodule/main" "$rev1_hash_main" &&
> +	git -C fully_cloned_submodule/main submodule update
> +'
>  
> -test_expect_success 'can see submodule diffs after independed cloning' \
> -    '(cd fully_cloned_submodule/main && git diff --submodule master"^!" | grep "file1 updated")'
> +test_expect_success 'can see submodule diffs after independent cloning' '
> +	git -C fully_cloned_submodule/main diff --submodule master"^!" >out &&
> +	grep "file1 updated" out
> +'
>  
> -test_expect_success 'checkout sub manually' \
> -    'mkdir linked_submodule &&
> -    (cd clone/main &&
> -	git worktree add "$base_path/linked_submodule/main" "$rev1_hash_main") &&
> -    (cd clone/main/sub &&
> -	git worktree add "$base_path/linked_submodule/main/sub" "$rev1_hash_sub")'
> +test_expect_success 'checkout sub manually' '
> +	mkdir linked_submodule &&
> +	git -C clone/main worktree add "$base_path/linked_submodule/main" "$rev1_hash_main" &&
> +	git -C clone/main/sub worktree add "$base_path/linked_submodule/main/sub" "$rev1_hash_sub"
> +'
>  
> -test_expect_success 'can see submodule diffs after manual checkout of linked submodule' \
> -    '(cd linked_submodule/main && git diff --submodule master"^!" | grep "file1 updated")'
> +test_expect_success 'can see submodule diffs after manual checkout of linked submodule' '
> +	git -C linked_submodule/main diff --submodule master"^!" >out &&
> +	grep "file1 updated" out
> +'
>  
>  test_done

^ permalink raw reply	[relevance 2%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-16  2:47                     ` Jonathan Nieder
@ 2018-08-16 17:34                       ` Brandon Williams
  0 siblings, 0 replies; 200+ results
From: Brandon Williams @ 2018-08-16 17:34 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Stefan Beller, Jeff King, git

On 08/15, Jonathan Nieder wrote:
> Stefan Beller wrote:
> > Jonathan Nieder wrote:
> 
> >> All at the cost of recording a little configuration somewhere.  If we
> >> want to decrease the configuration, we can avoid recording it there in
> >> the easy cases (e.g. when name == gitdirname).  That's "just" an
> >> optimization.
> >
> > Sounds good, but gerrit for example would not take advantage of such
> > optimisation as they have slashes in their submodules. :-(
> > I wonder if we can optimize further and keep slashes if there is
> > no conflict (as then name == gitdirname, so it can be optimized).
> 
> One possibility would be to treat gsub("/", "%2f") as another of the
> easy cases.
> 
> [...]
> >> And then we have the ability later to handle all the edge cases we
> >> haven't handled yet today:
> >>
> >> - sharding when the number of submodules is too large
> >> - case-insensitive filesystems
> >> - path name length limits
> >> - different sets of filesystem-special characters
> >>
> >> Sane?

Seems like a sensible thing to do. Let me work up some patches to
implement this using config primarily and these other schemes as
fallbacks.

> >
> > I'll keep thinking about it.
> 
> Thanks.
> 
> > FYI: the reduction in configuration was just sent out.
> 
> https://public-inbox.org/git/20180816023100.161626-1-sbeller@google.com/
> for those following along.
> 
> Ciao,
> Jonathan

-- 
Brandon Williams

^ permalink raw reply	[relevance 3%]

* Re: [PATCH 3/7] submodule: is_submodule_active to differentiate between new and old mode
  2018-08-16  2:30 ` [PATCH 3/7] submodule: is_submodule_active to differentiate between new and old mode Stefan Beller
@ 2018-08-16 17:37   ` Junio C Hamano
  2018-08-20 19:50     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-08-16 17:37 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, bmwill, jrnieder

Stefan Beller <sbeller@google.com> writes:

> The change a086f921a72 (submodule: decouple url and submodule interest,
> 2017-03-17) enables us to do more than originally thought.
> As the url setting was used both to actually set the url where to
> obtain the submodule from, as well as used as a boolean flag later
> to see if it was active, we would need to keep the url around.
>
> Now that submodules can be activated using the submodule.[<name>.]active
> setting, we could remove the url if the submodule is activated via that
> setting.

... as the cloned submodule repository has $GIT_DIR/config which
knows its own origin, we do not need to record URL in superproject's
$GIT_DIR/config.  Back before we started using a directory under
$GIT_DIR/modules/ as a more permanent location to store submodule,
and point at it by a gitdir file in $path/.git to allow removal of a
submodule from the working tree of the superproject without having
to reclone when resurrecting the same submodule, it may have been
useful to keep custom URL somewhere in the superproject, but that no
longer is the case.

> In preparation to do so, pave the way by providing an easy way to see
> if a submodule is considered active via the new .active setting or via
> the old .url setting.

Makes sense.

>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c | 5 +----
>  submodule.h | 6 ++++++
>  2 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/submodule.c b/submodule.c
> index 6e14547e9e0..d56350ed094 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -221,9 +221,6 @@ int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
>  	return 0;
>  }
>  
> -/*
> - * Determine if a submodule has been initialized at a given 'path'
> - */
>  int is_submodule_active(struct repository *repo, const char *path)
>  {
>  	int ret = 0;
> @@ -267,7 +264,7 @@ int is_submodule_active(struct repository *repo, const char *path)
>  
>  	/* fallback to checking if the URL is set */
>  	key = xstrfmt("submodule.%s.url", module->name);
> -	ret = !repo_config_get_string(repo, key, &value);
> +	ret = !repo_config_get_string(repo, key, &value) ? 2 : 0;
>
>  	free(value);
>  	free(key);
> diff --git a/submodule.h b/submodule.h
> index 4644683e6cb..bfc070e4629 100644
> --- a/submodule.h
> +++ b/submodule.h
> @@ -45,6 +45,12 @@ extern int git_default_submodule_config(const char *var, const char *value, void
>  struct option;
>  int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
>  						     const char *arg, int unset);
> +/*
> + * Determine if a submodule has been initialized at a given 'path'.
> + * Returns 1 if it is considered active via the submodule.[<name>.]active
> + * setting, or return 2 if it is active via the older submodule.url setting.
> + */
> +#define SUBMODULE_ACTIVE_VIA_URL 2
>  extern int is_submodule_active(struct repository *repo, const char *path);
>  /*
>   * Determine if a submodule has been populated at a given 'path' by checking if

This change assumes that all the existing return sites in the
is_submodule_active() function signals true with 1 (or at least some
value that is different from 2).

But the part that uses submodule.active as pathspec list calls
match_pathspec() and uses its return value to signal if the module
is active.  match_pathspec() in turn uses dir.c::do_match_pathspec()
which signals _how_ the set of pathspec list elements matched to the
given name by returning various forms of true, like MATCHED_FNMATCH,
etc.

So I think this patch is insufficient, and needs to at least change
the "submodule.active" codepath to return !!ret; otherwise, a caller
that now expects 0 (not active), 1 (active but can lose URL) and 2
(active and the presence of URL makes it so) will be confused when
one of the MATCHED_* constants from dir.h comes back.




^ permalink raw reply	[relevance 7%]

* Re: [PATCH 6/6] pack-objects: reuse on-disk deltas for thin "have" objects
      [irrelevant] ` <20180817210604.GF20088@sigill.intra.peff.net>
@ 2018-08-17 22:57   ` Stefan Beller
  2018-08-17 23:32     ` Jeff King
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-17 22:57 UTC (permalink / raw)
  To: Jeff King; +Cc: git

On Fri, Aug 17, 2018 at 2:06 PM Jeff King <peff@peff.net> wrote:
>
> When we serve a fetch, we pass the "wants" and "haves" from
> the fetch negotiation to pack-objects. That tells us not
> only which objects we need to send, but we also use the
> boundary commits as "preferred bases": their trees and blobs
> are candidates for delta bases, both for reusing on-disk
> deltas and for finding new ones.
>
> However, this misses some opportunities. Modulo some special
> cases like shallow or partial clones, we know that every
> object reachable from the "haves" could be a preferred base.
> We don't use them all for two reasons:

s/all/at all/ ?

> The first is that check_object() needs access to the
> relevant information (the thin flag and bitmap result). We
> can do this by pushing these into program-lifetime globals.

I discussed internally if extending the fetch protocol to include
submodule packs would be a good idea, as then you can get all
the superproject+submodule updates via one connection. This
gives some benefits, such as a more consistent view from the
superproject as well as already knowing the have/wants for
the submodule.

With this background story, moving things into globals
makes me sad, but I guess we can flip this decision once
we actually move towards "submodule packs in the
main connection".

>
> The second is that the rest of the code assumes that any
> reused delta will point to another "struct object_entry" as
> its base. But by definition, we don't have such an entry!

I got lost here by the definition (which def?).

  The delta that we look up from the bitmap, doesn't may
  not be in the pack, but it could be based off of an object
  the client already has in its object store and for that
  there is no struct object_entry in memory.

Is that correct?

> So taking all of those options into account, what I ended up
> with is a separate list of "external bases" that are not
> part of the main packing list. Each delta entry that points
> to an external base has a single-bit flag to do so; we have a
> little breathing room in the bitfield section of
> object_entry.
>
> This lets us limit the change primarily to the oe_delta()
> and oe_set_delta_ext() functions. And as a bonus, most of
> the rest of the code does not consider these dummy entries
> at all, saving both runtime CPU and code complexity.

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 6/6] pack-objects: reuse on-disk deltas for thin "have" objects
  2018-08-17 22:57   ` [PATCH 6/6] pack-objects: reuse on-disk deltas for thin "have" objects Stefan Beller
@ 2018-08-17 23:32     ` Jeff King
  0 siblings, 0 replies; 200+ results
From: Jeff King @ 2018-08-17 23:32 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

On Fri, Aug 17, 2018 at 03:57:18PM -0700, Stefan Beller wrote:

> On Fri, Aug 17, 2018 at 2:06 PM Jeff King <peff@peff.net> wrote:
> >
> > When we serve a fetch, we pass the "wants" and "haves" from
> > the fetch negotiation to pack-objects. That tells us not
> > only which objects we need to send, but we also use the
> > boundary commits as "preferred bases": their trees and blobs
> > are candidates for delta bases, both for reusing on-disk
> > deltas and for finding new ones.
> >
> > However, this misses some opportunities. Modulo some special
> > cases like shallow or partial clones, we know that every
> > object reachable from the "haves" could be a preferred base.
> > We don't use them all for two reasons:
> 
> s/all/at all/ ?

No, I meant "we don't use all of them". As in the Pokemon "gotta catch
'em all" slogan. ;)

Probably writing out "all of them" is better.

> > The first is that check_object() needs access to the
> > relevant information (the thin flag and bitmap result). We
> > can do this by pushing these into program-lifetime globals.
> 
> I discussed internally if extending the fetch protocol to include
> submodule packs would be a good idea, as then you can get all
> the superproject+submodule updates via one connection. This
> gives some benefits, such as a more consistent view from the
> superproject as well as already knowing the have/wants for
> the submodule.
> 
> With this background story, moving things into globals
> makes me sad, but I guess we can flip this decision once
> we actually move towards "submodule packs in the
> main connection".

I don't think it significantly changes the existing code, which is
already relying on a ton of globals (most notably to_pack). The first
step in doing multiple packs in the same process is going to be to shove
all of that into a "struct pack_objects_context" or similar, and these
can just follow the rest.

> >
> > The second is that the rest of the code assumes that any
> > reused delta will point to another "struct object_entry" as
> > its base. But by definition, we don't have such an entry!
> 
> I got lost here by the definition (which def?).
> 
>   The delta that we look up from the bitmap, doesn't may
>   not be in the pack, but it could be based off of an object
>   the client already has in its object store and for that
>   there is no struct object_entry in memory.
> 
> Is that correct?

Right, we are interested in objects that we _couldn't_ find a struct
for.  I agree this could be more clear.

-Peff

^ permalink raw reply	[relevance 2%]

* Re: [PATCH 7/7] submodule--helper: introduce new update-module-mode helper
  2018-08-13 22:42   ` [PATCH 7/7] submodule--helper: introduce new update-module-mode helper Stefan Beller
@ 2018-08-18 16:10     ` Duy Nguyen
  2018-08-20 19:44       ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Duy Nguyen @ 2018-08-18 16:10 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Junio C Hamano, Brandon Williams, Git Mailing List

On Tue, Aug 14, 2018 at 12:45 AM Stefan Beller <sbeller@google.com> wrote:
> +static int module_update_module_mode(int argc, const char **argv, const char *prefix)
> +{
> +       const char *path, *update = NULL;
> +       int just_cloned;
> +       struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT };
> +
> +       if (argc < 3 || argc > 4)
> +               die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]");

Maybe _() ?
-- 
Duy

^ permalink raw reply	[relevance 5%]

* Re: What's cooking in git.git (Aug 2018, #04; Fri, 17)
      [irrelevant] <xmqqva88aa0c.fsf@gitster-ct.c.googlers.com>
@ 2018-08-20 18:11 ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-20 18:11 UTC (permalink / raw)
  To: Junio C Hamano, Duy Nguyen, Antonio Ospite; +Cc: git

On Fri, Aug 17, 2018 at 3:44 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Usually, I refrain from merging larger topics in 'next' down to
> 'master' when we get close to -rc0, but I am wondering if it is
> better to merge all of them to 'master', even the ones on the larger
> and possibly undercooked side, expecting that we collectively spend
> effort on hunting and fixing bugs in them during the pre-release
> freeze period.  If we were to go that route, I'd want everybody's
> buy-in and I'll promise to ignore any shiny new toys that appear on
> list that are not regression fixes to topics merged to 'master'
> since the end of the previous cycle to make sure people are not
> distracted.

Speaking of releases, linux for example has some releases that are
more stable than others, as most distros pick the same release for
their 'stable' release, whereas the regular and new releases are just
off of the latest release of linux.

Would a similar model be an interesting thought to entertain?

I guess I could buy into a few weeks of bug fixing.

> * nd/config-blame-sort (2018-08-06) 1 commit
[...]
> * nd/no-extern (2018-08-03) 12 commits
[...]

Thanks Duy for these two series!

I would have expected the no-extern series to
have a bit of merge conflicts similar to  sb/object-store-lookup
as it touches a lot of headers, but so far this looks like smooth sailing?

> * sb/submodule-cleanup (2018-08-16) 2 commits
>   (merged to 'next' on 2018-08-17 at ca9d8aaef4)
>  + builtin/submodule--helper: remove stray new line
>  + t7410: update to new style
>
>  A few preliminary minor clean-ups in the area around submodules.
>
>  Will merge to 'master'.

Oh, that is the prologue of
https://public-inbox.org/git/20180816023100.161626-1-sbeller@google.com/
which I will resend to build on top. Given your question to hunt more bugs,
I'd delay its resend until after the release.

>
> * ao/submodule-wo-gitmodules-checked-out (2018-08-14) 7 commits
>  - submodule: support reading .gitmodules even when it's not checked out
>  - t7506: clean up .gitmodules properly before setting up new scenario
>  - submodule: use the 'submodule--helper config' command
>  - submodule--helper: add a new 'config' subcommand
>  - t7411: be nicer to future tests and really clean things up
>  - submodule: factor out a config_set_in_gitmodules_file_gently function
>  - submodule: add a print_config_from_gitmodules() helper
>
>  The submodule support has been updated to read from the blob at
>  HEAD:.gitmodules when the .gitmodules file is missing from the
>  working tree.
>
>  I find the design a bit iffy in that our usual "missing in the
>  working tree?  let's use the latest blob" fallback is to take it
>  from the index, not from the HEAD.

I am not sure; why does it feel iffy?

> * bw/submodule-name-to-dir (2018-08-10) 2 commits
>  In modern repository layout, the real body of a cloned submodule
>  repository is held in .git/modules/ of the superproject, indexed by
>  the submodule name.  URLencode the submodule name before computing
>  the name of the directory to make sure they form a flat namespace.
>
>  Will merge to 'next'.

Cool! Is the discussion on top of it still going whether to use a
new config for special cases or how we distinguish between a/b/
and a%2fb as submodule names?

> * md/filter-trees (2018-08-16) 6 commits
>  - list-objects-filter: implement filter tree:0
>  - revision: mark non-user-given objects instead
>  - rev-list: handle missing tree objects properly
>  - list-objects: always parse trees gently
>  - list-objects: refactor to process_tree_contents
>  - list-objects: store common func args in struct
>
>  The "rev-list --filter" feature learned to exclude all trees via
>  "tree:0" filter.

I gave this a read and think it is good to go.

> * sb/config-write-fix (2018-08-08) 3 commits
>   (merged to 'next' on 2018-08-17 at 7d9c7ce81f)
>  + git-config: document accidental multi-line setting in deprecated syntax
>  + config: fix case sensitive subsection names on writing
>  + t1300: document current behavior of setting options
>
>  Recent update to "git config" broke updating variable in a
>  subsection, which has been corrected.
>
>  Will merge to 'master'.

Thanks!

>
>
> * sb/range-diff-colors (2018-08-14) 8 commits
>  - diff.c: rewrite emit_line_0 more understandably
>  - diff.c: omit check for line prefix in emit_line_0
>  - diff: use emit_line_0 once per line
>  - diff.c: add set_sign to emit_line_0
>  - diff.c: reorder arguments for emit_line_ws_markup
>  - diff.c: simplify caller of emit_line_0
>  - t3206: add color test for range-diff --dual-color
>  - test_decode_color: understand FAINT and ITALIC
>  (this branch uses js/range-diff; is tangled with es/format-patch-rangediff.)
>
>  The color output support for recently introduced "range-diff"
>  command got tweaked a bit.

No, this series doesn't tweak the colored range-diff.
This might be:

  Add more test coverage to colored range-diff and
  refactor the diff machinery to be more readable.
  The test coverage proves no user visible changes
  are made.

The tweaking comes in on top of this via
https://public-inbox.org/git/20180817204354.108625-1-sbeller@google.com/

Thanks,
Stefan

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 7/7] submodule--helper: introduce new update-module-mode helper
  2018-08-18 16:10     ` Duy Nguyen
@ 2018-08-20 19:44       ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-20 19:44 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: Junio C Hamano, Brandon Williams, git

On Sat, Aug 18, 2018 at 9:11 AM Duy Nguyen <pclouds@gmail.com> wrote:
>
> On Tue, Aug 14, 2018 at 12:45 AM Stefan Beller <sbeller@google.com> wrote:
> > +static int module_update_module_mode(int argc, const char **argv, const char *prefix)
> > +{
> > +       const char *path, *update = NULL;
> > +       int just_cloned;
> > +       struct submodule_update_strategy update_strategy = { .type = SM_UPDATE_CHECKOUT };
> > +
> > +       if (argc < 3 || argc > 4)
> > +               die("submodule--helper update-module-clone expects <just-cloned> <path> [<update>]");
>
> Maybe _() ?

I would rather not, as the submodule--helper is "internal only" and these die()
calls could be clarified via

    #define BUG_IN_CALLING_SH(x) die(x)

After the conversion to C is done, all these submodule helpers would go away,
so I'd not burden the translators too much?

Thanks,
Stefan

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 3/7] submodule: is_submodule_active to differentiate between new and old mode
  2018-08-16 17:37   ` Junio C Hamano
@ 2018-08-20 19:50     ` Stefan Beller
  2018-08-21 21:39       ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-20 19:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Brandon Williams, Jonathan Nieder

On Thu, Aug 16, 2018 at 10:37 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > The change a086f921a72 (submodule: decouple url and submodule interest,
> > 2017-03-17) enables us to do more than originally thought.
> > As the url setting was used both to actually set the url where to
> > obtain the submodule from, as well as used as a boolean flag later
> > to see if it was active, we would need to keep the url around.
> >
> > Now that submodules can be activated using the submodule.[<name>.]active
> > setting, we could remove the url if the submodule is activated via that
> > setting.
>
> ... as the cloned submodule repository has $GIT_DIR/config which
> knows its own origin, we do not need to record URL in superproject's
> $GIT_DIR/config.  Back before we started using a directory under
> $GIT_DIR/modules/ as a more permanent location to store submodule,
> and point at it by a gitdir file in $path/.git to allow removal of a
> submodule from the working tree of the superproject without having
> to reclone when resurrecting the same submodule, it may have been
> useful to keep custom URL somewhere in the superproject, but that no
> longer is the case.
>
> > In preparation to do so, pave the way by providing an easy way to see
> > if a submodule is considered active via the new .active setting or via
> > the old .url setting.
>
> Makes sense.
>
> >
> > Signed-off-by: Stefan Beller <sbeller@google.com>
> > ---
> >  submodule.c | 5 +----
> >  submodule.h | 6 ++++++
> >  2 files changed, 7 insertions(+), 4 deletions(-)
> >
> > diff --git a/submodule.c b/submodule.c
> > index 6e14547e9e0..d56350ed094 100644
> > --- a/submodule.c
> > +++ b/submodule.c
> > @@ -221,9 +221,6 @@ int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
> >       return 0;
> >  }
> >
> > -/*
> > - * Determine if a submodule has been initialized at a given 'path'
> > - */
> >  int is_submodule_active(struct repository *repo, const char *path)
> >  {
> >       int ret = 0;
> > @@ -267,7 +264,7 @@ int is_submodule_active(struct repository *repo, const char *path)
> >
> >       /* fallback to checking if the URL is set */
> >       key = xstrfmt("submodule.%s.url", module->name);
> > -     ret = !repo_config_get_string(repo, key, &value);
> > +     ret = !repo_config_get_string(repo, key, &value) ? 2 : 0;
> >
> >       free(value);
> >       free(key);
> > diff --git a/submodule.h b/submodule.h
> > index 4644683e6cb..bfc070e4629 100644
> > --- a/submodule.h
> > +++ b/submodule.h
> > @@ -45,6 +45,12 @@ extern int git_default_submodule_config(const char *var, const char *value, void
> >  struct option;
> >  int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
> >                                                    const char *arg, int unset);
> > +/*
> > + * Determine if a submodule has been initialized at a given 'path'.
> > + * Returns 1 if it is considered active via the submodule.[<name>.]active
> > + * setting, or return 2 if it is active via the older submodule.url setting.
> > + */
> > +#define SUBMODULE_ACTIVE_VIA_URL 2
> >  extern int is_submodule_active(struct repository *repo, const char *path);
> >  /*
> >   * Determine if a submodule has been populated at a given 'path' by checking if
>
> This change assumes that all the existing return sites in the
> is_submodule_active() function signals true with 1 (or at least some
> value that is different from 2).

Yes.

> So I think this patch is insufficient, and needs to at least change
> the "submodule.active" codepath to return !!ret; otherwise, a caller
> that now expects 0 (not active), 1 (active but can lose URL) and 2
> (active and the presence of URL makes it so) will be confused when
> one of the MATCHED_* constants from dir.h comes back.

Yes.

I'll resend when appropriately.

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* [ANNOUNCE] Git v2.19.0-rc0
@ 2018-08-20 22:13 Junio C Hamano
  2018-08-20 22:41 ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-08-20 22:13 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

An early preview release Git v2.19.0-rc0 is now available for
testing at the usual places.  It is comprised of 707 non-merge
commits since v2.18.0, contributed by 60 people, 14 of which are
new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the
'v2.19.0-rc0' tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.18.0 are as follows.
Welcome to the Git development community!

  Aleksandr Makarov, Andrei Rybak, Chen Bin, Henning Schild,
  Isabella Stephens, Josh Steadmon, Jules Maselbas, Kana Natsuno,
  Marc Strapetz, Masaya Suzuki, Nicholas Guriev, Sebastian Kisela,
  Vladimir Parfinenko, and William Chargin.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Aaron Schrab, Ævar Arnfjörð Bjarmason, Alban Gruin, Alejandro
  R. Sedeño, Anthony Sottile, Antonio Ospite, Beat Bolli, Ben
  Peart, Brandon Williams, brian m. carlson, Christian Couder,
  Derrick Stolee, Elijah Newren, Eric Sunshine, Han-Wen Nienhuys,
  Jameson Miller, Jeff Hostetler, Jeff King, Johannes Schindelin,
  Johannes Sixt, Jonathan Nieder, Jonathan Tan, Junio C Hamano,
  Kim Gybels, Kirill Smelkov, Luis Marsano, Łukasz Stelmach,
  Luke Diamand, Martin Ågren, Max Kirillov, Michael Barabanov,
  Mike Hommey, Nguyễn Thái Ngọc Duy, Olga Telezhnaya,
  Phillip Wood, Prathamesh Chavan, Ramsay Jones, René Scharfe,
  Stefan Beller, SZEDER Gábor, Taylor Blau, Thomas Rast, Tobias
  Klauser, Todd Zullinger, Ville Skyttä, and Xiaolong Ye.

----------------------------------------------------------------

Git 2.19 Release Notes (draft)
==============================

Updates since v2.18
-------------------

UI, Workflows & Features

 * "git diff" compares the index and the working tree.  For paths
   added with intent-to-add bit, the command shows the full contents
   of them as added, but the paths themselves were not marked as new
   files.  They are now shown as new by default.

   "git apply" learned the "--intent-to-add" option so that an
   otherwise working-tree-only application of a patch will add new
   paths to the index marked with the "intent-to-add" bit.

 * "git grep" learned the "--column" option that gives not just the
   line number but the column number of the hit.

 * The "-l" option in "git branch -l" is an unfortunate short-hand for
   "--create-reflog", but many users, both old and new, somehow expect
   it to be something else, perhaps "--list".  This step warns when "-l"
   is used as a short-hand for "--create-reflog" and warns about the
   future repurposing of the it when it is used.

 * The userdiff pattern for .php has been updated.

 * The content-transfer-encoding of the message "git send-email" sends
   out by default was 8bit, which can cause trouble when there is an
   overlong line to bust RFC 5322/2822 limit.  A new option 'auto' to
   automatically switch to quoted-printable when there is such a line
   in the payload has been introduced and is made the default.

 * "git checkout" and "git worktree add" learned to honor
   checkout.defaultRemote when auto-vivifying a local branch out of a
   remote tracking branch in a repository with multiple remotes that
   have tracking branches that share the same names.
   (merge 8d7b558bae ab/checkout-default-remote later to maint).

 * "git grep" learned the "--only-matching" option.

 * "git rebase --rebase-merges" mode now handles octopus merges as
   well.

 * Add a server-side knob to skip commits in exponential/fibbonacci
   stride in an attempt to cover wider swath of history with a smaller
   number of iterations, potentially accepting a larger packfile
   transfer, instead of going back one commit a time during common
   ancestor discovery during the "git fetch" transaction.
   (merge 42cc7485a2 jt/fetch-negotiator-skipping later to maint).

 * A new configuration variable core.usereplacerefs has been added,
   primarily to help server installations that want to ignore the
   replace mechanism altogether.

 * Teach "git tag -s" etc. a few configuration variables (gpg.format
   that can be set to "openpgp" or "x509", and gpg.<format>.program
   that is used to specify what program to use to deal with the format)
   to allow x.509 certs with CMS via "gpgsm" to be used instead of
   openpgp via "gnupg".

 * Many more strings are prepared for l10n.

 * "git p4 submit" learns to ask its own pre-submit hook if it should
   continue with submitting.

 * The test performed at the receiving end of "git push" to prevent
   bad objects from entering repository can be customized via
   receive.fsck.* configuration variables; we now have gained a
   counterpart to do the same on the "git fetch" side, with
   fetch.fsck.* configuration variables.

 * "git pull --rebase=interactive" learned "i" as a short-hand for
   "interactive".

 * "git instaweb" has been adjusted to run better with newer Apache on
   RedHat based distros.

 * "git range-diff" is a reimplementation of "git tbdiff" that lets us
   compare individual patches in two iterations of a topic.

 * The sideband code learned to optionally paint selected keywords at
   the beginning of incoming lines on the receiving end.


Performance, Internal Implementation, Development Support etc.

 * The bulk of "git submodule foreach" has been rewritten in C.

 * The in-core "commit" object had an all-purpose "void *util" field,
   which was tricky to use especially in library-ish part of the
   code.  All of the existing uses of the field has been migrated to a
   more dedicated "commit-slab" mechanism and the field is eliminated.

 * A less often used command "git show-index" has been modernized.
   (merge fb3010c31f jk/show-index later to maint).

 * The conversion to pass "the_repository" and then "a_repository"
   throughout the object access API continues.

 * Continuing with the idea to programatically enumerate various
   pieces of data required for command line completion, teach the
   codebase to report the list of configuration variables
   subcommands care about to help complete them.

 * Separate "rebase -p" codepath out of "rebase -i" implementation to
   slim down the latter and make it easier to manage.

 * Make refspec parsing codepath more robust.

 * Some flaky tests have been fixed.

 * Continuing with the idea to programmatically enumerate various
   pieces of data required for command line completion, the codebase
   has been taught to enumerate options prefixed with "--no-" to
   negate them.

 * Build and test procedure for netrc credential helper (in contrib/)
   has been updated.

 * The conversion to pass "the_repository" and then "a_repository"
   throughout the object access API continues.

 * Remove unused function definitions and declarations from ewah
   bitmap subsystem.

 * Code preparation to make "git p4" closer to be usable with Python 3.

 * Tighten the API to make it harder to misuse in-tree .gitmodules
   file, even though it shares the same syntax with configuration
   files, to read random configuration items from it.

 * "git fast-import" has been updated to avoid attempting to create
   delta against a zero-byte-long string, which is pointless.

 * The codebase has been updated to compile cleanly with -pedantic
   option.
   (merge 2b647a05d7 bb/pedantic later to maint).

 * The character display width table has been updated to match the
   latest Unicode standard.
   (merge 570951eea2 bb/unicode-11-width later to maint).

 * test-lint now looks for broken use of "VAR=VAL shell_func" in test
   scripts.

 * Conversion from uchar[40] to struct object_id continues.

 * Recent "security fix" to pay attention to contents of ".gitmodules"
   while accepting "git push" was a bit overly strict than necessary,
   which has been adjusted.

 * "git fsck" learns to make sure the optional commit-graph file is in
   a sane state.

 * "git diff --color-moved" feature has further been tweaked.

 * Code restructuring and a small fix to transport protocol v2 during
   fetching.

 * Parsing of -L[<N>][,[<M>]] parameters "git blame" and "git log"
   take has been tweaked.

 * lookup_commit_reference() and friends have been updated to find
   in-core object for a specific in-core repository instance.

 * Various glitches in the heuristics of merge-recursive strategy have
   been documented in new tests.

 * "git fetch" learned a new option "--negotiation-tip" to limit the
   set of commits it tells the other end as "have", to reduce wasted
   bandwidth and cycles, which would be helpful when the receiving
   repository has a lot of refs that have little to do with the
   history at the remote it is fetching from.

 * For a large tree, the index needs to hold many cache entries
   allocated on heap.  These cache entries are now allocated out of a
   dedicated memory pool to amortize malloc(3) overhead.

 * Tests to cover various conflicting cases have been added for
   merge-recursive.

 * Tests to cover conflict cases that involve submodules have been
   added for merge-recursive.

 * Look for broken "&&" chains that are hidden in subshell, many of
   which have been found and corrected.

 * The singleton commit-graph in-core instance is made per in-core
   repository instance.

 * "make DEVELOPER=1 DEVOPTS=pedantic" allows developers to compile
   with -pedantic option, which may catch more problematic program
   constructs and potential bugs.

 * Preparatory code to later add json output for telemetry data has
   been added.

 * Update the way we use Coccinelle to find out-of-style code that
   need to be modernised.

 * It is too easy to misuse system API functions such as strcat();
   these selected functions are now forbidden in this codebase and
   will cause a compilation failure.

 * Add a script (in contrib/) to help users of VSCode work better with
   our codebase.

 * The Travis CI scripts were taught to ship back the test data from
   failed tests.
   (merge aea8879a6a sg/travis-retrieve-trash-upon-failure later to maint).

 * The parse-options machinery learned to refrain from enclosing
   placeholder string inside a "<bra" and "ket>" pair automatically
   without PARSE_OPT_LITERAL_ARGHELP.  Existing help text for option
   arguments that are not formatted correctly have been identified and
   fixed.
   (merge 5f0df44cd7 rs/parse-opt-lithelp later to maint).

 * Noiseword "extern" has been removed from function decls in the
   header files.

 * A few atoms like %(objecttype) and %(objectsize) in the format
   specifier of "for-each-ref --format=<format>" can be filled without
   getting the full contents of the object, but just with the object
   header.  These cases have been optimized by calling
   oid_object_info() API (instead of reading and inspecting the data).

 * The end result of documentation update has been made to be
   inspected more easily to help developers.

 * The API to iterate over all objects learned to optionally list
   objects in the order they appear in packfiles, which helps locality
   of access if the caller accesses these objects while as objects are
   enumerated.

 * Improve built-in facility to catch broken &&-chain in the tests.

 * The more library-ish parts of the codebase learned to work on the
   in-core index-state instance that is passed in by their callers,
   instead of always working on the singleton "the_index" instance.

 * A test prerequisite defined by various test scripts with slightly
   different semantics has been consolidated into a single copy and
   made into a lazily defined one.
   (merge 6ec633059a wc/make-funnynames-shared-lazy-prereq later to maint).

 * After a partial clone, repeated fetches from promisor remote would
   have accumulated many packfiles marked with .promisor bit without
   getting them coalesced into fewer packfiles, hurting performance.
   "git repack" now learned to repack them.


Fixes since v2.18
-----------------

 * "git remote update" can take both a single remote nickname and a
   nickname for remote groups, and the completion script (in contrib/)
   has been taught about it.
   (merge 9cd4382ad5 ls/complete-remote-update-names later to maint).

 * "git fetch --shallow-since=<cutoff>" that specifies the cut-off
   point that is newer than the existing history used to end up
   grabbing the entire history.  Such a request now errors out.
   (merge e34de73c56 nd/reject-empty-shallow-request later to maint).

 * Fix for 2.17-era regression around `core.safecrlf`.
   (merge 6cb09125be as/safecrlf-quiet-fix later to maint).

 * The recent addition of "partial clone" experimental feature kicked
   in when it shouldn't, namely, when there is no partial-clone filter
   defined even if extensions.partialclone is set.
   (merge cac1137dc4 jh/partial-clone later to maint).

 * "git send-pack --signed" (hence "git push --signed" over the http
   transport) did not read user ident from the config mechanism to
   determine whom to sign the push certificate as, which has been
   corrected.
   (merge d067d98887 ms/send-pack-honor-config later to maint).

 * "git fetch-pack --all" used to unnecessarily fail upon seeing an
   annotated tag that points at an object other than a commit.
   (merge c12c9df527 jk/fetch-all-peeled-fix later to maint).

 * When user edits the patch in "git add -p" and the user's editor is
   set to strip trailing whitespaces indiscriminately, an empty line
   that is unchanged in the patch would become completely empty
   (instead of a line with a sole SP on it).  The code introduced in
   Git 2.17 timeframe failed to parse such a patch, but now it learned
   to notice the situation and cope with it.
   (merge f4d35a6b49 pw/add-p-recount later to maint).

 * The code to try seeing if a fetch is necessary in a submodule
   during a fetch with --recurse-submodules got confused when the path
   to the submodule was changed in the range of commits in the
   superproject, sometimes showing "(null)".  This has been corrected.

 * "git submodule" did not correctly adjust core.worktree setting that
   indicates whether/where a submodule repository has its associated
   working tree across various state transitions, which has been
   corrected.
   (merge 984cd77ddb sb/submodule-core-worktree later to maint).

 * Bugfix for "rebase -i" corner case regression.
   (merge a9279c6785 pw/rebase-i-keep-reword-after-conflict later to maint).

 * Recently added "--base" option to "git format-patch" command did
   not correctly generate prereq patch ids.
   (merge 15b76c1fb3 xy/format-patch-prereq-patch-id-fix later to maint).

 * POSIX portability fix in Makefile to fix a glitch introduced a few
   releases ago.
   (merge 6600054e9b dj/runtime-prefix later to maint).

 * "git filter-branch" when used with the "--state-branch" option
   still attempted to rewrite the commits whose filtered result is
   known from the previous attempt (which is recorded on the state
   branch); the command has been corrected not to waste cycles doing
   so.
   (merge 709cfe848a mb/filter-branch-optim later to maint).

 * Clarify that setting core.ignoreCase to deviate from reality would
   not turn a case-incapable filesystem into a case-capable one.
   (merge 48294b512a ms/core-icase-doc later to maint).

 * "fsck.skipList" did not prevent a blob object listed there from
   being inspected for is contents (e.g. we recently started to
   inspect the contents of ".gitmodules" for certain malicious
   patterns), which has been corrected.
   (merge fb16287719 rj/submodule-fsck-skip later to maint).

 * "git checkout --recurse-submodules another-branch" did not report
   in which submodule it failed to update the working tree, which
   resulted in an unhelpful error message.
   (merge ba95d4e4bd sb/submodule-move-head-error-msg later to maint).

 * "git rebase" behaved slightly differently depending on which one of
   the three backends gets used; this has been documented and an
   effort to make them more uniform has begun.
   (merge b00bf1c9a8 en/rebase-consistency later to maint).

 * The "--ignore-case" option of "git for-each-ref" (and its friends)
   did not work correctly, which has been fixed.
   (merge e674eb2528 jk/for-each-ref-icase later to maint).

 * "git fetch" failed to correctly validate the set of objects it
   received when making a shallow history deeper, which has been
   corrected.
   (merge cf1e7c0770 jt/connectivity-check-after-unshallow later to maint).

 * Partial clone support of "git clone" has been updated to correctly
   validate the objects it receives from the other side.  The server
   side has been corrected to send objects that are directly
   requested, even if they may match the filtering criteria (e.g. when
   doing a "lazy blob" partial clone).
   (merge a7e67c11b8 jt/partial-clone-fsck-connectivity later to maint).

 * Handling of an empty range by "git cherry-pick" was inconsistent
   depending on how the range ended up to be empty, which has been
   corrected.
   (merge c5e358d073 jk/empty-pick-fix later to maint).

 * "git reset --merge" (hence "git merge ---abort") and "git reset --hard"
   had trouble working correctly in a sparsely checked out working
   tree after a conflict, which has been corrected.
   (merge b33fdfc34c mk/merge-in-sparse-checkout later to maint).

 * Correct a broken use of "VAR=VAL shell_func" in a test.
   (merge 650161a277 jc/t3404-one-shot-export-fix later to maint).

 * "git rev-parse ':/substring'" did not consider the history leading
   only to HEAD when looking for a commit with the given substring,
   when the HEAD is detached.  This has been fixed.
   (merge 6b3351e799 wc/find-commit-with-pattern-on-detached-head later to maint).

 * Build doc update for Windows.
   (merge ede8d89bb1 nd/command-list later to maint).

 * core.commentchar is now honored when preparing the list of commits
   to replay in "rebase -i".

 * "git pull --rebase" on a corrupt HEAD caused a segfault.  In
   general we substitute an empty tree object when running the in-core
   equivalent of the diff-index command, and the codepath has been
   corrected to do so as well to fix this issue.
   (merge 3506dc9445 jk/has-uncommitted-changes-fix later to maint).

 * httpd tests saw occasional breakage due to the way its access log
   gets inspected by the tests, which has been updated to make them
   less flaky.
   (merge e8b3b2e275 sg/httpd-test-unflake later to maint).

 * Tests to cover more D/F conflict cases have been added for
   merge-recursive.

 * "git gc --auto" opens file descriptors for the packfiles before
   spawning "git repack/prune", which would upset Windows that does
   not want a process to work on a file that is open by another
   process.  The issue has been worked around.
   (merge 12e73a3ce4 kg/gc-auto-windows-workaround later to maint).

 * The recursive merge strategy did not properly ensure there was no
   change between HEAD and the index before performing its operation,
   which has been corrected.
   (merge 55f39cf755 en/dirty-merge-fixes later to maint).

 * "git rebase" started exporting GIT_DIR environment variable and
   exposing it to hook scripts when part of it got rewritten in C.
   Instead of matching the old scripted Porcelains' behaviour,
   compensate by also exporting GIT_WORK_TREE environment as well to
   lessen the damage.  This can harm existing hooks that want to
   operate on different repository, but the current behaviour is
   already broken for them anyway.
   (merge ab5e67d751 bc/sequencer-export-work-tree-as-well later to maint).

 * "git send-email" when using in a batched mode that limits the
   number of messages sent in a single SMTP session lost the contents
   of the variable used to choose between tls/ssl, unable to send the
   second and later batches, which has been fixed.
   (merge 636f3d7ac5 jm/send-email-tls-auth-on-batch later to maint).

 * The lazy clone support had a few places where missing but promised
   objects were not correctly tolerated, which have been fixed.

 * One of the "diff --color-moved" mode "dimmed_zebra" that was named
   in an unusual way has been deprecated and replaced by
   "dimmed-zebra".
   (merge e3f2f5f9cd es/diff-color-moved-fix later to maint).

 * The wire-protocol v2 relies on the client to send "ref prefixes" to
   limit the bandwidth spent on the initial ref advertisement.  "git
   clone" when learned to speak v2 forgot to do so, which has been
   corrected.
   (merge 402c47d939 bw/clone-ref-prefixes later to maint).

 * "git diff --histogram" had a bad memory usage pattern, which has
   been rearranged to reduce the peak usage.
   (merge 79cb2ebb92 sb/histogram-less-memory later to maint).

 * Code clean-up to use size_t/ssize_t when they are the right type.
   (merge 7726d360b5 jk/size-t later to maint).

 * The wire-protocol v2 relies on the client to send "ref prefixes" to
   limit the bandwidth spent on the initial ref advertisement.  "git
   fetch $remote branch:branch" that asks tags that point into the
   history leading to the "branch" automatically followed sent to
   narrow prefix and broke the tag following, which has been fixed.
   (merge 2b554353a5 jt/tag-following-with-proto-v2-fix later to maint).

 * When the sparse checkout feature is in use, "git cherry-pick" and
   other mergy operations lost the skip_worktree bit when a path that
   is excluded from checkout requires content level merge, which is
   resolved as the same as the HEAD version, without materializing the
   merge result in the working tree, which made the path appear as
   deleted.  This has been corrected by preserving the skip_worktree
   bit (and not materializing the file in the working tree).
   (merge 2b75fb601c en/merge-recursive-skip-fix later to maint).

 * The "author-script" file "git rebase -i" creates got broken when
   we started to move the command away from shell script, which is
   getting fixed now.
   (merge 5522bbac20 es/rebase-i-author-script-fix later to maint).

 * The automatic tree-matching in "git merge -s subtree" was broken 5
   years ago and nobody has noticed since then, which is now fixed.
   (merge 2ec4150713 jk/merge-subtree-heuristics later to maint).

 * "git fetch $there refs/heads/s" ought to fetch the tip of the
   branch 's', but when "refs/heads/refs/heads/s", i.e. a branch whose
   name is "refs/heads/s" exists at the same time, fetched that one
   instead by mistake.  This has been corrected to honor the usual
   disambiguation rules for abbreviated refnames.
   (merge 60650a48c0 jt/refspec-dwim-precedence-fix later to maint).

 * Futureproofing a helper function that can easily be misused.
   (merge 65bb21e77e es/want-color-fd-defensive later to maint).

 * The http-backend (used for smart-http transport) used to slurp the
   whole input until EOF, without paying attention to CONTENT_LENGTH
   that is supplied in the environment and instead expecting the Web
   server to close the input stream.  This has been fixed.
   (merge eebfe40962 mk/http-backend-content-length later to maint).

 * "git merge --abort" etc. did not clean things up properly when
   there were conflicted entries in the index in certain order that
   are involved in D/F conflicts.  This has been corrected.
   (merge ad3762042a en/abort-df-conflict-fixes later to maint).

 * "git diff --indent-heuristic" had a bad corner case performance.
   (merge 301ef85401 sb/indent-heuristic-optim later to maint).

 * The "--exec" option to "git rebase --rebase-merges" placed the exec
   commands at wrong places, which has been corrected.

 * "git verify-tag" and "git verify-commit" have been taught to use
   the exit status of underlying "gpg --verify" to signal bad or
   untrusted signature they found.
   (merge 4e5dc9ca17 jc/gpg-status later to maint).

 * "git mergetool" stopped and gave an extra prompt to continue after
   the last path has been handled, which did not make much sense.
   (merge d651a54b8a ng/mergetool-lose-final-prompt later to maint).

 * Among the three codepaths we use O_APPEND to open a file for
   appending, one used for writing GIT_TRACE output requires O_APPEND
   implementation that behaves sensibly when multiple processes are
   writing to the same file.  POSIX emulation used in the Windows port
   has been updated to improve in this area.
   (merge d641097589 js/mingw-o-append later to maint).

 * "git pull --rebase -v" in a repository with a submodule barfed as
   an intermediate process did not understand what "-v(erbose)" flag
   meant, which has been fixed.
   (merge e84c3cf3dc sb/pull-rebase-submodule later to maint).

 * Recent update to "git config" broke updating variable in a
   subsection, which has been corrected.
   (merge bff7df7a87 sb/config-write-fix later to maint).

 * When "git rebase -i" is told to squash two or more commits into
   one, it labeled the log message for each commit with its number.
   It correctly called the first one "1st commit", but the next one
   was "commit #1", which was off-by-one.  This has been corrected.
   (merge dd2e36ebac pw/rebase-i-squash-number-fix later to maint).

 * "git rebase -i", when a 'merge <branch>' insn in its todo list
   fails, segfaulted, which has been (minimally) corrected.
   (merge bc9238bb09 pw/rebase-i-merge-segv-fix later to maint).

 * "git cherry-pick --quit" failed to remove CHERRY_PICK_HEAD even
   though we won't be in a cherry-pick session after it returns, which
   has been corrected.
   (merge 3e7dd99208 nd/cherry-pick-quit-fix later to maint).

 * Code cleanup, docfix, build fix, etc.
   (merge aee9be2ebe sg/update-ref-stdin-cleanup later to maint).
   (merge 037714252f jc/clean-after-sanity-tests later to maint).
   (merge 5b26c3c941 en/merge-recursive-cleanup later to maint).
   (merge 0dcbc0392e bw/config-refer-to-gitsubmodules-doc later to maint).
   (merge bb4d000e87 bw/protocol-v2 later to maint).
   (merge 928f0ab4ba vs/typofixes later to maint).
   (merge d7f590be84 en/rebase-i-microfixes later to maint).
   (merge 81d395cc85 js/rebase-recreate-merge later to maint).
   (merge 51d1863168 tz/exclude-doc-smallfixes later to maint).
   (merge a9aa3c0927 ds/commit-graph later to maint).
   (merge 5cf8e06474 js/enhanced-version-info later to maint).
   (merge 6aaded5509 tb/config-default later to maint).
   (merge 022d2ac1f3 sb/blame-color later to maint).
   (merge 5a06a20e0c bp/test-drop-caches-for-windows later to maint).
   (merge dd61cc1c2e jk/ui-color-always-to-auto later to maint).
   (merge 1e83b9bfdd sb/trailers-docfix later to maint).
   (merge ab29f1b329 sg/fast-import-dump-refs-on-checkpoint-fix later to maint).
   (merge 6a8ad880f0 jn/subtree-test-fixes later to maint).
   (merge ffbd51cc60 nd/pack-objects-threading-doc later to maint).
   (merge e9dac7be60 es/mw-to-git-chain-fix later to maint).
   (merge fe583c6c7a rs/remote-mv-leakfix later to maint).
   (merge 69885ab015 en/t3031-title-fix later to maint).
   (merge 8578037bed nd/config-blame-sort later to maint).
   (merge 8ad169c4ba hn/config-in-code-comment later to maint).
   (merge b7446fcfdf ar/t4150-am-scissors-test-fix later to maint).
   (merge a8132410ee js/typofixes later to maint).
   (merge 388d0ff6e5 en/update-index-doc later to maint).
   (merge e05aa688dd jc/update-index-doc later to maint).
   (merge 10c600172c sg/t5310-empty-input-fix later to maint).
   (merge 5641eb9465 jh/partial-clone-doc later to maint).
   (merge 2711b1ad5e ab/submodule-relative-url-tests later to maint).

----------------------------------------------------------------

Changes since v2.18.0 are as follows:

Aaron Schrab (1):
      sequencer: use configured comment character

Alban Gruin (4):
      rebase: introduce a dedicated backend for --preserve-merges
      rebase: strip unused code in git-rebase--preserve-merges.sh
      rebase: use the new git-rebase--preserve-merges.sh
      rebase: remove -p code from git-rebase--interactive.sh

Alejandro R. Sedeño (1):
      Makefile: tweak sed invocation

Aleksandr Makarov (1):
      for-each-ref: consistently pass WM_IGNORECASE flag

Andrei Rybak (2):
      Documentation: fix --color option formatting
      t4150: fix broken test for am --scissors

Anthony Sottile (1):
      config.c: fix regression for core.safecrlf false

Antonio Ospite (6):
      config: move config_from_gitmodules to submodule-config.c
      submodule-config: add helper function to get 'fetch' config from .gitmodules
      submodule-config: add helper to get 'update-clone' config from .gitmodules
      submodule-config: make 'config_from_gitmodules' private
      submodule-config: pass repository as argument to config_from_gitmodules
      submodule-config: reuse config_from_gitmodules in repo_read_gitmodules

Beat Bolli (10):
      builtin/config: work around an unsized array forward declaration
      unicode: update the width tables to Unicode 11
      connect.h: avoid forward declaration of an enum
      refs/refs-internal.h: avoid forward declaration of an enum
      convert.c: replace "\e" escapes with "\033".
      sequencer.c: avoid empty statements at top level
      string-list.c: avoid conversion from void * to function pointer
      utf8.c: avoid char overflow
      Makefile: add a DEVOPTS flag to get pedantic compilation
      packfile: ensure that enum object_type is defined

Ben Peart (3):
      convert log_ref_write_fd() to use strbuf
      handle lower case drive letters on Windows
      t3507: add a testcase showing failure with sparse checkout

Brandon Williams (15):
      commit: convert commit_graft_pos() to handle arbitrary repositories
      commit: convert register_commit_graft to handle arbitrary repositories
      commit: convert read_graft_file to handle arbitrary repositories
      test-pkt-line: add unpack-sideband subcommand
      docs: link to gitsubmodules
      upload-pack: implement ref-in-want
      upload-pack: test negotiation with changing repository
      fetch: refactor the population of peer ref OIDs
      fetch: refactor fetch_refs into two functions
      fetch: refactor to make function args narrower
      fetch-pack: put shallow info in output parameter
      fetch-pack: implement ref-in-want
      clone: send ref-prefixes when using protocol v2
      fetch-pack: mark die strings for translation
      pack-protocol: mention and point to docs for protocol v2

Chen Bin (1):
      git-p4: add the `p4-pre-submit` hook

Christian Couder (1):
      t9104: kosherly remove remote refs

Derrick Stolee (43):
      ref-filter: fix outdated comment on in_commit_list
      commit: add generation number to struct commit
      commit-graph: compute generation numbers
      commit: use generations in paint_down_to_common()
      commit-graph: always load commit-graph information
      ref-filter: use generation number for --contains
      commit: use generation numbers for in_merge_bases()
      commit: add short-circuit to paint_down_to_common()
      commit: use generation number in remove_redundant()
      merge: check config before loading commits
      commit-graph.txt: update design document
      commit-graph: fix UX issue when .lock file exists
      ewah/bitmap.c: delete unused 'bitmap_clear()'
      ewah/bitmap.c: delete unused 'bitmap_each_bit()'
      ewah_bitmap: delete unused 'ewah_and()'
      ewah_bitmap: delete unused 'ewah_and_not()'
      ewah_bitmap: delete unused 'ewah_not()'
      ewah_bitmap: delete unused 'ewah_or()'
      ewah_io: delete unused 'ewah_serialize()'
      t5318-commit-graph.sh: use core.commitGraph
      commit-graph: UNLEAK before die()
      commit-graph: fix GRAPH_MIN_SIZE
      commit-graph: parse commit from chosen graph
      commit: force commit to parse from object database
      commit-graph: load a root tree from specific graph
      commit-graph: add 'verify' subcommand
      commit-graph: verify catches corrupt signature
      commit-graph: verify required chunks are present
      commit-graph: verify corrupt OID fanout and lookup
      commit-graph: verify objects exist
      commit-graph: verify root tree OIDs
      commit-graph: verify parent list
      commit-graph: verify generation number
      commit-graph: verify commit date
      commit-graph: test for corrupted octopus edge
      commit-graph: verify contents match checksum
      fsck: verify commit-graph
      commit-graph: use string-list API for input
      commit-graph: add '--reachable' option
      gc: automatically write commit-graph files
      commit-graph: update design document
      commit-graph: fix documentation inconsistencies
      coccinelle: update commit.cocci

Elijah Newren (63):
      t6036, t6042: use test_create_repo to keep tests independent
      t6036, t6042: use test_line_count instead of wc -l
      t6036, t6042: prefer test_path_is_file, test_path_is_missing
      t6036, t6042: prefer test_cmp to sequences of test
      t6036: prefer test_when_finished to manual cleanup in following test
      merge-recursive: fix miscellaneous grammar error in comment
      merge-recursive: fix numerous argument alignment issues
      merge-recursive: align labels with their respective code blocks
      merge-recursive: clarify the rename_dir/RENAME_DIR meaning
      merge-recursive: rename conflict_rename_*() family of functions
      merge-recursive: add pointer about unduly complex looking code
      git-rebase.txt: document incompatible options
      git-rebase.sh: update help messages a bit
      t3422: new testcases for checking when incompatible options passed
      git-rebase: error out when incompatible options passed
      git-rebase.txt: address confusion between --no-ff vs --force-rebase
      directory-rename-detection.txt: technical docs on abilities and limitations
      git-rebase.txt: document behavioral differences between modes
      t3401: add directory rename testcases for rebase and am
      git-rebase: make --allow-empty-message the default
      t3418: add testcase showing problems with rebase -i and strategy options
      Fix use of strategy options with interactive rebases
      git-rebase--merge: modernize "git-$cmd" to "git $cmd"
      apply: fix grammar error in comment
      t5407: fix test to cover intended arguments
      read-cache.c: move index_has_changes() from merge.c
      index_has_changes(): avoid assuming operating on the_index
      t6044: verify that merges expected to abort actually abort
      t6036: add a failed conflict detection case with symlink modify/modify
      t6036: add a failed conflict detection case with symlink add/add
      t6036: add a failed conflict detection case with submodule modify/modify
      t6036: add a failed conflict detection case with submodule add/add
      t6036: add a failed conflict detection case with conflicting types
      t6042: add testcase covering rename/add/delete conflict type
      t6042: add testcase covering rename/rename(2to1)/delete/delete conflict
      t6042: add testcase covering long chains of rename conflicts
      t6036: add lots of detail for directory/file conflicts in recursive case
      t6036: add a failed conflict detection case: regular files, different modes
      t6044: add a testcase for index matching head, when head doesn't match HEAD
      merge-recursive: make sure when we say we abort that we actually abort
      merge-recursive: fix assumption that head tree being merged is HEAD
      t6044: add more testcases with staged changes before a merge is invoked
      merge-recursive: enforce rule that index matches head before merging
      merge: fix misleading pre-merge check documentation
      t7405: add a file/submodule conflict
      t7405: add a directory/submodule conflict
      t7405: verify 'merge --abort' works after submodule/path conflicts
      merge-recursive: preserve skip_worktree bit when necessary
      t1015: demonstrate directory/file conflict recovery failures
      read-cache: fix directory/file conflict handling in read_index_unmerged()
      t3031: update test description to mention desired behavior
      t7406: fix call that was failing for the wrong reason
      t7406: simplify by using diff --name-only instead of diff --raw
      t7406: avoid having git commands upstream of a pipe
      t7406: prefer test_* helper functions to test -[feds]
      t7406: avoid using test_must_fail for commands other than git
      git-update-index.txt: reword possibly confusing example
      Add missing includes and forward declarations
      alloc: make allocate_alloc_state and clear_alloc_state more consistent
      Move definition of enum branch_track from cache.h to branch.h
      urlmatch.h: fix include guard
      compat/precompose_utf8.h: use more common include guard style
      Remove forward declaration of an enum

Eric Sunshine (53):
      t: use test_might_fail() instead of manipulating exit code manually
      t: use test_write_lines() instead of series of 'echo' commands
      t: use sane_unset() rather than 'unset' with broken &&-chain
      t: drop unnecessary terminating semicolon in subshell
      t/lib-submodule-update: fix "absorbing" test
      t5405: use test_must_fail() instead of checking exit code manually
      t5406: use write_script() instead of birthing shell script manually
      t5505: modernize and simplify hard-to-digest test
      t6036: fix broken "merge fails but has appropriate contents" tests
      t7201: drop pointless "exit 0" at end of subshell
      t7400: fix broken "submodule add/reconfigure --force" test
      t7810: use test_expect_code() instead of hand-rolled comparison
      t9001: fix broken "invoke hook" test
      t9814: simplify convoluted check that command correctly errors out
      t0000-t0999: fix broken &&-chains
      t1000-t1999: fix broken &&-chains
      t2000-t2999: fix broken &&-chains
      t3000-t3999: fix broken &&-chains
      t3030: fix broken &&-chains
      t4000-t4999: fix broken &&-chains
      t5000-t5999: fix broken &&-chains
      t6000-t6999: fix broken &&-chains
      t7000-t7999: fix broken &&-chains
      t9000-t9999: fix broken &&-chains
      t9119: fix broken &&-chains
      t6046/t9833: fix use of "VAR=VAL cmd" with a shell function
      t/check-non-portable-shell: stop being so polite
      t/check-non-portable-shell: make error messages more compact
      t/check-non-portable-shell: detect "FOO=bar shell_func"
      t/test-lib: teach --chain-lint to detect broken &&-chains in subshells
      t/Makefile: add machinery to check correctness of chainlint.sed
      t/chainlint: add chainlint "basic" test cases
      t/chainlint: add chainlint "whitespace" test cases
      t/chainlint: add chainlint "one-liner" test cases
      t/chainlint: add chainlint "nested subshell" test cases
      t/chainlint: add chainlint "loop" and "conditional" test cases
      t/chainlint: add chainlint "cuddled" test cases
      t/chainlint: add chainlint "complex" test cases
      t/chainlint: add chainlint "specialized" test cases
      diff: --color-moved: rename "dimmed_zebra" to "dimmed-zebra"
      mw-to-git/t9360: fix broken &&-chain
      t/chainlint.sed: drop extra spaces from regex character class
      sequencer: fix "rebase -i --root" corrupting author header
      sequencer: fix "rebase -i --root" corrupting author header timezone
      sequencer: fix "rebase -i --root" corrupting author header timestamp
      sequencer: don't die() on bogus user-edited timestamp
      color: protect against out-of-bounds reads and writes
      chainlint: match arbitrary here-docs tags rather than hard-coded names
      chainlint: match 'quoted' here-doc tags
      chainlint: recognize multi-line $(...) when command cuddled with "$("
      chainlint: let here-doc and multi-line string commence on same line
      chainlint: recognize multi-line quoted strings more robustly
      chainlint: add test of pathological case which triggered false positive

Han-Wen Nienhuys (2):
      config: document git config getter return value
      sideband: highlight keywords in remote sideband output

Henning Schild (9):
      builtin/receive-pack: use check_signature from gpg-interface
      gpg-interface: make parse_gpg_output static and remove from interface header
      gpg-interface: add new config to select how to sign a commit
      t/t7510: check the validation of the new config gpg.format
      gpg-interface: introduce an abstraction for multiple gpg formats
      gpg-interface: do not hardcode the key string len anymore
      gpg-interface: introduce new config to select per gpg format program
      gpg-interface: introduce new signature format "x509" using gpgsm
      gpg-interface t: extend the existing GPG tests with GPGSM

Isabella Stephens (2):
      blame: prevent error if range ends past end of file
      log: prevent error if line range ends past end of file

Jameson Miller (8):
      read-cache: teach refresh_cache_entry to take istate
      read-cache: teach make_cache_entry to take object_id
      block alloc: add lifecycle APIs for cache_entry structs
      mem-pool: only search head block for available space
      mem-pool: add life cycle management functions
      mem-pool: fill out functionality
      block alloc: allocate cache entries from mem_pool
      block alloc: add validations around cache_entry lifecyle

Jeff Hostetler (1):
      json_writer: new routines to create JSON data

Jeff King (48):
      make show-index a builtin
      show-index: update documentation for index v2
      fetch-pack: don't try to fetch peel values with --all
      ewah: drop ewah_deserialize function
      ewah: drop ewah_serialize_native function
      t3200: unset core.logallrefupdates when testing reflog creation
      t: switch "branch -l" to "branch --create-reflog"
      branch: deprecate "-l" option
      config: turn die_on_error into caller-facing enum
      config: add CONFIG_ERROR_SILENT handler
      config: add options parameter to git_config_from_mem
      fsck: silence stderr when parsing .gitmodules
      t6300: add a test for --ignore-case
      ref-filter: avoid backend filtering with --ignore-case
      t5500: prettify non-commit tag tests
      sequencer: handle empty-set cases consistently
      sequencer: don't say BUG on bogus input
      has_uncommitted_changes(): fall back to empty tree
      fsck: split ".gitmodules too large" error from parse failure
      fsck: downgrade gitmodulesParse default to "info"
      blame: prefer xsnprintf to strcpy for colors
      check_replace_refs: fix outdated comment
      check_replace_refs: rename to read_replace_refs
      add core.usereplacerefs config option
      reencode_string: use st_add/st_mult helpers
      reencode_string: use size_t for string lengths
      strbuf: use size_t for length in intermediate variables
      strbuf_readlink: use ssize_t
      pass st.st_size as hint for strbuf_readlink()
      strbuf_humanise: use unsigned variables
      automatically ban strcpy()
      banned.h: mark strcat() as banned
      banned.h: mark sprintf() as banned
      banned.h: mark strncpy() as banned
      score_trees(): fix iteration over trees with missing entries
      add a script to diff rendered documentation
      t5552: suppress upload-pack trace output
      for_each_*_object: store flag definitions in a single location
      for_each_*_object: take flag arguments as enum
      for_each_*_object: give more comprehensive docstrings
      for_each_packed_object: support iterating in pack-order
      t1006: test cat-file --batch-all-objects with duplicates
      cat-file: rename batch_{loose,packed}_object callbacks
      cat-file: support "unordered" output for --batch-all-objects
      cat-file: use oidset check-and-insert
      cat-file: split batch "buf" into two variables
      cat-file: use a single strbuf for all output
      for_each_*_object: move declarations to object-store.h

Johannes Schindelin (41):
      Makefile: fix the "built from commit" code
      merge: allow reading the merge commit message from a file
      rebase --rebase-merges: add support for octopus merges
      rebase --rebase-merges: adjust man page for octopus support
      vcbuild/README: update to accommodate for missing common-cmds.h
      t7406: avoid failures solely due to timing issues
      contrib: add a script to initialize VS Code configuration
      vscode: hard-code a couple defines
      cache.h: extract enum declaration from inside a struct declaration
      mingw: define WIN32 explicitly
      vscode: only overwrite C/C++ settings
      vscode: wrap commit messages at column 72 by default
      vscode: use 8-space tabs, no trailing ws, etc for Git's source code
      vscode: add a dictionary for cSpell
      vscode: let cSpell work on commit messages, too
      pull --rebase=<type>: allow single-letter abbreviations for the type
      t3430: demonstrate what -r, --autosquash & --exec should do
      git-compat-util.h: fix typo
      remote-curl: remove spurious period
      rebase --exec: make it work with --rebase-merges
      linear-assignment: a function to solve least-cost assignment problems
      Introduce `range-diff` to compare iterations of a topic branch
      range-diff: first rudimentary implementation
      range-diff: improve the order of the shown commits
      range-diff: also show the diff between patches
      range-diff: right-trim commit messages
      range-diff: indent the diffs just like tbdiff
      range-diff: suppress the diff headers
      range-diff: adjust the output of the commit pairs
      range-diff: do not show "function names" in hunk headers
      range-diff: use color for the commit pairs
      color: add the meta color GIT_COLOR_REVERSE
      diff: add an internal option to dual-color diffs of diffs
      range-diff: offer to dual-color the diffs
      range-diff --dual-color: skip white-space warnings
      range-diff: populate the man page
      completion: support `git range-diff`
      range-diff: left-pad patch numbers
      range-diff: make --dual-color the default mode
      range-diff: use dim/bold cues to improve dual color mode
      chainlint: fix for core.autocrlf=true

Johannes Sixt (1):
      mingw: enable atomic O_APPEND

Jonathan Nieder (11):
      object: add repository argument to grow_object_hash
      object: move grafts to object parser
      commit: add repository argument to commit_graft_pos
      commit: add repository argument to register_commit_graft
      commit: add repository argument to read_graft_file
      commit: add repository argument to prepare_commit_graft
      commit: add repository argument to lookup_commit_graft
      subtree test: add missing && to &&-chain
      subtree test: simplify preparation of expected results
      doc hash-function-transition: pick SHA-256 as NewHash
      partial-clone: render design doc using asciidoc

Jonathan Tan (28):
      list-objects: check if filter is NULL before using
      fetch-pack: split up everything_local()
      fetch-pack: clear marks before re-marking
      fetch-pack: directly end negotiation if ACK ready
      fetch-pack: use ref adv. to prune "have" sent
      fetch-pack: make negotiation-related vars local
      fetch-pack: move common check and marking together
      fetch-pack: introduce negotiator API
      pack-bitmap: remove bitmap_git global variable
      pack-bitmap: add free function
      fetch-pack: write shallow, then check connectivity
      fetch-pack: support negotiation tip whitelist
      upload-pack: send refs' objects despite "filter"
      clone: check connectivity even if clone is partial
      revision: tolerate promised targets of tags
      tag: don't warn if target is missing but promised
      negotiator/skipping: skip commits during fetch
      commit-graph: refactor preparing commit graph
      object-store: add missing include
      commit-graph: add missing forward declaration
      commit-graph: add free_commit_graph
      commit-graph: store graph in struct object_store
      commit-graph: add repo arg to graph readers
      t5702: test fetch with multiple refspecs at a time
      fetch: send "refs/tags/" prefix upon CLI refspecs
      fetch-pack: unify ref in and out param
      repack: refactor setup of pack-objects cmd
      repack: repack promisor objects if -a or -A is set

Josh Steadmon (1):
      protocol-v2 doc: put HTTP headers after request

Jules Maselbas (1):
      send-email: fix tls AUTH when sending batch

Junio C Hamano (18):
      tests: clean after SANITY tests
      ewah: delete unused 'rlwit_discharge_empty()'
      Prepare to start 2.19 cycle
      First batch for 2.19 cycle
      Second batch for 2.19 cycle
      fixup! connect.h: avoid forward declaration of an enum
      fixup! refs/refs-internal.h: avoid forward declaration of an enum
      t3404: fix use of "VAR=VAL cmd" with a shell function
      Third batch for 2.19 cycle
      Fourth batch for 2.19 cycle
      remote: make refspec follow the same disambiguation rule as local refs
      Fifth batch for 2.19 cycle
      update-index: there no longer is `apply --index-info`
      gpg-interface: propagate exit status from gpg back to the callers
      Sixth batch for 2.19 cycle
      Seventh batch for 2.19 cycle
      sideband: do not read beyond the end of input
      Git 2.19-rc0

Kana Natsuno (2):
      t4018: add missing test cases for PHP
      userdiff: support new keywords in PHP hunk header

Kim Gybels (1):
      gc --auto: release pack files before auto packing

Kirill Smelkov (1):
      fetch-pack: test explicitly that --all can fetch tag references pointing to non-commits

Luis Marsano (2):
      git-credential-netrc: use in-tree Git.pm for tests
      git-credential-netrc: fix exit status when tests fail

Luke Diamand (6):
      git-p4: python3: replace <> with !=
      git-p4: python3: replace dict.has_key(k) with "k in dict"
      git-p4: python3: remove backticks
      git-p4: python3: basestring workaround
      git-p4: python3: use print() function
      git-p4: python3: fix octal constants

Marc Strapetz (1):
      Documentation: declare "core.ignoreCase" as internal variable

Martin Ågren (1):
      refspec: initalize `refspec_item` in `valid_fetch_refspec()`

Masaya Suzuki (2):
      builtin/send-pack: populate the default configs
      doc: fix want-capability separator

Max Kirillov (4):
      http-backend: cleanup writing to child process
      http-backend: respect CONTENT_LENGTH as specified by rfc3875
      unpack-trees: do not fail reset because of unmerged skipped entry
      http-backend: respect CONTENT_LENGTH for receive-pack

Michael Barabanov (1):
      filter-branch: skip commits present on --state-branch

Mike Hommey (1):
      fast-import: do not call diff_delta() with empty buffer

Nguyễn Thái Ngọc Duy (98):
      commit-slab.h: code split
      commit-slab: support shared commit-slab
      blame: use commit-slab for blame suspects instead of commit->util
      describe: use commit-slab for commit names instead of commit->util
      shallow.c: use commit-slab for commit depth instead of commit->util
      sequencer.c: use commit-slab to mark seen commits
      sequencer.c: use commit-slab to associate todo items to commits
      revision.c: use commit-slab for show_source
      bisect.c: use commit-slab for commit weight instead of commit->util
      name-rev: use commit-slab for rev-name instead of commit->util
      show-branch: use commit-slab for commit-name instead of commit->util
      show-branch: note about its object flags usage
      log: use commit-slab in prepare_bases() instead of commit->util
      merge: use commit-slab in merge remote desc instead of commit->util
      commit.h: delete 'util' field in struct commit
      diff: ignore --ita-[in]visible-in-index when diffing worktree-to-tree
      diff: turn --ita-invisible-in-index on by default
      t2203: add a test about "diff HEAD" case
      apply: add --intent-to-add
      parse-options: option to let --git-completion-helper show negative form
      completion: suppress some -no- options
      Add and use generic name->id mapping code for color slot parsing
      grep: keep all colors in an array
      fsck: factor out msg_id_info[] lazy initialization code
      help: add --config to list all available config
      fsck: produce camelCase config key names
      advice: keep config name in camelCase in advice_config[]
      am: move advice.amWorkDir parsing back to advice.c
      completion: drop the hard coded list of config vars
      completion: keep other config var completion in camelCase
      completion: support case-insensitive config vars
      log-tree: allow to customize 'grafted' color
      completion: complete general config vars in two steps
      upload-pack: reject shallow requests that would return nothing
      completion: collapse extra --no-.. options
      Update messages in preparation for i18n
      archive-tar.c: mark more strings for translation
      archive-zip.c: mark more strings for translation
      builtin/config.c: mark more strings for translation
      builtin/grep.c: mark strings for translation
      builtin/pack-objects.c: mark more strings for translation
      builtin/replace.c: mark more strings for translation
      commit-graph.c: mark more strings for translation
      config.c: mark more strings for translation
      connect.c: mark more strings for translation
      convert.c: mark more strings for translation
      dir.c: mark more strings for translation
      environment.c: mark more strings for translation
      exec-cmd.c: mark more strings for translation
      object.c: mark more strings for translation
      pkt-line.c: mark more strings for translation
      refs.c: mark more strings for translation
      refspec.c: mark more strings for translation
      replace-object.c: mark more strings for translation
      sequencer.c: mark more strings for translation
      sha1-file.c: mark more strings for translation
      transport.c: mark more strings for translation
      transport-helper.c: mark more strings for translation
      pack-objects: document about thread synchronization
      apply.h: drop extern on func declaration
      attr.h: drop extern from function declaration
      blame.h: drop extern on func declaration
      cache-tree.h: drop extern from function declaration
      convert.h: drop 'extern' from function declaration
      diffcore.h: drop extern from function declaration
      diff.h: remove extern from function declaration
      line-range.h: drop extern from function declaration
      rerere.h: drop extern from function declaration
      repository.h: drop extern from function declaration
      revision.h: drop extern from function declaration
      submodule.h: drop extern from function declaration
      config.txt: reorder blame stuff to keep config keys sorted
      Makefile: add missing dependency for command-list.h
      diff.c: move read_index() code back to the caller
      cache-tree: wrap the_index based wrappers with #ifdef
      attr: remove an implicit dependency on the_index
      convert.c: remove an implicit dependency on the_index
      dir.c: remove an implicit dependency on the_index in pathspec code
      preload-index.c: use the right index instead of the_index
      ls-files: correct index argument to get_convert_attr_ascii()
      unpack-trees: remove 'extern' on function declaration
      unpack-trees: add a note about path invalidation
      unpack-trees: don't shadow global var the_index
      unpack-trees: convert clear_ce_flags* to avoid the_index
      unpack-trees: avoid the_index in verify_absent()
      pathspec.c: use the right index instead of the_index
      submodule.c: use the right index instead of the_index
      entry.c: use the right index instead of the_index
      attr: remove index from git_attr_set_direction()
      grep: use the right index instead of the_index
      archive.c: avoid access to the_index
      archive-*.c: use the right repository
      resolve-undo.c: use the right index instead of the_index
      apply.c: pass struct apply_state to more functions
      apply.c: make init_apply_state() take a struct repository
      apply.c: remove implicit dependency on the_index
      blame.c: remove implicit dependency on the_index
      cherry-pick: fix --quit not deleting CHERRY_PICK_HEAD

Nicholas Guriev (1):
      mergetool: don't suggest to continue after last file

Olga Telezhnaya (5):
      ref-filter: add info_source to valid_atom
      ref-filter: fill empty fields with empty values
      ref-filter: initialize eaten variable
      ref-filter: merge get_obj and get_object
      ref-filter: use oid_object_info() to get object

Phillip Wood (5):
      add -p: fix counting empty context lines in edited patches
      sequencer: do not squash 'reword' commits when we hit conflicts
      rebase -i: fix numbering in squash message
      t3430: add conflicting commit
      rebase -i: fix SIGSEGV when 'merge <branch>' fails

Prathamesh Chavan (4):
      submodule foreach: correct '$path' in nested submodules from a subdirectory
      submodule foreach: document '$sm_path' instead of '$path'
      submodule foreach: document variable '$displaypath'
      submodule: port submodule subcommand 'foreach' from shell to C

Ramsay Jones (3):
      fsck: check skiplist for object in fsck_blob()
      t6036: fix broken && chain in sub-shell
      t5562: avoid non-portable "export FOO=bar" construct

René Scharfe (7):
      remote: clear string_list after use in mv()
      add, update-index: fix --chmod argument help
      difftool: remove angular brackets from argument help
      pack-objects: specify --index-version argument help explicitly
      send-pack: specify --force-with-lease argument help explicitly
      shortlog: correct option help for -w
      parse-options: automatically infer PARSE_OPT_LITERAL_ARGHELP

SZEDER Gábor (19):
      update-ref --stdin: use skip_prefix()
      t7510-signed-commit: use 'test_must_fail'
      tests: make forging GPG signed commits and tags more robust
      t5541: clean up truncating access log
      t/lib-httpd: add the strip_access_log() helper function
      t/lib-httpd: avoid occasional failures when checking access.log
      t5608: fix broken &&-chain
      t9300: wait for background fast-import process to die after killing it
      travis-ci: run Coccinelle static analysis with two parallel jobs
      travis-ci: fail if Coccinelle static analysis found something to transform
      coccinelle: mark the 'coccicheck' make target as .PHONY
      coccinelle: use $(addsuffix) in 'coccicheck' make target
      coccinelle: exclude sha1dc source files from static analysis
      coccinelle: put sane filenames into output patches
      coccinelle: extract dedicated make target to clean Coccinelle's results
      travis-ci: include the trash directories of failed tests in the trace log
      t5318: use 'test_cmp_bin' to compare commit-graph files
      t5318: avoid unnecessary command substitutions
      t5310-pack-bitmaps: fix bogus 'pack-objects to file can use bitmap' test

Sebastian Kisela (2):
      git-instaweb: support Fedora/Red Hat apache module path
      git-instaweb: fix apache2 config with apache >= 2.4

Stefan Beller (87):
      repository: introduce parsed objects field
      object: add repository argument to create_object
      alloc: add repository argument to alloc_blob_node
      alloc: add repository argument to alloc_tree_node
      alloc: add repository argument to alloc_commit_node
      alloc: add repository argument to alloc_tag_node
      alloc: add repository argument to alloc_object_node
      alloc: add repository argument to alloc_report
      alloc: add repository argument to alloc_commit_index
      object: allow grow_object_hash to handle arbitrary repositories
      object: allow create_object to handle arbitrary repositories
      alloc: allow arbitrary repositories for alloc functions
      object-store: move object access functions to object-store.h
      shallow: add repository argument to set_alternate_shallow_file
      shallow: add repository argument to register_shallow
      shallow: add repository argument to check_shallow_file_for_update
      shallow: add repository argument to is_repository_shallow
      cache: convert get_graft_file to handle arbitrary repositories
      path.c: migrate global git_path_* to take a repository argument
      shallow: migrate shallow information into the object parser
      commit: allow prepare_commit_graft to handle arbitrary repositories
      commit: allow lookup_commit_graft to handle arbitrary repositories
      refs/packed-backend.c: close fd of empty file
      submodule--helper: plug mem leak in print_default_remote
      sequencer.c: plug leaks in do_pick_commit
      submodule: fix NULL correctness in renamed broken submodules
      t5526: test recursive submodules when fetching moved submodules
      submodule: unset core.worktree if no working tree is present
      submodule: ensure core.worktree is set after update
      submodule deinit: unset core.worktree
      submodule.c: report the submodule that an error occurs in
      sequencer.c: plug mem leak in git_sequencer_config
      .mailmap: merge different spellings of names
      object: add repository argument to parse_object
      object: add repository argument to lookup_object
      object: add repository argument to parse_object_buffer
      object: add repository argument to object_as_type
      blob: add repository argument to lookup_blob
      tree: add repository argument to lookup_tree
      commit: add repository argument to lookup_commit_reference_gently
      commit: add repository argument to lookup_commit_reference
      commit: add repository argument to lookup_commit
      commit: add repository argument to parse_commit_buffer
      commit: add repository argument to set_commit_buffer
      commit: add repository argument to get_cached_commit_buffer
      tag: add repository argument to lookup_tag
      tag: add repository argument to parse_tag_buffer
      tag: add repository argument to deref_tag
      object: allow object_as_type to handle arbitrary repositories
      object: allow lookup_object to handle arbitrary repositories
      blob: allow lookup_blob to handle arbitrary repositories
      tree: allow lookup_tree to handle arbitrary repositories
      commit: allow lookup_commit to handle arbitrary repositories
      tag: allow lookup_tag to handle arbitrary repositories
      tag: allow parse_tag_buffer to handle arbitrary repositories
      commit.c: allow parse_commit_buffer to handle arbitrary repositories
      commit-slabs: remove realloc counter outside of slab struct
      commit.c: migrate the commit buffer to the parsed object store
      commit.c: allow set_commit_buffer to handle arbitrary repositories
      commit.c: allow get_cached_commit_buffer to handle arbitrary repositories
      object.c: allow parse_object_buffer to handle arbitrary repositories
      object.c: allow parse_object to handle arbitrary repositories
      tag.c: allow deref_tag to handle arbitrary repositories
      commit.c: allow lookup_commit_reference_gently to handle arbitrary repositories
      commit.c: allow lookup_commit_reference to handle arbitrary repositories
      xdiff/xdiff.h: remove unused flags
      xdiff/xdiffi.c: remove unneeded function declarations
      t4015: avoid git as a pipe input
      diff.c: do not pass diff options as keydata to hashmap
      diff.c: adjust hash function signature to match hashmap expectation
      diff.c: add a blocks mode for moved code detection
      diff.c: decouple white space treatment from move detection algorithm
      diff.c: factor advance_or_nullify out of mark_color_as_moved
      diff.c: add white space mode to move detection that allows indent changes
      diff.c: offer config option to control ws handling in move detection
      xdiff/xhistogram: pass arguments directly to fall_back_to_classic_diff
      xdiff/xhistogram: factor out memory cleanup into free_index()
      xdiff/xhistogram: move index allocation into find_lcs
      Documentation/git-interpret-trailers: explain possible values
      xdiff/histogram: remove tail recursion
      t1300: document current behavior of setting options
      xdiff: reduce indent heuristic overhead
      config: fix case sensitive subsection names on writing
      git-config: document accidental multi-line setting in deprecated syntax
      git-submodule.sh: accept verbose flag in cmd_update to be non-quiet
      t7410: update to new style
      builtin/submodule--helper: remove stray new line

Taylor Blau (9):
      Documentation/config.txt: camel-case lineNumber for consistency
      grep.c: expose {,inverted} match column in match_line()
      grep.[ch]: extend grep_opt to allow showing matched column
      grep.c: display column number of first match
      builtin/grep.c: add '--column' option to 'git-grep(1)'
      grep.c: add configuration variables to show matched option
      contrib/git-jump/git-jump: jump to exact location
      grep.c: extract show_line_header()
      grep.c: teach 'git grep --only-matching'

Thomas Rast (1):
      range-diff: add tests

Tobias Klauser (1):
      git-rebase--preserve-merges: fix formatting of todo help message

Todd Zullinger (4):
      git-credential-netrc: minor whitespace cleanup in test script
      git-credential-netrc: make "all" default target of Makefile
      gitignore.txt: clarify default core.excludesfile path
      dir.c: fix typos in core.excludesfile comment

Ville Skyttä (1):
      Documentation: spelling and grammar fixes

Vladimir Parfinenko (1):
      rebase: fix documentation formatting

William Chargin (2):
      sha1-name.c: for ":/", find detached HEAD commits
      t: factor out FUNNYNAMES as shared lazy prereq

Xiaolong Ye (1):
      format-patch: clear UNINTERESTING flag before prepare_bases

brian m. carlson (21):
      send-email: add an auto option for transfer encoding
      send-email: accept long lines with suitable transfer encoding
      send-email: automatically determine transfer-encoding
      docs: correct RFC specifying email line length
      sequencer: pass absolute GIT_WORK_TREE to exec commands
      cache: update object ID functions for the_hash_algo
      tree-walk: replace hard-coded constants with the_hash_algo
      hex: switch to using the_hash_algo
      commit: express tree entry constants in terms of the_hash_algo
      strbuf: allocate space with GIT_MAX_HEXSZ
      sha1-name: use the_hash_algo when parsing object names
      refs/files-backend: use the_hash_algo for writing refs
      builtin/update-index: convert to using the_hash_algo
      builtin/update-index: simplify parsing of cacheinfo
      builtin/fmt-merge-msg: make hash independent
      builtin/merge: switch to use the_hash_algo
      builtin/merge-recursive: make hash independent
      diff: switch GIT_SHA1_HEXSZ to use the_hash_algo
      log-tree: switch GIT_SHA1_HEXSZ to the_hash_algo->hexsz
      sha1-file: convert constants to uses of the_hash_algo
      pretty: switch hard-coded constants to the_hash_algo

Ævar Arnfjörð Bjarmason (36):
      checkout tests: index should be clean after dwim checkout
      checkout.h: wrap the arguments to unique_tracking_name()
      checkout.c: introduce an *_INIT macro
      checkout.c: change "unique" member to "num_matches"
      checkout: pass the "num_matches" up to callers
      builtin/checkout.c: use "ret" variable for return
      checkout: add advice for ambiguous "checkout <branch>"
      checkout & worktree: introduce checkout.defaultRemote
      refspec: s/refspec_item_init/&_or_die/g
      refspec: add back a refspec_item_init() function
      doc hash-function-transition: note the lack of a changelog
      receive.fsck.<msg-id> tests: remove dead code
      config doc: don't describe *.fetchObjects twice
      config doc: unify the description of fsck.* and receive.fsck.*
      config doc: elaborate on what transfer.fsckObjects does
      config doc: elaborate on fetch.fsckObjects security
      transfer.fsckObjects tests: untangle confusing setup
      fetch: implement fetch.fsck.*
      fsck: test & document {fetch,receive}.fsck.* config fallback
      fsck: add stress tests for fsck.skipList
      fsck: test and document unknown fsck.<msg-id> values
      tests: make use of the test_must_be_empty function
      tests: make use of the test_must_be_empty function
      fetch tests: change "Tag" test tag to "testTag"
      push tests: remove redundant 'git push' invocation
      push tests: fix logic error in "push" test assertion
      push tests: add more testing for forced tag pushing
      push tests: assert re-pushing annotated tags
      negotiator: unknown fetch.negotiationAlgorithm should error out
      fetch doc: cross-link two new negotiation options
      sha1dc: update from upstream
      push: use PARSE_OPT_LITERAL_ARGHELP instead of unbalanced brackets
      fetch tests: correct a comment "remove it" -> "remove them"
      pull doc: fix a long-standing grammar error
      submodule: add more exhaustive up-path testing
      t2024: mark test using "checkout -p" with PERL prerequisite

Łukasz Stelmach (1):
      completion: complete remote names too


^ permalink raw reply	[relevance 3%]

* Re: [ANNOUNCE] Git v2.19.0-rc0
  2018-08-20 22:13 [ANNOUNCE] Git v2.19.0-rc0 Junio C Hamano
@ 2018-08-20 22:41 ` Stefan Beller
  2018-08-20 23:39   ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-20 22:41 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Linux-Kernel@Vger. Kernel. Org, git-packagers

>  * The conversion to pass "the_repository" and then "a_repository"
>    throughout the object access API continues.
>
[...]
>
>  * The conversion to pass "the_repository" and then "a_repository"
>    throughout the object access API continues.

I guess it continues twice as two large series were merged? ;-)
sb/object-store-grafts
sb/object-store-lookup

The latter one is not the correct one, as later we'll have

  * lookup_commit_reference() and friends have been updated to find
    in-core object for a specific in-core repository instance.

>  * "git submodule" did not correctly adjust core.worktree setting that
>    indicates whether/where a submodule repository has its associated
>    working tree across various state transitions, which has been
>    corrected.
>    (merge 984cd77ddb sb/submodule-core-worktree later to maint).

Personally I do not view this as a bug fix but a feature
(but then again my thinking might be tainted of too much
submodule work) hence I would not merge it down.

Stefan

^ permalink raw reply	[relevance 5%]

* Re: [ANNOUNCE] Git v2.19.0-rc0
  2018-08-20 22:41 ` Stefan Beller
@ 2018-08-20 23:39   ` Jonathan Nieder
  2018-08-21  0:27     ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-08-20 23:39 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Junio C Hamano, git

(-cc: other lists)
Stefan Beller wrote:
> Junio C Hamano wrote:

>>  * "git submodule" did not correctly adjust core.worktree setting that
>>    indicates whether/where a submodule repository has its associated
>>    working tree across various state transitions, which has been
>>    corrected.
>>    (merge 984cd77ddb sb/submodule-core-worktree later to maint).
>
> Personally I do not view this as a bug fix but a feature
> (but then again my thinking might be tainted of too much
> submodule work) hence I would not merge it down.

Can you elaborate?

The symptom that this series fixes was pretty bad, so I'm pretty glad
you wrote it.

Thanks,
Jonathan

^ permalink raw reply	[relevance 2%]

* Re: [ANNOUNCE] Git v2.19.0-rc0
  2018-08-20 23:39   ` Jonathan Nieder
@ 2018-08-21  0:27     ` Jonathan Nieder
  2018-08-21  0:46       ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-08-21  0:27 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Junio C Hamano, git

Jonathan Nieder wrote:
> Stefan Beller wrote:
>> Junio C Hamano wrote:

>>>  * "git submodule" did not correctly adjust core.worktree setting that
>>>    indicates whether/where a submodule repository has its associated
>>>    working tree across various state transitions, which has been
>>>    corrected.
>>>    (merge 984cd77ddb sb/submodule-core-worktree later to maint).
>>
>> Personally I do not view this as a bug fix but a feature
>> (but then again my thinking might be tainted of too much
>> submodule work) hence I would not merge it down.
>
> Can you elaborate?

... ah, I figured it out.  You are saying "would not merge it down to
maint".  In that case, I agree, since this this is not a recent bug
(it's existed since before v1.7.10-rc1~14^2~2, 2012-03-02).

Thanks,
Jonathan

^ permalink raw reply	[relevance 0%]

* Re: [ANNOUNCE] Git v2.19.0-rc0
  2018-08-21  0:27     ` Jonathan Nieder
@ 2018-08-21  0:46       ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-21  0:46 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Junio C Hamano, git

On Mon, Aug 20, 2018 at 5:27 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> Jonathan Nieder wrote:
> > Stefan Beller wrote:
> >> Junio C Hamano wrote:
>
> >>>  * "git submodule" did not correctly adjust core.worktree setting that
> >>>    indicates whether/where a submodule repository has its associated
> >>>    working tree across various state transitions, which has been
> >>>    corrected.
> >>>    (merge 984cd77ddb sb/submodule-core-worktree later to maint).
> >>
> >> Personally I do not view this as a bug fix but a feature
> >> (but then again my thinking might be tainted of too much
> >> submodule work) hence I would not merge it down.
> >
> > Can you elaborate?
>
> ... ah, I figured it out.  You are saying "would not merge it down to
> maint".  In that case, I agree, since this this is not a recent bug
> (it's existed since before v1.7.10-rc1~14^2~2, 2012-03-02).

Yeah; the behavior was the gold standard for submodules ever since,
so I am wary of changing it under the guise of fixing a bug.
The core.worktree setting doesn't harm the user by default; you
need to craft a very specific situation to benefit from this feature.

Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 3/7] submodule: is_submodule_active to differentiate between new and old mode
  2018-08-20 19:50     ` Stefan Beller
@ 2018-08-21 21:39       ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-08-21 21:39 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, Brandon Williams, Jonathan Nieder

Stefan Beller <sbeller@google.com> writes:

>> So I think this patch is insufficient, and needs to at least change
>> the "submodule.active" codepath to return !!ret; otherwise, a caller
>> that now expects 0 (not active), 1 (active but can lose URL) and 2
>> (active and the presence of URL makes it so) will be confused when
>> one of the MATCHED_* constants from dir.h comes back.
>
> Yes.
>
> I'll resend when appropriately.

Thanks.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 00/21] Kill the_index part 4
      [irrelevant] <20180826100314.5137-1-pclouds@gmail.com>
@ 2018-08-27 17:32 ` Stefan Beller
      [irrelevant] ` <20180903180932.32260-1-pclouds@gmail.com>
  1 sibling, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-27 17:32 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

On Sun, Aug 26, 2018 at 3:03 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
>
> This continues the journey of getting rid of the_index at least in
> library code. The focus of part 4 is diff code. Since 'struct
> repository *' is passed around more (and even more in part 5), I take
> this opportunity to remove some the_repository references too.

yay! Thank you for continuing on the_index!

>
> Besides some small conflicts on 'pu', like the previous part, it also
> breaks 'pu' because of API changes. The fix is trivial though, just
> prepend the_repository as the first argument for the broken function
> calls.

This sounds like a problem. I said the same when sending the
object store lookup series, which ended via
3a2a1dc1707 (Merge branch 'sb/object-store-lookup', 2018-08-02)
in master, but I do recall Junio being somewhat unhappy about it[1].

By just adding the argument to the function, it might merge easily
but not compile, which would have to be fixed up; and that object store
series seemed to touch a lot of functions that were also used in series
in-flight.

I have since lost track of the refactoring and focused more on
submodules again, but plan to come back to more 'repositorification'.

> After this and ~20 more patches in part5, the_index is gone from
> library code.

This sounds promising! I'll take a look.

>  diff.c                 | 259 +++++++++++++++++++++++------------------

Ugh? That sounds like there is an interesting change coming.

Stefan

^ permalink raw reply	[relevance 4%]

* [PATCH 1/2] t2013: add test for missing but active submodule
@ 2018-08-27 22:12 Stefan Beller
  2018-08-27 22:12 ` [PATCH 2/2] submodule.c: warn about missing submodule git directories Stefan Beller
  2018-08-29 21:04 ` [PATCH 1/2] t2013: add test for missing but active submodule SZEDER Gábor
  0 siblings, 2 replies; 200+ results
From: Stefan Beller @ 2018-08-27 22:12 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

When cloning a superproject with the option
 --recurse-submodules='.', it is easy to find yourself wanting
a submodule active, but not having that submodule present in
the modules directory.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 t/t2013-checkout-submodule.sh | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
index 6ef15738e44..c69640fc341 100755
--- a/t/t2013-checkout-submodule.sh
+++ b/t/t2013-checkout-submodule.sh
@@ -63,6 +63,30 @@ test_expect_success '"checkout <submodule>" honors submodule.*.ignore from .git/
 	! test -s actual
 '
 
+test_expect_success 'setup superproject with historic submodule' '
+	test_create_repo super1 &&
+	test_create_repo sub1 &&
+	test_commit -C sub1 sub_content &&
+	git -C super1 submodule add ../sub1 &&
+	git -C super1 commit -a -m "sub1 added" &&
+	test_commit -C super1 historic_state &&
+	git -C super1 rm sub1 &&
+	git -C super1 commit -a -m "deleted sub" &&
+	test_commit -C super1 new_state &&
+	test_path_is_missing super1/sub &&
+
+	# The important part is to ensure sub1 is not in there any more.
+	# There is another series in flight, that may remove an
+	# empty .gitmodules file entirely.
+	test_must_be_empty super1/.gitmodules
+'
+
+test_expect_failure 'checkout old state with deleted submodule' '
+	test_when_finished "rm -rf super1 sub1 super1_clone" &&
+	git clone --recurse-submodules super1 super1_clone &&
+	git -C super1_clone checkout --recurse-submodules historic_state
+'
+
 KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1
 test_submodule_switch_recursing_with_args "checkout"
 
-- 
2.18.0


^ permalink raw reply	[relevance 23%]

* [PATCH 2/2] submodule.c: warn about missing submodule git directories
  2018-08-27 22:12 [PATCH 1/2] t2013: add test for missing but active submodule Stefan Beller
@ 2018-08-27 22:12 ` Stefan Beller
  2018-08-28 18:56   ` Junio C Hamano
  2018-09-05 19:18   ` Jonathan Nieder
  2018-08-29 21:04 ` [PATCH 1/2] t2013: add test for missing but active submodule SZEDER Gábor
  1 sibling, 2 replies; 200+ results
From: Stefan Beller @ 2018-08-27 22:12 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

This is the continuation of f2d48994dc1 (submodule.c: submodule_move_head
works with broken submodules, 2017-04-18), which tones down the case of
"broken submodule" in case of a missing git directory of the submodule to
be only a warning.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c                   | 16 ++++++++++++++++
 t/t2013-checkout-submodule.sh |  2 +-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/submodule.c b/submodule.c
index 50cbf5f13ed..689439a3d0c 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1641,6 +1641,22 @@ int submodule_move_head(const char *path,
 		} else {
 			char *gitdir = xstrfmt("%s/modules/%s",
 				    get_git_common_dir(), sub->name);
+
+			if (!is_git_directory(gitdir)) {
+				/*
+				 * It is safe to assume we could just clone
+				 * the submodule here, as we passed the
+				 * is_submodule_active test above (i.e. the
+				 * user is interested in this submodule.
+				 *
+				 * However as this code path is exercised
+				 * for operations that typically do not involve
+				 * network operations, let's not do that for now.
+				 */
+				warning(_("Submodule '%s' missing"), path);
+				free(gitdir);
+				return 0;
+			}
 			connect_work_tree_and_git_dir(path, gitdir, 0);
 			free(gitdir);
 
diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
index c69640fc341..82ef4576b91 100755
--- a/t/t2013-checkout-submodule.sh
+++ b/t/t2013-checkout-submodule.sh
@@ -81,7 +81,7 @@ test_expect_success 'setup superproject with historic submodule' '
 	test_must_be_empty super1/.gitmodules
 '
 
-test_expect_failure 'checkout old state with deleted submodule' '
+test_expect_success 'checkout old state with deleted submodule' '
 	test_when_finished "rm -rf super1 sub1 super1_clone" &&
 	git clone --recurse-submodules super1 super1_clone &&
 	git -C super1_clone checkout --recurse-submodules historic_state
-- 
2.18.0


^ permalink raw reply	[relevance 30%]

* Re: [PATCH 2/2] submodule.c: warn about missing submodule git directories
  2018-08-27 22:12 ` [PATCH 2/2] submodule.c: warn about missing submodule git directories Stefan Beller
@ 2018-08-28 18:56   ` Junio C Hamano
  2018-08-28 21:49     ` Stefan Beller
  2018-09-05 19:18   ` Jonathan Nieder
  1 sibling, 1 reply; 200+ results
From: Junio C Hamano @ 2018-08-28 18:56 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> This is the continuation of f2d48994dc1 (submodule.c: submodule_move_head
> works with broken submodules, 2017-04-18), which tones down the case of
> "broken submodule" in case of a missing git directory of the submodule to
> be only a warning.

After seeing this warning, as we do not do any remedial action in
this codepath, the user with a repository in this state will keep
seeing the 'missing' message.  Wouldn't we want to give a hint in
addition (e.g. 'you can run "git submodule update $name" to
recover', or something like that)?

The MOVE_HEAD_FORCE codepath that follows this hunk is, eh, already
forcing to correct the situation, so there is no need to touch that,
which makes sense, if I understand correctly.

> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c                   | 16 ++++++++++++++++
>  t/t2013-checkout-submodule.sh |  2 +-
>  2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/submodule.c b/submodule.c
> index 50cbf5f13ed..689439a3d0c 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1641,6 +1641,22 @@ int submodule_move_head(const char *path,
>  		} else {
>  			char *gitdir = xstrfmt("%s/modules/%s",
>  				    get_git_common_dir(), sub->name);
> +
> +			if (!is_git_directory(gitdir)) {
> +				/*
> +				 * It is safe to assume we could just clone
> +				 * the submodule here, as we passed the
> +				 * is_submodule_active test above (i.e. the
> +				 * user is interested in this submodule.
> +				 *
> +				 * However as this code path is exercised
> +				 * for operations that typically do not involve
> +				 * network operations, let's not do that for now.
> +				 */
> +				warning(_("Submodule '%s' missing"), path);
> +				free(gitdir);
> +				return 0;
> +			}
>  			connect_work_tree_and_git_dir(path, gitdir, 0);
>  			free(gitdir);
>  
> diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
> index c69640fc341..82ef4576b91 100755
> --- a/t/t2013-checkout-submodule.sh
> +++ b/t/t2013-checkout-submodule.sh
> @@ -81,7 +81,7 @@ test_expect_success 'setup superproject with historic submodule' '
>  	test_must_be_empty super1/.gitmodules
>  '
>  
> -test_expect_failure 'checkout old state with deleted submodule' '
> +test_expect_success 'checkout old state with deleted submodule' '
>  	test_when_finished "rm -rf super1 sub1 super1_clone" &&
>  	git clone --recurse-submodules super1 super1_clone &&
>  	git -C super1_clone checkout --recurse-submodules historic_state

^ permalink raw reply	[relevance 8%]

* [ANNOUNCE] Git v2.19.0-rc1
@ 2018-08-28 20:03 Junio C Hamano
  2018-08-29 14:50 ` Git for Windows v2.19.0-rc1, was " Johannes Schindelin
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-08-28 20:03 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

A release candidate Git v2.19.0-rc1 is now available for testing
at the usual places.  It is comprised of 735 non-merge commits
since v2.18.0, contributed by 64 people, 15 of which are new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/testing/

The following public repositories all have a copy of the
'v2.19.0-rc1' tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.18.0 are as follows.
Welcome to the Git development community!

  Aleksandr Makarov, Andrei Rybak, Chen Bin, Henning Schild,
  Isabella Stephens, Josh Steadmon, Jules Maselbas, Kana Natsuno,
  Marc Strapetz, Masaya Suzuki, Nicholas Guriev, Samuel Maftoul,
  Sebastian Kisela, Vladimir Parfinenko, and William Chargin.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Aaron Schrab, Ævar Arnfjörð Bjarmason, Alban Gruin, Alejandro
  R. Sedeño, Anthony Sottile, Antonio Ospite, Beat Bolli, Ben
  Peart, Brandon Williams, brian m. carlson, Christian Couder,
  Derrick Stolee, Elia Pinto, Elijah Newren, Eric Sunshine,
  Han-Wen Nienhuys, Jameson Miller, Jean-Noël Avila, Jeff
  Hostetler, Jeff King, Johannes Schindelin, Johannes Sixt,
  Jonathan Nieder, Jonathan Tan, Junio C Hamano, Kim Gybels,
  Kirill Smelkov, Kyle Meyer, Luis Marsano, Łukasz Stelmach,
  Luke Diamand, Martin Ågren, Max Kirillov, Michael Barabanov,
  Mike Hommey, Nguyễn Thái Ngọc Duy, Olga Telezhnaya,
  Phillip Wood, Prathamesh Chavan, Ramsay Jones, René Scharfe,
  Stefan Beller, SZEDER Gábor, Taylor Blau, Thomas Rast, Tobias
  Klauser, Todd Zullinger, Ville Skyttä, and Xiaolong Ye.

----------------------------------------------------------------

Git 2.19 Release Notes (draft)
==============================

Updates since v2.18
-------------------

UI, Workflows & Features

 * "git diff" compares the index and the working tree.  For paths
   added with intent-to-add bit, the command shows the full contents
   of them as added, but the paths themselves were not marked as new
   files.  They are now shown as new by default.

   "git apply" learned the "--intent-to-add" option so that an
   otherwise working-tree-only application of a patch will add new
   paths to the index marked with the "intent-to-add" bit.

 * "git grep" learned the "--column" option that gives not just the
   line number but the column number of the hit.

 * The "-l" option in "git branch -l" is an unfortunate short-hand for
   "--create-reflog", but many users, both old and new, somehow expect
   it to be something else, perhaps "--list".  This step warns when "-l"
   is used as a short-hand for "--create-reflog" and warns about the
   future repurposing of the it when it is used.

 * The userdiff pattern for .php has been updated.

 * The content-transfer-encoding of the message "git send-email" sends
   out by default was 8bit, which can cause trouble when there is an
   overlong line to bust RFC 5322/2822 limit.  A new option 'auto' to
   automatically switch to quoted-printable when there is such a line
   in the payload has been introduced and is made the default.

 * "git checkout" and "git worktree add" learned to honor
   checkout.defaultRemote when auto-vivifying a local branch out of a
   remote tracking branch in a repository with multiple remotes that
   have tracking branches that share the same names.
   (merge 8d7b558bae ab/checkout-default-remote later to maint).

 * "git grep" learned the "--only-matching" option.

 * "git rebase --rebase-merges" mode now handles octopus merges as
   well.

 * Add a server-side knob to skip commits in exponential/fibbonacci
   stride in an attempt to cover wider swath of history with a smaller
   number of iterations, potentially accepting a larger packfile
   transfer, instead of going back one commit a time during common
   ancestor discovery during the "git fetch" transaction.
   (merge 42cc7485a2 jt/fetch-negotiator-skipping later to maint).

 * A new configuration variable core.usereplacerefs has been added,
   primarily to help server installations that want to ignore the
   replace mechanism altogether.

 * Teach "git tag -s" etc. a few configuration variables (gpg.format
   that can be set to "openpgp" or "x509", and gpg.<format>.program
   that is used to specify what program to use to deal with the format)
   to allow x.509 certs with CMS via "gpgsm" to be used instead of
   openpgp via "gnupg".

 * Many more strings are prepared for l10n.

 * "git p4 submit" learns to ask its own pre-submit hook if it should
   continue with submitting.

 * The test performed at the receiving end of "git push" to prevent
   bad objects from entering repository can be customized via
   receive.fsck.* configuration variables; we now have gained a
   counterpart to do the same on the "git fetch" side, with
   fetch.fsck.* configuration variables.

 * "git pull --rebase=interactive" learned "i" as a short-hand for
   "interactive".

 * "git instaweb" has been adjusted to run better with newer Apache on
   RedHat based distros.

 * "git range-diff" is a reimplementation of "git tbdiff" that lets us
   compare individual patches in two iterations of a topic.

 * The sideband code learned to optionally paint selected keywords at
   the beginning of incoming lines on the receiving end.

 * "git branch --list" learned to take the default sort order from the
   'branch.sort' configuration variable, just like "git tag --list"
   pays attention to 'tag.sort'.

 * "git worktree" command learned "--quiet" option to make it less
   verbose.


Performance, Internal Implementation, Development Support etc.

 * The bulk of "git submodule foreach" has been rewritten in C.

 * The in-core "commit" object had an all-purpose "void *util" field,
   which was tricky to use especially in library-ish part of the
   code.  All of the existing uses of the field has been migrated to a
   more dedicated "commit-slab" mechanism and the field is eliminated.

 * A less often used command "git show-index" has been modernized.
   (merge fb3010c31f jk/show-index later to maint).

 * The conversion to pass "the_repository" and then "a_repository"
   throughout the object access API continues.

 * Continuing with the idea to programatically enumerate various
   pieces of data required for command line completion, teach the
   codebase to report the list of configuration variables
   subcommands care about to help complete them.

 * Separate "rebase -p" codepath out of "rebase -i" implementation to
   slim down the latter and make it easier to manage.

 * Make refspec parsing codepath more robust.

 * Some flaky tests have been fixed.

 * Continuing with the idea to programmatically enumerate various
   pieces of data required for command line completion, the codebase
   has been taught to enumerate options prefixed with "--no-" to
   negate them.

 * Build and test procedure for netrc credential helper (in contrib/)
   has been updated.

 * The conversion to pass "the_repository" and then "a_repository"
   throughout the object access API continues.

 * Remove unused function definitions and declarations from ewah
   bitmap subsystem.

 * Code preparation to make "git p4" closer to be usable with Python 3.

 * Tighten the API to make it harder to misuse in-tree .gitmodules
   file, even though it shares the same syntax with configuration
   files, to read random configuration items from it.

 * "git fast-import" has been updated to avoid attempting to create
   delta against a zero-byte-long string, which is pointless.

 * The codebase has been updated to compile cleanly with -pedantic
   option.
   (merge 2b647a05d7 bb/pedantic later to maint).

 * The character display width table has been updated to match the
   latest Unicode standard.
   (merge 570951eea2 bb/unicode-11-width later to maint).

 * test-lint now looks for broken use of "VAR=VAL shell_func" in test
   scripts.

 * Conversion from uchar[40] to struct object_id continues.

 * Recent "security fix" to pay attention to contents of ".gitmodules"
   while accepting "git push" was a bit overly strict than necessary,
   which has been adjusted.

 * "git fsck" learns to make sure the optional commit-graph file is in
   a sane state.

 * "git diff --color-moved" feature has further been tweaked.

 * Code restructuring and a small fix to transport protocol v2 during
   fetching.

 * Parsing of -L[<N>][,[<M>]] parameters "git blame" and "git log"
   take has been tweaked.

 * lookup_commit_reference() and friends have been updated to find
   in-core object for a specific in-core repository instance.

 * Various glitches in the heuristics of merge-recursive strategy have
   been documented in new tests.

 * "git fetch" learned a new option "--negotiation-tip" to limit the
   set of commits it tells the other end as "have", to reduce wasted
   bandwidth and cycles, which would be helpful when the receiving
   repository has a lot of refs that have little to do with the
   history at the remote it is fetching from.

 * For a large tree, the index needs to hold many cache entries
   allocated on heap.  These cache entries are now allocated out of a
   dedicated memory pool to amortize malloc(3) overhead.

 * Tests to cover various conflicting cases have been added for
   merge-recursive.

 * Tests to cover conflict cases that involve submodules have been
   added for merge-recursive.

 * Look for broken "&&" chains that are hidden in subshell, many of
   which have been found and corrected.

 * The singleton commit-graph in-core instance is made per in-core
   repository instance.

 * "make DEVELOPER=1 DEVOPTS=pedantic" allows developers to compile
   with -pedantic option, which may catch more problematic program
   constructs and potential bugs.

 * Preparatory code to later add json output for telemetry data has
   been added.

 * Update the way we use Coccinelle to find out-of-style code that
   need to be modernised.

 * It is too easy to misuse system API functions such as strcat();
   these selected functions are now forbidden in this codebase and
   will cause a compilation failure.

 * Add a script (in contrib/) to help users of VSCode work better with
   our codebase.

 * The Travis CI scripts were taught to ship back the test data from
   failed tests.
   (merge aea8879a6a sg/travis-retrieve-trash-upon-failure later to maint).

 * The parse-options machinery learned to refrain from enclosing
   placeholder string inside a "<bra" and "ket>" pair automatically
   without PARSE_OPT_LITERAL_ARGHELP.  Existing help text for option
   arguments that are not formatted correctly have been identified and
   fixed.
   (merge 5f0df44cd7 rs/parse-opt-lithelp later to maint).

 * Noiseword "extern" has been removed from function decls in the
   header files.

 * A few atoms like %(objecttype) and %(objectsize) in the format
   specifier of "for-each-ref --format=<format>" can be filled without
   getting the full contents of the object, but just with the object
   header.  These cases have been optimized by calling
   oid_object_info() API (instead of reading and inspecting the data).

 * The end result of documentation update has been made to be
   inspected more easily to help developers.

 * The API to iterate over all objects learned to optionally list
   objects in the order they appear in packfiles, which helps locality
   of access if the caller accesses these objects while as objects are
   enumerated.

 * Improve built-in facility to catch broken &&-chain in the tests.

 * The more library-ish parts of the codebase learned to work on the
   in-core index-state instance that is passed in by their callers,
   instead of always working on the singleton "the_index" instance.

 * A test prerequisite defined by various test scripts with slightly
   different semantics has been consolidated into a single copy and
   made into a lazily defined one.
   (merge 6ec633059a wc/make-funnynames-shared-lazy-prereq later to maint).

 * After a partial clone, repeated fetches from promisor remote would
   have accumulated many packfiles marked with .promisor bit without
   getting them coalesced into fewer packfiles, hurting performance.
   "git repack" now learned to repack them.

 * Partially revert the support for multiple hash functions to regain
   hash comparison performance; we'd think of a way to do this better
   in the next cycle.

 * "git help --config" (which is used in command line completion)
   missed the configuration variables not described in the main
   config.txt file but are described in another file that is included
   by it, which has been corrected.

Fixes since v2.18
-----------------

 * "git remote update" can take both a single remote nickname and a
   nickname for remote groups, and the completion script (in contrib/)
   has been taught about it.
   (merge 9cd4382ad5 ls/complete-remote-update-names later to maint).

 * "git fetch --shallow-since=<cutoff>" that specifies the cut-off
   point that is newer than the existing history used to end up
   grabbing the entire history.  Such a request now errors out.
   (merge e34de73c56 nd/reject-empty-shallow-request later to maint).

 * Fix for 2.17-era regression around `core.safecrlf`.
   (merge 6cb09125be as/safecrlf-quiet-fix later to maint).

 * The recent addition of "partial clone" experimental feature kicked
   in when it shouldn't, namely, when there is no partial-clone filter
   defined even if extensions.partialclone is set.
   (merge cac1137dc4 jh/partial-clone later to maint).

 * "git send-pack --signed" (hence "git push --signed" over the http
   transport) did not read user ident from the config mechanism to
   determine whom to sign the push certificate as, which has been
   corrected.
   (merge d067d98887 ms/send-pack-honor-config later to maint).

 * "git fetch-pack --all" used to unnecessarily fail upon seeing an
   annotated tag that points at an object other than a commit.
   (merge c12c9df527 jk/fetch-all-peeled-fix later to maint).

 * When user edits the patch in "git add -p" and the user's editor is
   set to strip trailing whitespaces indiscriminately, an empty line
   that is unchanged in the patch would become completely empty
   (instead of a line with a sole SP on it).  The code introduced in
   Git 2.17 timeframe failed to parse such a patch, but now it learned
   to notice the situation and cope with it.
   (merge f4d35a6b49 pw/add-p-recount later to maint).

 * The code to try seeing if a fetch is necessary in a submodule
   during a fetch with --recurse-submodules got confused when the path
   to the submodule was changed in the range of commits in the
   superproject, sometimes showing "(null)".  This has been corrected.

 * "git submodule" did not correctly adjust core.worktree setting that
   indicates whether/where a submodule repository has its associated
   working tree across various state transitions, which has been
   corrected.

 * Bugfix for "rebase -i" corner case regression.
   (merge a9279c6785 pw/rebase-i-keep-reword-after-conflict later to maint).

 * Recently added "--base" option to "git format-patch" command did
   not correctly generate prereq patch ids.
   (merge 15b76c1fb3 xy/format-patch-prereq-patch-id-fix later to maint).

 * POSIX portability fix in Makefile to fix a glitch introduced a few
   releases ago.
   (merge 6600054e9b dj/runtime-prefix later to maint).

 * "git filter-branch" when used with the "--state-branch" option
   still attempted to rewrite the commits whose filtered result is
   known from the previous attempt (which is recorded on the state
   branch); the command has been corrected not to waste cycles doing
   so.
   (merge 709cfe848a mb/filter-branch-optim later to maint).

 * Clarify that setting core.ignoreCase to deviate from reality would
   not turn a case-incapable filesystem into a case-capable one.
   (merge 48294b512a ms/core-icase-doc later to maint).

 * "fsck.skipList" did not prevent a blob object listed there from
   being inspected for is contents (e.g. we recently started to
   inspect the contents of ".gitmodules" for certain malicious
   patterns), which has been corrected.
   (merge fb16287719 rj/submodule-fsck-skip later to maint).

 * "git checkout --recurse-submodules another-branch" did not report
   in which submodule it failed to update the working tree, which
   resulted in an unhelpful error message.
   (merge ba95d4e4bd sb/submodule-move-head-error-msg later to maint).

 * "git rebase" behaved slightly differently depending on which one of
   the three backends gets used; this has been documented and an
   effort to make them more uniform has begun.
   (merge b00bf1c9a8 en/rebase-consistency later to maint).

 * The "--ignore-case" option of "git for-each-ref" (and its friends)
   did not work correctly, which has been fixed.
   (merge e674eb2528 jk/for-each-ref-icase later to maint).

 * "git fetch" failed to correctly validate the set of objects it
   received when making a shallow history deeper, which has been
   corrected.
   (merge cf1e7c0770 jt/connectivity-check-after-unshallow later to maint).

 * Partial clone support of "git clone" has been updated to correctly
   validate the objects it receives from the other side.  The server
   side has been corrected to send objects that are directly
   requested, even if they may match the filtering criteria (e.g. when
   doing a "lazy blob" partial clone).
   (merge a7e67c11b8 jt/partial-clone-fsck-connectivity later to maint).

 * Handling of an empty range by "git cherry-pick" was inconsistent
   depending on how the range ended up to be empty, which has been
   corrected.
   (merge c5e358d073 jk/empty-pick-fix later to maint).

 * "git reset --merge" (hence "git merge ---abort") and "git reset --hard"
   had trouble working correctly in a sparsely checked out working
   tree after a conflict, which has been corrected.
   (merge b33fdfc34c mk/merge-in-sparse-checkout later to maint).

 * Correct a broken use of "VAR=VAL shell_func" in a test.
   (merge 650161a277 jc/t3404-one-shot-export-fix later to maint).

 * "git rev-parse ':/substring'" did not consider the history leading
   only to HEAD when looking for a commit with the given substring,
   when the HEAD is detached.  This has been fixed.
   (merge 6b3351e799 wc/find-commit-with-pattern-on-detached-head later to maint).

 * Build doc update for Windows.
   (merge ede8d89bb1 nd/command-list later to maint).

 * core.commentchar is now honored when preparing the list of commits
   to replay in "rebase -i".

 * "git pull --rebase" on a corrupt HEAD caused a segfault.  In
   general we substitute an empty tree object when running the in-core
   equivalent of the diff-index command, and the codepath has been
   corrected to do so as well to fix this issue.
   (merge 3506dc9445 jk/has-uncommitted-changes-fix later to maint).

 * httpd tests saw occasional breakage due to the way its access log
   gets inspected by the tests, which has been updated to make them
   less flaky.
   (merge e8b3b2e275 sg/httpd-test-unflake later to maint).

 * Tests to cover more D/F conflict cases have been added for
   merge-recursive.

 * "git gc --auto" opens file descriptors for the packfiles before
   spawning "git repack/prune", which would upset Windows that does
   not want a process to work on a file that is open by another
   process.  The issue has been worked around.
   (merge 12e73a3ce4 kg/gc-auto-windows-workaround later to maint).

 * The recursive merge strategy did not properly ensure there was no
   change between HEAD and the index before performing its operation,
   which has been corrected.
   (merge 55f39cf755 en/dirty-merge-fixes later to maint).

 * "git rebase" started exporting GIT_DIR environment variable and
   exposing it to hook scripts when part of it got rewritten in C.
   Instead of matching the old scripted Porcelains' behaviour,
   compensate by also exporting GIT_WORK_TREE environment as well to
   lessen the damage.  This can harm existing hooks that want to
   operate on different repository, but the current behaviour is
   already broken for them anyway.
   (merge ab5e67d751 bc/sequencer-export-work-tree-as-well later to maint).

 * "git send-email" when using in a batched mode that limits the
   number of messages sent in a single SMTP session lost the contents
   of the variable used to choose between tls/ssl, unable to send the
   second and later batches, which has been fixed.
   (merge 636f3d7ac5 jm/send-email-tls-auth-on-batch later to maint).

 * The lazy clone support had a few places where missing but promised
   objects were not correctly tolerated, which have been fixed.

 * One of the "diff --color-moved" mode "dimmed_zebra" that was named
   in an unusual way has been deprecated and replaced by
   "dimmed-zebra".
   (merge e3f2f5f9cd es/diff-color-moved-fix later to maint).

 * The wire-protocol v2 relies on the client to send "ref prefixes" to
   limit the bandwidth spent on the initial ref advertisement.  "git
   clone" when learned to speak v2 forgot to do so, which has been
   corrected.
   (merge 402c47d939 bw/clone-ref-prefixes later to maint).

 * "git diff --histogram" had a bad memory usage pattern, which has
   been rearranged to reduce the peak usage.
   (merge 79cb2ebb92 sb/histogram-less-memory later to maint).

 * Code clean-up to use size_t/ssize_t when they are the right type.
   (merge 7726d360b5 jk/size-t later to maint).

 * The wire-protocol v2 relies on the client to send "ref prefixes" to
   limit the bandwidth spent on the initial ref advertisement.  "git
   fetch $remote branch:branch" that asks tags that point into the
   history leading to the "branch" automatically followed sent to
   narrow prefix and broke the tag following, which has been fixed.
   (merge 2b554353a5 jt/tag-following-with-proto-v2-fix later to maint).

 * When the sparse checkout feature is in use, "git cherry-pick" and
   other mergy operations lost the skip_worktree bit when a path that
   is excluded from checkout requires content level merge, which is
   resolved as the same as the HEAD version, without materializing the
   merge result in the working tree, which made the path appear as
   deleted.  This has been corrected by preserving the skip_worktree
   bit (and not materializing the file in the working tree).
   (merge 2b75fb601c en/merge-recursive-skip-fix later to maint).

 * The "author-script" file "git rebase -i" creates got broken when
   we started to move the command away from shell script, which is
   getting fixed now.
   (merge 5522bbac20 es/rebase-i-author-script-fix later to maint).

 * The automatic tree-matching in "git merge -s subtree" was broken 5
   years ago and nobody has noticed since then, which is now fixed.
   (merge 2ec4150713 jk/merge-subtree-heuristics later to maint).

 * "git fetch $there refs/heads/s" ought to fetch the tip of the
   branch 's', but when "refs/heads/refs/heads/s", i.e. a branch whose
   name is "refs/heads/s" exists at the same time, fetched that one
   instead by mistake.  This has been corrected to honor the usual
   disambiguation rules for abbreviated refnames.
   (merge 60650a48c0 jt/refspec-dwim-precedence-fix later to maint).

 * Futureproofing a helper function that can easily be misused.
   (merge 65bb21e77e es/want-color-fd-defensive later to maint).

 * The http-backend (used for smart-http transport) used to slurp the
   whole input until EOF, without paying attention to CONTENT_LENGTH
   that is supplied in the environment and instead expecting the Web
   server to close the input stream.  This has been fixed.
   (merge eebfe40962 mk/http-backend-content-length later to maint).

 * "git merge --abort" etc. did not clean things up properly when
   there were conflicted entries in the index in certain order that
   are involved in D/F conflicts.  This has been corrected.
   (merge ad3762042a en/abort-df-conflict-fixes later to maint).

 * "git diff --indent-heuristic" had a bad corner case performance.
   (merge 301ef85401 sb/indent-heuristic-optim later to maint).

 * The "--exec" option to "git rebase --rebase-merges" placed the exec
   commands at wrong places, which has been corrected.

 * "git verify-tag" and "git verify-commit" have been taught to use
   the exit status of underlying "gpg --verify" to signal bad or
   untrusted signature they found.
   (merge 4e5dc9ca17 jc/gpg-status later to maint).

 * "git mergetool" stopped and gave an extra prompt to continue after
   the last path has been handled, which did not make much sense.
   (merge d651a54b8a ng/mergetool-lose-final-prompt later to maint).

 * Among the three codepaths we use O_APPEND to open a file for
   appending, one used for writing GIT_TRACE output requires O_APPEND
   implementation that behaves sensibly when multiple processes are
   writing to the same file.  POSIX emulation used in the Windows port
   has been updated to improve in this area.
   (merge d641097589 js/mingw-o-append later to maint).

 * "git pull --rebase -v" in a repository with a submodule barfed as
   an intermediate process did not understand what "-v(erbose)" flag
   meant, which has been fixed.
   (merge e84c3cf3dc sb/pull-rebase-submodule later to maint).

 * Recent update to "git config" broke updating variable in a
   subsection, which has been corrected.
   (merge bff7df7a87 sb/config-write-fix later to maint).

 * When "git rebase -i" is told to squash two or more commits into
   one, it labeled the log message for each commit with its number.
   It correctly called the first one "1st commit", but the next one
   was "commit #1", which was off-by-one.  This has been corrected.
   (merge dd2e36ebac pw/rebase-i-squash-number-fix later to maint).

 * "git rebase -i", when a 'merge <branch>' insn in its todo list
   fails, segfaulted, which has been (minimally) corrected.
   (merge bc9238bb09 pw/rebase-i-merge-segv-fix later to maint).

 * "git cherry-pick --quit" failed to remove CHERRY_PICK_HEAD even
   though we won't be in a cherry-pick session after it returns, which
   has been corrected.
   (merge 3e7dd99208 nd/cherry-pick-quit-fix later to maint).

 * In a recent update in 2.18 era, "git pack-objects" started
   producing a larger than necessary packfiles by missing
   opportunities to use large deltas.  This has been corrected.

 * The meaning of the possible values the "core.checkStat"
   configuration variable can take were not adequately documented,
   which has been fixed.
   (merge 9bf5d4c4e2 nd/config-core-checkstat-doc later to maint).

 * Code cleanup, docfix, build fix, etc.
   (merge aee9be2ebe sg/update-ref-stdin-cleanup later to maint).
   (merge 037714252f jc/clean-after-sanity-tests later to maint).
   (merge 5b26c3c941 en/merge-recursive-cleanup later to maint).
   (merge 0dcbc0392e bw/config-refer-to-gitsubmodules-doc later to maint).
   (merge bb4d000e87 bw/protocol-v2 later to maint).
   (merge 928f0ab4ba vs/typofixes later to maint).
   (merge d7f590be84 en/rebase-i-microfixes later to maint).
   (merge 81d395cc85 js/rebase-recreate-merge later to maint).
   (merge 51d1863168 tz/exclude-doc-smallfixes later to maint).
   (merge a9aa3c0927 ds/commit-graph later to maint).
   (merge 5cf8e06474 js/enhanced-version-info later to maint).
   (merge 6aaded5509 tb/config-default later to maint).
   (merge 022d2ac1f3 sb/blame-color later to maint).
   (merge 5a06a20e0c bp/test-drop-caches-for-windows later to maint).
   (merge dd61cc1c2e jk/ui-color-always-to-auto later to maint).
   (merge 1e83b9bfdd sb/trailers-docfix later to maint).
   (merge ab29f1b329 sg/fast-import-dump-refs-on-checkpoint-fix later to maint).
   (merge 6a8ad880f0 jn/subtree-test-fixes later to maint).
   (merge ffbd51cc60 nd/pack-objects-threading-doc later to maint).
   (merge e9dac7be60 es/mw-to-git-chain-fix later to maint).
   (merge fe583c6c7a rs/remote-mv-leakfix later to maint).
   (merge 69885ab015 en/t3031-title-fix later to maint).
   (merge 8578037bed nd/config-blame-sort later to maint).
   (merge 8ad169c4ba hn/config-in-code-comment later to maint).
   (merge b7446fcfdf ar/t4150-am-scissors-test-fix later to maint).
   (merge a8132410ee js/typofixes later to maint).
   (merge 388d0ff6e5 en/update-index-doc later to maint).
   (merge e05aa688dd jc/update-index-doc later to maint).
   (merge 10c600172c sg/t5310-empty-input-fix later to maint).
   (merge 5641eb9465 jh/partial-clone-doc later to maint).
   (merge 2711b1ad5e ab/submodule-relative-url-tests later to maint).
   (merge ce528de023 ab/unconditional-free-and-null later to maint).
   (merge bbc072f5d8 rs/opt-updates later to maint).
   (merge 69d846f053 jk/use-compat-util-in-test-tool later to maint).
   (merge 1820703045 js/larger-timestamps later to maint).
   (merge c8b35b95e1 sg/t4051-fix later to maint).
   (merge 30612cb670 sg/t0020-conversion-fix later to maint).
   (merge 15da753709 sg/t7501-thinkofix later to maint).
   (merge 79b04f9b60 sg/t3903-missing-fix later to maint).
   (merge 2745817028 sg/t3420-autostash-fix later to maint).
   (merge 7afb0d6777 sg/test-rebase-editor-fix later to maint).

^ permalink raw reply	[relevance 2%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
      [irrelevant]       ` <20180814180406.GA86804@google.com>
      [irrelevant]         ` <20180814185743.GE142615@aiede.svl.corp.google.com>
@ 2018-08-28 21:35         ` Stefan Beller
  2018-08-29  5:25           ` Jeff King
  1 sibling, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-28 21:35 UTC (permalink / raw)
  To: Brandon Williams; +Cc: Jeff King, git

> > > -           echo "gitdir: ../../../.git/modules/sub3/modules/dirdir/subsub" >./sub3/dirdir/subsub/.git_expect
> > > +           echo "gitdir: ../../../.git/modules/sub3/modules/dirdir%2fsubsub" >./sub3/dirdir/subsub/.git_expect
> >
> > One interesting thing about url-encoding is that it's not one-to-one.
> > This case could also be %2F, which is a different file (on a
> > case-sensitive filesystem). I think "%20" and "+" are similarly
> > interchangeable.
> >
> > If we were decoding the filenames, that's fine. The round-trip is
> > lossless.
> >
> > But that's not quite how the new code behaves. We encode the input and
> > then check to see if it matches an encoding we previously performed. So
> > if our urlencode routines ever change, this will subtly break.

And this is the problem:
a) we have a 'complicated' encoding here, which must never change
b) the "encode and check if it matches", will produce ugly code going forward,
    as it tries to differentiate between submodules named "url_encoded(a)"
    and "a" (e.g. "a%20b" and "a b" would conflict and we have to resolve
    the conflict, although those two names are perfectly fine as they do not
    have the original problem of having slashes)

Hence I would propose a simpler encoding:

1)    / -> _ ( replace a slash by an underscore)
2)    _ -> __ (replace any underscore by 2 underscores, this is just the
          escaping mechanism to differentiate a/b and a_b)

3) (optional) instead of putting it all in modules/, use another
directory gitmodules/
    for example. this will make sure we can tell if a repository has
been converted
    or is stuck with a setup of a current git.

> This is exactly the reason why I wanted to get some opinions on what the
> best thing to do here would be.  I _think_ the best thing would probably
> be to write a specific routine to do the conversion, and it wouldn't
> even have to be all that complex.  Basically I'm just interested in
> converting '/' characters so that things no longer behave like
> nested directories.

Yeah, then let's just convert '/' with as little overhead as possible.

Thanks,
Stefan

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 2/2] submodule.c: warn about missing submodule git directories
  2018-08-28 18:56   ` Junio C Hamano
@ 2018-08-28 21:49     ` Stefan Beller
  2018-08-29 17:16       ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-28 21:49 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Tue, Aug 28, 2018 at 11:56 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > This is the continuation of f2d48994dc1 (submodule.c: submodule_move_head
> > works with broken submodules, 2017-04-18), which tones down the case of
> > "broken submodule" in case of a missing git directory of the submodule to
> > be only a warning.
>
> After seeing this warning, as we do not do any remedial action in
> this codepath, the user with a repository in this state will keep
> seeing the 'missing' message.  Wouldn't we want to give a hint in
> addition (e.g. 'you can run "git submodule update $name" to
> recover', or something like that)?

Not quite, as this is only triggered in the case of 'old_head = NULL', which
is when you have a superproject that is missing the submodule in the
working tree before and wants to have it afterwards.

Looking at the test in the previous patch, I would think a reasonable workflow
in the test is

    git clone --recurse-submodules super1 super1_clone && cd super1_clone
    git checkout --recurse-submodules historic_state
    # see warning, but checkout proceeds

    git fetch --recurse-submodules
    # clones the submodule as it was configured active via the clone

    git checkout --recurse-submodules historic_state
    # this checkout will put the submodule in place
    #  not sure if -f is needed here, though.


I am currently working on the cloning of submodules that are not currently
in the working tree while fetching in the superproject, which would address
the latter part.

> The MOVE_HEAD_FORCE codepath that follows this hunk is, eh, already
> forcing to correct the situation, so there is no need to touch that,
> which makes sense, if I understand correctly.

No, that is not executed for now as it depends on 'old_head'.

In case of FORCE we might want to die instead of just warn about that submodule.

Stefan

^ permalink raw reply	[relevance 9%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-28 21:35         ` Stefan Beller
@ 2018-08-29  5:25           ` Jeff King
  2018-08-29 18:10             ` Stefan Beller
  2018-08-29 21:09             ` Jonathan Nieder
  0 siblings, 2 replies; 200+ results
From: Jeff King @ 2018-08-29  5:25 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Brandon Williams, git

On Tue, Aug 28, 2018 at 02:35:25PM -0700, Stefan Beller wrote:

> 3) (optional) instead of putting it all in modules/, use another
>    directory gitmodules/ for example. this will make sure we can tell
>    if a repository has been converted or is stuck with a setup of a
>    current git.

I actually kind of like that idea, as it makes the interaction between
old and new names much simpler to reason about.

And since old code won't know about the new names anyway, there's in
theory no downside. In practice, of course, the encoding may often be a
noop, and lazy scripts would continue to work most of the time if you
didn't change out the prefix directory. I'm not sure if that is an
argument for the scheme (because it will suss out broken scripts more
consistently) or against it (because 99% of the time those old scripts
would just happen to work).

> > This is exactly the reason why I wanted to get some opinions on what the
> > best thing to do here would be.  I _think_ the best thing would probably
> > be to write a specific routine to do the conversion, and it wouldn't
> > even have to be all that complex.  Basically I'm just interested in
> > converting '/' characters so that things no longer behave like
> > nested directories.
> 
> Yeah, then let's just convert '/' with as little overhead as possible.

Do you care about case-folding issues (e.g., submodules "FOO" and "foo"
colliding)?

I'm OK if the answer is "no", but if you do want to deal with it, the
time is probably now.

-Peff

^ permalink raw reply	[relevance 7%]

* Git for Windows v2.19.0-rc1, was Re: [ANNOUNCE] Git v2.19.0-rc1
  2018-08-28 20:03 [ANNOUNCE] Git v2.19.0-rc1 Junio C Hamano
@ 2018-08-29 14:50 ` " Johannes Schindelin
  0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2018-08-29 14:50 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, git-for-windows, git-packagers

[-- Attachment #1: Type: text/plain, Size: 32152 bytes --]

Team,

the corresponding Git for Windows v2.19.0-rc1 (most notably with the
Experimental Options page in the installer letting you opt into using the
built-in `stash` and `rebase`) was built by Jameson Miller (and me) last
night and can be found here:

https://github.com/git-for-windows/git/releases/v2.19.0-rc1.windows.1

Ciao,
Johannes

On Tue, 28 Aug 2018, Junio C Hamano wrote:

> A release candidate Git v2.19.0-rc1 is now available for testing
> at the usual places.  It is comprised of 735 non-merge commits
> since v2.18.0, contributed by 64 people, 15 of which are new faces.
> 
> The tarballs are found at:
> 
>     https://www.kernel.org/pub/software/scm/git/testing/
> 
> The following public repositories all have a copy of the
> 'v2.19.0-rc1' tag and the 'master' branch that the tag points at:
> 
>   url = https://kernel.googlesource.com/pub/scm/git/git
>   url = git://repo.or.cz/alt-git.git
>   url = https://github.com/gitster/git
> 
> New contributors whose contributions weren't in v2.18.0 are as follows.
> Welcome to the Git development community!
> 
>   Aleksandr Makarov, Andrei Rybak, Chen Bin, Henning Schild,
>   Isabella Stephens, Josh Steadmon, Jules Maselbas, Kana Natsuno,
>   Marc Strapetz, Masaya Suzuki, Nicholas Guriev, Samuel Maftoul,
>   Sebastian Kisela, Vladimir Parfinenko, and William Chargin.
> 
> Returning contributors who helped this release are as follows.
> Thanks for your continued support.
> 
>   Aaron Schrab, Ævar Arnfjörð Bjarmason, Alban Gruin, Alejandro
>   R. Sedeño, Anthony Sottile, Antonio Ospite, Beat Bolli, Ben
>   Peart, Brandon Williams, brian m. carlson, Christian Couder,
>   Derrick Stolee, Elia Pinto, Elijah Newren, Eric Sunshine,
>   Han-Wen Nienhuys, Jameson Miller, Jean-Noël Avila, Jeff
>   Hostetler, Jeff King, Johannes Schindelin, Johannes Sixt,
>   Jonathan Nieder, Jonathan Tan, Junio C Hamano, Kim Gybels,
>   Kirill Smelkov, Kyle Meyer, Luis Marsano, Łukasz Stelmach,
>   Luke Diamand, Martin Ågren, Max Kirillov, Michael Barabanov,
>   Mike Hommey, Nguyễn Thái Ngọc Duy, Olga Telezhnaya,
>   Phillip Wood, Prathamesh Chavan, Ramsay Jones, René Scharfe,
>   Stefan Beller, SZEDER Gábor, Taylor Blau, Thomas Rast, Tobias
>   Klauser, Todd Zullinger, Ville Skyttä, and Xiaolong Ye.
> 
> ----------------------------------------------------------------
> 
> Git 2.19 Release Notes (draft)
> ==============================
> 
> Updates since v2.18
> -------------------
> 
> UI, Workflows & Features
> 
>  * "git diff" compares the index and the working tree.  For paths
>    added with intent-to-add bit, the command shows the full contents
>    of them as added, but the paths themselves were not marked as new
>    files.  They are now shown as new by default.
> 
>    "git apply" learned the "--intent-to-add" option so that an
>    otherwise working-tree-only application of a patch will add new
>    paths to the index marked with the "intent-to-add" bit.
> 
>  * "git grep" learned the "--column" option that gives not just the
>    line number but the column number of the hit.
> 
>  * The "-l" option in "git branch -l" is an unfortunate short-hand for
>    "--create-reflog", but many users, both old and new, somehow expect
>    it to be something else, perhaps "--list".  This step warns when "-l"
>    is used as a short-hand for "--create-reflog" and warns about the
>    future repurposing of the it when it is used.
> 
>  * The userdiff pattern for .php has been updated.
> 
>  * The content-transfer-encoding of the message "git send-email" sends
>    out by default was 8bit, which can cause trouble when there is an
>    overlong line to bust RFC 5322/2822 limit.  A new option 'auto' to
>    automatically switch to quoted-printable when there is such a line
>    in the payload has been introduced and is made the default.
> 
>  * "git checkout" and "git worktree add" learned to honor
>    checkout.defaultRemote when auto-vivifying a local branch out of a
>    remote tracking branch in a repository with multiple remotes that
>    have tracking branches that share the same names.
>    (merge 8d7b558bae ab/checkout-default-remote later to maint).
> 
>  * "git grep" learned the "--only-matching" option.
> 
>  * "git rebase --rebase-merges" mode now handles octopus merges as
>    well.
> 
>  * Add a server-side knob to skip commits in exponential/fibbonacci
>    stride in an attempt to cover wider swath of history with a smaller
>    number of iterations, potentially accepting a larger packfile
>    transfer, instead of going back one commit a time during common
>    ancestor discovery during the "git fetch" transaction.
>    (merge 42cc7485a2 jt/fetch-negotiator-skipping later to maint).
> 
>  * A new configuration variable core.usereplacerefs has been added,
>    primarily to help server installations that want to ignore the
>    replace mechanism altogether.
> 
>  * Teach "git tag -s" etc. a few configuration variables (gpg.format
>    that can be set to "openpgp" or "x509", and gpg.<format>.program
>    that is used to specify what program to use to deal with the format)
>    to allow x.509 certs with CMS via "gpgsm" to be used instead of
>    openpgp via "gnupg".
> 
>  * Many more strings are prepared for l10n.
> 
>  * "git p4 submit" learns to ask its own pre-submit hook if it should
>    continue with submitting.
> 
>  * The test performed at the receiving end of "git push" to prevent
>    bad objects from entering repository can be customized via
>    receive.fsck.* configuration variables; we now have gained a
>    counterpart to do the same on the "git fetch" side, with
>    fetch.fsck.* configuration variables.
> 
>  * "git pull --rebase=interactive" learned "i" as a short-hand for
>    "interactive".
> 
>  * "git instaweb" has been adjusted to run better with newer Apache on
>    RedHat based distros.
> 
>  * "git range-diff" is a reimplementation of "git tbdiff" that lets us
>    compare individual patches in two iterations of a topic.
> 
>  * The sideband code learned to optionally paint selected keywords at
>    the beginning of incoming lines on the receiving end.
> 
>  * "git branch --list" learned to take the default sort order from the
>    'branch.sort' configuration variable, just like "git tag --list"
>    pays attention to 'tag.sort'.
> 
>  * "git worktree" command learned "--quiet" option to make it less
>    verbose.
> 
> 
> Performance, Internal Implementation, Development Support etc.
> 
>  * The bulk of "git submodule foreach" has been rewritten in C.
> 
>  * The in-core "commit" object had an all-purpose "void *util" field,
>    which was tricky to use especially in library-ish part of the
>    code.  All of the existing uses of the field has been migrated to a
>    more dedicated "commit-slab" mechanism and the field is eliminated.
> 
>  * A less often used command "git show-index" has been modernized.
>    (merge fb3010c31f jk/show-index later to maint).
> 
>  * The conversion to pass "the_repository" and then "a_repository"
>    throughout the object access API continues.
> 
>  * Continuing with the idea to programatically enumerate various
>    pieces of data required for command line completion, teach the
>    codebase to report the list of configuration variables
>    subcommands care about to help complete them.
> 
>  * Separate "rebase -p" codepath out of "rebase -i" implementation to
>    slim down the latter and make it easier to manage.
> 
>  * Make refspec parsing codepath more robust.
> 
>  * Some flaky tests have been fixed.
> 
>  * Continuing with the idea to programmatically enumerate various
>    pieces of data required for command line completion, the codebase
>    has been taught to enumerate options prefixed with "--no-" to
>    negate them.
> 
>  * Build and test procedure for netrc credential helper (in contrib/)
>    has been updated.
> 
>  * The conversion to pass "the_repository" and then "a_repository"
>    throughout the object access API continues.
> 
>  * Remove unused function definitions and declarations from ewah
>    bitmap subsystem.
> 
>  * Code preparation to make "git p4" closer to be usable with Python 3.
> 
>  * Tighten the API to make it harder to misuse in-tree .gitmodules
>    file, even though it shares the same syntax with configuration
>    files, to read random configuration items from it.
> 
>  * "git fast-import" has been updated to avoid attempting to create
>    delta against a zero-byte-long string, which is pointless.
> 
>  * The codebase has been updated to compile cleanly with -pedantic
>    option.
>    (merge 2b647a05d7 bb/pedantic later to maint).
> 
>  * The character display width table has been updated to match the
>    latest Unicode standard.
>    (merge 570951eea2 bb/unicode-11-width later to maint).
> 
>  * test-lint now looks for broken use of "VAR=VAL shell_func" in test
>    scripts.
> 
>  * Conversion from uchar[40] to struct object_id continues.
> 
>  * Recent "security fix" to pay attention to contents of ".gitmodules"
>    while accepting "git push" was a bit overly strict than necessary,
>    which has been adjusted.
> 
>  * "git fsck" learns to make sure the optional commit-graph file is in
>    a sane state.
> 
>  * "git diff --color-moved" feature has further been tweaked.
> 
>  * Code restructuring and a small fix to transport protocol v2 during
>    fetching.
> 
>  * Parsing of -L[<N>][,[<M>]] parameters "git blame" and "git log"
>    take has been tweaked.
> 
>  * lookup_commit_reference() and friends have been updated to find
>    in-core object for a specific in-core repository instance.
> 
>  * Various glitches in the heuristics of merge-recursive strategy have
>    been documented in new tests.
> 
>  * "git fetch" learned a new option "--negotiation-tip" to limit the
>    set of commits it tells the other end as "have", to reduce wasted
>    bandwidth and cycles, which would be helpful when the receiving
>    repository has a lot of refs that have little to do with the
>    history at the remote it is fetching from.
> 
>  * For a large tree, the index needs to hold many cache entries
>    allocated on heap.  These cache entries are now allocated out of a
>    dedicated memory pool to amortize malloc(3) overhead.
> 
>  * Tests to cover various conflicting cases have been added for
>    merge-recursive.
> 
>  * Tests to cover conflict cases that involve submodules have been
>    added for merge-recursive.
> 
>  * Look for broken "&&" chains that are hidden in subshell, many of
>    which have been found and corrected.
> 
>  * The singleton commit-graph in-core instance is made per in-core
>    repository instance.
> 
>  * "make DEVELOPER=1 DEVOPTS=pedantic" allows developers to compile
>    with -pedantic option, which may catch more problematic program
>    constructs and potential bugs.
> 
>  * Preparatory code to later add json output for telemetry data has
>    been added.
> 
>  * Update the way we use Coccinelle to find out-of-style code that
>    need to be modernised.
> 
>  * It is too easy to misuse system API functions such as strcat();
>    these selected functions are now forbidden in this codebase and
>    will cause a compilation failure.
> 
>  * Add a script (in contrib/) to help users of VSCode work better with
>    our codebase.
> 
>  * The Travis CI scripts were taught to ship back the test data from
>    failed tests.
>    (merge aea8879a6a sg/travis-retrieve-trash-upon-failure later to maint).
> 
>  * The parse-options machinery learned to refrain from enclosing
>    placeholder string inside a "<bra" and "ket>" pair automatically
>    without PARSE_OPT_LITERAL_ARGHELP.  Existing help text for option
>    arguments that are not formatted correctly have been identified and
>    fixed.
>    (merge 5f0df44cd7 rs/parse-opt-lithelp later to maint).
> 
>  * Noiseword "extern" has been removed from function decls in the
>    header files.
> 
>  * A few atoms like %(objecttype) and %(objectsize) in the format
>    specifier of "for-each-ref --format=<format>" can be filled without
>    getting the full contents of the object, but just with the object
>    header.  These cases have been optimized by calling
>    oid_object_info() API (instead of reading and inspecting the data).
> 
>  * The end result of documentation update has been made to be
>    inspected more easily to help developers.
> 
>  * The API to iterate over all objects learned to optionally list
>    objects in the order they appear in packfiles, which helps locality
>    of access if the caller accesses these objects while as objects are
>    enumerated.
> 
>  * Improve built-in facility to catch broken &&-chain in the tests.
> 
>  * The more library-ish parts of the codebase learned to work on the
>    in-core index-state instance that is passed in by their callers,
>    instead of always working on the singleton "the_index" instance.
> 
>  * A test prerequisite defined by various test scripts with slightly
>    different semantics has been consolidated into a single copy and
>    made into a lazily defined one.
>    (merge 6ec633059a wc/make-funnynames-shared-lazy-prereq later to maint).
> 
>  * After a partial clone, repeated fetches from promisor remote would
>    have accumulated many packfiles marked with .promisor bit without
>    getting them coalesced into fewer packfiles, hurting performance.
>    "git repack" now learned to repack them.
> 
>  * Partially revert the support for multiple hash functions to regain
>    hash comparison performance; we'd think of a way to do this better
>    in the next cycle.
> 
>  * "git help --config" (which is used in command line completion)
>    missed the configuration variables not described in the main
>    config.txt file but are described in another file that is included
>    by it, which has been corrected.
> 
> Fixes since v2.18
> -----------------
> 
>  * "git remote update" can take both a single remote nickname and a
>    nickname for remote groups, and the completion script (in contrib/)
>    has been taught about it.
>    (merge 9cd4382ad5 ls/complete-remote-update-names later to maint).
> 
>  * "git fetch --shallow-since=<cutoff>" that specifies the cut-off
>    point that is newer than the existing history used to end up
>    grabbing the entire history.  Such a request now errors out.
>    (merge e34de73c56 nd/reject-empty-shallow-request later to maint).
> 
>  * Fix for 2.17-era regression around `core.safecrlf`.
>    (merge 6cb09125be as/safecrlf-quiet-fix later to maint).
> 
>  * The recent addition of "partial clone" experimental feature kicked
>    in when it shouldn't, namely, when there is no partial-clone filter
>    defined even if extensions.partialclone is set.
>    (merge cac1137dc4 jh/partial-clone later to maint).
> 
>  * "git send-pack --signed" (hence "git push --signed" over the http
>    transport) did not read user ident from the config mechanism to
>    determine whom to sign the push certificate as, which has been
>    corrected.
>    (merge d067d98887 ms/send-pack-honor-config later to maint).
> 
>  * "git fetch-pack --all" used to unnecessarily fail upon seeing an
>    annotated tag that points at an object other than a commit.
>    (merge c12c9df527 jk/fetch-all-peeled-fix later to maint).
> 
>  * When user edits the patch in "git add -p" and the user's editor is
>    set to strip trailing whitespaces indiscriminately, an empty line
>    that is unchanged in the patch would become completely empty
>    (instead of a line with a sole SP on it).  The code introduced in
>    Git 2.17 timeframe failed to parse such a patch, but now it learned
>    to notice the situation and cope with it.
>    (merge f4d35a6b49 pw/add-p-recount later to maint).
> 
>  * The code to try seeing if a fetch is necessary in a submodule
>    during a fetch with --recurse-submodules got confused when the path
>    to the submodule was changed in the range of commits in the
>    superproject, sometimes showing "(null)".  This has been corrected.
> 
>  * "git submodule" did not correctly adjust core.worktree setting that
>    indicates whether/where a submodule repository has its associated
>    working tree across various state transitions, which has been
>    corrected.
> 
>  * Bugfix for "rebase -i" corner case regression.
>    (merge a9279c6785 pw/rebase-i-keep-reword-after-conflict later to maint).
> 
>  * Recently added "--base" option to "git format-patch" command did
>    not correctly generate prereq patch ids.
>    (merge 15b76c1fb3 xy/format-patch-prereq-patch-id-fix later to maint).
> 
>  * POSIX portability fix in Makefile to fix a glitch introduced a few
>    releases ago.
>    (merge 6600054e9b dj/runtime-prefix later to maint).
> 
>  * "git filter-branch" when used with the "--state-branch" option
>    still attempted to rewrite the commits whose filtered result is
>    known from the previous attempt (which is recorded on the state
>    branch); the command has been corrected not to waste cycles doing
>    so.
>    (merge 709cfe848a mb/filter-branch-optim later to maint).
> 
>  * Clarify that setting core.ignoreCase to deviate from reality would
>    not turn a case-incapable filesystem into a case-capable one.
>    (merge 48294b512a ms/core-icase-doc later to maint).
> 
>  * "fsck.skipList" did not prevent a blob object listed there from
>    being inspected for is contents (e.g. we recently started to
>    inspect the contents of ".gitmodules" for certain malicious
>    patterns), which has been corrected.
>    (merge fb16287719 rj/submodule-fsck-skip later to maint).
> 
>  * "git checkout --recurse-submodules another-branch" did not report
>    in which submodule it failed to update the working tree, which
>    resulted in an unhelpful error message.
>    (merge ba95d4e4bd sb/submodule-move-head-error-msg later to maint).
> 
>  * "git rebase" behaved slightly differently depending on which one of
>    the three backends gets used; this has been documented and an
>    effort to make them more uniform has begun.
>    (merge b00bf1c9a8 en/rebase-consistency later to maint).
> 
>  * The "--ignore-case" option of "git for-each-ref" (and its friends)
>    did not work correctly, which has been fixed.
>    (merge e674eb2528 jk/for-each-ref-icase later to maint).
> 
>  * "git fetch" failed to correctly validate the set of objects it
>    received when making a shallow history deeper, which has been
>    corrected.
>    (merge cf1e7c0770 jt/connectivity-check-after-unshallow later to maint).
> 
>  * Partial clone support of "git clone" has been updated to correctly
>    validate the objects it receives from the other side.  The server
>    side has been corrected to send objects that are directly
>    requested, even if they may match the filtering criteria (e.g. when
>    doing a "lazy blob" partial clone).
>    (merge a7e67c11b8 jt/partial-clone-fsck-connectivity later to maint).
> 
>  * Handling of an empty range by "git cherry-pick" was inconsistent
>    depending on how the range ended up to be empty, which has been
>    corrected.
>    (merge c5e358d073 jk/empty-pick-fix later to maint).
> 
>  * "git reset --merge" (hence "git merge ---abort") and "git reset --hard"
>    had trouble working correctly in a sparsely checked out working
>    tree after a conflict, which has been corrected.
>    (merge b33fdfc34c mk/merge-in-sparse-checkout later to maint).
> 
>  * Correct a broken use of "VAR=VAL shell_func" in a test.
>    (merge 650161a277 jc/t3404-one-shot-export-fix later to maint).
> 
>  * "git rev-parse ':/substring'" did not consider the history leading
>    only to HEAD when looking for a commit with the given substring,
>    when the HEAD is detached.  This has been fixed.
>    (merge 6b3351e799 wc/find-commit-with-pattern-on-detached-head later to maint).
> 
>  * Build doc update for Windows.
>    (merge ede8d89bb1 nd/command-list later to maint).
> 
>  * core.commentchar is now honored when preparing the list of commits
>    to replay in "rebase -i".
> 
>  * "git pull --rebase" on a corrupt HEAD caused a segfault.  In
>    general we substitute an empty tree object when running the in-core
>    equivalent of the diff-index command, and the codepath has been
>    corrected to do so as well to fix this issue.
>    (merge 3506dc9445 jk/has-uncommitted-changes-fix later to maint).
> 
>  * httpd tests saw occasional breakage due to the way its access log
>    gets inspected by the tests, which has been updated to make them
>    less flaky.
>    (merge e8b3b2e275 sg/httpd-test-unflake later to maint).
> 
>  * Tests to cover more D/F conflict cases have been added for
>    merge-recursive.
> 
>  * "git gc --auto" opens file descriptors for the packfiles before
>    spawning "git repack/prune", which would upset Windows that does
>    not want a process to work on a file that is open by another
>    process.  The issue has been worked around.
>    (merge 12e73a3ce4 kg/gc-auto-windows-workaround later to maint).
> 
>  * The recursive merge strategy did not properly ensure there was no
>    change between HEAD and the index before performing its operation,
>    which has been corrected.
>    (merge 55f39cf755 en/dirty-merge-fixes later to maint).
> 
>  * "git rebase" started exporting GIT_DIR environment variable and
>    exposing it to hook scripts when part of it got rewritten in C.
>    Instead of matching the old scripted Porcelains' behaviour,
>    compensate by also exporting GIT_WORK_TREE environment as well to
>    lessen the damage.  This can harm existing hooks that want to
>    operate on different repository, but the current behaviour is
>    already broken for them anyway.
>    (merge ab5e67d751 bc/sequencer-export-work-tree-as-well later to maint).
> 
>  * "git send-email" when using in a batched mode that limits the
>    number of messages sent in a single SMTP session lost the contents
>    of the variable used to choose between tls/ssl, unable to send the
>    second and later batches, which has been fixed.
>    (merge 636f3d7ac5 jm/send-email-tls-auth-on-batch later to maint).
> 
>  * The lazy clone support had a few places where missing but promised
>    objects were not correctly tolerated, which have been fixed.
> 
>  * One of the "diff --color-moved" mode "dimmed_zebra" that was named
>    in an unusual way has been deprecated and replaced by
>    "dimmed-zebra".
>    (merge e3f2f5f9cd es/diff-color-moved-fix later to maint).
> 
>  * The wire-protocol v2 relies on the client to send "ref prefixes" to
>    limit the bandwidth spent on the initial ref advertisement.  "git
>    clone" when learned to speak v2 forgot to do so, which has been
>    corrected.
>    (merge 402c47d939 bw/clone-ref-prefixes later to maint).
> 
>  * "git diff --histogram" had a bad memory usage pattern, which has
>    been rearranged to reduce the peak usage.
>    (merge 79cb2ebb92 sb/histogram-less-memory later to maint).
> 
>  * Code clean-up to use size_t/ssize_t when they are the right type.
>    (merge 7726d360b5 jk/size-t later to maint).
> 
>  * The wire-protocol v2 relies on the client to send "ref prefixes" to
>    limit the bandwidth spent on the initial ref advertisement.  "git
>    fetch $remote branch:branch" that asks tags that point into the
>    history leading to the "branch" automatically followed sent to
>    narrow prefix and broke the tag following, which has been fixed.
>    (merge 2b554353a5 jt/tag-following-with-proto-v2-fix later to maint).
> 
>  * When the sparse checkout feature is in use, "git cherry-pick" and
>    other mergy operations lost the skip_worktree bit when a path that
>    is excluded from checkout requires content level merge, which is
>    resolved as the same as the HEAD version, without materializing the
>    merge result in the working tree, which made the path appear as
>    deleted.  This has been corrected by preserving the skip_worktree
>    bit (and not materializing the file in the working tree).
>    (merge 2b75fb601c en/merge-recursive-skip-fix later to maint).
> 
>  * The "author-script" file "git rebase -i" creates got broken when
>    we started to move the command away from shell script, which is
>    getting fixed now.
>    (merge 5522bbac20 es/rebase-i-author-script-fix later to maint).
> 
>  * The automatic tree-matching in "git merge -s subtree" was broken 5
>    years ago and nobody has noticed since then, which is now fixed.
>    (merge 2ec4150713 jk/merge-subtree-heuristics later to maint).
> 
>  * "git fetch $there refs/heads/s" ought to fetch the tip of the
>    branch 's', but when "refs/heads/refs/heads/s", i.e. a branch whose
>    name is "refs/heads/s" exists at the same time, fetched that one
>    instead by mistake.  This has been corrected to honor the usual
>    disambiguation rules for abbreviated refnames.
>    (merge 60650a48c0 jt/refspec-dwim-precedence-fix later to maint).
> 
>  * Futureproofing a helper function that can easily be misused.
>    (merge 65bb21e77e es/want-color-fd-defensive later to maint).
> 
>  * The http-backend (used for smart-http transport) used to slurp the
>    whole input until EOF, without paying attention to CONTENT_LENGTH
>    that is supplied in the environment and instead expecting the Web
>    server to close the input stream.  This has been fixed.
>    (merge eebfe40962 mk/http-backend-content-length later to maint).
> 
>  * "git merge --abort" etc. did not clean things up properly when
>    there were conflicted entries in the index in certain order that
>    are involved in D/F conflicts.  This has been corrected.
>    (merge ad3762042a en/abort-df-conflict-fixes later to maint).
> 
>  * "git diff --indent-heuristic" had a bad corner case performance.
>    (merge 301ef85401 sb/indent-heuristic-optim later to maint).
> 
>  * The "--exec" option to "git rebase --rebase-merges" placed the exec
>    commands at wrong places, which has been corrected.
> 
>  * "git verify-tag" and "git verify-commit" have been taught to use
>    the exit status of underlying "gpg --verify" to signal bad or
>    untrusted signature they found.
>    (merge 4e5dc9ca17 jc/gpg-status later to maint).
> 
>  * "git mergetool" stopped and gave an extra prompt to continue after
>    the last path has been handled, which did not make much sense.
>    (merge d651a54b8a ng/mergetool-lose-final-prompt later to maint).
> 
>  * Among the three codepaths we use O_APPEND to open a file for
>    appending, one used for writing GIT_TRACE output requires O_APPEND
>    implementation that behaves sensibly when multiple processes are
>    writing to the same file.  POSIX emulation used in the Windows port
>    has been updated to improve in this area.
>    (merge d641097589 js/mingw-o-append later to maint).
> 
>  * "git pull --rebase -v" in a repository with a submodule barfed as
>    an intermediate process did not understand what "-v(erbose)" flag
>    meant, which has been fixed.
>    (merge e84c3cf3dc sb/pull-rebase-submodule later to maint).
> 
>  * Recent update to "git config" broke updating variable in a
>    subsection, which has been corrected.
>    (merge bff7df7a87 sb/config-write-fix later to maint).
> 
>  * When "git rebase -i" is told to squash two or more commits into
>    one, it labeled the log message for each commit with its number.
>    It correctly called the first one "1st commit", but the next one
>    was "commit #1", which was off-by-one.  This has been corrected.
>    (merge dd2e36ebac pw/rebase-i-squash-number-fix later to maint).
> 
>  * "git rebase -i", when a 'merge <branch>' insn in its todo list
>    fails, segfaulted, which has been (minimally) corrected.
>    (merge bc9238bb09 pw/rebase-i-merge-segv-fix later to maint).
> 
>  * "git cherry-pick --quit" failed to remove CHERRY_PICK_HEAD even
>    though we won't be in a cherry-pick session after it returns, which
>    has been corrected.
>    (merge 3e7dd99208 nd/cherry-pick-quit-fix later to maint).
> 
>  * In a recent update in 2.18 era, "git pack-objects" started
>    producing a larger than necessary packfiles by missing
>    opportunities to use large deltas.  This has been corrected.
> 
>  * The meaning of the possible values the "core.checkStat"
>    configuration variable can take were not adequately documented,
>    which has been fixed.
>    (merge 9bf5d4c4e2 nd/config-core-checkstat-doc later to maint).
> 
>  * Code cleanup, docfix, build fix, etc.
>    (merge aee9be2ebe sg/update-ref-stdin-cleanup later to maint).
>    (merge 037714252f jc/clean-after-sanity-tests later to maint).
>    (merge 5b26c3c941 en/merge-recursive-cleanup later to maint).
>    (merge 0dcbc0392e bw/config-refer-to-gitsubmodules-doc later to maint).
>    (merge bb4d000e87 bw/protocol-v2 later to maint).
>    (merge 928f0ab4ba vs/typofixes later to maint).
>    (merge d7f590be84 en/rebase-i-microfixes later to maint).
>    (merge 81d395cc85 js/rebase-recreate-merge later to maint).
>    (merge 51d1863168 tz/exclude-doc-smallfixes later to maint).
>    (merge a9aa3c0927 ds/commit-graph later to maint).
>    (merge 5cf8e06474 js/enhanced-version-info later to maint).
>    (merge 6aaded5509 tb/config-default later to maint).
>    (merge 022d2ac1f3 sb/blame-color later to maint).
>    (merge 5a06a20e0c bp/test-drop-caches-for-windows later to maint).
>    (merge dd61cc1c2e jk/ui-color-always-to-auto later to maint).
>    (merge 1e83b9bfdd sb/trailers-docfix later to maint).
>    (merge ab29f1b329 sg/fast-import-dump-refs-on-checkpoint-fix later to maint).
>    (merge 6a8ad880f0 jn/subtree-test-fixes later to maint).
>    (merge ffbd51cc60 nd/pack-objects-threading-doc later to maint).
>    (merge e9dac7be60 es/mw-to-git-chain-fix later to maint).
>    (merge fe583c6c7a rs/remote-mv-leakfix later to maint).
>    (merge 69885ab015 en/t3031-title-fix later to maint).
>    (merge 8578037bed nd/config-blame-sort later to maint).
>    (merge 8ad169c4ba hn/config-in-code-comment later to maint).
>    (merge b7446fcfdf ar/t4150-am-scissors-test-fix later to maint).
>    (merge a8132410ee js/typofixes later to maint).
>    (merge 388d0ff6e5 en/update-index-doc later to maint).
>    (merge e05aa688dd jc/update-index-doc later to maint).
>    (merge 10c600172c sg/t5310-empty-input-fix later to maint).
>    (merge 5641eb9465 jh/partial-clone-doc later to maint).
>    (merge 2711b1ad5e ab/submodule-relative-url-tests later to maint).
>    (merge ce528de023 ab/unconditional-free-and-null later to maint).
>    (merge bbc072f5d8 rs/opt-updates later to maint).
>    (merge 69d846f053 jk/use-compat-util-in-test-tool later to maint).
>    (merge 1820703045 js/larger-timestamps later to maint).
>    (merge c8b35b95e1 sg/t4051-fix later to maint).
>    (merge 30612cb670 sg/t0020-conversion-fix later to maint).
>    (merge 15da753709 sg/t7501-thinkofix later to maint).
>    (merge 79b04f9b60 sg/t3903-missing-fix later to maint).
>    (merge 2745817028 sg/t3420-autostash-fix later to maint).
>    (merge 7afb0d6777 sg/test-rebase-editor-fix later to maint).
> 
> -- 
> You received this message because you are subscribed to the Google Groups "git-packagers" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to git-packagers+unsubscribe@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/git-packagers/xmqqftyyfecy.fsf%40gitster-ct.c.googlers.com.
> For more options, visit https://groups.google.com/d/optout.
> 
^ permalink raw reply	[relevance 0%]

* Re: [PATCH 2/2] submodule.c: warn about missing submodule git directories
  2018-08-28 21:49     ` Stefan Beller
@ 2018-08-29 17:16       ` Junio C Hamano
  2018-08-29 20:32         ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-08-29 17:16 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> Not quite, as this is ...
>
> Looking at the test in the previous patch, I would think a reasonable workflow
> in the test is ...
> 
>> The MOVE_HEAD_FORCE codepath that follows this hunk is, eh, already
>> forcing to correct the situation, so there is no need to touch that,
>> which makes sense, if I understand correctly.
>
> No, that is not executed for now as it depends on 'old_head'.

All explanation worth having in the log message to help future
readers, don't you think?

Thanks.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29  5:25           ` Jeff King
@ 2018-08-29 18:10             ` Stefan Beller
  2018-08-29 21:03               ` Jeff King
  2018-08-29 21:09             ` Jonathan Nieder
  1 sibling, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-29 18:10 UTC (permalink / raw)
  To: Jeff King; +Cc: Brandon Williams, git

On Tue, Aug 28, 2018 at 10:25 PM Jeff King <peff@peff.net> wrote:
>
> On Tue, Aug 28, 2018 at 02:35:25PM -0700, Stefan Beller wrote:
>
> > 3) (optional) instead of putting it all in modules/, use another
> >    directory gitmodules/ for example. this will make sure we can tell
> >    if a repository has been converted or is stuck with a setup of a
> >    current git.
>
> I actually kind of like that idea, as it makes the interaction between
> old and new names much simpler to reason about.
>
> And since old code won't know about the new names anyway, there's in
> theory no downside. In practice, of course, the encoding may often be a
> noop, and lazy scripts would continue to work most of the time if you
> didn't change out the prefix directory. I'm not sure if that is an
> argument for the scheme (because it will suss out broken scripts more
> consistently) or against it (because 99% of the time those old scripts
> would just happen to work).
>
> > > This is exactly the reason why I wanted to get some opinions on what the
> > > best thing to do here would be.  I _think_ the best thing would probably
> > > be to write a specific routine to do the conversion, and it wouldn't
> > > even have to be all that complex.  Basically I'm just interested in
> > > converting '/' characters so that things no longer behave like
> > > nested directories.
> >
> > Yeah, then let's just convert '/' with as little overhead as possible.
>
> Do you care about case-folding issues (e.g., submodules "FOO" and "foo"
> colliding)?

I do. :(

2d84f13dcb6 (config: fix case sensitive subsection names on writing, 2018-08-08)
explains the latest episode of case folding with submodules involved.

> I'm OK if the answer is "no", but if you do want to deal with it, the
> time is probably now.

Good point. But as soon as we start discussing case sensitivity, we
are drawn down the rabbit hole of funny file names. (Try naming
a submodule "CON1" and obtain it on Windows for example)
So we would need to have a file system specific encoding function for
submodule names, which sounds like a maintenance night mare.

The CON1 example shows that URL encoding may not be enough
on Windows and we'd have to extend the encoding if we care about
FS issues.

Another example would be "a" and "a\b" which would be a mess
in Windows as the '\' would work as a dir separator whereas these
two names were ok on linux. This would be fixed with url encoding.

URL encoding would not fix the case-folding issue that you
mentioned above.

So if I was thinking in the scheme presented above, we could just
have another rule that is

  [A-Z]  -> _[a-z]

(lowercase capital letters and escape them with an underscore)

But with that rule added, we are inventing a really complicated
encoding scheme already.

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 2/2] submodule.c: warn about missing submodule git directories
  2018-08-29 17:16       ` Junio C Hamano
@ 2018-08-29 20:32         ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-29 20:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Wed, Aug 29, 2018 at 10:17 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > Not quite, as this is ...
> >
> > Looking at the test in the previous patch, I would think a reasonable workflow
> > in the test is ...
> >
> >> The MOVE_HEAD_FORCE codepath that follows this hunk is, eh, already
> >> forcing to correct the situation, so there is no need to touch that,
> >> which makes sense, if I understand correctly.
> >
> > No, that is not executed for now as it depends on 'old_head'.
>
> All explanation worth having in the log message to help future
> readers, don't you think?

ok, will do.

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29 18:10             ` Stefan Beller
@ 2018-08-29 21:03               ` Jeff King
  2018-08-29 21:10                 ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Jeff King @ 2018-08-29 21:03 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Brandon Williams, git

On Wed, Aug 29, 2018 at 11:10:51AM -0700, Stefan Beller wrote:

> > Do you care about case-folding issues (e.g., submodules "FOO" and "foo"
> > colliding)?
> 
> I do. :(
> 
> 2d84f13dcb6 (config: fix case sensitive subsection names on writing, 2018-08-08)
> explains the latest episode of case folding with submodules involved.
> 
> > I'm OK if the answer is "no", but if you do want to deal with it, the
> > time is probably now.
> 
> Good point. But as soon as we start discussing case sensitivity, we
> are drawn down the rabbit hole of funny file names. (Try naming
> a submodule "CON1" and obtain it on Windows for example)
> So we would need to have a file system specific encoding function for
> submodule names, which sounds like a maintenance night mare.

Hmph. I'd hoped that simply escaping metacharacters and doing some
obvious case-folding would be enough. And I think that would cover most
accidental cases. But yeah, Windows reserved names are basically
indistinguishable from reasonable names. They'd probably need
special-cased.

OTOH, I'm not sure how we handle those for entries in the actual tree.
Poking around git-for-windows/git, I think it uses the magic "\\?"
marker to tell the OS to interpret the name literally.

So I wonder if it might be sufficient to just deal with the more obvious
folding issues. Or as you noted, if we just choose lowercase names as
the normalized form, that might also be enough. :)

> So if I was thinking in the scheme presented above, we could just
> have another rule that is
> 
>   [A-Z]  -> _[a-z]
> 
> (lowercase capital letters and escape them with an underscore)

Yes, that makes even the capitalized "CON" issues go away. It's not a
one-to-one mapping, though ("foo-" and "foo_" map to the same entity).

If we want that, too, I think something like url-encoding is fine, with
the caveat that we simply urlencode _more_ things (i.e., anything not in
[a-z_]).

-Peff

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 1/2] t2013: add test for missing but active submodule
  2018-08-27 22:12 [PATCH 1/2] t2013: add test for missing but active submodule Stefan Beller
  2018-08-27 22:12 ` [PATCH 2/2] submodule.c: warn about missing submodule git directories Stefan Beller
@ 2018-08-29 21:04 ` SZEDER Gábor
  1 sibling, 0 replies; 200+ results
From: SZEDER Gábor @ 2018-08-29 21:04 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

On Mon, Aug 27, 2018 at 03:12:56PM -0700, Stefan Beller wrote:
> When cloning a superproject with the option
>  --recurse-submodules='.', it is easy to find yourself wanting
> a submodule active, but not having that submodule present in
> the modules directory.
> 
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  t/t2013-checkout-submodule.sh | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
> index 6ef15738e44..c69640fc341 100755
> --- a/t/t2013-checkout-submodule.sh
> +++ b/t/t2013-checkout-submodule.sh
> @@ -63,6 +63,30 @@ test_expect_success '"checkout <submodule>" honors submodule.*.ignore from .git/
>  	! test -s actual
>  '
>  
> +test_expect_success 'setup superproject with historic submodule' '
> +	test_create_repo super1 &&
> +	test_create_repo sub1 &&
> +	test_commit -C sub1 sub_content &&
> +	git -C super1 submodule add ../sub1 &&
> +	git -C super1 commit -a -m "sub1 added" &&
> +	test_commit -C super1 historic_state &&
> +	git -C super1 rm sub1 &&
> +	git -C super1 commit -a -m "deleted sub" &&
> +	test_commit -C super1 new_state &&

These six consecutive commands above all specify the '-C super1'
options ...

> +	test_path_is_missing super1/sub &&
> +
> +	# The important part is to ensure sub1 is not in there any more.
> +	# There is another series in flight, that may remove an
> +	# empty .gitmodules file entirely.
> +	test_must_be_empty super1/.gitmodules

... and both of these two checks use the 'super1/' path prefix.  I
think it would be more readable to simply 'cd super1' first.

> +'
> +
> +test_expect_failure 'checkout old state with deleted submodule' '
> +	test_when_finished "rm -rf super1 sub1 super1_clone" &&
> +	git clone --recurse-submodules super1 super1_clone &&
> +	git -C super1_clone checkout --recurse-submodules historic_state
> +'
> +
>  KNOWN_FAILURE_DIRECTORY_SUBMODULE_CONFLICTS=1
>  test_submodule_switch_recursing_with_args "checkout"
>  
> -- 
> 2.18.0
> 

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29  5:25           ` Jeff King
  2018-08-29 18:10             ` Stefan Beller
@ 2018-08-29 21:09             ` Jonathan Nieder
  2018-08-29 21:14               ` Stefan Beller
  2018-08-29 21:32               ` Jeff King
  1 sibling, 2 replies; 200+ results
From: Jonathan Nieder @ 2018-08-29 21:09 UTC (permalink / raw)
  To: Jeff King; +Cc: Stefan Beller, Brandon Williams, git

Jeff King wrote:
> On Tue, Aug 28, 2018 at 02:35:25PM -0700, Stefan Beller wrote:

>> Yeah, then let's just convert '/' with as little overhead as possible.
>
> Do you care about case-folding issues (e.g., submodules "FOO" and "foo"
> colliding)?
>
> I'm OK if the answer is "no", but if you do want to deal with it, the
> time is probably now.

Have we rejected the config approach?  I really liked the attribute of
not having to solve everything right away.  I'm getting scared that
we've forgotten that goal.

It mixes well with Stefan's idea of setting up a new .git/submodules/
directory.  We could require that everything in .git/submodules/ have
configuration (or that everything in that directory either have
configuration or be the result of a "very simple" transformation) and
that way, all ambiguity goes away.

Part of the definition of "very simple" could be that the submodule
name must consist of some whitelisted list of characters (including no
uppercase), for example.

Thanks,
Jonathan

^ permalink raw reply	[relevance 6%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29 21:03               ` Jeff King
@ 2018-08-29 21:10                 ` Stefan Beller
  2018-08-29 21:18                   ` Jonathan Nieder
  2018-08-29 21:30                   ` Jeff King
  0 siblings, 2 replies; 200+ results
From: Stefan Beller @ 2018-08-29 21:10 UTC (permalink / raw)
  To: Jeff King; +Cc: Brandon Williams, git

> Yes, that makes even the capitalized "CON" issues go away. It's not a
> one-to-one mapping, though ("foo-" and "foo_" map to the same entity).

foo_ would map to foo__, and foo- would map to something else.
(foo- as we do not rewrite dashes, yet?)

>
> If we want that, too, I think something like url-encoding is fine, with
> the caveat that we simply urlencode _more_ things (i.e., anything not in
> [a-z_]).

Yeah I think we need more than url encoding now.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29 21:09             ` Jonathan Nieder
@ 2018-08-29 21:14               ` Stefan Beller
  2018-08-29 21:25                 ` Brandon Williams
  2018-08-29 21:32               ` Jeff King
  1 sibling, 1 reply; 200+ results
From: Stefan Beller @ 2018-08-29 21:14 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Jeff King, Brandon Williams, git

On Wed, Aug 29, 2018 at 2:09 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> Jeff King wrote:
> > On Tue, Aug 28, 2018 at 02:35:25PM -0700, Stefan Beller wrote:
>
> >> Yeah, then let's just convert '/' with as little overhead as possible.
> >
> > Do you care about case-folding issues (e.g., submodules "FOO" and "foo"
> > colliding)?
> >
> > I'm OK if the answer is "no", but if you do want to deal with it, the
> > time is probably now.
>
> Have we rejected the config approach?

I did not reject that approach, but am rather waiting for patches. ;-)

> I really liked the attribute of
> not having to solve everything right away.  I'm getting scared that
> we've forgotten that goal.

Eh, sorry for side tracking this issue.

I am just under the impression that the URL encoding is not particularly
good for our use case as it solves just one out of many things, whereas
the one thing (having no slashes) can also be solved in an easier way.

> It mixes well with Stefan's idea of setting up a new .git/submodules/
> directory.  We could require that everything in .git/submodules/ have
> configuration (or that everything in that directory either have
> configuration or be the result of a "very simple" transformation) and
> that way, all ambiguity goes away.

I would not want to have a world where we require that config, but I
would agree to the latter, hence we would need to discuss "very simple".
I guess that are 2 or 3 rules at most.

> Part of the definition of "very simple" could be that the submodule
> name must consist of some whitelisted list of characters (including no
> uppercase), for example.

Good catch!

Thanks for chiming in,
Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29 21:10                 ` Stefan Beller
@ 2018-08-29 21:18                   ` Jonathan Nieder
  2018-08-29 21:27                     ` Stefan Beller
  2018-08-29 21:30                   ` Jeff King
  1 sibling, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-08-29 21:18 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Jeff King, Brandon Williams, git

Hi,

Stefan Beller wrote:

>> Yes, that makes even the capitalized "CON" issues go away. It's not a
>> one-to-one mapping, though ("foo-" and "foo_" map to the same entity).
>
> foo_ would map to foo__, and foo- would map to something else.
> (foo- as we do not rewrite dashes, yet?)
>
>> If we want that, too, I think something like url-encoding is fine, with
>> the caveat that we simply urlencode _more_ things (i.e., anything not in
>> [a-z_]).
>
> Yeah I think we need more than url encoding now.

Can you say more?  Perhaps my expectations have been poisoned by tools
like dpkg-buildpackage that use urlencode.  As far as I can tell, it
works fine.

Moreover, urlencode has some attributes that make it a good potential
fit: it's intuitive, it's unambiguous (yes, it's one-to-many, but at
least it's not many-to-many), and people know how to deal with it from
their lives using browsers.  Can you spell out for me what problem
we're solving with something more custom?

Stepping back, I am very worried about any design that doesn't give us
the ability to tweak things later.  See [1] and [2] for more on that
subject.

Thanks,
Jonathan

[1] https://public-inbox.org/git/20180816023446.GA127655@aiede.svl.corp.google.com/
[2] https://public-inbox.org/git/20180829210913.GF7547@aiede.svl.corp.google.com/

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29 21:14               ` Stefan Beller
@ 2018-08-29 21:25                 ` Brandon Williams
  0 siblings, 0 replies; 200+ results
From: Brandon Williams @ 2018-08-29 21:25 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Jonathan Nieder, Jeff King, git

On 08/29, Stefan Beller wrote:
> On Wed, Aug 29, 2018 at 2:09 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
> >
> > Jeff King wrote:
> > > On Tue, Aug 28, 2018 at 02:35:25PM -0700, Stefan Beller wrote:
> >
> > >> Yeah, then let's just convert '/' with as little overhead as possible.
> > >
> > > Do you care about case-folding issues (e.g., submodules "FOO" and "foo"
> > > colliding)?
> > >
> > > I'm OK if the answer is "no", but if you do want to deal with it, the
> > > time is probably now.
> >
> > Have we rejected the config approach?
> 
> I did not reject that approach, but am rather waiting for patches. ;-)

Note I did send out a patch using this approach, so no need to wait any
longer! :D

https://public-inbox.org/git/20180816181940.46114-1-bmwill@google.com/

-- 
Brandon Williams

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29 21:18                   ` Jonathan Nieder
@ 2018-08-29 21:27                     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-08-29 21:27 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Jeff King, Brandon Williams, git

On Wed, Aug 29, 2018 at 2:18 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> Hi,
>
> Stefan Beller wrote:
>
> >> Yes, that makes even the capitalized "CON" issues go away. It's not a
> >> one-to-one mapping, though ("foo-" and "foo_" map to the same entity).
> >
> > foo_ would map to foo__, and foo- would map to something else.
> > (foo- as we do not rewrite dashes, yet?)
> >
> >> If we want that, too, I think something like url-encoding is fine, with
> >> the caveat that we simply urlencode _more_ things (i.e., anything not in
> >> [a-z_]).
> >
> > Yeah I think we need more than url encoding now.
>
> Can you say more?

https://public-inbox.org/git/CAGZ79kZv4BjRq=kq_1UeT2Kn38OZwYFgnMsTe6X_WP41=hBtSQ@mail.gmail.com/

> Can you spell out for me what problem we're solving with something more custom?

case sensitivity for example.

> the ability to tweak things later.

That is unrelated to the choice of encoding, but more related to
https://public-inbox.org/git/20180816181940.46114-1-bmwill@google.com/

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29 21:10                 ` Stefan Beller
  2018-08-29 21:18                   ` Jonathan Nieder
@ 2018-08-29 21:30                   ` Jeff King
  1 sibling, 0 replies; 200+ results
From: Jeff King @ 2018-08-29 21:30 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Brandon Williams, git

On Wed, Aug 29, 2018 at 02:10:37PM -0700, Stefan Beller wrote:

> > Yes, that makes even the capitalized "CON" issues go away. It's not a
> > one-to-one mapping, though ("foo-" and "foo_" map to the same entity).
> 
> foo_ would map to foo__, and foo- would map to something else.
> (foo- as we do not rewrite dashes, yet?)

Ah, OK, I took your:

>   [A-Z]  -> _[a-z]

to mean "A-Z becomes a-z, and everything else becomes underscore".

If you mean a real one-to-one mapping that allows a-z and only a few
safe metacharacters, then yeah, that's what I was thinking, too.

> > If we want that, too, I think something like url-encoding is fine, with
> > the caveat that we simply urlencode _more_ things (i.e., anything not in
> > [a-z_]).
> 
> Yeah I think we need more than url encoding now.

If you take "url encoding" to only be the mechanical transformation of
quoting, not the set of _what_ gets quoting, we can still stick with it.
We don't need to, but it's probably no worse than inventing our own
set of quoting rules.

-Peff

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule: munge paths to submodule git directories
  2018-08-29 21:09             ` Jonathan Nieder
  2018-08-29 21:14               ` Stefan Beller
@ 2018-08-29 21:32               ` Jeff King
  1 sibling, 0 replies; 200+ results
From: Jeff King @ 2018-08-29 21:32 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Stefan Beller, Brandon Williams, git

On Wed, Aug 29, 2018 at 02:09:13PM -0700, Jonathan Nieder wrote:

> Jeff King wrote:
> > On Tue, Aug 28, 2018 at 02:35:25PM -0700, Stefan Beller wrote:
> 
> >> Yeah, then let's just convert '/' with as little overhead as possible.
> >
> > Do you care about case-folding issues (e.g., submodules "FOO" and "foo"
> > colliding)?
> >
> > I'm OK if the answer is "no", but if you do want to deal with it, the
> > time is probably now.
> 
> Have we rejected the config approach?  I really liked the attribute of
> not having to solve everything right away.  I'm getting scared that
> we've forgotten that goal.

I personally have no problem with that approach, but I also haven't
thought that hard about it (I was mostly ignoring the discussion since
it seemed like submodule-interested folks, but I happened to see what
looked like a potentially bad idea cc'd to me ;) ).

-Peff

^ permalink raw reply	[relevance 5%]

* Re: [GSoC][PATCH v8 14/20] stash: convert create to builtin
      [irrelevant] ` <a4faed3c8aa5ea8f0d4c578b693f3b5de3e3a709.1535665109.git.ungureanupaulsebastian@gmail.com>
@ 2018-09-03 16:00   ` Johannes Schindelin
  0 siblings, 0 replies; 200+ results
From: Johannes Schindelin @ 2018-09-03 16:00 UTC (permalink / raw)
  To: Paul-Sebastian Ungureanu; +Cc: git

Hi Paul,

On Fri, 31 Aug 2018, Paul-Sebastian Ungureanu wrote:

> diff --git a/builtin/stash--helper.c b/builtin/stash--helper.c
> index 87568b0f34..ce360a569d 100644
> --- a/builtin/stash--helper.c
> +++ b/builtin/stash--helper.c
> @@ -290,6 +296,18 @@ static int reset_head(void)
>  	return run_command(&cp);
>  }
>  
> +static void add_diff_to_buf(struct diff_queue_struct *q,
> +			    struct diff_options *options,
> +			    void *data)
> +{
> +	int i;
> +	for (i = 0; i < q->nr; i++) {
> +		struct diff_filepair *p = q->queue[i];
> +		strbuf_addstr(data, p->one->path);

Maybe `q->queue[i]->one->path` would be okay, too? Dunno.

> +		strbuf_addch(data, 0);

Neat trick. However, I had to study the code to see that the output of
this function will be fed to `update-index -z` to see why the NUL is
appended here. Maybe add a code comment here?

> +	}
> +}
> +
>  static int get_newly_staged(struct strbuf *out, struct object_id *c_tree)
>  {
>  	struct child_process cp = CHILD_PROCESS_INIT;
> @@ -776,6 +794,416 @@ static int store_stash(int argc, const char **argv, const char *prefix)
>  	return do_store_stash(argv[0], stash_msg, quiet);
>  }
>  
> +/*
> + * `out` will be filled with the names of untracked files. The return value is:
> + *
> + * = 0 if there are not any untracked files
> + * > 0 if there are untracked files
> + */
> +static int get_untracked_files(struct pathspec ps, int include_untracked,
> +			       struct strbuf *out)
> +{
> +	int max_len;
> +	int i;
> +	char *seen;
> +	struct dir_struct dir;
> +
> +	memset(&dir, 0, sizeof(dir));
> +	if (include_untracked != 2)

If you follow my suggestion to replace this magic `2` by a symbol that
describes the meaning "include all", then this line would need to be
changed, too.

> +		setup_standard_excludes(&dir);
> +
> +	seen = xcalloc(ps.nr, 1);
> +
> +	max_len = fill_directory(&dir, the_repository->index, &ps);
> +	for (i = 0; i < dir.nr; i++) {
> +		struct dir_entry *ent = dir.entries[i];
> +		if (!dir_path_match(&the_index, ent, &ps, max_len, seen)) {
> +			free(ent);
> +			continue;
> +		}
> +		strbuf_addf(out, "%s%c", ent->name, '\0');
> +		free(ent);

This is a *very* minor nit pick... I would have written it this way
instead:

		if (dir_path_match(&the_index, ent, &ps, max_len, seen)) {
			strbuf_addstr(out, ent->name);
			/* NUL-terminate: will be fed to update-index -z */
			strbuf_addch(out, 0);
		}
		free(ent);

Just an idea...

> +	}
> +
> +	free(dir.entries);
> +	free(dir.ignored);
> +	clear_directory(&dir);
> +	free(seen);
> +	return out->len;
> +}

If you introduce a local variable `found` and increase it whenever a match
was found, then you could also handle `out == NULL` by skipping the
`strbuf_*()` calls, which would come in handin in the `check_changes()`
function that does not actually want to use the output.

> +
> +/*
> + * The return value of `check_changes()` can be:
> + *
> + * < 0 if there was an error
> + * = 0 if there are no changes.
> + * > 0 if there are changes.
> + */
> +static int check_changes(struct pathspec ps, int include_untracked)
> +{
> +	int result;
> +	int ret = 0;
> +	struct rev_info rev;
> +	struct object_id dummy;
> +	struct strbuf out = STRBUF_INIT;
> +
> +	init_revisions(&rev, NULL);
> +	rev.prune_data = ps;
> +
> +	rev.diffopt.flags.quick = 1;
> +	rev.diffopt.flags.ignore_submodules = 1;
> +	rev.abbrev = 0;
> +
> +	/* No initial commit. */
> +	if (get_oid("HEAD", &dummy))
> +		return -1;
> +
> +	add_head_to_pending(&rev);
> +	diff_setup_done(&rev.diffopt);
> +
> +	if (read_cache() < 0)
> +		return 1;
> +	result = run_diff_index(&rev, 1);
> +	if (diff_result_code(&rev.diffopt, result))
> +		return 1;
> +
> +	object_array_clear(&rev.pending);
> +	result = run_diff_files(&rev, 0);
> +	if (diff_result_code(&rev.diffopt, result))
> +		return 1;

These lines look familiar... Maybe call has_unstaged_changes() and
has_uncommitted_changes() here? (I have to admit that I have no idea what
those functions do with unborn branches.)

> +
> +	if (include_untracked && get_untracked_files(ps, include_untracked,
> +						     &out)) {
> +		strbuf_release(&out);
> +		return 1;
> +	}
> +
> +	strbuf_release(&out);
> +	return 0;
> +}
> +
> +static int save_untracked_files(struct stash_info *info, struct strbuf *msg,
> +				struct strbuf *in)
> +{
> +	int ret = 0;
> +	struct strbuf untracked_msg = STRBUF_INIT;
> +	struct strbuf out = STRBUF_INIT;
> +	struct child_process cp_upd_index = CHILD_PROCESS_INIT;
> +	struct child_process cp_write_tree = CHILD_PROCESS_INIT;
> +
> +	cp_upd_index.git_cmd = 1;
> +	argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
> +			 "--remove", "--stdin", NULL);
> +	argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s",
> +			 stash_index_path.buf);
> +
> +	strbuf_addf(&untracked_msg, "untracked files on %s\n", msg->buf);
> +	if (pipe_command(&cp_upd_index, in->buf, in->len, NULL, 0, NULL, 0)) {
> +		ret = -1;
> +		goto done;
> +	}
> +
> +	cp_write_tree.git_cmd = 1;
> +	argv_array_push(&cp_write_tree.args, "write-tree");
> +	argv_array_pushf(&cp_write_tree.env_array, "GIT_INDEX_FILE=%s",
> +			 stash_index_path.buf);
> +	if (pipe_command(&cp_write_tree, NULL, 0, &out, 0,NULL, 0)) {
> +		ret = -1;
> +		goto done;
> +	}
> +	get_oid_hex(out.buf, &info->u_tree);
> +
> +	if (commit_tree(untracked_msg.buf, untracked_msg.len,
> +			&info->u_tree, NULL, &info->u_commit, NULL, NULL)) {
> +		ret = -1;
> +		goto done;
> +	}
> +
> +done:
> +	strbuf_release(&untracked_msg);
> +	strbuf_release(&out);
> +	remove_path(stash_index_path.buf);
> +	return ret;
> +}
> +
> +static struct strbuf patch = STRBUF_INIT;

As far as I can see, this variable should be local to `stash_patch` (and
released at the end).

[Coming back after reading the shell script code and realizing that it
wrote the $TMP-patch file that is then used in `push_stash`]

Ah! So the output of `stash_patch()` is not just a return value indicating
success, but it also wants to return the patch. How about passing this in
via a parameter after `struct pathspec ps`, say, `struct strbuf
*out_patch`?

> +
> +static int stash_patch(struct stash_info *info, struct pathspec ps)
> +{
> +	int i;
> +	int ret = 0;
> +	struct strbuf out = STRBUF_INIT;
> +	struct child_process cp_read_tree = CHILD_PROCESS_INIT;
> +	struct child_process cp_add_i = CHILD_PROCESS_INIT;
> +	struct child_process cp_write_tree = CHILD_PROCESS_INIT;
> +	struct child_process cp_diff_tree = CHILD_PROCESS_INIT;
> +
> +	remove_path(stash_index_path.buf);
> +
> +	cp_read_tree.git_cmd = 1;
> +	argv_array_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL);
> +	argv_array_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s",
> +			 stash_index_path.buf);
> +	if (run_command(&cp_read_tree)) {
> +		ret = -1;
> +		goto done;
> +	}
> +

Maybe insert the comment "find out what the user wants" here?

> +	cp_add_i.git_cmd = 1;
> +	argv_array_pushl(&cp_add_i.args, "add--interactive", "--patch=stash",
> +			"--", NULL);
> +	for (i = 0; i < ps.nr; ++i)
> +		argv_array_push(&cp_add_i.args, ps.items[i].match);

I guess you could use `add_ps_items_to_argv_array(&cp_add_i.args, &ps)` here.

> +	argv_array_pushf(&cp_add_i.env_array, "GIT_INDEX_FILE=%s",
> +			 stash_index_path.buf);
> +	if (run_command(&cp_add_i)) {
> +		ret = -1;
> +		goto done;
> +	}
> +

Maybe insert the comment "state of the working tree" here?

> +	cp_write_tree.git_cmd = 1;
> +	argv_array_push(&cp_write_tree.args, "write-tree");
> +	argv_array_pushf(&cp_write_tree.env_array, "GIT_INDEX_FILE=%s",
> +			 stash_index_path.buf);
> +	if (pipe_command(&cp_write_tree, NULL, 0, &out, 0,NULL, 0)) {
> +		ret = -1;
> +		goto done;
> +	}
> +
> +	get_oid_hex(out.buf, &info->w_tree);
> +
> +	cp_diff_tree.git_cmd = 1;
> +	argv_array_pushl(&cp_diff_tree.args, "diff-tree", "-p", "HEAD",
> +			 oid_to_hex(&info->w_tree), "--", NULL);
> +	if (pipe_command(&cp_diff_tree, NULL, 0, &patch, 0, NULL, 0)) {
> +		ret = -1;
> +		goto done;
> +	}
> +
> +	if (!patch.len) {
> +		fprintf_ln(stderr, _("No changes selected"));
> +		ret = 1;
> +	}
> +
> +done:
> +	strbuf_release(&out);
> +	remove_path(stash_index_path.buf);
> +	return ret;
> +}
> +
> +static int stash_working_tree(struct stash_info *info, struct pathspec ps)
> +{
> +	int ret = 0;
> +	struct child_process cp_upd_index = CHILD_PROCESS_INIT;
> +	struct child_process cp_write_tree = CHILD_PROCESS_INIT;
> +	struct strbuf out = STRBUF_INIT;
> +	struct strbuf diff_output = STRBUF_INIT;
> +	struct rev_info rev;
> +
> +	set_alternate_index_output(stash_index_path.buf);
> +	if (reset_tree(&info->i_tree, 0, 0)) {

So this is the `git read-tree --index-output="$TMPindex" -m $i_tree` call.

At first, I thought that one of the zeros meant that the `merge` flag
would be turned off, but that is always turned on. Okay. (I guess
positional parameters make this a bit less readable, not your fault, but
C's.)

> +		ret = -1;
> +		goto done;
> +	}
> +	set_alternate_index_output(NULL);

Side note (i.e. rant): I wish this was more thread-safe. Granted, right
now it does not make sense to reset_tree() in parallel. But Stefan Beller
is working on being able to reset_tree() submodules, in which case
running reset_tree() in parallel will make a ton of sense.

> +
> +	git_config(git_diff_basic_config, NULL);

Is this not called in as part of `git_config(git_default_config, NULL);`
in cmd_stash() already?

*clicketyclick*

I guess not. But then, maybe it would make sense to run with
`git_diff_basic_config` from the get go, to avoid having to run
`git_config()` twice.

> +	init_revisions(&rev, NULL);
> +	rev.prune_data = ps;
> +	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
> +	rev.diffopt.format_callback = add_diff_to_buf;
> +	rev.diffopt.format_callback_data = &diff_output;
> +
> +	if (read_cache_preload(&rev.diffopt.pathspec) < 0) {
> +		ret = -1;
> +		goto done;
> +	}
> +
> +	add_pending_object(&rev, parse_object(the_repository, &info->b_commit), "");
> +	if (run_diff_index(&rev, 0)) {
> +		ret = -1;
> +		goto done;
> +	}
> +
> +	cp_upd_index.git_cmd = 1;
> +	argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
> +			 "--remove", "--stdin", NULL);
> +	argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s",
> +			 stash_index_path.buf);
> +
> +	if (pipe_command(&cp_upd_index, diff_output.buf, diff_output.len,
> +			 NULL, 0, NULL, 0)) {
> +		ret = -1;
> +		goto done;
> +	}
> +
> +	cp_write_tree.git_cmd = 1;
> +	argv_array_push(&cp_write_tree.args, "write-tree");
> +	argv_array_pushf(&cp_write_tree.env_array, "GIT_INDEX_FILE=%s",
> +			 stash_index_path.buf);
> +	if (pipe_command(&cp_write_tree, NULL, 0, &out, 0,NULL, 0)) {
> +		ret = -1;
> +		goto done;
> +	}
> +
> +	get_oid_hex(out.buf, &info->w_tree);
> +
> +done:
> +	UNLEAK(rev);
> +	strbuf_release(&out);
> +	object_array_clear(&rev.pending);
> +	strbuf_release(&diff_output);
> +	remove_path(stash_index_path.buf);
> +	return ret;
> +}
> +
> +static int do_create_stash(struct pathspec ps, const char **stash_msg,

As the `stash_msg` will receive an allocated buffer that will need to be
released by the caller, this should be a `char **stash_msg` (no `const`).

> +			   int include_untracked, int patch_mode,
> +			   struct stash_info *info)
> +{
> +	int untracked_commit_option = 0;
> +	int ret = 0;
> +	int flags;
> +	const char *head_short_sha1 = NULL;
> +	const char *branch_ref = NULL;
> +	const char *branch_name = "(no branch)";
> +	struct commit *head_commit = NULL;
> +	struct commit_list *parents = NULL;
> +	struct strbuf msg = STRBUF_INIT;
> +	struct strbuf commit_tree_label = STRBUF_INIT;
> +	struct strbuf out = STRBUF_INIT;
> +	struct strbuf stash_msg_buf = STRBUF_INIT;
> +
> +	read_cache_preload(NULL);
> +	refresh_cache(REFRESH_QUIET);
> +
> +	if (!check_changes(ps, include_untracked)) {
> +		ret = 1;
> +		*stash_msg = NULL;
> +		goto done;
> +	}
> +
> +	if (get_oid("HEAD", &info->b_commit)) {
> +		fprintf_ln(stderr, _("You do not have the initial commit yet"));
> +		ret = -1;
> +		*stash_msg = NULL;

Oh, so we actually do not even have to handle an unborn branch if we move
the `check_changes()` call after this block?

> +		goto done;
> +	} else {
> +		head_commit = lookup_commit(the_repository, &info->b_commit);
> +	}
> +
> +	branch_ref = resolve_ref_unsafe("HEAD", 0, NULL, &flags);
> +	if (flags & REF_ISSYMREF)
> +		branch_name = strrchr(branch_ref, '/') + 1;
> +	head_short_sha1 = find_unique_abbrev(&head_commit->object.oid,
> +					     DEFAULT_ABBREV);
> +	strbuf_addf(&msg, "%s: %s ", branch_name, head_short_sha1);
> +	pp_commit_easy(CMIT_FMT_ONELINE, head_commit, &msg);
> +
> +	strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf);
> +	commit_list_insert(head_commit, &parents);
> +	if (write_cache_as_tree(&info->i_tree, 0, NULL) ||
> +	    commit_tree(commit_tree_label.buf, commit_tree_label.len,
> +			&info->i_tree, parents, &info->i_commit, NULL, NULL)) {
> +		fprintf_ln(stderr, _("Cannot save the current index state"));
> +		ret = -1;
> +		*stash_msg = NULL;
> +		goto done;
> +	}
> +
> +	if (include_untracked && get_untracked_files(ps, include_untracked,
> +						     &out)) {
> +		if (save_untracked_files(info, &msg, &out)) {
> +			fprintf_ln(stderr, _("Cannot save the untracked files"));
> +			ret = -1;
> +			*stash_msg = NULL;
> +			goto done;
> +		}
> +		untracked_commit_option = 1;
> +	}
> +	if (patch_mode) {
> +		ret = stash_patch(info, ps);
> +		*stash_msg = NULL;
> +		if (ret < 0) {
> +			fprintf_ln(stderr, _("Cannot save the current worktree state"));
> +			goto done;
> +		} else if (ret > 0) {
> +			goto done;
> +		}
> +	} else {
> +		if (stash_working_tree(info, ps)) {
> +			fprintf_ln(stderr, _("Cannot save the current worktree state"));
> +			ret = -1;
> +			*stash_msg = NULL;
> +			goto done;
> +		}
> +	}
> +
> +	if (!*stash_msg || !strlen(*stash_msg))
> +		strbuf_addf(&stash_msg_buf, "WIP on %s", msg.buf);
> +	else
> +		strbuf_addf(&stash_msg_buf, "On %s: %s", branch_name,
> +			    *stash_msg);
> +	*stash_msg = strbuf_detach(&stash_msg_buf, NULL);
> +
> +	/*
> +	 * `parents` will be empty after calling `commit_tree()`, so there is
> +	 * no need to call `free_commit_list()`

If it is empty, why do we need to set it to `NULL` explicitly?

> +	 */
> +	parents = NULL;
> +	if (untracked_commit_option)
> +		commit_list_insert(lookup_commit(the_repository, &info->u_commit), &parents);
> +	commit_list_insert(lookup_commit(the_repository, &info->i_commit), &parents);
> +	commit_list_insert(head_commit, &parents);
> +
> +	if (commit_tree(*stash_msg, strlen(*stash_msg), &info->w_tree,
> +			parents, &info->w_commit, NULL, NULL)) {
> +		fprintf_ln(stderr, _("Cannot record working tree state"));
> +		ret = -1;
> +		goto done;
> +	}
> +
> +done:
> +	strbuf_release(&commit_tree_label);
> +	strbuf_release(&msg);
> +	strbuf_release(&out);
> +	strbuf_release(&stash_msg_buf);
> +	return ret;
> +}
> +
> +static int create_stash(int argc, const char **argv, const char *prefix)
> +{
> +	int include_untracked = 0;
> +	int ret = 0;
> +	const char *stash_msg = NULL;

As we are taking custody of the buffer here, `stash_msg` should be of type
`char *`, i.e. no `const`.

The rest of the patch looks good to me.

Phew! What a patch! This took quite a while to review, so I am taking a
break with this patch series here, and hope to continue in a few hours
from now.

Thanks,
Dscho

> +	struct stash_info info;
> +	struct pathspec ps;
> +	struct option options[] = {
> +		OPT_BOOL('u', "include-untracked", &include_untracked,
> +			 N_("include untracked files in stash")),
> +		OPT_STRING('m', "message", &stash_msg, N_("message"),
> +			 N_("stash message")),
> +		OPT_END()
> +	};
> +
> +	argc = parse_options(argc, argv, prefix, options,
> +			     git_stash_helper_create_usage,
> +			     0);
> +
> +	memset(&ps, 0, sizeof(ps));
> +	ret = do_create_stash(ps, &stash_msg, include_untracked, 0, &info);
> +
> +	if (!ret)
> +		printf_ln("%s", oid_to_hex(&info.w_commit));
> +
> +	/*
> +	 * ret can be 1 if there were no changes. In this case, we should
> +	 * not error out.
> +	 */
> +	free((char *) stash_msg);
> +	return ret < 0;
> +}
> +
>  int cmd_stash__helper(int argc, const char **argv, const char *prefix)
>  {
>  	pid_t pid = getpid();
> @@ -812,6 +1240,8 @@ int cmd_stash__helper(int argc, const char **argv, const char *prefix)
>  		return !!show_stash(argc, argv, prefix);
>  	else if (!strcmp(argv[0], "store"))
>  		return !!store_stash(argc, argv, prefix);
> +	else if (!strcmp(argv[0], "create"))
> +		return !!create_stash(argc, argv, prefix);
>  
>  	usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
>  		      git_stash_helper_usage, options);
> diff --git a/git-stash.sh b/git-stash.sh
> index 5739c51527..ab06e4ffb8 100755
> --- a/git-stash.sh
> +++ b/git-stash.sh
> @@ -425,7 +425,7 @@ clear)
>  	;;
>  create)
>  	shift
> -	create_stash -m "$*" && echo "$w_commit"
> +	git stash--helper create --message "$*"
>  	;;
>  store)
>  	shift
> -- 
> 2.19.0.rc0.22.gc26283d74e
> 
> 

^ permalink raw reply	[relevance 3%]

* Re: [PATCH v2 22/24] revision.c: remove implicit dependency on the_index
      [irrelevant]   ` <20180903180932.32260-23-pclouds@gmail.com>
@ 2018-09-04 20:05     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-04 20:05 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

On Mon, Sep 3, 2018 at 11:10 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
>
> "remove" is probably a strong word because the dependency is still
> there, hidden behind the_repository. This patch is almost mechanical,
> all call sites are updated to take the_repository, no exception.
>
> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
> ---
>  bisect.c                         |  4 ++--
>  builtin/add.c                    |  4 ++--
>  builtin/am.c                     |  6 +++---
>  builtin/blame.c                  |  2 +-
>  builtin/checkout.c               |  4 ++--
>  builtin/commit.c                 |  2 +-
>  builtin/describe.c               |  4 ++--
>  builtin/diff-files.c             |  2 +-
>  builtin/diff-index.c             |  2 +-
>  builtin/diff-tree.c              |  2 +-
>  builtin/diff.c                   |  2 +-
>  builtin/fast-export.c            |  2 +-
>  builtin/fmt-merge-msg.c          |  2 +-
>  builtin/log.c                    | 16 ++++++++--------
>  builtin/merge.c                  |  4 ++--
>  builtin/pack-objects.c           |  2 +-
>  builtin/prune.c                  |  2 +-
>  builtin/reflog.c                 |  2 +-
>  builtin/rev-list.c               |  2 +-
>  builtin/revert.c                 |  2 +-
>  builtin/shortlog.c               |  2 +-
>  builtin/submodule--helper.c      |  2 +-
>  bundle.c                         |  4 ++--
>  diff-lib.c                       |  4 ++--
>  http-push.c                      |  2 +-
>  merge-recursive.c                |  2 +-
>  pack-bitmap-write.c              |  2 +-
>  ref-filter.c                     |  2 +-
>  remote.c                         |  2 +-
>  revision.c                       | 32 ++++++++++++++++++--------------
>  revision.h                       | 10 +++++++---
>  sequencer.c                      |  8 ++++----
>  shallow.c                        |  2 +-
>  submodule.c                      |  6 +++---
>  t/helper/test-revision-walking.c |  2 +-
>  wt-status.c                      | 10 +++++-----
>  36 files changed, 84 insertions(+), 76 deletions(-)
>
> diff --git a/bisect.c b/bisect.c
> index e1275ba79e..e19c60829c 100644
> --- a/bisect.c
> +++ b/bisect.c
> @@ -632,7 +632,7 @@ static void bisect_rev_setup(struct rev_info *revs, const char *prefix,
>         struct argv_array rev_argv = ARGV_ARRAY_INIT;
>         int i;
>
> -       init_revisions(revs, prefix);
> +       init_revisions(revs, the_repository, prefix);

Thanks for this patch!

At first I wondered why we put the repository as the second argument,
but that comes down to personal preference, so I wanted to keep it silent.
(FWIW: Thinking about it, I'd either go with this order or with (repo,
prefix, revs)
as it puts the target struct to initialize either first or last, and
then the repo
struct first in the number of parameters. I think the order is fine
after thinking
about it.)

However we have Documentation/technical/api-revision-walking.txt
which would break with this change:

    `init_revisions`::
        Initialize a rev_info structure with default values. The second
        parameter may be NULL or can be prefix path, [...]

The second parameter changes, so we'd want to update the docs
eventually, too. for now I'd think a cheap s/second/prefix/ would do
in that part of the doc.

That said, we can do that on top depending on quickly this merges down
(it touches a lot of code, so keeping the churn down would be nice).

Thanks,
Stefan

^ permalink raw reply	[relevance 2%]

* Re: [PATCH v2 24/24] Rename functions to avoid breaking in-flight topics
      [irrelevant]     ` <xmqqo9dd6kx1.fsf@gitster-ct.c.googlers.com>
@ 2018-09-04 21:12       ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-04 21:12 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Duy Nguyen, git

On Tue, Sep 4, 2018 at 1:57 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:
>
> > The three functions init_revisions(), diff_setup() and rerere() are
> > prefixed temporarily with repo_ to avoid breaking other topics which
> > add new call sites for these functions. This is a temporary
> > measure. Once everything is merged, it will be reverted and the new
> > call sites fixed.
>
> That's a sensible thing to do, but isn't it too late at 24/24 stage?
> IOW, doesn't in-flight topics break if up to 23/24 of this series is
> merged?

Presumably you merge the tip of this series (which contains 24/24)
with the other in-flight topics, that make new uses of
init_revisions(revs, prefix), which 24/24 allows. Going on either
parent side of such a merge will have working commits, that compile.

So from that POV it doesn't matter when the #define is introduced.

> IOW, the one that teaches "work in this repository" to rerere(int)
> for example should have introduced
>
>         repo_rerere(struct repository *, int);
>         #define rerere(x) repo_rerere(the_repository, x)
>
> in its own step, not this late in the series, no?

That might make for a better presentation to reviewers
now and here, but at some later date, we would want to
'git revert 24/24' after fixing all in-flights of today. And with
that in mind it makes sense to separate out all these changes
into this patch, as that allows us to have the revert rename
back to easy names.

You may be asking this question as it was done differently in
the series sb/object-store-lookup. But there the #define's served
a different purpose. That series used the #define to aid
author&reviewer to know where dependencies to the_repository
are and which function is done already.

This series solely uses the #define after the main series is done
to aid the maintainer to merge it which as you noted was one
of the problems with that other approach. The downside of the
series as it is presented here is that it is very easy to miss some
hidden dependency, that leads to a bug only discovered later
(e.g. some function still uses the_repository, when working on
a submodule for example, but as that function is used in some
corner case our test suite would not find it).

So why don't we try this approach as well and see how
well it goes over time?

Thanks,
Stefan

^ permalink raw reply	[relevance 4%]

* [PATCH 00/11] fetch: make sure submodule oids are fetched
@ 2018-09-04 23:01 Stefan Beller
  2018-09-04 23:01 ` [PATCH 04/11] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
                   ` (7 more replies)
  0 siblings, 8 replies; 200+ results
From: Stefan Beller @ 2018-09-04 23:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

This is a resend of [1] and was rebased to origin/master and all review comments
have been addressed.

Thanks,
Stefan

[1] https://public-inbox.org/git/20180808221752.195419-1-sbeller@google.com/

Stefan Beller (11):
  string_list: print_string_list to use trace_printf
  string-list.h: add string_list_{pop, last} functions
  sha1-array: provide oid_array_filter
  submodule.c: convert submodule_move_head new argument to object id
  submodule.c: fix indentation
  submodule.c: sort changed_submodule_names before searching it
  submodule: move global changed_submodule_names into fetch submodule
    struct
  submodule.c: do not copy around submodule list
  submodule: fetch in submodules git directory instead of in worktree
  fetch: retry fetching submodules if sha1 were not fetched
  builtin/fetch: check for submodule updates for non branch fetches

 builtin/fetch.c             |  14 +--
 entry.c                     |   6 +-
 sha1-array.c                |  18 ++++
 sha1-array.h                |   5 +
 string-list.c               |  20 +++-
 string-list.h               |  15 ++-
 submodule.c                 | 200 ++++++++++++++++++++++++++++--------
 submodule.h                 |   2 +-
 t/t5526-fetch-submodules.sh |  23 ++++-
 unpack-trees.c              |  13 +--
 10 files changed, 246 insertions(+), 70 deletions(-)

-- 
2.19.0.rc1.350.ge57e33dbd1-goog


^ permalink raw reply	[relevance 11%]

* [PATCH 04/11] submodule.c: convert submodule_move_head new argument to object id
  2018-09-04 23:01 [PATCH 00/11] fetch: make sure submodule oids are fetched Stefan Beller
@ 2018-09-04 23:01 ` Stefan Beller
  2018-09-06 17:31   ` Junio C Hamano
  2018-09-04 23:01 ` [PATCH 05/11] submodule.c: fix indentation Stefan Beller
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-04 23:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

All callers use oid_to_hex to convert the desired oid to a string before
calling submodule_move_head. Defer the conversion to the
submodule_move_head as it will turn out to be useful in a bit.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 entry.c        |  6 +++---
 submodule.c    | 12 ++++++------
 submodule.h    |  2 +-
 unpack-trees.c | 13 +++++--------
 4 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/entry.c b/entry.c
index 2a2ab6c8394..0b676f997b2 100644
--- a/entry.c
+++ b/entry.c
@@ -358,7 +358,7 @@ static int write_entry(struct cache_entry *ce,
 		sub = submodule_from_ce(ce);
 		if (sub)
 			return submodule_move_head(ce->name,
-				NULL, oid_to_hex(&ce->oid),
+				NULL, &ce->oid,
 				state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
 		break;
 
@@ -439,10 +439,10 @@ int checkout_entry(struct cache_entry *ce,
 					unlink_or_warn(ce->name);
 
 				return submodule_move_head(ce->name,
-					NULL, oid_to_hex(&ce->oid), 0);
+					NULL, &ce->oid, 0);
 			} else
 				return submodule_move_head(ce->name,
-					"HEAD", oid_to_hex(&ce->oid),
+					"HEAD", &ce->oid,
 					state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
 		}
 
diff --git a/submodule.c b/submodule.c
index 50cbf5f13ed..da2ed8696f5 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1597,9 +1597,9 @@ static void submodule_reset_index(const char *path)
  * pass NULL for old or new respectively.
  */
 int submodule_move_head(const char *path,
-			 const char *old_head,
-			 const char *new_head,
-			 unsigned flags)
+			const char *old_head,
+			const struct object_id *new_oid,
+			unsigned flags)
 {
 	int ret = 0;
 	struct child_process cp = CHILD_PROCESS_INIT;
@@ -1679,7 +1679,7 @@ int submodule_move_head(const char *path,
 	if (!(flags & SUBMODULE_MOVE_HEAD_FORCE))
 		argv_array_push(&cp.args, old_head ? old_head : empty_tree_oid_hex());
 
-	argv_array_push(&cp.args, new_head ? new_head : empty_tree_oid_hex());
+	argv_array_push(&cp.args, new_oid ? oid_to_hex(new_oid) : empty_tree_oid_hex());
 
 	if (run_command(&cp)) {
 		ret = error(_("Submodule '%s' could not be updated."), path);
@@ -1687,7 +1687,7 @@ int submodule_move_head(const char *path,
 	}
 
 	if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
-		if (new_head) {
+		if (new_oid) {
 			child_process_init(&cp);
 			/* also set the HEAD accordingly */
 			cp.git_cmd = 1;
@@ -1696,7 +1696,7 @@ int submodule_move_head(const char *path,
 
 			prepare_submodule_repo_env(&cp.env_array);
 			argv_array_pushl(&cp.args, "update-ref", "HEAD",
-					 "--no-deref", new_head, NULL);
+					 "--no-deref", oid_to_hex(new_oid), NULL);
 
 			if (run_command(&cp)) {
 				ret = -1;
diff --git a/submodule.h b/submodule.h
index 7d476cefa7e..ef34d5a7ca8 100644
--- a/submodule.h
+++ b/submodule.h
@@ -124,7 +124,7 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule);
 #define SUBMODULE_MOVE_HEAD_FORCE   (1<<1)
 int submodule_move_head(const char *path,
 			const char *old,
-			const char *new_head,
+			const struct object_id *new_oid,
 			unsigned flags);
 
 void submodule_unset_core_worktree(const struct submodule *sub);
diff --git a/unpack-trees.c b/unpack-trees.c
index f25089b878a..75d1b294ade 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -256,7 +256,7 @@ static void display_error_msgs(struct unpack_trees_options *o)
 
 static int check_submodule_move_head(const struct cache_entry *ce,
 				     const char *old_id,
-				     const char *new_id,
+				     const struct object_id *new_id,
 				     struct unpack_trees_options *o)
 {
 	unsigned flags = SUBMODULE_MOVE_HEAD_DRY_RUN;
@@ -1517,7 +1517,7 @@ static int verify_uptodate_1(const struct cache_entry *ce,
 
 		if (submodule_from_ce(ce)) {
 			int r = check_submodule_move_head(ce,
-				"HEAD", oid_to_hex(&ce->oid), o);
+				"HEAD", &ce->oid, o);
 			if (r)
 				return o->gently ? -1 :
 					add_rejected_path(o, error_type, ce->name);
@@ -1591,8 +1591,7 @@ static int verify_clean_submodule(const char *old_sha1,
 	if (!submodule_from_ce(ce))
 		return 0;
 
-	return check_submodule_move_head(ce, old_sha1,
-					 oid_to_hex(&ce->oid), o);
+	return check_submodule_move_head(ce, old_sha1, &ce->oid, o);
 }
 
 static int verify_clean_subdirectory(const struct cache_entry *ce,
@@ -1836,8 +1835,7 @@ static int merged_entry(const struct cache_entry *ce,
 
 		if (submodule_from_ce(ce)) {
 			int ret = check_submodule_move_head(ce, NULL,
-							    oid_to_hex(&ce->oid),
-							    o);
+							    &ce->oid, o);
 			if (ret)
 				return ret;
 		}
@@ -1865,8 +1863,7 @@ static int merged_entry(const struct cache_entry *ce,
 
 		if (submodule_from_ce(ce)) {
 			int ret = check_submodule_move_head(ce, oid_to_hex(&old->oid),
-							    oid_to_hex(&ce->oid),
-							    o);
+							    &ce->oid, o);
 			if (ret)
 				return ret;
 		}
-- 
2.19.0.rc1.350.ge57e33dbd1-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 05/11] submodule.c: fix indentation
  2018-09-04 23:01 [PATCH 00/11] fetch: make sure submodule oids are fetched Stefan Beller
  2018-09-04 23:01 ` [PATCH 04/11] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
@ 2018-09-04 23:01 ` Stefan Beller
  2018-09-06 17:34   ` Junio C Hamano
  2018-09-04 23:01 ` [PATCH 06/11] submodule.c: sort changed_submodule_names before searching it Stefan Beller
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-04 23:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

The submodule subsystem is really bad at staying within 80 characters.
Fix it while we are here.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index da2ed8696f5..8345d423fda 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1244,7 +1244,8 @@ static int get_next_submodule(struct child_process *cp,
 		if (!submodule) {
 			const char *name = default_name_or_path(ce->name);
 			if (name) {
-				default_submodule.path = default_submodule.name = name;
+				default_submodule.path = name;
+				default_submodule.name = name;
 				submodule = &default_submodule;
 			}
 		}
@@ -1254,8 +1255,9 @@ static int get_next_submodule(struct child_process *cp,
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule || !unsorted_string_list_lookup(&changed_submodule_names,
-							 submodule->name))
+			if (!submodule || !unsorted_string_list_lookup(
+					&changed_submodule_names,
+					submodule->name))
 				continue;
 			default_argv = "on-demand";
 			break;
-- 
2.19.0.rc1.350.ge57e33dbd1-goog


^ permalink raw reply	[relevance 26%]

* [PATCH 06/11] submodule.c: sort changed_submodule_names before searching it
  2018-09-04 23:01 [PATCH 00/11] fetch: make sure submodule oids are fetched Stefan Beller
  2018-09-04 23:01 ` [PATCH 04/11] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
  2018-09-04 23:01 ` [PATCH 05/11] submodule.c: fix indentation Stefan Beller
@ 2018-09-04 23:01 ` Stefan Beller
  2018-09-06 18:03   ` Junio C Hamano
  2018-09-04 23:01 ` [PATCH 07/11] submodule: move global changed_submodule_names into fetch submodule struct Stefan Beller
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-04 23:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

Instead of sorting it after we created an unsorted list, we could insert
correctly into the list.  As the unsorted append is in order of cache entry
names, this is already sorted if names were equal to paths for submodules.

As submodule names are often the same as their path, the input is sorted
pretty well already, so let's just do the sort afterwards.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/submodule.c b/submodule.c
index 8345d423fda..8bee455137a 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1255,7 +1255,7 @@ static int get_next_submodule(struct child_process *cp,
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule || !unsorted_string_list_lookup(
+			if (!submodule || !string_list_lookup(
 					&changed_submodule_names,
 					submodule->name))
 				continue;
@@ -1349,6 +1349,7 @@ int fetch_populated_submodules(struct repository *r,
 	/* default value, "--submodule-prefix" and its value are added later */
 
 	calculate_changed_submodule_paths();
+	string_list_sort(&changed_submodule_names);
 	run_processes_parallel(max_parallel_jobs,
 			       get_next_submodule,
 			       fetch_start_failure,
-- 
2.19.0.rc1.350.ge57e33dbd1-goog


^ permalink raw reply	[relevance 24%]

* [PATCH 07/11] submodule: move global changed_submodule_names into fetch submodule struct
  2018-09-04 23:01 [PATCH 00/11] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (2 preceding siblings ...)
  2018-09-04 23:01 ` [PATCH 06/11] submodule.c: sort changed_submodule_names before searching it Stefan Beller
@ 2018-09-04 23:01 ` Stefan Beller
  2018-09-06 18:04   ` Junio C Hamano
  2018-09-04 23:01 ` [PATCH 08/11] submodule.c: do not copy around submodule list Stefan Beller
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-04 23:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

The `changed_submodule_names` are only used for fetching, so let's make it
part of the struct that is passed around for fetching submodules.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/submodule.c b/submodule.c
index 8bee455137a..582c0263b91 100644
--- a/submodule.c
+++ b/submodule.c
@@ -24,7 +24,7 @@
 #include "object-store.h"
 
 static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
-static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
+
 static int initialized_fetch_ref_tips;
 static struct oid_array ref_tips_before_fetch;
 static struct oid_array ref_tips_after_fetch;
@@ -1110,7 +1110,22 @@ void check_for_new_submodule_commits(struct object_id *oid)
 	oid_array_append(&ref_tips_after_fetch, oid);
 }
 
-static void calculate_changed_submodule_paths(void)
+struct submodule_parallel_fetch {
+	int count;
+	struct argv_array args;
+	struct repository *r;
+	const char *prefix;
+	int command_line_option;
+	int default_option;
+	int quiet;
+	int result;
+
+	struct string_list changed_submodule_names;
+};
+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
+
+static void calculate_changed_submodule_paths(
+	struct submodule_parallel_fetch *spf)
 {
 	struct argv_array argv = ARGV_ARRAY_INIT;
 	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
@@ -1148,7 +1163,8 @@ static void calculate_changed_submodule_paths(void)
 			continue;
 
 		if (!submodule_has_commits(path, commits))
-			string_list_append(&changed_submodule_names, name->string);
+			string_list_append(&spf->changed_submodule_names,
+					   name->string);
 	}
 
 	free_submodules_oids(&changed_submodules);
@@ -1185,18 +1201,6 @@ int submodule_touches_in_range(struct object_id *excl_oid,
 	return ret;
 }
 
-struct submodule_parallel_fetch {
-	int count;
-	struct argv_array args;
-	struct repository *r;
-	const char *prefix;
-	int command_line_option;
-	int default_option;
-	int quiet;
-	int result;
-};
-#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0}
-
 static int get_fetch_recurse_config(const struct submodule *submodule,
 				    struct submodule_parallel_fetch *spf)
 {
@@ -1256,7 +1260,7 @@ static int get_next_submodule(struct child_process *cp,
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
 			if (!submodule || !string_list_lookup(
-					&changed_submodule_names,
+					&spf->changed_submodule_names,
 					submodule->name))
 				continue;
 			default_argv = "on-demand";
@@ -1348,8 +1352,8 @@ int fetch_populated_submodules(struct repository *r,
 	argv_array_push(&spf.args, "--recurse-submodules-default");
 	/* default value, "--submodule-prefix" and its value are added later */
 
-	calculate_changed_submodule_paths();
-	string_list_sort(&changed_submodule_names);
+	calculate_changed_submodule_paths(&spf);
+	string_list_sort(&spf.changed_submodule_names);
 	run_processes_parallel(max_parallel_jobs,
 			       get_next_submodule,
 			       fetch_start_failure,
@@ -1358,7 +1362,7 @@ int fetch_populated_submodules(struct repository *r,
 
 	argv_array_clear(&spf.args);
 out:
-	string_list_clear(&changed_submodule_names, 1);
+	string_list_clear(&spf.changed_submodule_names, 1);
 	return spf.result;
 }
 
-- 
2.19.0.rc1.350.ge57e33dbd1-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 08/11] submodule.c: do not copy around submodule list
  2018-09-04 23:01 [PATCH 00/11] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (3 preceding siblings ...)
  2018-09-04 23:01 ` [PATCH 07/11] submodule: move global changed_submodule_names into fetch submodule struct Stefan Beller
@ 2018-09-04 23:01 ` Stefan Beller
  2018-09-06 18:20   ` Junio C Hamano
  2018-09-04 23:01 ` [PATCH 09/11] submodule: fetch in submodules git directory instead of in worktree Stefan Beller
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-04 23:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

'calculate_changed_submodule_paths' uses a local list to compute the
changed submodules, and then produces the result by copying appropriate
items into the result list.

Instead use the result list directly and prune items afterwards
using string_list_remove_empty_items.

As a side effect, we'll have access to the util pointer for longer that
contains the commits that we need to fetch.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/submodule.c b/submodule.c
index 582c0263b91..0efe6711a8c 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1128,8 +1128,7 @@ static void calculate_changed_submodule_paths(
 	struct submodule_parallel_fetch *spf)
 {
 	struct argv_array argv = ARGV_ARRAY_INIT;
-	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
-	const struct string_list_item *name;
+	struct string_list_item *name;
 
 	/* No need to check if there are no submodules configured */
 	if (!submodule_from_path(the_repository, NULL, NULL))
@@ -1146,9 +1145,9 @@ static void calculate_changed_submodule_paths(
 	 * Collect all submodules (whether checked out or not) for which new
 	 * commits have been recorded upstream in "changed_submodule_names".
 	 */
-	collect_changed_submodules(&changed_submodules, &argv);
+	collect_changed_submodules(&spf->changed_submodule_names, &argv);
 
-	for_each_string_list_item(name, &changed_submodules) {
+	for_each_string_list_item(name, &spf->changed_submodule_names) {
 		struct oid_array *commits = name->util;
 		const struct submodule *submodule;
 		const char *path = NULL;
@@ -1162,12 +1161,14 @@ static void calculate_changed_submodule_paths(
 		if (!path)
 			continue;
 
-		if (!submodule_has_commits(path, commits))
-			string_list_append(&spf->changed_submodule_names,
-					   name->string);
+		if (submodule_has_commits(path, commits)) {
+			oid_array_clear(commits);
+			*name->string = '\0';
+		}
 	}
 
-	free_submodules_oids(&changed_submodules);
+	string_list_remove_empty_items(&spf->changed_submodule_names, 1);
+
 	argv_array_clear(&argv);
 	oid_array_clear(&ref_tips_before_fetch);
 	oid_array_clear(&ref_tips_after_fetch);
@@ -1362,7 +1363,7 @@ int fetch_populated_submodules(struct repository *r,
 
 	argv_array_clear(&spf.args);
 out:
-	string_list_clear(&spf.changed_submodule_names, 1);
+	free_submodules_oids(&spf.changed_submodule_names);
 	return spf.result;
 }
 
-- 
2.19.0.rc1.350.ge57e33dbd1-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 09/11] submodule: fetch in submodules git directory instead of in worktree
  2018-09-04 23:01 [PATCH 00/11] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (4 preceding siblings ...)
  2018-09-04 23:01 ` [PATCH 08/11] submodule.c: do not copy around submodule list Stefan Beller
@ 2018-09-04 23:01 ` Stefan Beller
  2018-09-04 23:01 ` [PATCH 10/11] fetch: retry fetching submodules if sha1 were not fetched Stefan Beller
  2018-09-04 23:01 ` [PATCH 11/11] builtin/fetch: check for submodule updates for non branch fetches Stefan Beller
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-04 23:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

This patch started as a refactoring to make 'get_next_submodule' more
readable, but upon doing so, I realized that git-fetch actually doesn't
need to be run in the worktree. So let's run it in the git dir instead.

That should pave the way towards fetching submodules that are currently
not checked out.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c                 | 43 ++++++++++++++++++++++++++-----------
 t/t5526-fetch-submodules.sh |  7 +++++-
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/submodule.c b/submodule.c
index 0efe6711a8c..8b67f086895 100644
--- a/submodule.c
+++ b/submodule.c
@@ -481,6 +481,12 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
+static void prepare_submodule_repo_env_in_gitdir(struct argv_array *out)
+{
+	prepare_submodule_repo_env_no_git_dir(out);
+	argv_array_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT);
+}
+
 /* Helper function to display the submodule header line prior to the full
  * summary output. If it can locate the submodule objects directory it will
  * attempt to lookup both the left and right commits and put them into the
@@ -1227,6 +1233,27 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+static const char *get_submodule_git_dir(struct repository *r, const char *path)
+{
+	struct repository subrepo;
+	const char *ret;
+
+	if (repo_submodule_init(&subrepo, r, path)) {
+		/* no entry in .gitmodules? */
+		struct strbuf gitdir = STRBUF_INIT;
+		strbuf_repo_worktree_path(&gitdir, r, "%s/.git", path);
+		if (repo_init(&subrepo, gitdir.buf, NULL)) {
+			strbuf_release(&gitdir);
+			return NULL;
+		}
+	}
+
+	ret = xstrdup(subrepo.gitdir);
+	repo_clear(&subrepo);
+
+	return ret;
+}
+
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
@@ -1234,8 +1261,6 @@ static int get_next_submodule(struct child_process *cp,
 	struct submodule_parallel_fetch *spf = data;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
-		struct strbuf submodule_path = STRBUF_INIT;
-		struct strbuf submodule_git_dir = STRBUF_INIT;
 		struct strbuf submodule_prefix = STRBUF_INIT;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *git_dir, *default_argv;
@@ -1273,16 +1298,12 @@ static int get_next_submodule(struct child_process *cp,
 			continue;
 		}
 
-		strbuf_repo_worktree_path(&submodule_path, spf->r, "%s", ce->name);
-		strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
 		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
-		git_dir = read_gitfile(submodule_git_dir.buf);
-		if (!git_dir)
-			git_dir = submodule_git_dir.buf;
-		if (is_directory(git_dir)) {
+		git_dir = get_submodule_git_dir(spf->r, ce->name);
+		if (git_dir) {
 			child_process_init(cp);
-			cp->dir = strbuf_detach(&submodule_path, NULL);
-			prepare_submodule_repo_env(&cp->env_array);
+			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+			cp->dir = git_dir;
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
@@ -1294,8 +1315,6 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_push(&cp->args, submodule_prefix.buf);
 			ret = 1;
 		}
-		strbuf_release(&submodule_path);
-		strbuf_release(&submodule_git_dir);
 		strbuf_release(&submodule_prefix);
 		if (ret) {
 			spf->count++;
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 6c2f9b2ba26..42692219a1a 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -566,7 +566,12 @@ test_expect_success 'fetching submodule into a broken repository' '
 
 	test_must_fail git -C dst status &&
 	test_must_fail git -C dst diff &&
-	test_must_fail git -C dst fetch --recurse-submodules
+
+	# git-fetch cannot find the git directory of the submodule,
+	# so it will do nothing, successfully, as it cannot distinguish between
+	# this broken submodule and a submodule that was just set active but
+	# not cloned yet
+	git -C dst fetch --recurse-submodules
 '
 
 test_expect_success "fetch new commits when submodule got renamed" '
-- 
2.19.0.rc1.350.ge57e33dbd1-goog


^ permalink raw reply	[relevance 28%]

* [PATCH 10/11] fetch: retry fetching submodules if sha1 were not fetched
  2018-09-04 23:01 [PATCH 00/11] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (5 preceding siblings ...)
  2018-09-04 23:01 ` [PATCH 09/11] submodule: fetch in submodules git directory instead of in worktree Stefan Beller
@ 2018-09-04 23:01 ` Stefan Beller
  2018-09-04 23:01 ` [PATCH 11/11] builtin/fetch: check for submodule updates for non branch fetches Stefan Beller
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-04 23:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

Currently when git-fetch is asked to recurse into submodules, it dispatches
a plain "git-fetch -C <submodule-dir>" (and some submodule related options
such as prefix and recusing strategy, but) without any information of the
remote or the tip that should be fetched.

This works surprisingly well in some workflows (such as using submodules
as a third party library), while not so well in other scenarios, such
as in a Gerrit topic-based workflow, that can tie together changes
(potentially across repositories) on the server side. One of the parts
of such a Gerrit workflow is to download a change when wanting to examine
it, and you'd want to have its submodule changes that are in the same
topic downloaded as well. However these submodule changes reside in their
own repository in their own ref (refs/changes/<int>).

Retry fetching a submodule if the object id that the superproject points
to, cannot be found.

Note: This is an RFC and doesn't support fetching to FETCH_HEAD yet, but
only into a local branch. To make fetching into FETCH_HEAD work, we need
some refactoring in builtin/fetch.c to adjust the calls to
'check_for_new_submodule_commits'.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/fetch.c             |  9 ++--
 submodule.c                 | 87 ++++++++++++++++++++++++++++++++++++-
 t/t5526-fetch-submodules.sh | 16 +++++++
 3 files changed, 104 insertions(+), 8 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 61bec5d213d..95c44bf6ffa 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -700,8 +700,7 @@ static int update_local_ref(struct ref *ref,
 			what = _("[new ref]");
 		}
 
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
+		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
 			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref(msg, ref, 0);
 		format_display(display, r ? '!' : '*', what,
@@ -716,8 +715,7 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "..");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
+		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
 			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("fast-forward", ref, 1);
 		format_display(display, r ? '!' : ' ', quickref.buf,
@@ -731,8 +729,7 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "...");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
+		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
 			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("forced-update", ref, 1);
 		format_display(display, r ? '!' : '+', quickref.buf,
diff --git a/submodule.c b/submodule.c
index 8b67f086895..702cba138be 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1127,8 +1127,11 @@ struct submodule_parallel_fetch {
 	int result;
 
 	struct string_list changed_submodule_names;
+	struct string_list retry;
 };
-#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \
+		  STRING_LIST_INIT_DUP, \
+		  STRING_LIST_INIT_NODUP}
 
 static void calculate_changed_submodule_paths(
 	struct submodule_parallel_fetch *spf)
@@ -1259,8 +1262,10 @@ static int get_next_submodule(struct child_process *cp,
 {
 	int ret = 0;
 	struct submodule_parallel_fetch *spf = data;
+	struct string_list_item *it;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
+		int recurse_config;
 		struct strbuf submodule_prefix = STRBUF_INIT;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *git_dir, *default_argv;
@@ -1280,7 +1285,9 @@ static int get_next_submodule(struct child_process *cp,
 			}
 		}
 
-		switch (get_fetch_recurse_config(submodule, spf))
+		recurse_config = get_fetch_recurse_config(submodule, spf);
+
+		switch (recurse_config)
 		{
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
@@ -1318,9 +1325,50 @@ static int get_next_submodule(struct child_process *cp,
 		strbuf_release(&submodule_prefix);
 		if (ret) {
 			spf->count++;
+			if (submodule != &default_submodule)
+				/* discard const-ness: */
+				*task_cb = (void*)submodule;
 			return 1;
 		}
 	}
+
+retry_next:
+
+	if (spf->retry.nr) {
+		struct strbuf submodule_prefix = STRBUF_INIT;
+		const struct submodule *sub;
+
+		it = string_list_last(&spf->retry);
+		sub = submodule_from_name(spf->r, &null_oid,
+					  it->string);
+
+		child_process_init(cp);
+		cp->dir = get_submodule_git_dir(spf->r, sub->path);
+		if (!cp->dir) {
+			string_list_pop(&spf->retry, 0);
+			goto retry_next;
+		}
+		prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+		cp->git_cmd = 1;
+
+		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, sub->path);
+		argv_array_init(&cp->args);
+		argv_array_pushv(&cp->args, spf->args.argv);
+		argv_array_push(&cp->args, "on-demand");
+		argv_array_push(&cp->args, "--submodule-prefix");
+		argv_array_push(&cp->args, submodule_prefix.buf);
+
+		/* NEEDSWORK: have get_default_remote from s--h */
+		argv_array_push(&cp->args, "origin");
+		oid_array_for_each_unique(it->util,
+					  append_oid_to_argv, &cp->args);
+
+		*task_cb = NULL; /* make sure we do not recurse forever */
+		strbuf_release(&submodule_prefix);
+		string_list_pop(&spf->retry, 0);
+		return 1;
+	}
+
 	return 0;
 }
 
@@ -1334,14 +1382,49 @@ static int fetch_start_failure(struct strbuf *err,
 	return 0;
 }
 
+static int commit_exists_in_sub(const struct object_id *oid, void *data)
+{
+	struct repository *subrepo = data;
+
+	enum object_type type = oid_object_info(subrepo, oid, NULL);
+
+	return type == OBJ_COMMIT;
+}
+
 static int fetch_finish(int retvalue, struct strbuf *err,
 			void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
+	struct submodule *sub = task_cb;
+	struct repository subrepo;
 
 	if (retvalue)
 		spf->result = 1;
 
+	if (!sub)
+		return 0;
+
+	if (repo_submodule_init(&subrepo, spf->r, sub->path) < 0)
+		warning(_("Could not get submodule repository for submodule '%s' in repository '%s'"),
+			  sub->path, spf->r->worktree);
+	else {
+		struct string_list_item *it;
+		struct oid_array *commits;
+
+		it = string_list_lookup(&spf->changed_submodule_names, sub->name);
+		if (!it)
+			return 0;
+
+		commits = it->util;
+		oid_array_filter(commits,
+				 commit_exists_in_sub,
+				 &subrepo);
+
+		if (commits->nr)
+			string_list_append(&spf->retry, sub->name)
+				->util = commits;
+	}
+
 	return 0;
 }
 
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 42692219a1a..af12c50e7dd 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -605,4 +605,20 @@ test_expect_success "fetch new commits when submodule got renamed" '
 	test_cmp expect actual
 '
 
+test_expect_success "fetch new commits on-demand when they are not reachable" '
+	git checkout --detach &&
+	C=$(git -C submodule commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/1 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	git commit -m "updated submodule outside of refs/heads" &&
+	D=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/2 $D &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules --recurse-submodules-default on-demand origin refs/changes/2:refs/heads/my_branch &&
+		git -C submodule cat-file -t $C &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
 test_done
-- 
2.19.0.rc1.350.ge57e33dbd1-goog


^ permalink raw reply	[relevance 19%]

* [PATCH 11/11] builtin/fetch: check for submodule updates for non branch fetches
  2018-09-04 23:01 [PATCH 00/11] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (6 preceding siblings ...)
  2018-09-04 23:01 ` [PATCH 10/11] fetch: retry fetching submodules if sha1 were not fetched Stefan Beller
@ 2018-09-04 23:01 ` Stefan Beller
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-04 23:01 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

For Gerrit users that use submodules the invocation of fetch without a
branch is their main use case.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/fetch.c             | 5 ++++-
 t/t5526-fetch-submodules.sh | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 95c44bf6ffa..ea6ecd123e7 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -887,11 +887,14 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
 				rc |= update_local_ref(ref, what, rm, &note,
 						       summary_width);
 				free(ref);
-			} else
+			} else {
+				check_for_new_submodule_commits(&rm->old_oid);
 				format_display(&note, '*',
 					       *kind ? kind : "branch", NULL,
 					       *what ? what : "HEAD",
 					       "FETCH_HEAD", summary_width);
+			}
+
 			if (note.len) {
 				if (verbosity >= 0 && !shown_url) {
 					fprintf(stderr, _("From %.*s\n"),
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index af12c50e7dd..a509eabb044 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -615,7 +615,7 @@ test_expect_success "fetch new commits on-demand when they are not reachable" '
 	git update-ref refs/changes/2 $D &&
 	(
 		cd downstream &&
-		git fetch --recurse-submodules --recurse-submodules-default on-demand origin refs/changes/2:refs/heads/my_branch &&
+		git fetch --recurse-submodules origin refs/changes/2 &&
 		git -C submodule cat-file -t $C &&
 		git checkout --recurse-submodules FETCH_HEAD
 	)
-- 
2.19.0.rc1.350.ge57e33dbd1-goog


^ permalink raw reply	[relevance 24%]

* Re: [PATCH 2/2] submodule.c: warn about missing submodule git directories
  2018-08-27 22:12 ` [PATCH 2/2] submodule.c: warn about missing submodule git directories Stefan Beller
  2018-08-28 18:56   ` Junio C Hamano
@ 2018-09-05 19:18   ` Jonathan Nieder
  2018-09-07 18:49     ` Stefan Beller
  1 sibling, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-09-05 19:18 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Hi,

Stefan Beller wrote:

> This is the continuation of f2d48994dc1 (submodule.c: submodule_move_head
> works with broken submodules, 2017-04-18), which tones down the case of
> "broken submodule" in case of a missing git directory of the submodule to
> be only a warning.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c                   | 16 ++++++++++++++++
>  t/t2013-checkout-submodule.sh |  2 +-
>  2 files changed, 17 insertions(+), 1 deletion(-)

I don't understand what workflow this is a part of.

If the submodule is missing, shouldn't we make it non-missing instead
of producing a partial checkout that doesn't build?

Thanks,
Jonathan

^ permalink raw reply	[relevance 8%]

* [PATCH] submodule.sh update --remote: default to oid instead of master
@ 2018-09-05 22:48 Stefan Beller
  2018-09-05 23:10 ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-05 22:48 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

gitmodules(5) sayeth:

   submodule.<name>.branch
       A remote branch name for tracking updates in the upstream
       submodule. If the option is not specified, it defaults to master.

This doesn't allow having a "pinned" submodule that should not be updated
from upstream. We should change this to have no default --- if branch is
not specified, don't update that submodule, just like in Gerrit's
corresponding feature[1].

[1] https://gerrit-review.googlesource.com/Documentation/user-submodules.html#_defining_the_submodule_branch

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 Documentation/gitmodules.txt | 11 ++++++-----
 git-submodule.sh             | 19 +++++++++++--------
 t/t7406-submodule-update.sh  | 22 ++++++++++++++++++++++
 3 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
index 4d63def2069..3b8739f8294 100644
--- a/Documentation/gitmodules.txt
+++ b/Documentation/gitmodules.txt
@@ -50,11 +50,12 @@ submodule.<name>.update::
 
 submodule.<name>.branch::
 	A remote branch name for tracking updates in the upstream submodule.
-	If the option is not specified, it defaults to 'master'.  A special
-	value of `.` is used to indicate that the name of the branch in the
-	submodule should be the same name as the current branch in the
-	current repository.  See the `--remote` documentation in
-	linkgit:git-submodule[1] for details.
+	A special value of `.` is used to indicate that the name of the
+	branch in the submodule should be the same name as the current
+	branch in the current repository.  See the `--remote` documentation
+	in linkgit:git-submodule[1] for details.
+	If the option is not specified, do not update to any branch but
+	the object id of the remote.
 
 submodule.<name>.fetchRecurseSubmodules::
 	This option can be used to control recursive fetching of this
diff --git a/git-submodule.sh b/git-submodule.sh
index f7fd80345cd..342050ae934 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -568,16 +568,19 @@ cmd_update()
 		if test -n "$remote"
 		then
 			branch=$(git submodule--helper remote-branch "$sm_path")
-			if test -z "$nofetch"
+			if test -n "$branch"
 			then
-				# Fetch remote before determining tracking $sha1
-				fetch_in_submodule "$sm_path" $depth ||
-				die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
+				if test -z "$nofetch"
+				then
+					# Fetch remote before determining tracking $sha1
+					fetch_in_submodule "$sm_path" $depth ||
+					die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
+				fi
+				remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote)
+				sha1=$(sanitize_submodule_env; cd "$sm_path" &&
+					git rev-parse --verify "${remote_name}/${branch}") ||
+				die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
 			fi
-			remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote)
-			sha1=$(sanitize_submodule_env; cd "$sm_path" &&
-				git rev-parse --verify "${remote_name}/${branch}") ||
-			die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
 		fi
 
 		if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 10dc91620a6..f04884743fd 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -260,6 +260,28 @@ test_expect_success 'submodule update --remote should fetch upstream changes wit
 	)
 '
 
+test_expect_success 'submodule update --remote should not fetch upstream when no branch is set' '
+	(
+		cd super &&
+		test_might_fail git config --unset -f .gitmodules submodule."submodule".branch &&
+		git add .gitmodules &&
+		git commit --allow-empty -m "submodules: pin in superproject branch"
+	) &&
+	(
+		cd submodule &&
+		echo line4b >>file &&
+		git add file &&
+		test_tick &&
+		git commit -m "upstream line4b"
+	) &&
+	(
+		cd super &&
+		git submodule update --remote --force submodule &&
+		git -C submodule log -1 --oneline >actual &&
+		! grep line4b actual
+	)
+'
+
 test_expect_success 'local config should override .gitmodules branch' '
 	(cd submodule &&
 	 git checkout test-branch &&
-- 
2.19.0.rc2.392.g5ba43deb5a-goog


^ permalink raw reply	[relevance 29%]

* [PATCH] diff: allow --recurse-submodules as an synonym for --submodule
@ 2018-09-05 22:58 Stefan Beller
  2018-09-05 23:12 ` Jonathan Nieder
  2018-09-06  6:19 ` Martin Ågren
  0 siblings, 2 replies; 200+ results
From: Stefan Beller @ 2018-09-05 22:58 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

Many commands have flags to recurse into submodules, which is named
--recurse-submodules. The diff family also has a submodule recursion flag,
but that is named differently. Add a synonym --recurse-submodules, which
means the same as the --submodule flag, such that across all git commands
supporting submodules we have the --recurse-submodules flag available.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 Documentation/diff-options.txt | 1 +
 diff.c                         | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 0378cd574eb..694c97338c9 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -227,6 +227,7 @@ linkgit:git-config[1]).
 	of the `--diff-filter` option on what the status letters mean.
 
 --submodule[=<format>]::
+--recurse-submodules[=<format>]::
 	Specify how differences in submodules are shown.  When specifying
 	`--submodule=short` the 'short' format is used.  This format just
 	shows the names of the commits at the beginning and end of the range.
diff --git a/diff.c b/diff.c
index 145cfbae592..d3d5a989bd1 100644
--- a/diff.c
+++ b/diff.c
@@ -5023,6 +5023,8 @@ int diff_opt_parse(struct diff_options *options,
 		handle_ignore_submodules_arg(options, arg);
 	} else if (skip_to_optional_arg_default(arg, "--submodule", &arg, "log"))
 		return parse_submodule_opt(options, arg);
+	else if (skip_to_optional_arg_default(arg, "--recurse-submodules", &arg, "log"))
+		return parse_submodule_opt(options, arg);
 	else if (skip_prefix(arg, "--ws-error-highlight=", &arg))
 		return parse_ws_error_highlight_opt(options, arg);
 	else if (!strcmp(arg, "--ita-invisible-in-index"))
-- 
2.19.0.rc2.392.g5ba43deb5a-goog


^ permalink raw reply	[relevance 19%]

* Re: [PATCH] submodule.sh update --remote: default to oid instead of master
  2018-09-05 22:48 [PATCH] submodule.sh update --remote: default to oid instead of master Stefan Beller
@ 2018-09-05 23:10 ` Jonathan Nieder
  2018-09-06 18:06   ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-09-05 23:10 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller wrote:

> Subject: submodule.sh update --remote: default to oid instead of master

Yay!

Nit: it wasn't clear to me at first what default this subject line was
referring to.  Perhaps:

	submodule update --remote: skip GITLINK update when no branch is set

[...]
> --- a/Documentation/gitmodules.txt
> +++ b/Documentation/gitmodules.txt
> @@ -50,11 +50,12 @@ submodule.<name>.update::
>  
>  submodule.<name>.branch::
[...]
> +	If the option is not specified, do not update to any branch but
> +	the object id of the remote.

Likewise: how about something like

	If not set, the default is for `git submodule update --remote`
	to update the submodule to the superproject's recorded SHA-1.

[...]
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -568,16 +568,19 @@ cmd_update()
>  		if test -n "$remote"
>  		then
>  			branch=$(git submodule--helper remote-branch "$sm_path")
> -			if test -z "$nofetch"
> +			if test -n "$branch"
>  			then
> -				# Fetch remote before determining tracking $sha1
> -				fetch_in_submodule "$sm_path" $depth ||
> -				die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
> +				if test -z "$nofetch"
> +				then
> +					# Fetch remote before determining tracking $sha1
> +					fetch_in_submodule "$sm_path" $depth ||

Makes sense.  If $sha1 isn't available in the submodule, it will fetch
again later.

[...]
> --- a/t/t7406-submodule-update.sh
> +++ b/t/t7406-submodule-update.sh
> @@ -260,6 +260,28 @@ test_expect_success 'submodule update --remote should fetch upstream changes wit
>  	)
>  '
>  
> +test_expect_success 'submodule update --remote should not fetch upstream when no branch is set' '
> +	(
> +		cd super &&
> +		test_might_fail git config --unset -f .gitmodules submodule."submodule".branch &&

Not about this patch: the quoting here is strange.

> +		git add .gitmodules &&
> +		git commit --allow-empty -m "submodules: pin in superproject branch"
> +	) &&

I wonder if we can do simpler by using -C + some helpers: something like

	git config --unset -f super/.gitmodules ... &&
	test_commit -C submodule ... &&
	git -C super submodule update ... &&
	test_cmp_rev ...

Unfortunately test_cmp_rev doesn't accept a -C argument.

Broader comment: do you think people will be surprised by this new
behavior?  Is there anything special we'd need to do to call it out
(e.g., print a warning or put something in release notes)?

Thanks,
Jonathan

^ permalink raw reply	[relevance 8%]

* Re: [PATCH] diff: allow --recurse-submodules as an synonym for --submodule
  2018-09-05 22:58 [PATCH] diff: allow --recurse-submodules as an synonym for --submodule Stefan Beller
@ 2018-09-05 23:12 ` Jonathan Nieder
  2018-09-06 18:27   ` Stefan Beller
      [irrelevant]   ` <xmqqefe6z5ws.fsf@gitster-ct.c.googlers.com>
  2018-09-06  6:19 ` Martin Ågren
  1 sibling, 2 replies; 200+ results
From: Jonathan Nieder @ 2018-09-05 23:12 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller wrote:

> Many commands have flags to recurse into submodules, which is named
> --recurse-submodules. The diff family also has a submodule recursion flag,
> but that is named differently. Add a synonym --recurse-submodules, which
> means the same as the --submodule flag, such that across all git commands
> supporting submodules we have the --recurse-submodules flag available.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  Documentation/diff-options.txt | 1 +
>  diff.c                         | 2 ++
>  2 files changed, 3 insertions(+)

Makes sense.

[...]
> --- a/Documentation/diff-options.txt
> +++ b/Documentation/diff-options.txt
> @@ -227,6 +227,7 @@ linkgit:git-config[1]).
>  	of the `--diff-filter` option on what the status letters mean.
>  
>  --submodule[=<format>]::
> +--recurse-submodules[=<format>]::
>  	Specify how differences in submodules are shown.  When specifying
>  	`--submodule=short` the 'short' format is used.  This format just
>  	shows the names of the commits at the beginning and end of the range.
> diff --git a/diff.c b/diff.c
> index 145cfbae592..d3d5a989bd1 100644
> --- a/diff.c
> +++ b/diff.c
> @@ -5023,6 +5023,8 @@ int diff_opt_parse(struct diff_options *options,
>  		handle_ignore_submodules_arg(options, arg);
>  	} else if (skip_to_optional_arg_default(arg, "--submodule", &arg, "log"))
>  		return parse_submodule_opt(options, arg);
> +	else if (skip_to_optional_arg_default(arg, "--recurse-submodules", &arg, "log"))
> +		return parse_submodule_opt(options, arg);

It seems like various commands are gaining --recurse-submodules options
taking different kinds of arguments:

- clone takes --recurse-submodules=<pathspec>
- fetch takes --recurse-submodules=<mode>
- after this patch, diff takes --recurse-submodules=<mode>

Is there a unifying principle?  Can Documentation/gitsubmodules.txt
say a word or two about what kind of argument values the user should
expect to be accepted by these options?

Thanks,
Jonathan

^ permalink raw reply	[relevance 9%]

* [PATCH 1/2] submodule.c: convert submodule_move_head new argument to object id
@ 2018-09-05 23:19 Stefan Beller
  2018-09-05 23:19 ` [PATCH 2/2] submodule.c: warn about missing submodule commit in recursive actions Stefan Beller
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Stefan Beller @ 2018-09-05 23:19 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

All callers use oid_to_hex to convert the desired oid to a string before
calling submodule_move_head. Defer the conversion to the
submodule_move_head as it will turn out to be useful in a bit.

Signed-off-by: Stefan Beller <sbeller@google.com>
---

This is also part of the other series sent out yesterday, 
https://public-inbox.org/git/20180904230149.180332-5-sbeller@google.com/

 entry.c        |  6 +++---
 submodule.c    | 12 ++++++------
 submodule.h    |  2 +-
 unpack-trees.c | 13 +++++--------
 4 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/entry.c b/entry.c
index 2a2ab6c8394..0b676f997b2 100644
--- a/entry.c
+++ b/entry.c
@@ -358,7 +358,7 @@ static int write_entry(struct cache_entry *ce,
 		sub = submodule_from_ce(ce);
 		if (sub)
 			return submodule_move_head(ce->name,
-				NULL, oid_to_hex(&ce->oid),
+				NULL, &ce->oid,
 				state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
 		break;
 
@@ -439,10 +439,10 @@ int checkout_entry(struct cache_entry *ce,
 					unlink_or_warn(ce->name);
 
 				return submodule_move_head(ce->name,
-					NULL, oid_to_hex(&ce->oid), 0);
+					NULL, &ce->oid, 0);
 			} else
 				return submodule_move_head(ce->name,
-					"HEAD", oid_to_hex(&ce->oid),
+					"HEAD", &ce->oid,
 					state->force ? SUBMODULE_MOVE_HEAD_FORCE : 0);
 		}
 
diff --git a/submodule.c b/submodule.c
index 50cbf5f13ed..da2ed8696f5 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1597,9 +1597,9 @@ static void submodule_reset_index(const char *path)
  * pass NULL for old or new respectively.
  */
 int submodule_move_head(const char *path,
-			 const char *old_head,
-			 const char *new_head,
-			 unsigned flags)
+			const char *old_head,
+			const struct object_id *new_oid,
+			unsigned flags)
 {
 	int ret = 0;
 	struct child_process cp = CHILD_PROCESS_INIT;
@@ -1679,7 +1679,7 @@ int submodule_move_head(const char *path,
 	if (!(flags & SUBMODULE_MOVE_HEAD_FORCE))
 		argv_array_push(&cp.args, old_head ? old_head : empty_tree_oid_hex());
 
-	argv_array_push(&cp.args, new_head ? new_head : empty_tree_oid_hex());
+	argv_array_push(&cp.args, new_oid ? oid_to_hex(new_oid) : empty_tree_oid_hex());
 
 	if (run_command(&cp)) {
 		ret = error(_("Submodule '%s' could not be updated."), path);
@@ -1687,7 +1687,7 @@ int submodule_move_head(const char *path,
 	}
 
 	if (!(flags & SUBMODULE_MOVE_HEAD_DRY_RUN)) {
-		if (new_head) {
+		if (new_oid) {
 			child_process_init(&cp);
 			/* also set the HEAD accordingly */
 			cp.git_cmd = 1;
@@ -1696,7 +1696,7 @@ int submodule_move_head(const char *path,
 
 			prepare_submodule_repo_env(&cp.env_array);
 			argv_array_pushl(&cp.args, "update-ref", "HEAD",
-					 "--no-deref", new_head, NULL);
+					 "--no-deref", oid_to_hex(new_oid), NULL);
 
 			if (run_command(&cp)) {
 				ret = -1;
diff --git a/submodule.h b/submodule.h
index 7d476cefa7e..ef34d5a7ca8 100644
--- a/submodule.h
+++ b/submodule.h
@@ -124,7 +124,7 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule);
 #define SUBMODULE_MOVE_HEAD_FORCE   (1<<1)
 int submodule_move_head(const char *path,
 			const char *old,
-			const char *new_head,
+			const struct object_id *new_oid,
 			unsigned flags);
 
 void submodule_unset_core_worktree(const struct submodule *sub);
diff --git a/unpack-trees.c b/unpack-trees.c
index f25089b878a..75d1b294ade 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -256,7 +256,7 @@ static void display_error_msgs(struct unpack_trees_options *o)
 
 static int check_submodule_move_head(const struct cache_entry *ce,
 				     const char *old_id,
-				     const char *new_id,
+				     const struct object_id *new_id,
 				     struct unpack_trees_options *o)
 {
 	unsigned flags = SUBMODULE_MOVE_HEAD_DRY_RUN;
@@ -1517,7 +1517,7 @@ static int verify_uptodate_1(const struct cache_entry *ce,
 
 		if (submodule_from_ce(ce)) {
 			int r = check_submodule_move_head(ce,
-				"HEAD", oid_to_hex(&ce->oid), o);
+				"HEAD", &ce->oid, o);
 			if (r)
 				return o->gently ? -1 :
 					add_rejected_path(o, error_type, ce->name);
@@ -1591,8 +1591,7 @@ static int verify_clean_submodule(const char *old_sha1,
 	if (!submodule_from_ce(ce))
 		return 0;
 
-	return check_submodule_move_head(ce, old_sha1,
-					 oid_to_hex(&ce->oid), o);
+	return check_submodule_move_head(ce, old_sha1, &ce->oid, o);
 }
 
 static int verify_clean_subdirectory(const struct cache_entry *ce,
@@ -1836,8 +1835,7 @@ static int merged_entry(const struct cache_entry *ce,
 
 		if (submodule_from_ce(ce)) {
 			int ret = check_submodule_move_head(ce, NULL,
-							    oid_to_hex(&ce->oid),
-							    o);
+							    &ce->oid, o);
 			if (ret)
 				return ret;
 		}
@@ -1865,8 +1863,7 @@ static int merged_entry(const struct cache_entry *ce,
 
 		if (submodule_from_ce(ce)) {
 			int ret = check_submodule_move_head(ce, oid_to_hex(&old->oid),
-							    oid_to_hex(&ce->oid),
-							    o);
+							    &ce->oid, o);
 			if (ret)
 				return ret;
 		}
-- 
2.19.0.rc2.392.g5ba43deb5a-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 2/2] submodule.c: warn about missing submodule commit in recursive actions
  2018-09-05 23:19 [PATCH 1/2] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
@ 2018-09-05 23:19 ` Stefan Beller
  2018-09-05 23:32   ` Jonathan Nieder
  2018-09-05 23:40 ` [PATCH 1/2] submodule.c: convert submodule_move_head new argument to object id Jonathan Nieder
  2018-09-06 21:18 ` Junio C Hamano
  2 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-05 23:19 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

By checking if a submodule commit exists before attempting the update
we can improve the error message from the
    error(_("Submodule '%s' could not be updated."), path);
to the new and more specific
    error(_("Submodule '%s' doesn't have commit '%s'"),
          path, oid_to_hex(new_oid));

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/submodule.c b/submodule.c
index da2ed8696f5..56104af1c7c 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1605,6 +1605,7 @@ int submodule_move_head(const char *path,
 	struct child_process cp = CHILD_PROCESS_INIT;
 	const struct submodule *sub;
 	int *error_code_ptr, error_code;
+	struct repository subrepo;
 
 	if (!is_submodule_active(the_repository, path))
 		return 0;
@@ -1627,6 +1628,13 @@ int submodule_move_head(const char *path,
 	if (!sub)
 		BUG("could not get submodule information for '%s'", path);
 
+	if (repo_submodule_init(&subrepo, the_repository, path) < 0)
+		warning(_("Could not get submodule repository for submodule 's'"), path);
+	else if (new_oid && !lookup_commit(subrepo, new_oid)) {
+		return error(_("Submodule '%s' doesn't have commit '%s'"),
+			     path, oid_to_hex(new_oid));
+	}
+
 	if (old_head && !(flags & SUBMODULE_MOVE_HEAD_FORCE)) {
 		/* Check if the submodule has a dirty index. */
 		if (submodule_has_dirty_index(sub))
-- 
2.19.0.rc2.392.g5ba43deb5a-goog


^ permalink raw reply	[relevance 23%]

* Re: [PATCH 2/2] submodule.c: warn about missing submodule commit in recursive actions
  2018-09-05 23:19 ` [PATCH 2/2] submodule.c: warn about missing submodule commit in recursive actions Stefan Beller
@ 2018-09-05 23:32   ` Jonathan Nieder
  0 siblings, 0 replies; 200+ results
From: Jonathan Nieder @ 2018-09-05 23:32 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Hi,

Stefan Beller wrote:

> Subject: submodule.c: warn about missing submodule commit in recursive actions

Nit: the diff already tells me what file the change is in.  What I'd
be more interested in is the subsystem or what commands this affects.
Does this affect all --recurse-submodules commands, or just some?

Here, I think it's about common submodule code, so I guess
'submodule:' would be a fine prefix.

> By checking if a submodule commit exists before attempting the update
> we can improve the error message from the
>     error(_("Submodule '%s' could not be updated."), path);
> to the new and more specific
>     error(_("Submodule '%s' doesn't have commit '%s'"),
>           path, oid_to_hex(new_oid));

Maybe it's just me, but I find this formatting where I cannot
distinguish between a line that was wrapped early and the start of a
callout hard to read.  Some extra line breaks would help:

  By checking if a submodule commit exists before attempting the update
  we can improve the error message from the

      error(_("Submodule '%s' could not be updated."), path);

  to the new and more specific

      error(_("Submodule '%s' doesn't have commit '%s'"),
            path, oid_to_hex(new_oid));

Beyond that, I still don't know what this change does.  Can you give
an example?  For example, what command would I run before and what bad
result would I get, and what result does this patch produce instead?

Thanks,
Jonathan

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 1/2] submodule.c: convert submodule_move_head new argument to object id
  2018-09-05 23:19 [PATCH 1/2] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
  2018-09-05 23:19 ` [PATCH 2/2] submodule.c: warn about missing submodule commit in recursive actions Stefan Beller
@ 2018-09-05 23:40 ` Jonathan Nieder
  2018-09-06 21:18 ` Junio C Hamano
  2 siblings, 0 replies; 200+ results
From: Jonathan Nieder @ 2018-09-05 23:40 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller wrote:

> Subject: submodule.c: convert submodule_move_head new argument to object id

Same nit as in https://public-inbox.org/git/20180905233203.GE120842@aiede.svl.corp.google.com/
applies about wondering which subsystem this is in.

[...]
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1597,9 +1597,9 @@ static void submodule_reset_index(const char *path)
>   * pass NULL for old or new respectively.
>   */
>  int submodule_move_head(const char *path,
> -			 const char *old_head,
> -			 const char *new_head,
> -			 unsigned flags)
> +			const char *old_head,
> +			const struct object_id *new_oid,
> +			unsigned flags)

This seems oddly asymmetrical.  Should the old value be passed as an
object_id as well?

Curious,
Jonathan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH] diff: allow --recurse-submodules as an synonym for --submodule
  2018-09-05 22:58 [PATCH] diff: allow --recurse-submodules as an synonym for --submodule Stefan Beller
  2018-09-05 23:12 ` Jonathan Nieder
@ 2018-09-06  6:19 ` Martin Ågren
  2018-09-06 18:23   ` Stefan Beller
  1 sibling, 1 reply; 200+ results
From: Martin Ågren @ 2018-09-06  6:19 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Git Mailing List

On Thu, 6 Sep 2018 at 00:59, Stefan Beller <sbeller@google.com> wrote:
>
>  --submodule[=<format>]::

Maybe drop `--submodule` here ...

> +--recurse-submodules[=<format>]::
>         Specify how differences in submodules are shown.  When specifying
>         `--submodule=short` the 'short' format is used.  This format just

... and use `--recurse-submodules` here ...

>         shows the names of the commits at the beginning and end of the range.

... and mention `--submodule` here as a historical alias? Maybe
deprecate it? I suppose the implementation of the aliasing is easy
enough that we can carry `--submodule` around forever, though.

> diff --git a/diff.c b/diff.c
> index 145cfbae592..d3d5a989bd1 100644
> --- a/diff.c
> +++ b/diff.c
> @@ -5023,6 +5023,8 @@ int diff_opt_parse(struct diff_options *options,
>                 handle_ignore_submodules_arg(options, arg);
>         } else if (skip_to_optional_arg_default(arg, "--submodule", &arg, "log"))
>                 return parse_submodule_opt(options, arg);
> +       else if (skip_to_optional_arg_default(arg, "--recurse-submodules", &arg, "log"))
> +               return parse_submodule_opt(options, arg);

How about (whitespace-damaged)

} else if (skip_to_optional_arg_default(arg, "--submodule", &arg, "log") ||
           skip_to_optional_arg_default(arg, "--recurse-submodules",
&arg, "log"))
        return parse_submodule_opt(options, arg);

to make this future-proof? Sure, they're close enough that one should
notice the two instances, and any future work work would supposedly
happen in `parse_submodule_opt()` or anywhere else but here, but still.

Just a few thoughts.

Martin

^ permalink raw reply	[relevance 9%]

* Re: sb/submodule-move-nested breaks t7411 under GIT_FSMONITOR_TEST
      [irrelevant]   ` <CAGZ79kae4k=uLx-oX5emxas4KrqObzQhzgir0coOSBzzpO8APw@mail.gmail.com>
@ 2018-09-06 12:31     ` Ævar Arnfjörð Bjarmason
  2018-09-06 16:57       ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Ævar Arnfjörð Bjarmason @ 2018-09-06 12:31 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Junio C Hamano, git, Ben Peart


On Fri, May 25 2018, Stefan Beller wrote:

> On Fri, May 25, 2018 at 5:28 AM, Ævar Arnfjörð Bjarmason
> <avarab@gmail.com> wrote:
>>
>> On Thu, May 17 2018, Junio C Hamano wrote:
>>
>>> * sb/submodule-move-nested (2018-03-29) 6 commits
>>>   (merged to 'next' on 2018-04-25 at 86b177433a)
>>>  + submodule: fixup nested submodules after moving the submodule
>>>  + submodule-config: remove submodule_from_cache
>>>  + submodule-config: add repository argument to submodule_from_{name, path}
>>>  + submodule-config: allow submodule_free to handle arbitrary repositories
>>>  + grep: remove "repo" arg from non-supporting funcs
>>>  + submodule.h: drop declaration of connect_work_tree_and_git_dir
>>>
>>>  Moving a submodule that itself has submodule in it with "git mv"
>>>  forgot to make necessary adjustment to the nested sub-submodules;
>>>  now the codepath learned to recurse into the submodules.
>>
>> I didn't spot this earlier because I don't test this a lot, but I've
>> bisected the following breakage down to da62f786d2 ("submodule: fixup
>> nested submodules after moving the submodule", 2018-03-28) (and manually
>> confirmed by reverting). On Linux both Debian & CentOS I get tests 3 and
>> 4 failing with:
>>
>>      GIT_FSMONITOR_TEST=$PWD/t7519/fsmonitor-all ./t7411-submodule-config.sh
>>
>> -v -x output follows:
>>
>> expecting success:
>>         mkdir submodule &&
>>         (cd submodule &&
>>                 git init &&
>>                 echo a >a &&
>>                 git add . &&
>>                 git commit -ma
>>         ) &&
>>         mkdir super &&
>>         (cd super &&
>>                 git init &&
>>                 git submodule add ../submodule &&
>>                 git submodule add ../submodule a &&
>>                 git commit -m "add as submodule and as a" &&
>>                 git mv a b &&
>>                 git commit -m "move a to b"
>>         )
>
> when you add a test_pause here and dump the
> state of the setup, then it can be observed that when the fsmonitor is active
> the last commit is different; without fsmonitor the moved gitlink and the change
> to the .gitmodules file is part of the commit, i.e.
>
> $ git -C super show
>         commit d3d90b70a01bd17d026f75a803c8b65f5903a7c0 (HEAD -> master)
>         Author: A U Thor <author@example.com>
>         Date:   Fri May 25 19:21:58 2018 +0000
>
>             move a to b
>
>         diff --git a/.gitmodules b/.gitmodules
>         index 3f4d474..6149210 100644
>         --- a/.gitmodules
>         +++ b/.gitmodules
>         @@ -2,5 +2,5 @@
>           path = submodule
>           url = ../submodule
>          [submodule "a"]
>         - path = a
>         + path = b
>           url = ../submodule
>         diff --git a/a b/b
>         similarity index 100%
>         rename from a
>         rename to b
> When running with the fsmonitor:
>
> $ git -C super show
>         commit 57022a92acf46f303498c045440ec099cbc35a2d (HEAD -> master)
>         Author: A U Thor <author@example.com>
>         Date:   Fri May 25 19:22:52 2018 +0000
>
>             move a to b
>
>         diff --git a/a b/b
>         similarity index 100%
>         rename from a
>         rename to b
> $ git -C super diff
>         diff --git a/.gitmodules b/.gitmodules
>         index 3f4d474..6149210 100644
>         --- a/.gitmodules
>         +++ b/.gitmodules
>         @@ -2,5 +2,5 @@
>           path = submodule
>           url = ../submodule
>          [submodule "a"]
>         - path = a
>         + path = b
>           url = ../submodule
>
> This hints at a problem with git commit;
>
> I tried adding test_tick, to unconfuse the fsmonitor, but that doesn't help,
> digging further, the problem is in the git mv command, which fails to
> add the change in
> .gitmodules to the index.
>
> Adding the verbose flag to stage_updated_gitmodules() that is called by
> git-mv very late in the game, such that
>
> void stage_updated_gitmodules(struct index_state *istate)
> {
>     trace_printf("staging .gitmodules files");
>     if (add_file_to_index(istate, GITMODULES_FILE, ADD_CACHE_VERBOSE))
>         die(_("staging updated .gitmodules failed"));
> }
>
> We would get a message if the .gitmodules file is staged correctly, as
> add_file_to_index() that calls add_to_index that would print
>
>     if (verbose && !was_same)
>         printf("add '%s'\n", path);
>
> I could not see that message, so I suspect, that there is something
> racy.
>
> Will debug further.

I spotted this again after testing the split index (see
https://public-inbox.org/git/87va7ireuu.fsf@evledraar.gmail.com/) and
was testing the fsmonitor test mode as well.

So gentle *poke*: Did you get anywhere with debugging this? It's still
failing on "master" now.

^ permalink raw reply	[relevance 5%]

* Re: sb/submodule-move-nested breaks t7411 under GIT_FSMONITOR_TEST
  2018-09-06 12:31     ` sb/submodule-move-nested breaks t7411 under GIT_FSMONITOR_TEST Ævar Arnfjörð Bjarmason
@ 2018-09-06 16:57       ` Stefan Beller
  2018-09-06 19:03         ` Ben Peart
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-06 16:57 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason; +Cc: Junio C Hamano, git, Ben Peart

> > Will debug further.
>
> I spotted this again after testing the split index (see
> https://public-inbox.org/git/87va7ireuu.fsf@evledraar.gmail.com/) and
> was testing the fsmonitor test mode as well.
>
> So gentle *poke*: Did you get anywhere with debugging this? It's still
> failing on "master" now.

I started looking into this again, help would be appreciated, as I do not
quite understand the fsmonitor part.

The error is in the setup, where we have "git mv a b"

GIT_TRACE_FSMONITOR=1 GIT_TRACE=1
GIT_FSMONITOR_TEST=$PWD/t7519/fsmonitor-all
./t7411-submodule-config.sh -d -i -v -x
++ git mv a b
trace: built-in: git mv a b
read fsmonitor extension successful
add fsmonitor
refresh fsmonitor
trace: run_command: cd '/u/git/t/trash
directory.t7411-submodule-config/super'; /u/git/t/t7519/fsmonitor-all
1 1536252819824793728
fsmonitor process '/u/git/t/t7519/fsmonitor-all' returned success
mark_fsmonitor_clean '.gitmodules'
write fsmonitor extension successful

or with more trace_printfs littered through the code
(https://github.com/stefanbeller/git/tree/submodule_fsmoitor_debug)

trace: built-in: git mv a b
read fsmonitor extension successful
add fsmonitor
refresh fsmonitor
trace: run_command: cd '/u/git/t/trash
directory.t7411-submodule-config/super'; /u/git/t/t7519/fsmonitor-all
1 1536252497951329341
fsmonitor process '/u/git/t/t7519/fsmonitor-all' returned success
need to stage .gitmodules
calling add_file_to_index


I suspect that the FSMONITOR API is handled wrongly by the part of git-mv
that writes out the .gitmodules file (if needed) and the .git/index (as needed).

Ben, do you have an idea?

Thanks,
Stefan

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 04/11] submodule.c: convert submodule_move_head new argument to object id
  2018-09-04 23:01 ` [PATCH 04/11] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
@ 2018-09-06 17:31   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-09-06 17:31 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> All callers use oid_to_hex to convert the desired oid to a string before
> calling submodule_move_head. Defer the conversion to the
> submodule_move_head as it will turn out to be useful in a bit.

I would think this is a good change even without "as it will turn
out..." which readers do not have enough information to judge for
themselves at this point.

> diff --git a/submodule.c b/submodule.c
> index 50cbf5f13ed..da2ed8696f5 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1597,9 +1597,9 @@ static void submodule_reset_index(const char *path)
>   * pass NULL for old or new respectively.
>   */
>  int submodule_move_head(const char *path,
> -			 const char *old_head,
> -			 const char *new_head,
> -			 unsigned flags)
> +			const char *old_head,
> +			const struct object_id *new_oid,
> +			unsigned flags)

The new calling convention feels somewhat uneven, though, that "new"
(does it mean "switching to this commit object"?) takes an object
id, but "old" ("switching from this commit object"?) still wants a
textual representation.

So, I no longer am sure that this is a good change by itself.  It
would be a good change by itself if we deferred _both_ to keep them
in sync (otherwise those who write (or read) callers will be forced
to wonder which one takes the object id and which one takes the
textual representation and why they need to remember the
difference).

Perhaps not all callers use oid_to_hex() to come up with old_head,
and some may even use branch names, etc., which is passed through
from this function to its callee, to convey more information than
mere object names?  If that is the case, then converting old_head to
old_oid would be a bad move as it can lose information and we'd need
to reconsider the strategy used here (e.g. perhaps we may be better
off sending both textual name and object id down the callchain, and
a caller without a meaningful textual name may indicate that by
passing NULL, or something like that).

> @@ -1865,8 +1863,7 @@ static int merged_entry(const struct cache_entry *ce,
>  
>  		if (submodule_from_ce(ce)) {
>  			int ret = check_submodule_move_head(ce, oid_to_hex(&old->oid),
> -							    oid_to_hex(&ce->oid),
> -							    o);
> +							    &ce->oid, o);
>  			if (ret)
>  				return ret;
>  		}

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 05/11] submodule.c: fix indentation
  2018-09-04 23:01 ` [PATCH 05/11] submodule.c: fix indentation Stefan Beller
@ 2018-09-06 17:34   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-09-06 17:34 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> The submodule subsystem is really bad at staying within 80 characters.
> Fix it while we are here.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/submodule.c b/submodule.c
> index da2ed8696f5..8345d423fda 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1244,7 +1244,8 @@ static int get_next_submodule(struct child_process *cp,
>  		if (!submodule) {
>  			const char *name = default_name_or_path(ce->name);
>  			if (name) {
> -				default_submodule.path = default_submodule.name = name;
> +				default_submodule.path = name;
> +				default_submodule.name = name;

Besides indentation, it is good to avoid A = B = C assignment.
Written this way, it is more obvious that these two fields share the
same pointer.

Good.

>  				submodule = &default_submodule;
>  			}
>  		}
> @@ -1254,8 +1255,9 @@ static int get_next_submodule(struct child_process *cp,
>  		default:
>  		case RECURSE_SUBMODULES_DEFAULT:
>  		case RECURSE_SUBMODULES_ON_DEMAND:
> -			if (!submodule || !unsorted_string_list_lookup(&changed_submodule_names,
> -							 submodule->name))
> +			if (!submodule || !unsorted_string_list_lookup(
> +					&changed_submodule_names,
> +					submodule->name))

			if (!submodule ||
			    !unsorted_string_list_lookup(
					&changed_submodule_names,
					submodule->name))

would be easier to see what is going on.

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 06/11] submodule.c: sort changed_submodule_names before searching it
  2018-09-04 23:01 ` [PATCH 06/11] submodule.c: sort changed_submodule_names before searching it Stefan Beller
@ 2018-09-06 18:03   ` Junio C Hamano
  2018-09-11 18:31     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-09-06 18:03 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> Instead of sorting it after we created an unsorted list, we could insert
> correctly into the list.

It is unclear what problem you are solving, especially with
subjunctive "could" there.  We are creating an unsorted list and
then sorting it and you see it as a problem because it is just as
easy and efficient to do the insertion sort while building up the
list?  (don't react and answer without reading all the way to the
end; I think I know what is going on).

> As the unsorted append is in order of cache entry
> names, this is already sorted if names were equal to paths for submodules.

That may be a statement of a fact, but it is unclear how that fact
relates to what the code is doing before this patch, or what the
code updated by this patch is doing.

> As submodule names are often the same as their path, the input is sorted
> pretty well already, so let's just do the sort afterwards.

It is unclear what (performance?) trade-off this senttence is trying
to make.  It sounds as if it is claiming this:

	We can string_list_insert() to maintain sorted-ness of the
	list as we find new items, or we can string_list_append() to
	build an unsorted list and sort it at the end just once.

	To pick which one is more appropriate, we notice the fact
	that we discover new items more or less in the already
	sorted order.  That makes "append then sort" more
	appropriate.

But is that reasoning sensible?  

I'd imagine that append-then-sort would always be more efficient
than insert-at-the-right-place-as-we-go, and the reason why we
sometimes would need to do the latter is when we need to look up
elements in the middle of building the list (e.g. we may want to
de-dup, which requires us to look up a name from the ones we
collected so far).

And in this application, calculate_changed_submodule_paths()
discover paths by calling collect_changed_submodules() which finds a
mapping <submodule name, oid of commits> into a list sorted by
submodule name, and then goes through that list and builds a list of
submodules paths (which could be different from submodule names) by
appending.  Only after this list is fully built, get_next_submodule()
gets called, so making the latter use string_list_lookup() that assumes
a sorted list is safe if we built the list by append-then-sort (iow,
sortedness while building the list does not matter).

Having analysed all that, I find it somewhat iffy that _append() is
used there in the calculate_changed_submodule_paths() function.  It
would cause the resulting changed_submodule_names list to hold the
same name twice (or more), but I do not know if that would pose a
problem to the consumer of the list.  Using "accumulate then sort
before calling look-up" would not change it as string_list_sort()
would not dedup, so I do not think this patch would introduce a new
problem, though.



> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/submodule.c b/submodule.c
> index 8345d423fda..8bee455137a 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1255,7 +1255,7 @@ static int get_next_submodule(struct child_process *cp,
>  		default:
>  		case RECURSE_SUBMODULES_DEFAULT:
>  		case RECURSE_SUBMODULES_ON_DEMAND:
> -			if (!submodule || !unsorted_string_list_lookup(
> +			if (!submodule || !string_list_lookup(
>  					&changed_submodule_names,
>  					submodule->name))
>  				continue;
> @@ -1349,6 +1349,7 @@ int fetch_populated_submodules(struct repository *r,
>  	/* default value, "--submodule-prefix" and its value are added later */
>  
>  	calculate_changed_submodule_paths();
> +	string_list_sort(&changed_submodule_names);
>  	run_processes_parallel(max_parallel_jobs,
>  			       get_next_submodule,
>  			       fetch_start_failure,

^ permalink raw reply	[relevance 6%]

* Re: [PATCH 07/11] submodule: move global changed_submodule_names into fetch submodule struct
  2018-09-04 23:01 ` [PATCH 07/11] submodule: move global changed_submodule_names into fetch submodule struct Stefan Beller
@ 2018-09-06 18:04   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-09-06 18:04 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> The `changed_submodule_names` are only used for fetching, so let's make it
> part of the struct that is passed around for fetching submodules.

Yay.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH] submodule.sh update --remote: default to oid instead of master
  2018-09-05 23:10 ` Jonathan Nieder
@ 2018-09-06 18:06   ` Stefan Beller
  2018-09-06 22:54     ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-06 18:06 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git

On Wed, Sep 5, 2018 at 4:10 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> Stefan Beller wrote:
>
> > Subject: submodule.sh update --remote: default to oid instead of master
>
> Yay!
>
> Nit: it wasn't clear to me at first what default this subject line was
> referring to.  Perhaps:
>
>         submodule update --remote: skip GITLINK update when no branch is set
>
> [...]
> > --- a/Documentation/gitmodules.txt
> > +++ b/Documentation/gitmodules.txt
> > @@ -50,11 +50,12 @@ submodule.<name>.update::
> >
> >  submodule.<name>.branch::
> [...]
> > +     If the option is not specified, do not update to any branch but
> > +     the object id of the remote.
>
> Likewise: how about something like
>
>         If not set, the default is for `git submodule update --remote`
>         to update the submodule to the superproject's recorded SHA-1.

... recorded object id.

sounds good.

> > +             git add .gitmodules &&
> > +             git commit --allow-empty -m "submodules: pin in superproject branch"
> > +     ) &&
>
> I wonder if we can do simpler by using -C + some helpers: something like
>
>         git config --unset -f super/.gitmodules ... &&
>         test_commit -C submodule ... &&
>         git -C super submodule update ... &&
>         test_cmp_rev ...
>
> Unfortunately test_cmp_rev doesn't accept a -C argument.

and the lack of fortune goes further, as test_cmp_rev needs to have
2 revisions in the same repository, i.e. both need to exist,
which is not the case.

> Broader comment: do you think people will be surprised by this new
> behavior?  Is there anything special we'd need to do to call it out
> (e.g., print a warning or put something in release notes)?

I guess. Not sure how to approach this best. Maybe we can
extend the output of 'submodule update' to print that branch names
instead of hashes for the configured case and keep printing hashes
only for this case. Although that would not help someone who relies
on the default solely.

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 08/11] submodule.c: do not copy around submodule list
  2018-09-04 23:01 ` [PATCH 08/11] submodule.c: do not copy around submodule list Stefan Beller
@ 2018-09-06 18:20   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-09-06 18:20 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> 'calculate_changed_submodule_paths' uses a local list to compute the
> changed submodules, and then produces the result by copying appropriate
> items into the result list.
>
> Instead use the result list directly and prune items afterwards
> using string_list_remove_empty_items.

That may describe what the patch does, but does not explain why we
would even want to do so in the first place.  

It may be a safe thing to do to munge the list in place as there is
nobody that looks at the list after we are done in the current code,
but the above description does not tell that to readers and fails to
give readers warm and fuzzy feeling that the safety likely will stay
with us in the future.

> As a side effect, we'll have access to the util pointer for longer that
> contains the commits that we need to fetch.

If this patch does not move free-submodules-oids call to out: label
(i.e. instead do so after the call to string-list-remove-empty-items
is made, perhaps), then the list of oids will have the same lifespan
as the original code, no?  Then it is not a "side effect" but is
deliberate change of behaviour this patch makes.  We can access the
list for longer time than before, which may be a good thing, in
which case we'd want to explain the potential benefit we could reap
with future changes, no?

>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c | 19 ++++++++++---------
>  1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/submodule.c b/submodule.c
> index 582c0263b91..0efe6711a8c 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1128,8 +1128,7 @@ static void calculate_changed_submodule_paths(
>  	struct submodule_parallel_fetch *spf)
>  {
>  	struct argv_array argv = ARGV_ARRAY_INIT;
> -	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
> -	const struct string_list_item *name;
> +	struct string_list_item *name;
>  
>  	/* No need to check if there are no submodules configured */
>  	if (!submodule_from_path(the_repository, NULL, NULL))
> @@ -1146,9 +1145,9 @@ static void calculate_changed_submodule_paths(
>  	 * Collect all submodules (whether checked out or not) for which new
>  	 * commits have been recorded upstream in "changed_submodule_names".
>  	 */
> -	collect_changed_submodules(&changed_submodules, &argv);
> +	collect_changed_submodules(&spf->changed_submodule_names, &argv);
>  
> -	for_each_string_list_item(name, &changed_submodules) {
> +	for_each_string_list_item(name, &spf->changed_submodule_names) {
>  		struct oid_array *commits = name->util;
>  		const struct submodule *submodule;
>  		const char *path = NULL;
> @@ -1162,12 +1161,14 @@ static void calculate_changed_submodule_paths(
>  		if (!path)
>  			continue;
>  
> -		if (!submodule_has_commits(path, commits))
> -			string_list_append(&spf->changed_submodule_names,
> -					   name->string);
> +		if (submodule_has_commits(path, commits)) {
> +			oid_array_clear(commits);
> +			*name->string = '\0';
> +		}
>  	}
>  
> -	free_submodules_oids(&changed_submodules);
> +	string_list_remove_empty_items(&spf->changed_submodule_names, 1);
> +
>  	argv_array_clear(&argv);
>  	oid_array_clear(&ref_tips_before_fetch);
>  	oid_array_clear(&ref_tips_after_fetch);
> @@ -1362,7 +1363,7 @@ int fetch_populated_submodules(struct repository *r,
>  
>  	argv_array_clear(&spf.args);
>  out:
> -	string_list_clear(&spf.changed_submodule_names, 1);
> +	free_submodules_oids(&spf.changed_submodule_names);
>  	return spf.result;
>  }

^ permalink raw reply	[relevance 7%]

* [PATCH] diff: allow --recurse-submodules as an synonym for --submodule
  2018-09-06  6:19 ` Martin Ågren
@ 2018-09-06 18:23   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-06 18:23 UTC (permalink / raw)
  To: git; +Cc: martin.agren, jrnieder, Stefan Beller

Many commands have flags to recurse into submodules, which is named
--recurse-submodules. The diff family also has a submodule recursion flag,
but that is named differently. Add a synonym --recurse-submodules, which
means the same as the --submodule flag, such that across all git commands
supporting submodules we have the --recurse-submodules flag available.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 Documentation/diff-options.txt | 21 +++++++++++----------
 diff.c                         |  3 ++-
 2 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 0378cd574eb..28c6c7f939f 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -226,17 +226,18 @@ linkgit:git-config[1]).
 	Show only names and status of changed files. See the description
 	of the `--diff-filter` option on what the status letters mean.
 
---submodule[=<format>]::
+--recurse-submodules[=<format>]::
 	Specify how differences in submodules are shown.  When specifying
-	`--submodule=short` the 'short' format is used.  This format just
-	shows the names of the commits at the beginning and end of the range.
-	When `--submodule` or `--submodule=log` is specified, the 'log'
-	format is used.  This format lists the commits in the range like
-	linkgit:git-submodule[1] `summary` does.  When `--submodule=diff`
-	is specified, the 'diff' format is used.  This format shows an
-	inline diff of the changes in the submodule contents between the
-	commit range.  Defaults to `diff.submodule` or the 'short' format
-	if the config option is unset.
+	`--recurse-submodules=short` the 'short' format is used.  This format
+	just shows the names of the commits at the beginning and end of the
+	range. When `--recurse-submodules` or `--recurse-submodules=log` is
+	specified, the 'log' format is used.  This format lists the commits
+	in the range like linkgit:git-submodule[1] `summary` does.
+	When `--recurse-submodules=diff` is specified, the 'diff' format
+	is used. This format shows an inline diff of the changes in the
+	submodule contents between the commit range.  Defaults to
+	`diff.submodule` or the 'short' format if the config option is unset.
+	`--submodule[=<format>]` is a historic synonym for this option.
 
 --color[=<when>]::
 	Show colored diff.
diff --git a/diff.c b/diff.c
index 145cfbae592..b874f166c00 100644
--- a/diff.c
+++ b/diff.c
@@ -5021,7 +5021,8 @@ int diff_opt_parse(struct diff_options *options,
 	else if (skip_to_optional_arg_default(arg, "--ignore-submodules", &arg, "all")) {
 		options->flags.override_submodule_config = 1;
 		handle_ignore_submodules_arg(options, arg);
-	} else if (skip_to_optional_arg_default(arg, "--submodule", &arg, "log"))
+	} else if (skip_to_optional_arg_default(arg, "--submodule", &arg, "log") ||
+	    skip_to_optional_arg_default(arg, "--recurse-submodules", &arg, "log"))
 		return parse_submodule_opt(options, arg);
 	else if (skip_prefix(arg, "--ws-error-highlight=", &arg))
 		return parse_ws_error_highlight_opt(options, arg);
-- 
2.19.0.rc2.392.g5ba43deb5a-goog


^ permalink raw reply	[relevance 24%]

* Re: [PATCH] diff: allow --recurse-submodules as an synonym for --submodule
  2018-09-05 23:12 ` Jonathan Nieder
@ 2018-09-06 18:27   ` Stefan Beller
      [irrelevant]   ` <xmqqefe6z5ws.fsf@gitster-ct.c.googlers.com>
  1 sibling, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-06 18:27 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git

On Wed, Sep 5, 2018 at 4:13 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> Stefan Beller wrote:
>
> > Many commands have flags to recurse into submodules, which is named
> > --recurse-submodules. The diff family also has a submodule recursion flag,
> > but that is named differently. Add a synonym --recurse-submodules, which
> > means the same as the --submodule flag, such that across all git commands
> > supporting submodules we have the --recurse-submodules flag available.
> >
> > Signed-off-by: Stefan Beller <sbeller@google.com>
> > ---
> >  Documentation/diff-options.txt | 1 +
> >  diff.c                         | 2 ++
> >  2 files changed, 3 insertions(+)
>
> Makes sense.
>
> [...]
> > --- a/Documentation/diff-options.txt
> > +++ b/Documentation/diff-options.txt
> > @@ -227,6 +227,7 @@ linkgit:git-config[1]).
> >       of the `--diff-filter` option on what the status letters mean.
> >
> >  --submodule[=<format>]::
> > +--recurse-submodules[=<format>]::
> >       Specify how differences in submodules are shown.  When specifying
> >       `--submodule=short` the 'short' format is used.  This format just
> >       shows the names of the commits at the beginning and end of the range.
> > diff --git a/diff.c b/diff.c
> > index 145cfbae592..d3d5a989bd1 100644
> > --- a/diff.c
> > +++ b/diff.c
> > @@ -5023,6 +5023,8 @@ int diff_opt_parse(struct diff_options *options,
> >               handle_ignore_submodules_arg(options, arg);
> >       } else if (skip_to_optional_arg_default(arg, "--submodule", &arg, "log"))
> >               return parse_submodule_opt(options, arg);
> > +     else if (skip_to_optional_arg_default(arg, "--recurse-submodules", &arg, "log"))
> > +             return parse_submodule_opt(options, arg);
>
> It seems like various commands are gaining --recurse-submodules options
> taking different kinds of arguments:
>
> - clone takes --recurse-submodules=<pathspec>
> - fetch takes --recurse-submodules=<mode>
> - after this patch, diff takes --recurse-submodules=<mode>
>
> Is there a unifying principle?  Can Documentation/gitsubmodules.txt
> say a word or two about what kind of argument values the user should
> expect to be accepted by these options?

I don't think there is a unifying principle deep down.
Everything but clone is specifying a mode (you could imagine
that we extend "git reset --recurse-submodules" as well to take
some sort of mode, either the hard/soft differentiation or how to treat
dirty submodules or a mode that could differentiate between superprojects
sha1 and branch of the same name)

Care to send a patch on top to talk about these issues in
Documentation/gitsubmodules.txt ?

Thanks,
Stefan

^ permalink raw reply	[relevance 8%]

* RE: sb/submodule-move-nested breaks t7411 under GIT_FSMONITOR_TEST
  2018-09-06 16:57       ` Stefan Beller
@ 2018-09-06 19:03         ` Ben Peart
  2018-09-06 20:14           ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Ben Peart @ 2018-09-06 19:03 UTC (permalink / raw)
  To: Stefan Beller, Ævar Arnfjörð Bjarmason; +Cc: Junio C Hamano, git

> -----Original Message-----
> From: Stefan Beller <sbeller@google.com>
> Sent: Thursday, September 6, 2018 12:57 PM
> To: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> Cc: Junio C Hamano <gitster@pobox.com>; git <git@vger.kernel.org>; Ben
> Peart <Ben.Peart@microsoft.com>
> Subject: Re: sb/submodule-move-nested breaks t7411 under
> GIT_FSMONITOR_TEST
> 
> > > Will debug further.
> >
> > I spotted this again after testing the split index (see
> >
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpublic-
> inbox.org%2Fgit%2F87va7ireuu.fsf%40evledraar.gmail.com%2F&amp;data=0
> 2%7C01%7CBen.Peart%40microsoft.com%7C27c901f198a24e5a045a08d6141
> 9ce42%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636718498401
> 788697&amp;sdata=JfavHtKafiJRAVnvMXU3nw1RI27G4OFxs3Ymt7STbvM%3
> D&amp;reserved=0) and
> > was testing the fsmonitor test mode as well.
> >
> > So gentle *poke*: Did you get anywhere with debugging this? It's still
> > failing on "master" now.
> 
> I started looking into this again, help would be appreciated, as I do not
> quite understand the fsmonitor part.
> 
> The error is in the setup, where we have "git mv a b"
> 
> GIT_TRACE_FSMONITOR=1 GIT_TRACE=1
> GIT_FSMONITOR_TEST=$PWD/t7519/fsmonitor-all
> ./t7411-submodule-config.sh -d -i -v -x
> ++ git mv a b
> trace: built-in: git mv a b
> read fsmonitor extension successful
> add fsmonitor
> refresh fsmonitor
> trace: run_command: cd '/u/git/t/trash
> directory.t7411-submodule-config/super'; /u/git/t/t7519/fsmonitor-all
> 1 1536252819824793728
> fsmonitor process '/u/git/t/t7519/fsmonitor-all' returned success
> mark_fsmonitor_clean '.gitmodules'
> write fsmonitor extension successful
> 
> or with more trace_printfs littered through the code
> (https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub
> .com%2Fstefanbeller%2Fgit%2Ftree%2Fsubmodule_fsmoitor_debug&amp;d
> ata=02%7C01%7CBen.Peart%40microsoft.com%7C27c901f198a24e5a045a08
> d61419ce42%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C6367184
> 98401788697&amp;sdata=poAUFlVDkoNP56t1hmdxHHyChrH05cut1iSVt70yJ
> eo%3D&amp;reserved=0)
> 
> trace: built-in: git mv a b
> read fsmonitor extension successful
> add fsmonitor
> refresh fsmonitor
> trace: run_command: cd '/u/git/t/trash
> directory.t7411-submodule-config/super'; /u/git/t/t7519/fsmonitor-all
> 1 1536252497951329341
> fsmonitor process '/u/git/t/t7519/fsmonitor-all' returned success
> need to stage .gitmodules
> calling add_file_to_index
> 
> 
> I suspect that the FSMONITOR API is handled wrongly by the part of git-mv
> that writes out the .gitmodules file (if needed) and the .git/index (as needed).
> 
> Ben, do you have an idea?
> 

I'll take a look as soon as I can (and at the other fsmonitor test issue Ævar sent email about) but it may be a few days before I get a chance.

I haven't had a chance to look into this yet but here are a couple of SWAG's I'd start with:

I wonder if there is a missing call to mark_fsmonitor_invalid() in the "git mv" codepath somewhere.

refresh_fsmonitor() only runs once per git command - is it possible that "git mv" is triggering it early, making a change, and then updating the index with stale fsmonitor data?

Sorry, I'll look as soon as I can.

Ben

> Thanks,
> Stefan

^ permalink raw reply	[relevance 2%]

* Re: ordered string-list considered harmful, was Re: [PATCH v3] Allow aliases that include other aliases
      [irrelevant] <20180906191203.GA26184@sigill.intra.peff.net>
@ 2018-09-06 20:04 ` Stefan Beller
  2018-09-06 20:49   ` Jeff King
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-06 20:04 UTC (permalink / raw)
  To: Jeff King; +Cc: git, timschumi, Junio C Hamano, Duy Nguyen

On Thu, Sep 6, 2018 at 12:12 PM Jeff King <peff@peff.net> wrote:
>
> On Thu, Sep 06, 2018 at 10:59:42AM -0400, Jeff King wrote:
>
> > > +           string_list_append(&cmd_list, *argv[0]);
> >
> > This will create an unsorted list. You'd have to use
> > string_list_insert() here for a sorted list, or
> > unsorted_string_list_has_string() in the earlier call.
> >
> > It's unfortunate that string_list makes this so easy to get wrong.
>
> This is getting really off-topic (since it sounds like we'd probably
> want to use an ordered list here), but is it crazy to think that
> basically every use of an ordered string list could just be a hashmap?

Does a hashmap guarantee an order?
I thought we had an example of an ordered list in the submodule code
but could not find it, maybe it is gone already or did not rely on the order
as I thought.

It turns out we make never use of a custom compare function in
the stringlist, which helps gaining confidence this use case is nowhere
to be found in the code.

> And then the sometimes-sorted/sometimes-not duality of string-list could
> go away?

Sounds good, ship it. :-)

Stefan

^ permalink raw reply	[relevance 5%]

* Re: sb/submodule-move-nested breaks t7411 under GIT_FSMONITOR_TEST
  2018-09-06 19:03         ` Ben Peart
@ 2018-09-06 20:14           ` Stefan Beller
  2018-09-06 20:34             ` [PATCH] git-mv: allow submodules and fsmonitor to work together Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-06 20:14 UTC (permalink / raw)
  To: Ben Peart; +Cc: Ævar Arnfjörð Bjarmason, Junio C Hamano, git

> > Ben, do you have an idea?
> >
>
> I'll take a look as soon as I can (and at the other fsmonitor test issue Ævar sent email about) but it may be a few days before I get a chance.
>
> I haven't had a chance to look into this yet but here are a couple of SWAG's I'd start with:
>

> is it possible that "git mv" is triggering it early, making a change, and then updating the index with stale fsmonitor data?

This is exactly what is happening. Thanks for describing the situation
precisely.

> I wonder if there is a missing call to mark_fsmonitor_invalid() in the "git mv" codepath somewhere.
>
> refresh_fsmonitor() only runs once per git command

Just naively adding mark_fsmonitor_invalid doesn't work, as then
we have a sequence of

fsmonitor process '/u/git/t/t7519/fsmonitor-all' returned success
mark_fsmonitor_clean '.gitmodules'
mark_fsmonitor_invalid '.gitmodules'
write fsmonitor extension successful

and the marking invalid doesn't seem to override the first
mark as valid ?

>
> Sorry, I'll look as soon as I can.
>
> Ben

Thanks!
Stefan

^ permalink raw reply	[relevance 5%]

* [PATCH] git-mv: allow submodules and fsmonitor to work together
  2018-09-06 20:14           ` Stefan Beller
@ 2018-09-06 20:34             ` Stefan Beller
  2018-09-10 15:58               ` Ben Peart
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-06 20:34 UTC (permalink / raw)
  To: git; +Cc: Ben.Peart, avarab, gitster, Stefan Beller

It was reported that

  GIT_FSMONITOR_TEST=$PWD/t7519/fsmonitor-all ./t7411-submodule-config.sh

breaks as the .gitmodules file is modified and staged after the fsmonitor
considers it clean. Mark the .gitmodules file to be not clean before
staging.

Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Inspired-by: Ben Peart <benpeart@microsoft.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---

I am not quite sure if this is the correct approach and handling of the
fsmonitor API, but it unbreaks the test.

> Just naively adding mark_fsmonitor_invalid doesn't work, as then ...

Adding it before the staging, works.

Please double check!

Thanks,
Stefan

 submodule.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/submodule.c b/submodule.c
index 50cbf5f13ed..56b0d5fe24e 100644
--- a/submodule.c
+++ b/submodule.c
@@ -22,6 +22,7 @@
 #include "worktree.h"
 #include "parse-options.h"
 #include "object-store.h"
+#include "fsmonitor.h"
 
 static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
 static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
@@ -149,6 +150,15 @@ int remove_path_from_gitmodules(const char *path)
 
 void stage_updated_gitmodules(struct index_state *istate)
 {
+	struct cache_entry *ce;
+	int pos;
+
+	pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));
+	ce = (0 <= pos) ? istate->cache[pos] : NULL;
+
+	if (ce)
+		mark_fsmonitor_invalid(istate, ce);
+
 	if (add_file_to_index(istate, GITMODULES_FILE, 0))
 		die(_("staging updated .gitmodules failed"));
 }
-- 
2.19.0.rc2.392.g5ba43deb5a-goog


^ permalink raw reply	[relevance 13%]

* Re: ordered string-list considered harmful, was Re: [PATCH v3] Allow aliases that include other aliases
  2018-09-06 20:04 ` ordered string-list considered harmful, was Re: [PATCH v3] Allow aliases that include other aliases Stefan Beller
@ 2018-09-06 20:49   ` Jeff King
  2018-09-06 20:54     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Jeff King @ 2018-09-06 20:49 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, timschumi, Junio C Hamano, Duy Nguyen

On Thu, Sep 06, 2018 at 01:04:18PM -0700, Stefan Beller wrote:

> On Thu, Sep 6, 2018 at 12:12 PM Jeff King <peff@peff.net> wrote:
> >
> > On Thu, Sep 06, 2018 at 10:59:42AM -0400, Jeff King wrote:
> >
> > > > +           string_list_append(&cmd_list, *argv[0]);
> > >
> > > This will create an unsorted list. You'd have to use
> > > string_list_insert() here for a sorted list, or
> > > unsorted_string_list_has_string() in the earlier call.
> > >
> > > It's unfortunate that string_list makes this so easy to get wrong.
> >
> > This is getting really off-topic (since it sounds like we'd probably
> > want to use an ordered list here), but is it crazy to think that
> > basically every use of an ordered string list could just be a hashmap?
> 
> Does a hashmap guarantee an order?

No, it definitely doesn't.

I guess the reading-between-the-lines assumption that I didn't quite say
is: I think most (if not all) of the users of sorted string lists don't
actually care about a particular order. They just want efficient lookup.

> I thought we had an example of an ordered list in the submodule code
> but could not find it, maybe it is gone already or did not rely on the order
> as I thought.
> 
> It turns out we make never use of a custom compare function in
> the stringlist, which helps gaining confidence this use case is nowhere
> to be found in the code.

Plenty of code uses the default strcmp. You can find users which assume
sorting by their use of string_list_insert() versus _append(). Or ones
that call string_list_sort(), of course.

-Peff

^ permalink raw reply	[relevance 2%]

* Re: ordered string-list considered harmful, was Re: [PATCH v3] Allow aliases that include other aliases
  2018-09-06 20:49   ` Jeff King
@ 2018-09-06 20:54     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-06 20:54 UTC (permalink / raw)
  To: Jeff King; +Cc: git, timschumi, Junio C Hamano, Duy Nguyen

> > Does a hashmap guarantee an order?
>
> No, it definitely doesn't.
>
> I guess the reading-between-the-lines assumption that I didn't quite say
> is: I think most (if not all) of the users of sorted string lists don't
> actually care about a particular order. They just want efficient lookup.
>
> > I thought we had an example of an ordered list in the submodule code
> > but could not find it, maybe it is gone already or did not rely on the order
> > as I thought.
> >
> > It turns out we make never use of a custom compare function in
> > the stringlist, which helps gaining confidence this use case is nowhere
> > to be found in the code.
>
> Plenty of code uses the default strcmp. You can find users which assume
> sorting by their use of string_list_insert() versus _append(). Or ones
> that call string_list_sort(), of course.

Here comes my reading-between-the-lines assumption:

When using the default comparison function, you probably only care
about the efficient lookup as described above, but if you had a non-default
order, then we'd have strong evidence of the contrary as the author of such
code would have found reasons why that order is superior than default order
(and don't tell me a different order helps making lookups even more efficient,
this must be another reason).

^ permalink raw reply	[relevance 2%]

* Re: [PATCH 1/2] submodule.c: convert submodule_move_head new argument to object id
  2018-09-05 23:19 [PATCH 1/2] submodule.c: convert submodule_move_head new argument to object id Stefan Beller
  2018-09-05 23:19 ` [PATCH 2/2] submodule.c: warn about missing submodule commit in recursive actions Stefan Beller
  2018-09-05 23:40 ` [PATCH 1/2] submodule.c: convert submodule_move_head new argument to object id Jonathan Nieder
@ 2018-09-06 21:18 ` Junio C Hamano
  2 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-09-06 21:18 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> All callers use oid_to_hex to convert the desired oid to a string before
> calling submodule_move_head. Defer the conversion to the
> submodule_move_head as it will turn out to be useful in a bit.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>
> This is also part of the other series sent out yesterday, 
> https://public-inbox.org/git/20180904230149.180332-5-sbeller@google.com/

And what is your intention wrt the other one?

Do you want two separate copies of essentially the same patch queued
as part of two separate topics?  Did you change your mind since
yesterday and decided to retract these patches, and instead
concentrate on these two patches that address an issue with tigher
focus before moving on to other things?

Exactly the same comment applies to this copy.  It is somewhat
disturbing to see that new and old, which correspond to each other
and ought to be symmetrical, take the same "commit object" in
different shapes.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH] diff: allow --recurse-submodules as an synonym for --submodule
      [irrelevant]   ` <xmqqefe6z5ws.fsf@gitster-ct.c.googlers.com>
@ 2018-09-06 21:25     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-06 21:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jonathan Nieder, git

On Thu, Sep 6, 2018 at 2:12 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Jonathan Nieder <jrnieder@gmail.com> writes:
>
> > It seems like various commands are gaining --recurse-submodules options
> > taking different kinds of arguments:
> >
> > - clone takes --recurse-submodules=<pathspec>
> > - fetch takes --recurse-submodules=<mode>
> > - after this patch, diff takes --recurse-submodules=<mode>
> >
> > Is there a unifying principle?  Can Documentation/gitsubmodules.txt
> > say a word or two about what kind of argument values the user should
> > expect to be accepted by these options?
>
> I am not sure if the above is rhetorical.  The only thing such a
> document can say about status-quo is that the user cannot make an
> educated guess, as there is no consistency.  Some take an option to
> clarify which subset of submodules to act on, others take an option
> to specify what variant of operation to be made on the submodules.
>
> In the ideal world, the users ought to be able to give these two
> independently, i.e. "fetch" should be able to say "only fetch these
> submodules" with pathspec while "run the fetch in all of these
> submodules specified (with the pathspec) as necessary" with
> "on-demand" mode, for example.
>
> It may mean that it is too early to add "diff --recurse-submodules"
> as a synonym for "diff --submodule", before what we can do to
> improve the situation for commands that already take that
> "--recurse-submodules" option.

Good point. So let's retreat that patch for now?

Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH] submodule.sh update --remote: default to oid instead of master
  2018-09-06 18:06   ` Stefan Beller
@ 2018-09-06 22:54     ` Jonathan Nieder
  0 siblings, 0 replies; 200+ results
From: Jonathan Nieder @ 2018-09-06 22:54 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller wrote:
> On Wed, Sep 5, 2018 at 4:10 PM Jonathan Nieder <jrnieder@gmail.com> wrote:

>> Broader comment: do you think people will be surprised by this new
>> behavior?  Is there anything special we'd need to do to call it out
>> (e.g., print a warning or put something in release notes)?
>
> I guess. Not sure how to approach this best. Maybe we can
> extend the output of 'submodule update' to print that branch names
> instead of hashes for the configured case and keep printing hashes
> only for this case. Although that would not help someone who relies
> on the default solely.

Thinking more out loud: often the simplest migration path involves
multiple steps:

 1. Warn in the case that is going to change, with no behavior change
    yet.

 2. Treat the case that will change as an error.  This should
    help flush out cases where people were relying on the old behavior.

 3. Introduce the new behavior.  Warn that old versions of Git don't
    support it yet.

 4. Eliminate the warning.  You're all clear now.

Sometimes some of these steps can be combined.

Another possible approach is to measure.  For example, is there some
way to find out how many people are relying in this "git submodule
update --remote" defaulting behavior?  One example of this approach is
to make the change (all in one step) in "next" and deploy to some
relevant subpopulation and see if anyone screams.  By making the
change in "next" instead of something with more stability guarantees,
you get the ability to roll back quickly.

There are other tools at our disposal --- e.g. command-line flags,
config, other kinds of research.

Here my first instinct would be to say this should be a command-line
flag.  To start out, we can keep the historical behavior as a default,
but introduce a command-line option for the new behavior.  This way,
people can pass the negation of that command-line option if they want
the older behavior, throughout the transition.

For example (please ignore names):

 Step 0: introduce

	git submodule update --remote --default-to-master; # current behavior
	git submodule update --remote --no-default-to-master; # new behavior

 and treat plain "git submodule update --remote" as --default-to-master.

 Step 1: when neither --default-to-master nor --no-default-to-master
 has been passed, warn when encountering a submodule with no branch
 and treat it as "master".

 Step 2: when neither --default-to-master nor --no-default-to-master
 has been passed, error out when encountering a submodule with no
 branch.

 Step 3: when neither --default-to-master nor --no-default-to-master
 has been passed, warn when encountering a submodule with no branch
 and treat it as pinned.

 Step 4: eliminate the warning.

What do you think?

Thanks,
Jonathan

^ permalink raw reply	[relevance 7%]

* Re: Old submodules broken in 2.19rc1 and 2.19rc2
      [irrelevant] <2659750.rG6xLiZASK@twilight>
@ 2018-09-07 17:08 ` Stefan Beller
  2018-09-07 20:20   ` Jonathan Nieder
                     ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Stefan Beller @ 2018-09-07 17:08 UTC (permalink / raw)
  To: allan.jensen; +Cc: git

On Fri, Sep 7, 2018 at 2:53 AM Allan Sandfeld Jensen <allan.jensen@qt.io> wrote:
>
> Submodules checked out with older versions of git not longer works in the
> latest 2.19 releases. A "git submodule update --recursive" command wil fail
> for each submodule with a line saying "fatal: could not open
> '<submodule>/.git' for writing> Is a directory.

Can you run the update again with

    GIT_TRACE=1 git submodule update ....

and post the output?

I have the suspicion that e98317508c0 (submodule:
ensure core.worktree is set after update, 2018-06-18)
might be the offender.

Could you try reverting that commit and check as well?

    git clone https://github.com/git/git && cd git
    git revert e98317508c0
    make install # installs to you home dir at ~/bin

and then try again, as well?
(though bisection may be more fruitful if this doesn't pan out)

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 2/2] submodule.c: warn about missing submodule git directories
  2018-09-05 19:18   ` Jonathan Nieder
@ 2018-09-07 18:49     ` Stefan Beller
  2018-09-07 19:53       ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-07 18:49 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: git

On Wed, Sep 5, 2018 at 12:18 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> Hi,
>
> Stefan Beller wrote:
>
> > This is the continuation of f2d48994dc1 (submodule.c: submodule_move_head
> > works with broken submodules, 2017-04-18), which tones down the case of
> > "broken submodule" in case of a missing git directory of the submodule to
> > be only a warning.
> >
> > Signed-off-by: Stefan Beller <sbeller@google.com>
> > ---
> >  submodule.c                   | 16 ++++++++++++++++
> >  t/t2013-checkout-submodule.sh |  2 +-
> >  2 files changed, 17 insertions(+), 1 deletion(-)
>
> I don't understand what workflow this is a part of.
>
> If the submodule is missing, shouldn't we make it non-missing instead
> of producing a partial checkout that doesn't build?

No. checkout and friends do not want to touch the network
(unless we are in a partial clone world; that is the user is fully
aware that commands can use the network at totally unexpected
times)

So for that, all we can do is better error messages.

Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 2/2] submodule.c: warn about missing submodule git directories
  2018-09-07 18:49     ` Stefan Beller
@ 2018-09-07 19:53       ` Jonathan Nieder
  0 siblings, 0 replies; 200+ results
From: Jonathan Nieder @ 2018-09-07 19:53 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Hi,

Stefan Beller wrote:
> On Wed, Sep 5, 2018 at 12:18 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
>> Stefan Beller wrote:

>>> This is the continuation of f2d48994dc1 (submodule.c: submodule_move_head
>>> works with broken submodules, 2017-04-18), which tones down the case of
>>> "broken submodule" in case of a missing git directory of the submodule to
>>> be only a warning.
[...]
>> I don't understand what workflow this is a part of.
>>
>> If the submodule is missing, shouldn't we make it non-missing instead
>> of producing a partial checkout that doesn't build?
>
> No. checkout and friends do not want to touch the network
> (unless we are in a partial clone world; that is the user is fully
> aware that commands can use the network at totally unexpected
> times)
>
> So for that, all we can do is better error messages.

Thanks.  This patch doesn't just improve error messages, though, but
it makes the operation report success instead of failing.

Isn't that likely to produce more confusion when I run additional
commands afterward?  In other words, instead of

	$ git checkout --recurse-submodules -B master origin/new-fancy-branch
	Branch 'master' set up to track remote branch 'new-fancy-branch' from 'origin'.
	Switched to a new branch 'master'
	warning: Submodule 'new-fancy-submodule' is missing
	$ git status
[some unclean state]

I would prefer to experience

	$ git checkout --recurse-submodules -B master origin/new-fancy-branch
	fatal: missing submodule 'new-fancy-submodule'
	hint: run "git fetch --recurse-submodules" to fetch it
	$ git status
[clean state]
	$ git fetch --recurse-submodules
[...]
	$ git checkout --recurse-submodules -B master origin/new-fancy-branch
	Branch 'master' set up to track remote branch 'new-fancy-branch' from 'origin'.
	Switched to a new branch 'master'
	$ git status
[clean state]

Thanks,
Jonathan

^ permalink raw reply	[relevance 9%]

* Re: Old submodules broken in 2.19rc1 and 2.19rc2
  2018-09-07 17:08 ` Old submodules broken in 2.19rc1 and 2.19rc2 Stefan Beller
@ 2018-09-07 20:20   ` Jonathan Nieder
  2018-09-07 22:33   ` Allan Sandfeld Jensen
  2018-09-07 22:35   ` Jonathan Nieder
  2 siblings, 0 replies; 200+ results
From: Jonathan Nieder @ 2018-09-07 20:20 UTC (permalink / raw)
  To: Stefan Beller; +Cc: allan.jensen, git

Stefan Beller wrote:
> On Fri, Sep 7, 2018 at 2:53 AM Allan Sandfeld Jensen <allan.jensen@qt.io> wrote:

>>                       A "git submodule update --recursive" command wil fail
>> for each submodule with a line saying "fatal: could not open
>> '<submodule>/.git' for writing> Is a directory.
[...]
> I have the suspicion that e98317508c0 (submodule:
> ensure core.worktree is set after update, 2018-06-18)
> might be the offender.

Oh!  That seems likely.

Allan, output from "strace -f git submodule update --init" would also
be interesting.

Jonathan

^ permalink raw reply	[relevance 7%]

* Re: Old submodules broken in 2.19rc1 and 2.19rc2
  2018-09-07 17:08 ` Old submodules broken in 2.19rc1 and 2.19rc2 Stefan Beller
  2018-09-07 20:20   ` Jonathan Nieder
  2018-09-07 22:33   ` Allan Sandfeld Jensen
@ 2018-09-07 22:35   ` Jonathan Nieder
  2018-09-07 22:45     ` Stefan Beller
  2 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-09-07 22:35 UTC (permalink / raw)
  To: Stefan Beller; +Cc: allan.jensen, git

Stefan Beller wrote:
> On Fri, Sep 7, 2018 at 2:53 AM Allan Sandfeld Jensen <allan.jensen@qt.io> wrote:

>> Submodules checked out with older versions of git not longer works in the
>> latest 2.19 releases. A "git submodule update --recursive" command wil fail
>> for each submodule with a line saying "fatal: could not open
>> '<submodule>/.git' for writing> Is a directory.
[...]
> I have the suspicion that e98317508c0 (submodule:
> ensure core.worktree is set after update, 2018-06-18)
> might be the offender.

I still was not able to reproduce it, but after a bit of staring at
the code, I'm pretty sure I just did something wrong in the
reproduction process.  That commit is indeed the offender.

It introduces the following code (rewrapped for clarity) in
git-submodule.sh:

	if ! $(
		git config -f \
			"$(git rev-parse --git-common-dir)/modules/$name/config" \
			core.worktree
	) 2>/dev/null
	then
		git submodule--helper connect-gitdir-workingtree "$name" "$sm_path"
	fi

Staring at it for a while, you can see one problem: the 'if ! $(git
config)' should be simply 'if ! git config'.  This ends up trying to
run the core.worktree value as a command, which would usually fail.

That brings us into connect_work_tree_and_git_dir, which does

	/* Prepare .git file */
	strbuf_addf(&gitfile_sb, "%s/.git", work_tree_);
	if (safe_create_leading_directories_const(gitfile_sb.buf))
		die(_("could not create directories for %s"), gitfile_sb.buf);

	/* Prepare config file */
	strbuf_addf(&cfg_sb, "%s/config", git_dir_);
	if (safe_create_leading_directories_const(cfg_sb.buf))
		die(_("could not create directories for %s"), cfg_sb.buf);

	git_dir = real_pathdup(git_dir_, 1);
	work_tree = real_pathdup(work_tree_, 1);

	/* Write .git file */
	write_file(gitfile_sb.buf, "gitdir: %s",
		   relative_path(git_dir, work_tree, &rel_path));

The write_file runs into .git already existing as a directory, failing
with the message Allan saw.

This would happen in at least two cases:

- if the submodule exists both in .git/modules/ *and* in the worktree
  (due to flipping between Git versions and branches with and without
  the submodule), the above will happen

- likewise if the submodule exists only in the worktree, like for Allan.

In "next" there is 74d4731d (submodule--helper: replace
connect-gitdir-workingtree by ensure-core-worktree, 2018-08-13) which
uses robust helpers in C that handle this much better.  I think we
should revert e98317508c0 in "master" (for 2.19) and keep making use
of that 'second try' in "next" (for 2.20).

I'll try to pin down a reproduction case and send a revert + testsuite
patch.

Thanks again,
Jonathan

^ permalink raw reply	[relevance 7%]

* Re: Old submodules broken in 2.19rc1 and 2.19rc2
  2018-09-07 17:08 ` Old submodules broken in 2.19rc1 and 2.19rc2 Stefan Beller
  2018-09-07 20:20   ` Jonathan Nieder
@ 2018-09-07 22:33   ` Allan Sandfeld Jensen
  2018-09-07 22:35   ` Jonathan Nieder
  2 siblings, 0 replies; 200+ results
From: Allan Sandfeld Jensen @ 2018-09-07 22:33 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 1272 bytes --]

On Freitag, 7. September 2018 19:08:43 CEST Stefan Beller wrote:
> On Fri, Sep 7, 2018 at 2:53 AM Allan Sandfeld Jensen <allan.jensen@qt.io> 
wrote:
> > Submodules checked out with older versions of git not longer works in the
> > latest 2.19 releases. A "git submodule update --recursive" command wil
> > fail
> > for each submodule with a line saying "fatal: could not open
> > '<submodule>/.git' for writing> Is a directory.
> 
> Can you run the update again with
> 
>     GIT_TRACE=1 git submodule update ....
> 
> and post the output?
> 
> I have the suspicion that e98317508c0 (submodule:
> ensure core.worktree is set after update, 2018-06-18)
> might be the offender.
> 
> Could you try reverting that commit and check as well?
> 
>     git clone https://github.com/git/git && cd git
>     git revert e98317508c0
>     make install # installs to you home dir at ~/bin
> 
> and then try again, as well?
> (though bisection may be more fruitful if this doesn't pan out)

Okay. I had the issue on my workstation at work which I won't be back to until 
friday next week, but I managed to reproduce the exact same issue on separate 
machine running Ubuntu, and a freshly built git from git master, on another 
roughly one year old checkout of qt5.git with submodules



[-- Attachment #2: git-trace.txt --]
[-- Type: text/plain, Size: 68895 bytes --]

[127] carewolf@twilight% GIT_TRACE=1 ~src/git/git submodule update --recursive                                               [5.11.2] ~qt5
00:28:32.234453 git.c:659               trace: exec: git-submodule update --recursive
00:28:32.234491 run-command.c:637       trace: run_command: git-submodule update --recursive
00:28:32.240792 git.c:415               trace: built-in: git rev-parse --git-dir
00:28:32.241981 git.c:415               trace: built-in: git rev-parse --git-path objects
00:28:32.242905 git.c:415               trace: built-in: git rev-parse -q --git-dir
00:28:32.244794 git.c:415               trace: built-in: git rev-parse --show-prefix
00:28:32.245699 git.c:415               trace: built-in: git rev-parse --show-toplevel
00:28:32.247181 git.c:415               trace: built-in: git submodule--helper update-clone
00:28:32.247463 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.247764 run-command.c:1585      run_processes_parallel: done
00:28:32.248626 git.c:415               trace: built-in: git submodule--helper name qt3d
00:28:32.249751 git.c:415               trace: built-in: git config submodule.qt3d.update
00:28:32.250608 git.c:415               trace: built-in: git submodule--helper relative-path qt3d 
00:28:32.251399 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.252120 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.253096 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.253982 git.c:415               trace: built-in: git config -f .git/modules/qt3d/config core.worktree
00:28:32.254771 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qt3d qt3d
fatal: could not open 'qt3d/.git' for writing: Is a directory
00:28:32.255930 git.c:415               trace: built-in: git submodule--helper relative-path qt3d/ 
00:28:32.256712 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.257878 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qt3d/
00:28:32.258510 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.258544 run-command.c:1585      run_processes_parallel: done
00:28:32.260356 git.c:415               trace: built-in: git submodule--helper name qtactiveqt
00:28:32.261475 git.c:415               trace: built-in: git config submodule.qtactiveqt.update
00:28:32.262321 git.c:415               trace: built-in: git submodule--helper relative-path qtactiveqt 
00:28:32.263259 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.263987 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.264929 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.265775 git.c:415               trace: built-in: git config -f .git/modules/qtactiveqt/config core.worktree
00:28:32.266563 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtactiveqt qtactiveqt
fatal: could not open 'qtactiveqt/.git' for writing: Is a directory
00:28:32.267595 git.c:415               trace: built-in: git submodule--helper relative-path qtactiveqt/ 
00:28:32.268310 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.269481 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtactiveqt/
00:28:32.269626 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.269652 run-command.c:1585      run_processes_parallel: done
00:28:32.270893 git.c:415               trace: built-in: git submodule--helper name qtandroidextras
00:28:32.272151 git.c:415               trace: built-in: git config submodule.qtandroidextras.update
00:28:32.273213 git.c:415               trace: built-in: git submodule--helper relative-path qtandroidextras 
00:28:32.274162 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.274856 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.275879 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.276995 git.c:415               trace: built-in: git config -f .git/modules/qtandroidextras/config core.worktree
00:28:32.277883 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtandroidextras qtandroidextras
fatal: could not open 'qtandroidextras/.git' for writing: Is a directory
00:28:32.278974 git.c:415               trace: built-in: git submodule--helper relative-path qtandroidextras/ 
00:28:32.279721 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.280735 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtandroidextras/
00:28:32.280854 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.280881 run-command.c:1585      run_processes_parallel: done
00:28:32.281938 git.c:415               trace: built-in: git submodule--helper name qtbase
00:28:32.283009 git.c:415               trace: built-in: git config submodule.qtbase.update
00:28:32.283947 git.c:415               trace: built-in: git submodule--helper relative-path qtbase 
00:28:32.284835 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.285594 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.286639 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.287548 git.c:415               trace: built-in: git config -f .git/modules/qtbase/config core.worktree
00:28:32.288399 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtbase qtbase
fatal: could not open 'qtbase/.git' for writing: Is a directory
00:28:32.289379 git.c:415               trace: built-in: git submodule--helper relative-path qtbase/ 
00:28:32.290073 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.291003 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtbase/
00:28:32.293437 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.293450 run-command.c:1585      run_processes_parallel: done
00:28:32.294761 git.c:415               trace: built-in: git submodule--helper name qtcanvas3d
00:28:32.295955 git.c:415               trace: built-in: git config submodule.qtcanvas3d.update
00:28:32.296830 git.c:415               trace: built-in: git submodule--helper relative-path qtcanvas3d 
00:28:32.297737 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.298323 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.299308 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.300424 git.c:415               trace: built-in: git config -f .git/modules/qtcanvas3d/config core.worktree
00:28:32.301219 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtcanvas3d qtcanvas3d
fatal: could not open 'qtcanvas3d/.git' for writing: Is a directory
00:28:32.302298 git.c:415               trace: built-in: git submodule--helper relative-path qtcanvas3d/ 
00:28:32.303135 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.304144 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtcanvas3d/
00:28:32.304305 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.304312 run-command.c:1585      run_processes_parallel: done
00:28:32.305436 git.c:415               trace: built-in: git submodule--helper name qtcharts
00:28:32.306623 git.c:415               trace: built-in: git config submodule.qtcharts.update
00:28:32.307733 git.c:415               trace: built-in: git submodule--helper relative-path qtcharts 
00:28:32.309132 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.309953 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.310872 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.311715 git.c:415               trace: built-in: git config -f .git/modules/qtcharts/config core.worktree
00:28:32.312694 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtcharts qtcharts
fatal: could not open 'qtcharts/.git' for writing: Is a directory
00:28:32.313739 git.c:415               trace: built-in: git submodule--helper relative-path qtcharts/ 
00:28:32.314476 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.315474 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtcharts/
00:28:32.315706 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.315714 run-command.c:1585      run_processes_parallel: done
00:28:32.317048 git.c:415               trace: built-in: git submodule--helper name qtconnectivity
00:28:32.318220 git.c:415               trace: built-in: git config submodule.qtconnectivity.update
00:28:32.319278 git.c:415               trace: built-in: git submodule--helper relative-path qtconnectivity 
00:28:32.320454 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.321200 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.322107 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.323086 git.c:415               trace: built-in: git config -f .git/modules/qtconnectivity/config core.worktree
00:28:32.323983 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtconnectivity qtconnectivity
fatal: could not open 'qtconnectivity/.git' for writing: Is a directory
00:28:32.325043 git.c:415               trace: built-in: git submodule--helper relative-path qtconnectivity/ 
00:28:32.325810 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.326789 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtconnectivity/
00:28:32.326978 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.326987 run-command.c:1585      run_processes_parallel: done
00:28:32.328155 git.c:415               trace: built-in: git submodule--helper name qtdatavis3d
00:28:32.329275 git.c:415               trace: built-in: git config submodule.qtdatavis3d.update
00:28:32.330125 git.c:415               trace: built-in: git submodule--helper relative-path qtdatavis3d 
00:28:32.331069 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.331678 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.332616 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.333516 git.c:415               trace: built-in: git config -f .git/modules/qtdatavis3d/config core.worktree
00:28:32.334445 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtdatavis3d qtdatavis3d
fatal: could not open 'qtdatavis3d/.git' for writing: Is a directory
00:28:32.335636 git.c:415               trace: built-in: git submodule--helper relative-path qtdatavis3d/ 
00:28:32.336442 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.337468 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtdatavis3d/
00:28:32.337696 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.337724 run-command.c:1585      run_processes_parallel: done
00:28:32.338780 git.c:415               trace: built-in: git submodule--helper name qtdeclarative
00:28:32.339940 git.c:415               trace: built-in: git config submodule.qtdeclarative.update
00:28:32.340751 git.c:415               trace: built-in: git submodule--helper relative-path qtdeclarative 
00:28:32.341537 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.342183 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.343111 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.343997 git.c:415               trace: built-in: git config -f .git/modules/qtdeclarative/config core.worktree
00:28:32.344743 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtdeclarative qtdeclarative
fatal: could not open 'qtdeclarative/.git' for writing: Is a directory
00:28:32.345732 git.c:415               trace: built-in: git submodule--helper relative-path qtdeclarative/ 
00:28:32.346490 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.347495 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtdeclarative/
00:28:32.348619 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.348690 run-command.c:1585      run_processes_parallel: done
00:28:32.349524 git.c:415               trace: built-in: git submodule--helper name tests/auto/qml/ecmascripttests/test262
00:28:32.351213 git.c:415               trace: built-in: git config submodule.tests/auto/qml/ecmascripttests/test262.update
00:28:32.352106 git.c:415               trace: built-in: git submodule--helper relative-path qtdeclarative/tests/auto/qml/ecmascripttests/test262 
00:28:32.352996 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.353646 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.354640 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.355437 git.c:415               trace: built-in: git config -f .git/modules/tests/auto/qml/ecmascripttests/test262/config core.worktree
00:28:32.356344 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree tests/auto/qml/ecmascripttests/test262 tests/auto/qml/ecmascripttests/test262
00:28:32.357659 git.c:415               trace: built-in: git submodule--helper relative-path qtdeclarative/tests/auto/qml/ecmascripttests/test262/ 
00:28:32.358693 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.360070 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtdeclarative/tests/auto/qml/ecmascripttests/test262/
00:28:32.361641 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.361673 run-command.c:1585      run_processes_parallel: done
00:28:32.363347 git.c:415               trace: built-in: git submodule--helper name qtdoc
00:28:32.364557 git.c:415               trace: built-in: git config submodule.qtdoc.update
00:28:32.365526 git.c:415               trace: built-in: git submodule--helper relative-path qtdoc 
00:28:32.366413 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.367022 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.368012 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.368810 git.c:415               trace: built-in: git config -f .git/modules/qtdoc/config core.worktree
00:28:32.369720 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtdoc qtdoc
fatal: could not open 'qtdoc/.git' for writing: Is a directory
00:28:32.370824 git.c:415               trace: built-in: git submodule--helper relative-path qtdoc/ 
00:28:32.371573 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.372563 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtdoc/
00:28:32.372766 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.372775 run-command.c:1585      run_processes_parallel: done
00:28:32.373799 git.c:415               trace: built-in: git submodule--helper name qtdocgallery
00:28:32.374757 git.c:415               trace: built-in: git config submodule.qtdocgallery.update
00:28:32.375489 git.c:415               trace: built-in: git submodule--helper relative-path qtdocgallery 
00:28:32.376272 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.376930 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.377819 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.378643 git.c:415               trace: built-in: git config -f .git/modules/qtdocgallery/config core.worktree
00:28:32.379545 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtdocgallery qtdocgallery
00:28:32.380811 git.c:415               trace: built-in: git submodule--helper relative-path qtdocgallery/ 
00:28:32.381563 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.382596 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtdocgallery/
00:28:32.382712 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.382738 run-command.c:1585      run_processes_parallel: done
00:28:32.383858 git.c:415               trace: built-in: git submodule--helper name qtfeedback
00:28:32.384939 git.c:415               trace: built-in: git config submodule.qtfeedback.update
00:28:32.385747 git.c:415               trace: built-in: git submodule--helper relative-path qtfeedback 
00:28:32.386554 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.387206 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.388173 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.388989 git.c:415               trace: built-in: git config -f .git/modules/qtfeedback/config core.worktree
00:28:32.389997 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtfeedback qtfeedback
00:28:32.391155 git.c:415               trace: built-in: git submodule--helper relative-path qtfeedback/ 
00:28:32.391946 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.392937 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtfeedback/
00:28:32.393042 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.393053 run-command.c:1585      run_processes_parallel: done
00:28:32.394070 git.c:415               trace: built-in: git submodule--helper name qtgamepad
00:28:32.395037 git.c:415               trace: built-in: git config submodule.qtgamepad.update
00:28:32.395778 git.c:415               trace: built-in: git submodule--helper relative-path qtgamepad 
00:28:32.396736 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.397423 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.398334 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.399191 git.c:415               trace: built-in: git config -f .git/modules/qtgamepad/config core.worktree
00:28:32.400069 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtgamepad qtgamepad
fatal: could not open 'qtgamepad/.git' for writing: Is a directory
00:28:32.401080 git.c:415               trace: built-in: git submodule--helper relative-path qtgamepad/ 
00:28:32.401843 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.402868 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtgamepad/
00:28:32.402976 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.402988 run-command.c:1585      run_processes_parallel: done
00:28:32.404108 git.c:415               trace: built-in: git submodule--helper name qtgraphicaleffects
00:28:32.405122 git.c:415               trace: built-in: git config submodule.qtgraphicaleffects.update
00:28:32.406006 git.c:415               trace: built-in: git submodule--helper relative-path qtgraphicaleffects 
00:28:32.407290 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.408276 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.409773 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.410889 git.c:415               trace: built-in: git config -f .git/modules/qtgraphicaleffects/config core.worktree
00:28:32.411702 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtgraphicaleffects qtgraphicaleffects
fatal: could not open 'qtgraphicaleffects/.git' for writing: Is a directory
00:28:32.412798 git.c:415               trace: built-in: git submodule--helper relative-path qtgraphicaleffects/ 
00:28:32.413551 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.414577 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtgraphicaleffects/
00:28:32.414724 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.414732 run-command.c:1585      run_processes_parallel: done
00:28:32.416013 git.c:415               trace: built-in: git submodule--helper name qtimageformats
00:28:32.417100 git.c:415               trace: built-in: git config submodule.qtimageformats.update
00:28:32.418063 git.c:415               trace: built-in: git submodule--helper relative-path qtimageformats 
00:28:32.419038 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.419763 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.420765 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.421611 git.c:415               trace: built-in: git config -f .git/modules/qtimageformats/config core.worktree
00:28:32.422395 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtimageformats qtimageformats
fatal: could not open 'qtimageformats/.git' for writing: Is a directory
00:28:32.423463 git.c:415               trace: built-in: git submodule--helper relative-path qtimageformats/ 
00:28:32.424255 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.425276 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtimageformats/
00:28:32.425454 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.425462 run-command.c:1585      run_processes_parallel: done
00:28:32.426548 git.c:415               trace: built-in: git submodule--helper name qtlocation
00:28:32.427653 git.c:415               trace: built-in: git config submodule.qtlocation.update
00:28:32.428520 git.c:415               trace: built-in: git submodule--helper relative-path qtlocation 
00:28:32.429392 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.430081 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.430948 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.431883 git.c:415               trace: built-in: git config -f .git/modules/qtlocation/config core.worktree
00:28:32.432644 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtlocation qtlocation
fatal: could not open 'qtlocation/.git' for writing: Is a directory
00:28:32.433659 git.c:415               trace: built-in: git submodule--helper relative-path qtlocation/ 
00:28:32.434425 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.435419 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtlocation/
00:28:32.435658 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.435689 run-command.c:1585      run_processes_parallel: done
00:28:32.436536 git.c:415               trace: built-in: git submodule--helper name src/3rdparty/mapbox-gl-native
00:28:32.437460 git.c:415               trace: built-in: git config submodule.src/3rdparty/mapbox-gl-native.update
00:28:32.438238 git.c:415               trace: built-in: git submodule--helper relative-path qtlocation/src/3rdparty/mapbox-gl-native 
00:28:32.439093 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.439705 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.440802 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.441577 git.c:415               trace: built-in: git config -f .git/modules/src/3rdparty/mapbox-gl-native/config core.worktree
00:28:32.442548 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree src/3rdparty/mapbox-gl-native src/3rdparty/mapbox-gl-native
00:28:32.443595 git.c:415               trace: built-in: git submodule--helper relative-path qtlocation/src/3rdparty/mapbox-gl-native/ 
00:28:32.444333 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.445350 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtlocation/src/3rdparty/mapbox-gl-native/
00:28:32.445928 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.445938 run-command.c:1585      run_processes_parallel: done
00:28:32.447234 git.c:415               trace: built-in: git submodule--helper name qtmacextras
00:28:32.448286 git.c:415               trace: built-in: git config submodule.qtmacextras.update
00:28:32.449142 git.c:415               trace: built-in: git submodule--helper relative-path qtmacextras 
00:28:32.450001 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.450815 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.451994 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.452936 git.c:415               trace: built-in: git config -f .git/modules/qtmacextras/config core.worktree
00:28:32.453738 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtmacextras qtmacextras
fatal: could not open 'qtmacextras/.git' for writing: Is a directory
00:28:32.454821 git.c:415               trace: built-in: git submodule--helper relative-path qtmacextras/ 
00:28:32.455618 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.456636 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtmacextras/
00:28:32.456803 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.456812 run-command.c:1585      run_processes_parallel: done
00:28:32.458217 git.c:415               trace: built-in: git submodule--helper name qtmultimedia
00:28:32.459897 git.c:415               trace: built-in: git config submodule.qtmultimedia.update
00:28:32.460908 git.c:415               trace: built-in: git submodule--helper relative-path qtmultimedia 
00:28:32.461787 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.462588 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.463611 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.464496 git.c:415               trace: built-in: git config -f .git/modules/qtmultimedia/config core.worktree
00:28:32.465265 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtmultimedia qtmultimedia
fatal: could not open 'qtmultimedia/.git' for writing: Is a directory
00:28:32.466329 git.c:415               trace: built-in: git submodule--helper relative-path qtmultimedia/ 
00:28:32.467121 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.468129 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtmultimedia/
00:28:32.468431 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.468441 run-command.c:1585      run_processes_parallel: done
00:28:32.469470 git.c:415               trace: built-in: git submodule--helper name qtnetworkauth
00:28:32.470535 git.c:415               trace: built-in: git config submodule.qtnetworkauth.update
00:28:32.471371 git.c:415               trace: built-in: git submodule--helper relative-path qtnetworkauth 
00:28:32.472263 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.472913 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.473816 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.474659 git.c:415               trace: built-in: git config -f .git/modules/qtnetworkauth/config core.worktree
00:28:32.475434 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtnetworkauth qtnetworkauth
fatal: could not open 'qtnetworkauth/.git' for writing: Is a directory
00:28:32.476461 git.c:415               trace: built-in: git submodule--helper relative-path qtnetworkauth/ 
00:28:32.477322 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.478451 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtnetworkauth/
00:28:32.478570 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.478597 run-command.c:1585      run_processes_parallel: done
00:28:32.479732 git.c:415               trace: built-in: git submodule--helper name qtpim
00:28:32.480914 git.c:415               trace: built-in: git config submodule.qtpim.update
00:28:32.481850 git.c:415               trace: built-in: git submodule--helper relative-path qtpim 
00:28:32.482689 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.483373 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.484330 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.485198 git.c:415               trace: built-in: git config -f .git/modules/qtpim/config core.worktree
00:28:32.486164 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtpim qtpim
00:28:32.487302 git.c:415               trace: built-in: git submodule--helper relative-path qtpim/ 
00:28:32.488150 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.489140 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtpim/
00:28:32.489344 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.489352 run-command.c:1585      run_processes_parallel: done
00:28:32.490484 git.c:415               trace: built-in: git submodule--helper name qtpurchasing
00:28:32.491559 git.c:415               trace: built-in: git config submodule.qtpurchasing.update
00:28:32.492429 git.c:415               trace: built-in: git submodule--helper relative-path qtpurchasing 
00:28:32.493215 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.493847 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.495112 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.496041 git.c:415               trace: built-in: git config -f .git/modules/qtpurchasing/config core.worktree
00:28:32.496843 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtpurchasing qtpurchasing
fatal: could not open 'qtpurchasing/.git' for writing: Is a directory
00:28:32.497956 git.c:415               trace: built-in: git submodule--helper relative-path qtpurchasing/ 
00:28:32.498768 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.499883 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtpurchasing/
00:28:32.500003 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.500011 run-command.c:1585      run_processes_parallel: done
00:28:32.501056 git.c:415               trace: built-in: git submodule--helper name qtqa
00:28:32.502126 git.c:415               trace: built-in: git config submodule.qtqa.update
00:28:32.502974 git.c:415               trace: built-in: git submodule--helper relative-path qtqa 
00:28:32.503773 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.504591 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.505645 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.506732 git.c:415               trace: built-in: git config -f .git/modules/qtqa/config core.worktree
00:28:32.507875 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtqa qtqa
fatal: could not open 'qtqa/.git' for writing: Is a directory
00:28:32.509175 git.c:415               trace: built-in: git submodule--helper relative-path qtqa/ 
00:28:32.509985 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.510882 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtqa/
00:28:32.511002 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.511010 run-command.c:1585      run_processes_parallel: done
00:28:32.512184 git.c:415               trace: built-in: git submodule--helper name qtquickcontrols
00:28:32.513251 git.c:415               trace: built-in: git config submodule.qtquickcontrols.update
00:28:32.514082 git.c:415               trace: built-in: git submodule--helper relative-path qtquickcontrols 
00:28:32.514961 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.515611 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.516612 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.517380 git.c:415               trace: built-in: git config -f .git/modules/qtquickcontrols/config core.worktree
00:28:32.518168 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtquickcontrols qtquickcontrols
fatal: could not open 'qtquickcontrols/.git' for writing: Is a directory
00:28:32.519164 git.c:415               trace: built-in: git submodule--helper relative-path qtquickcontrols/ 
00:28:32.519987 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.521262 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtquickcontrols/
00:28:32.521463 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.521472 run-command.c:1585      run_processes_parallel: done
00:28:32.522591 git.c:415               trace: built-in: git submodule--helper name qtquickcontrols2
00:28:32.523636 git.c:415               trace: built-in: git config submodule.qtquickcontrols2.update
00:28:32.524524 git.c:415               trace: built-in: git submodule--helper relative-path qtquickcontrols2 
00:28:32.525398 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.526081 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.527044 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.527925 git.c:415               trace: built-in: git config -f .git/modules/qtquickcontrols2/config core.worktree
00:28:32.528793 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtquickcontrols2 qtquickcontrols2
fatal: could not open 'qtquickcontrols2/.git' for writing: Is a directory
00:28:32.529877 git.c:415               trace: built-in: git submodule--helper relative-path qtquickcontrols2/ 
00:28:32.530626 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.531571 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtquickcontrols2/
00:28:32.532079 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.532090 run-command.c:1585      run_processes_parallel: done
00:28:32.533173 git.c:415               trace: built-in: git submodule--helper name qtremoteobjects
00:28:32.534263 git.c:415               trace: built-in: git config submodule.qtremoteobjects.update
00:28:32.535105 git.c:415               trace: built-in: git submodule--helper relative-path qtremoteobjects 
00:28:32.536033 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.536725 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.537674 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.538553 git.c:415               trace: built-in: git config -f .git/modules/qtremoteobjects/config core.worktree
00:28:32.539863 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtremoteobjects qtremoteobjects
00:28:32.541153 git.c:415               trace: built-in: git submodule--helper relative-path qtremoteobjects/ 
00:28:32.541930 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.543141 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtremoteobjects/
00:28:32.543315 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.543323 run-command.c:1585      run_processes_parallel: done
00:28:32.544545 git.c:415               trace: built-in: git submodule--helper name qtrepotools
00:28:32.545673 git.c:415               trace: built-in: git config submodule.qtrepotools.update
00:28:32.546525 git.c:415               trace: built-in: git submodule--helper relative-path qtrepotools 
00:28:32.547372 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.548026 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.548941 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.550163 git.c:415               trace: built-in: git config -f .git/modules/qtrepotools/config core.worktree
00:28:32.551057 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtrepotools qtrepotools
fatal: could not open 'qtrepotools/.git' for writing: Is a directory
00:28:32.552245 git.c:415               trace: built-in: git submodule--helper relative-path qtrepotools/ 
00:28:32.552994 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.553990 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtrepotools/
00:28:32.554068 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.554078 run-command.c:1585      run_processes_parallel: done
00:28:32.555115 git.c:415               trace: built-in: git submodule--helper name qtscript
00:28:32.556249 git.c:415               trace: built-in: git config submodule.qtscript.update
00:28:32.557242 git.c:415               trace: built-in: git submodule--helper relative-path qtscript 
00:28:32.558261 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.559396 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.560545 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.561380 git.c:415               trace: built-in: git config -f .git/modules/qtscript/config core.worktree
00:28:32.562155 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtscript qtscript
fatal: could not open 'qtscript/.git' for writing: Is a directory
00:28:32.563124 git.c:415               trace: built-in: git submodule--helper relative-path qtscript/ 
00:28:32.563927 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.564905 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtscript/
00:28:32.565221 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.565231 run-command.c:1585      run_processes_parallel: done
00:28:32.566411 git.c:415               trace: built-in: git submodule--helper name qtscxml
00:28:32.567548 git.c:415               trace: built-in: git config submodule.qtscxml.update
00:28:32.568436 git.c:415               trace: built-in: git submodule--helper relative-path qtscxml 
00:28:32.569265 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.569916 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.570831 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.571669 git.c:415               trace: built-in: git config -f .git/modules/qtscxml/config core.worktree
00:28:32.572460 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtscxml qtscxml
fatal: could not open 'qtscxml/.git' for writing: Is a directory
00:28:32.573413 git.c:415               trace: built-in: git submodule--helper relative-path qtscxml/ 
00:28:32.574148 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.575136 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtscxml/
00:28:32.575381 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.575389 run-command.c:1585      run_processes_parallel: done
00:28:32.576437 git.c:415               trace: built-in: git submodule--helper name qtsensors
00:28:32.577525 git.c:415               trace: built-in: git config submodule.qtsensors.update
00:28:32.578342 git.c:415               trace: built-in: git submodule--helper relative-path qtsensors 
00:28:32.579090 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.579769 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.580707 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.581594 git.c:415               trace: built-in: git config -f .git/modules/qtsensors/config core.worktree
00:28:32.582376 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtsensors qtsensors
fatal: could not open 'qtsensors/.git' for writing: Is a directory
00:28:32.583481 git.c:415               trace: built-in: git submodule--helper relative-path qtsensors/ 
00:28:32.584231 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.585326 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtsensors/
00:28:32.585508 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.585534 run-command.c:1585      run_processes_parallel: done
00:28:32.586897 git.c:415               trace: built-in: git submodule--helper name qtserialbus
00:28:32.588337 git.c:415               trace: built-in: git config submodule.qtserialbus.update
00:28:32.589209 git.c:415               trace: built-in: git submodule--helper relative-path qtserialbus 
00:28:32.590098 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.590756 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.591667 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.592607 git.c:415               trace: built-in: git config -f .git/modules/qtserialbus/config core.worktree
00:28:32.593610 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtserialbus qtserialbus
fatal: could not open 'qtserialbus/.git' for writing: Is a directory
00:28:32.594737 git.c:415               trace: built-in: git submodule--helper relative-path qtserialbus/ 
00:28:32.595530 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.596573 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtserialbus/
00:28:32.596704 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.596713 run-command.c:1585      run_processes_parallel: done
00:28:32.597783 git.c:415               trace: built-in: git submodule--helper name qtserialport
00:28:32.598892 git.c:415               trace: built-in: git config submodule.qtserialport.update
00:28:32.599733 git.c:415               trace: built-in: git submodule--helper relative-path qtserialport 
00:28:32.600596 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.601270 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.602151 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.603026 git.c:415               trace: built-in: git config -f .git/modules/qtserialport/config core.worktree
00:28:32.603836 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtserialport qtserialport
fatal: could not open 'qtserialport/.git' for writing: Is a directory
00:28:32.604865 git.c:415               trace: built-in: git submodule--helper relative-path qtserialport/ 
00:28:32.605611 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.606636 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtserialport/
00:28:32.606810 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.606839 run-command.c:1585      run_processes_parallel: done
00:28:32.608349 git.c:415               trace: built-in: git submodule--helper name qtspeech
00:28:32.609706 git.c:415               trace: built-in: git config submodule.qtspeech.update
00:28:32.610607 git.c:415               trace: built-in: git submodule--helper relative-path qtspeech 
00:28:32.611487 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.612204 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.613232 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.614108 git.c:415               trace: built-in: git config -f .git/modules/qtspeech/config core.worktree
00:28:32.614933 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtspeech qtspeech
fatal: could not open 'qtspeech/.git' for writing: Is a directory
00:28:32.616036 git.c:415               trace: built-in: git submodule--helper relative-path qtspeech/ 
00:28:32.616776 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.617739 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtspeech/
00:28:32.617837 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.617848 run-command.c:1585      run_processes_parallel: done
00:28:32.619008 git.c:415               trace: built-in: git submodule--helper name qtsvg
00:28:32.620270 git.c:415               trace: built-in: git config submodule.qtsvg.update
00:28:32.621128 git.c:415               trace: built-in: git submodule--helper relative-path qtsvg 
00:28:32.622013 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.622629 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.623561 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.624515 git.c:415               trace: built-in: git config -f .git/modules/qtsvg/config core.worktree
00:28:32.625298 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtsvg qtsvg
fatal: could not open 'qtsvg/.git' for writing: Is a directory
00:28:32.626287 git.c:415               trace: built-in: git submodule--helper relative-path qtsvg/ 
00:28:32.627145 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.628338 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtsvg/
00:28:32.628495 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.628506 run-command.c:1585      run_processes_parallel: done
00:28:32.629807 git.c:415               trace: built-in: git submodule--helper name qtsystems
00:28:32.631235 git.c:415               trace: built-in: git config submodule.qtsystems.update
00:28:32.632216 git.c:415               trace: built-in: git submodule--helper relative-path qtsystems 
00:28:32.633090 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.633793 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.634746 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.635733 git.c:415               trace: built-in: git config -f .git/modules/qtsystems/config core.worktree
00:28:32.636868 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtsystems qtsystems
00:28:32.638098 git.c:415               trace: built-in: git submodule--helper relative-path qtsystems/ 
00:28:32.638884 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.640013 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtsystems/
00:28:32.640214 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.640223 run-command.c:1585      run_processes_parallel: done
00:28:32.641300 git.c:415               trace: built-in: git submodule--helper name qttools
00:28:32.642395 git.c:415               trace: built-in: git config submodule.qttools.update
00:28:32.643236 git.c:415               trace: built-in: git submodule--helper relative-path qttools 
00:28:32.644077 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.644769 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.645713 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.646548 git.c:415               trace: built-in: git config -f .git/modules/qttools/config core.worktree
00:28:32.647334 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qttools qttools
fatal: could not open 'qttools/.git' for writing: Is a directory
00:28:32.648349 git.c:415               trace: built-in: git submodule--helper relative-path qttools/ 
00:28:32.649095 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.650073 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qttools/
00:28:32.650421 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.650430 run-command.c:1585      run_processes_parallel: done
00:28:32.651506 git.c:415               trace: built-in: git submodule--helper name qttranslations
00:28:32.652684 git.c:415               trace: built-in: git config submodule.qttranslations.update
00:28:32.653475 git.c:415               trace: built-in: git submodule--helper relative-path qttranslations 
00:28:32.654350 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.654959 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.656013 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.656890 git.c:415               trace: built-in: git config -f .git/modules/qttranslations/config core.worktree
00:28:32.657870 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qttranslations qttranslations
fatal: could not open 'qttranslations/.git' for writing: Is a directory
00:28:32.659252 git.c:415               trace: built-in: git submodule--helper relative-path qttranslations/ 
00:28:32.660213 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.661187 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qttranslations/
00:28:32.661332 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.661361 run-command.c:1585      run_processes_parallel: done
00:28:32.662521 git.c:415               trace: built-in: git submodule--helper name qtvirtualkeyboard
00:28:32.663699 git.c:415               trace: built-in: git config submodule.qtvirtualkeyboard.update
00:28:32.664602 git.c:415               trace: built-in: git submodule--helper relative-path qtvirtualkeyboard 
00:28:32.665572 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.666259 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.667181 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.668119 git.c:415               trace: built-in: git config -f .git/modules/qtvirtualkeyboard/config core.worktree
00:28:32.669040 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtvirtualkeyboard qtvirtualkeyboard
fatal: could not open 'qtvirtualkeyboard/.git' for writing: Is a directory
00:28:32.670111 git.c:415               trace: built-in: git submodule--helper relative-path qtvirtualkeyboard/ 
00:28:32.671037 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.672260 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtvirtualkeyboard/
00:28:32.672510 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.672522 run-command.c:1585      run_processes_parallel: done
00:28:32.673824 git.c:415               trace: built-in: git submodule--helper name qtwayland
00:28:32.675254 git.c:415               trace: built-in: git config submodule.qtwayland.update
00:28:32.676254 git.c:415               trace: built-in: git submodule--helper relative-path qtwayland 
00:28:32.677149 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.677815 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.678705 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.679515 git.c:415               trace: built-in: git config -f .git/modules/qtwayland/config core.worktree
00:28:32.680378 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtwayland qtwayland
fatal: could not open 'qtwayland/.git' for writing: Is a directory
00:28:32.681349 git.c:415               trace: built-in: git submodule--helper relative-path qtwayland/ 
00:28:32.682068 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.683020 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtwayland/
00:28:32.683211 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.683220 run-command.c:1585      run_processes_parallel: done
00:28:32.684288 git.c:415               trace: built-in: git submodule--helper name qtwebchannel
00:28:32.685365 git.c:415               trace: built-in: git config submodule.qtwebchannel.update
00:28:32.686197 git.c:415               trace: built-in: git submodule--helper relative-path qtwebchannel 
00:28:32.687250 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.688053 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.689027 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.689828 git.c:415               trace: built-in: git config -f .git/modules/qtwebchannel/config core.worktree
00:28:32.690649 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtwebchannel qtwebchannel
fatal: could not open 'qtwebchannel/.git' for writing: Is a directory
00:28:32.691673 git.c:415               trace: built-in: git submodule--helper relative-path qtwebchannel/ 
00:28:32.692395 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.693337 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtwebchannel/
00:28:32.693440 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.693450 run-command.c:1585      run_processes_parallel: done
00:28:32.694513 git.c:415               trace: built-in: git submodule--helper name qtwebengine
00:28:32.695558 git.c:415               trace: built-in: git config submodule.qtwebengine.update
00:28:32.696394 git.c:415               trace: built-in: git submodule--helper relative-path qtwebengine 
00:28:32.697128 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.697813 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.698713 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.699550 git.c:415               trace: built-in: git config -f .git/modules/qtwebengine/config core.worktree
00:28:32.700365 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtwebengine qtwebengine
fatal: could not open 'qtwebengine/.git' for writing: Is a directory
00:28:32.701368 git.c:415               trace: built-in: git submodule--helper relative-path qtwebengine/ 
00:28:32.702128 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.703122 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtwebengine/
00:28:32.703383 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.703414 run-command.c:1585      run_processes_parallel: done
00:28:32.704307 git.c:415               trace: built-in: git submodule--helper name src/3rdparty
00:28:32.705228 git.c:415               trace: built-in: git config submodule.src/3rdparty.update
00:28:32.706067 git.c:415               trace: built-in: git submodule--helper relative-path qtwebengine/src/3rdparty 
00:28:32.707040 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.707919 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.709130 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.709996 git.c:415               trace: built-in: git config -f .git/modules/src/3rdparty/config core.worktree
00:28:32.710800 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree src/3rdparty src/3rdparty
fatal: could not open 'src/3rdparty/.git' for writing: Is a directory
00:28:32.711881 git.c:415               trace: built-in: git submodule--helper relative-path qtwebengine/src/3rdparty/ 
00:28:32.712760 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.713700 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtwebengine/src/3rdparty/
00:28:32.725343 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.725361 run-command.c:1585      run_processes_parallel: done
00:28:32.727259 git.c:415               trace: built-in: git submodule--helper name qtwebglplugin
00:28:32.728403 git.c:415               trace: built-in: git config submodule.qtwebglplugin.update
00:28:32.729247 git.c:415               trace: built-in: git submodule--helper relative-path qtwebglplugin 
00:28:32.730030 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.730647 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.731663 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.732627 git.c:415               trace: built-in: git config -f .git/modules/qtwebglplugin/config core.worktree
00:28:32.733597 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtwebglplugin qtwebglplugin
00:28:32.734749 git.c:415               trace: built-in: git submodule--helper relative-path qtwebglplugin/ 
00:28:32.735528 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.736522 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtwebglplugin/
00:28:32.736647 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.736675 run-command.c:1585      run_processes_parallel: done
00:28:32.737777 git.c:415               trace: built-in: git submodule--helper name qtwebsockets
00:28:32.738846 git.c:415               trace: built-in: git config submodule.qtwebsockets.update
00:28:32.739635 git.c:415               trace: built-in: git submodule--helper relative-path qtwebsockets 
00:28:32.740495 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.741177 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.742182 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.742995 git.c:415               trace: built-in: git config -f .git/modules/qtwebsockets/config core.worktree
00:28:32.743886 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtwebsockets qtwebsockets
fatal: could not open 'qtwebsockets/.git' for writing: Is a directory
00:28:32.744957 git.c:415               trace: built-in: git submodule--helper relative-path qtwebsockets/ 
00:28:32.745717 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.746692 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtwebsockets/
00:28:32.746840 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.746866 run-command.c:1585      run_processes_parallel: done
00:28:32.748007 git.c:415               trace: built-in: git submodule--helper name qtwebview
00:28:32.749097 git.c:415               trace: built-in: git config submodule.qtwebview.update
00:28:32.749954 git.c:415               trace: built-in: git submodule--helper relative-path qtwebview 
00:28:32.750826 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.751483 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.752413 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.753361 git.c:415               trace: built-in: git config -f .git/modules/qtwebview/config core.worktree
00:28:32.754127 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtwebview qtwebview
fatal: could not open 'qtwebview/.git' for writing: Is a directory
00:28:32.755139 git.c:415               trace: built-in: git submodule--helper relative-path qtwebview/ 
00:28:32.755984 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.757138 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtwebview/
00:28:32.757282 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.757296 run-command.c:1585      run_processes_parallel: done
00:28:32.758804 git.c:415               trace: built-in: git submodule--helper name qtwinextras
00:28:32.760424 git.c:415               trace: built-in: git config submodule.qtwinextras.update
00:28:32.761271 git.c:415               trace: built-in: git submodule--helper relative-path qtwinextras 
00:28:32.762207 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.762894 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.763791 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.764976 git.c:415               trace: built-in: git config -f .git/modules/qtwinextras/config core.worktree
00:28:32.765725 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtwinextras qtwinextras
fatal: could not open 'qtwinextras/.git' for writing: Is a directory
00:28:32.766885 git.c:415               trace: built-in: git submodule--helper relative-path qtwinextras/ 
00:28:32.767774 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.768941 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtwinextras/
00:28:32.769102 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.769131 run-command.c:1585      run_processes_parallel: done
00:28:32.770438 git.c:415               trace: built-in: git submodule--helper name qtx11extras
00:28:32.771952 git.c:415               trace: built-in: git config submodule.qtx11extras.update
00:28:32.772819 git.c:415               trace: built-in: git submodule--helper relative-path qtx11extras 
00:28:32.773589 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.774251 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.775162 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.776071 git.c:415               trace: built-in: git config -f .git/modules/qtx11extras/config core.worktree
00:28:32.776842 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtx11extras qtx11extras
fatal: could not open 'qtx11extras/.git' for writing: Is a directory
00:28:32.777843 git.c:415               trace: built-in: git submodule--helper relative-path qtx11extras/ 
00:28:32.778635 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.779692 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtx11extras/
00:28:32.779869 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.779879 run-command.c:1585      run_processes_parallel: done
00:28:32.780894 git.c:415               trace: built-in: git submodule--helper name qtxmlpatterns
00:28:32.781947 git.c:415               trace: built-in: git config submodule.qtxmlpatterns.update
00:28:32.782800 git.c:415               trace: built-in: git submodule--helper relative-path qtxmlpatterns
00:28:32.784034 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.784739 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.785617 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.786458 git.c:415               trace: built-in: git config -f .git/modules/qtxmlpatterns/config core.worktree
00:28:32.787263 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree qtxmlpatterns qtxmlpatterns
fatal: could not open 'qtxmlpatterns/.git' for writing: Is a directory
00:28:32.788317 git.c:415               trace: built-in: git submodule--helper relative-path qtxmlpatterns/
00:28:32.789011 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.789985 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtxmlpatterns/
00:28:32.790227 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.790256 run-command.c:1585      run_processes_parallel: done
00:28:32.791071 git.c:415               trace: built-in: git submodule--helper name tests/auto/3rdparty/testsuites
00:28:32.792081 git.c:415               trace: built-in: git config submodule.testsuites.update
00:28:32.792875 git.c:415               trace: built-in: git submodule--helper relative-path qtxmlpatterns/tests/auto/3rdparty/testsuites
00:28:32.793713 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.794363 git.c:415               trace: built-in: git rev-parse --verify HEAD
00:28:32.795249 git.c:415               trace: built-in: git rev-parse --git-common-dir
00:28:32.796074 git.c:415               trace: built-in: git config -f .git/modules/testsuites/config core.worktree
00:28:32.796861 git.c:415               trace: built-in: git submodule--helper connect-gitdir-workingtree testsuites tests/auto/3rdparty/testsuites
fatal: could not open 'tests/auto/3rdparty/testsuites/.git' for writing: Is a directory
00:28:32.798041 git.c:415               trace: built-in: git submodule--helper relative-path qtxmlpatterns/tests/auto/3rdparty/testsuites/
00:28:32.798785 git.c:415               trace: built-in: git rev-parse --local-env-vars
00:28:32.799766 git.c:415               trace: built-in: git submodule--helper update-clone --recursive-prefix qtxmlpatterns/tests/auto/3rdparty/testsuites/
00:28:32.805569 run-command.c:1553      run_processes_parallel: preparing to run up to 1 tasks
00:28:32.805586 run-command.c:1585      run_processes_parallel: done

^ permalink raw reply	[relevance 4%]

* Re: Old submodules broken in 2.19rc1 and 2.19rc2
  2018-09-07 22:35   ` Jonathan Nieder
@ 2018-09-07 22:45     ` Stefan Beller
  2018-09-08  0:09       ` [PATCH] Revert "Merge branch 'sb/submodule-core-worktree'" (was Re: Old submodules broken in 2.19rc1 and 2.19rc2) Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-07 22:45 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: allan.jensen, git

 I think we
> should revert e98317508c0 in "master" (for 2.19) and keep making use
> of that 'second try' in "next" (for 2.20).

Actually I'd rather revert the whole topic leading up to
7e25437d35a (Merge branch 'sb/submodule-core-worktree', 2018-07-18)
as the last patch in there doesn't work well without e98317508c0 IIRC.

And having only the first patch would bring an inconsistent state as
then different commands behave differently w.r.t. setting core.worktree.

So for this release we'd

  git revert 984cd77ddbf0 e98317508c 4fa4f90ccd85

and then can

  git cherry-pick 4fa4f90ccd8 984cd77ddbf0

on top of sb/submodule-update-in-c, as that re-instates the behavior
going forward.

Thoughts?

Thanks,
Stefan

^ permalink raw reply	[relevance 8%]

* [PATCH] Revert "Merge branch 'sb/submodule-core-worktree'" (was Re: Old submodules broken in 2.19rc1 and 2.19rc2)
  2018-09-07 22:45     ` Stefan Beller
@ 2018-09-08  0:09       ` Jonathan Nieder
  2018-09-08  2:04         ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-09-08  0:09 UTC (permalink / raw)
  To: Stefan Beller; +Cc: allan.jensen, git, Junio C Hamano

Subject: Revert "Merge branch 'sb/submodule-core-worktree'"

This reverts commit 7e25437d35a70791b345872af202eabfb3e1a8bc, reversing
changes made to 00624d608cc69bd62801c93e74d1ea7a7ddd6598.

v2.19.0-rc0~165^2~1 (submodule: ensure core.worktree is set after
update, 2018-06-18) assumes an "absorbed" submodule layout, where the
submodule's Git directory is in the superproject's .git/modules/
directory and .git in the submodule worktree is a .git file pointing
there.  In particular, it uses $GIT_DIR/modules/$name to find the
submodule to find out whether it already has core.worktree set, and it
uses connect_work_tree_and_git_dir if not, resulting in

	fatal: could not open sub/.git for writing

The context behind that patch: v2.19.0-rc0~165^2~2 (submodule: unset
core.worktree if no working tree is present, 2018-06-12) unsets
core.worktree when running commands like "git checkout
--recurse-submodules" to switch to a branch without the submodule.  If
a user then uses "git checkout --no-recurse-submodules" to switch back
to a branch with the submodule and runs "git submodule update", this
patch is needed to ensure that commands using the submodule directly
are aware of the path to the worktree.

It is late in the release cycle, so revert the whole 3-patch series.
We can try again later for 2.20.

Reported-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Helped-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Stefan Beller wrote:
> Jonathan Nieder wrote:

>> I think we
>> should revert e98317508c0 in "master" (for 2.19) and keep making use
>> of that 'second try' in "next" (for 2.20).
>
> Actually I'd rather revert the whole topic leading up to
> 7e25437d35a (Merge branch 'sb/submodule-core-worktree', 2018-07-18)
> as the last patch in there doesn't work well without e98317508c0 IIRC.
>
> And having only the first patch would bring an inconsistent state as
> then different commands behave differently w.r.t. setting core.worktree.

Like this (generated using "git revert -m1)?

 builtin/submodule--helper.c | 26 --------------------------
 git-submodule.sh            |  5 -----
 submodule.c                 | 14 --------------
 submodule.h                 |  2 --
 t/lib-submodule-update.sh   |  5 ++---
 t/t7400-submodule-basic.sh  |  5 -----
 6 files changed, 2 insertions(+), 55 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b56028ba9d..f6fb8991f3 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1123,8 +1123,6 @@ static void deinit_submodule(const char *path, const char *prefix,
 		if (!(flags & OPT_QUIET))
 			printf(format, displaypath);
 
-		submodule_unset_core_worktree(sub);
-
 		strbuf_release(&sb_rm);
 	}
 
@@ -2005,29 +2003,6 @@ static int check_name(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
-static int connect_gitdir_workingtree(int argc, const char **argv, const char *prefix)
-{
-	struct strbuf sb = STRBUF_INIT;
-	const char *name, *path;
-	char *sm_gitdir;
-
-	if (argc != 3)
-		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
-
-	name = argv[1];
-	path = argv[2];
-
-	strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
-	sm_gitdir = absolute_pathdup(sb.buf);
-
-	connect_work_tree_and_git_dir(path, sm_gitdir, 0);
-
-	strbuf_release(&sb);
-	free(sm_gitdir);
-
-	return 0;
-}
-
 #define SUPPORT_SUPER_PREFIX (1<<0)
 
 struct cmd_struct {
@@ -2041,7 +2016,6 @@ static struct cmd_struct commands[] = {
 	{"name", module_name, 0},
 	{"clone", module_clone, 0},
 	{"update-clone", update_clone, 0},
-	{"connect-gitdir-workingtree", connect_gitdir_workingtree, 0},
 	{"relative-path", resolve_relative_path, 0},
 	{"resolve-relative-url", resolve_relative_url, 0},
 	{"resolve-relative-url-test", resolve_relative_url_test, 0},
diff --git a/git-submodule.sh b/git-submodule.sh
index f7fd80345c..1cb2c0a31b 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -580,11 +580,6 @@ cmd_update()
 			die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
 		fi
 
-		if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
-		then
-			git submodule--helper connect-gitdir-workingtree "$name" "$sm_path"
-		fi
-
 		if test "$subsha1" != "$sha1" || test -n "$force"
 		then
 			subforce=$force
diff --git a/submodule.c b/submodule.c
index 50cbf5f13e..a2b266fbfa 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1534,18 +1534,6 @@ int bad_to_remove_submodule(const char *path, unsigned flags)
 	return ret;
 }
 
-void submodule_unset_core_worktree(const struct submodule *sub)
-{
-	char *config_path = xstrfmt("%s/modules/%s/config",
-				    get_git_common_dir(), sub->name);
-
-	if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
-		warning(_("Could not unset core.worktree setting in submodule '%s'"),
-			  sub->path);
-
-	free(config_path);
-}
-
 static const char *get_super_prefix_or_empty(void)
 {
 	const char *s = get_super_prefix();
@@ -1711,8 +1699,6 @@ int submodule_move_head(const char *path,
 
 			if (is_empty_dir(path))
 				rmdir_or_warn(path);
-
-			submodule_unset_core_worktree(sub);
 		}
 	}
 out:
diff --git a/submodule.h b/submodule.h
index 7d476cefa7..e452919aa4 100644
--- a/submodule.h
+++ b/submodule.h
@@ -127,8 +127,6 @@ int submodule_move_head(const char *path,
 			const char *new_head,
 			unsigned flags);
 
-void submodule_unset_core_worktree(const struct submodule *sub);
-
 /*
  * Prepare the "env_array" parameter of a "struct child_process" for executing
  * a submodule by clearing any repo-specific environment variables, but
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 5b56b23166..016391723c 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -235,7 +235,7 @@ reset_work_tree_to_interested () {
 	then
 		mkdir -p submodule_update/.git/modules/sub1/modules &&
 		cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2
-		# core.worktree is unset for sub2 as it is not checked out
+		GIT_WORK_TREE=. git -C submodule_update/.git/modules/sub1/modules/sub2 config --unset core.worktree
 	fi &&
 	# indicate we are interested in the submodule:
 	git -C submodule_update config submodule.sub1.url "bogus" &&
@@ -709,8 +709,7 @@ test_submodule_recursing_with_args_common() {
 			git branch -t remove_sub1 origin/remove_sub1 &&
 			$command remove_sub1 &&
 			test_superproject_content origin/remove_sub1 &&
-			! test -e sub1 &&
-			test_must_fail git config -f .git/modules/sub1/config core.worktree
+			! test -e sub1
 		)
 	'
 	# ... absorbing a .git directory along the way.
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 7d3d984210..c0ffc1022a 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -984,11 +984,6 @@ test_expect_success 'submodule deinit should remove the whole submodule section
 	rmdir init
 '
 
-test_expect_success 'submodule deinit should unset core.worktree' '
-	test_path_is_file .git/modules/example/config &&
-	test_must_fail git config -f .git/modules/example/config core.worktree
-'
-
 test_expect_success 'submodule deinit from subdirectory' '
 	git submodule update --init &&
 	git config submodule.example.foo bar &&
-- 
2.19.0.rc2.392.g5ba43deb5a


^ permalink raw reply	[relevance 24%]

* Re: [PATCH] Revert "Merge branch 'sb/submodule-core-worktree'" (was Re: Old submodules broken in 2.19rc1 and 2.19rc2)
  2018-09-08  0:09       ` [PATCH] Revert "Merge branch 'sb/submodule-core-worktree'" (was Re: Old submodules broken in 2.19rc1 and 2.19rc2) Jonathan Nieder
@ 2018-09-08  2:04         ` Junio C Hamano
  2018-09-08 18:39           ` Johannes Sixt
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-09-08  2:04 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Stefan Beller, allan.jensen, git

Jonathan Nieder <jrnieder@gmail.com> writes:

> It is late in the release cycle, so revert the whole 3-patch series.
> We can try again later for 2.20.
>
> Reported-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
> Helped-by: Stefan Beller <sbeller@google.com>
> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
> ---
> Stefan Beller wrote:
>> Jonathan Nieder wrote:
>
>>> I think we
>>> should revert e98317508c0 in "master" (for 2.19) and keep making use
>>> of that 'second try' in "next" (for 2.20).
>>
>> Actually I'd rather revert the whole topic leading up to
>> 7e25437d35a (Merge branch 'sb/submodule-core-worktree', 2018-07-18)
>> as the last patch in there doesn't work well without e98317508c0 IIRC.
>>
>> And having only the first patch would bring an inconsistent state as
>> then different commands behave differently w.r.t. setting core.worktree.
>
> Like this (generated using "git revert -m1)?

OK.  Thanks for taking care of it.

>
>  builtin/submodule--helper.c | 26 --------------------------
>  git-submodule.sh            |  5 -----
>  submodule.c                 | 14 --------------
>  submodule.h                 |  2 --
>  t/lib-submodule-update.sh   |  5 ++---
>  t/t7400-submodule-basic.sh  |  5 -----
>  6 files changed, 2 insertions(+), 55 deletions(-)
>
> diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
> index b56028ba9d..f6fb8991f3 100644
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -1123,8 +1123,6 @@ static void deinit_submodule(const char *path, const char *prefix,
>  		if (!(flags & OPT_QUIET))
>  			printf(format, displaypath);
>  
> -		submodule_unset_core_worktree(sub);
> -
>  		strbuf_release(&sb_rm);
>  	}
>  
> @@ -2005,29 +2003,6 @@ static int check_name(int argc, const char **argv, const char *prefix)
>  	return 0;
>  }
>  
> -static int connect_gitdir_workingtree(int argc, const char **argv, const char *prefix)
> -{
> -	struct strbuf sb = STRBUF_INIT;
> -	const char *name, *path;
> -	char *sm_gitdir;
> -
> -	if (argc != 3)
> -		BUG("submodule--helper connect-gitdir-workingtree <name> <path>");
> -
> -	name = argv[1];
> -	path = argv[2];
> -
> -	strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
> -	sm_gitdir = absolute_pathdup(sb.buf);
> -
> -	connect_work_tree_and_git_dir(path, sm_gitdir, 0);
> -
> -	strbuf_release(&sb);
> -	free(sm_gitdir);
> -
> -	return 0;
> -}
> -
>  #define SUPPORT_SUPER_PREFIX (1<<0)
>  
>  struct cmd_struct {
> @@ -2041,7 +2016,6 @@ static struct cmd_struct commands[] = {
>  	{"name", module_name, 0},
>  	{"clone", module_clone, 0},
>  	{"update-clone", update_clone, 0},
> -	{"connect-gitdir-workingtree", connect_gitdir_workingtree, 0},
>  	{"relative-path", resolve_relative_path, 0},
>  	{"resolve-relative-url", resolve_relative_url, 0},
>  	{"resolve-relative-url-test", resolve_relative_url_test, 0},
> diff --git a/git-submodule.sh b/git-submodule.sh
> index f7fd80345c..1cb2c0a31b 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -580,11 +580,6 @@ cmd_update()
>  			die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
>  		fi
>  
> -		if ! $(git config -f "$(git rev-parse --git-common-dir)/modules/$name/config" core.worktree) 2>/dev/null
> -		then
> -			git submodule--helper connect-gitdir-workingtree "$name" "$sm_path"
> -		fi
> -
>  		if test "$subsha1" != "$sha1" || test -n "$force"
>  		then
>  			subforce=$force
> diff --git a/submodule.c b/submodule.c
> index 50cbf5f13e..a2b266fbfa 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1534,18 +1534,6 @@ int bad_to_remove_submodule(const char *path, unsigned flags)
>  	return ret;
>  }
>  
> -void submodule_unset_core_worktree(const struct submodule *sub)
> -{
> -	char *config_path = xstrfmt("%s/modules/%s/config",
> -				    get_git_common_dir(), sub->name);
> -
> -	if (git_config_set_in_file_gently(config_path, "core.worktree", NULL))
> -		warning(_("Could not unset core.worktree setting in submodule '%s'"),
> -			  sub->path);
> -
> -	free(config_path);
> -}
> -
>  static const char *get_super_prefix_or_empty(void)
>  {
>  	const char *s = get_super_prefix();
> @@ -1711,8 +1699,6 @@ int submodule_move_head(const char *path,
>  
>  			if (is_empty_dir(path))
>  				rmdir_or_warn(path);
> -
> -			submodule_unset_core_worktree(sub);
>  		}
>  	}
>  out:
> diff --git a/submodule.h b/submodule.h
> index 7d476cefa7..e452919aa4 100644
> --- a/submodule.h
> +++ b/submodule.h
> @@ -127,8 +127,6 @@ int submodule_move_head(const char *path,
>  			const char *new_head,
>  			unsigned flags);
>  
> -void submodule_unset_core_worktree(const struct submodule *sub);
> -
>  /*
>   * Prepare the "env_array" parameter of a "struct child_process" for executing
>   * a submodule by clearing any repo-specific environment variables, but
> diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
> index 5b56b23166..016391723c 100755
> --- a/t/lib-submodule-update.sh
> +++ b/t/lib-submodule-update.sh
> @@ -235,7 +235,7 @@ reset_work_tree_to_interested () {
>  	then
>  		mkdir -p submodule_update/.git/modules/sub1/modules &&
>  		cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2
> -		# core.worktree is unset for sub2 as it is not checked out
> +		GIT_WORK_TREE=. git -C submodule_update/.git/modules/sub1/modules/sub2 config --unset core.worktree
>  	fi &&
>  	# indicate we are interested in the submodule:
>  	git -C submodule_update config submodule.sub1.url "bogus" &&
> @@ -709,8 +709,7 @@ test_submodule_recursing_with_args_common() {
>  			git branch -t remove_sub1 origin/remove_sub1 &&
>  			$command remove_sub1 &&
>  			test_superproject_content origin/remove_sub1 &&
> -			! test -e sub1 &&
> -			test_must_fail git config -f .git/modules/sub1/config core.worktree
> +			! test -e sub1
>  		)
>  	'
>  	# ... absorbing a .git directory along the way.
> diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
> index 7d3d984210..c0ffc1022a 100755
> --- a/t/t7400-submodule-basic.sh
> +++ b/t/t7400-submodule-basic.sh
> @@ -984,11 +984,6 @@ test_expect_success 'submodule deinit should remove the whole submodule section
>  	rmdir init
>  '
>  
> -test_expect_success 'submodule deinit should unset core.worktree' '
> -	test_path_is_file .git/modules/example/config &&
> -	test_must_fail git config -f .git/modules/example/config core.worktree
> -'
> -
>  test_expect_success 'submodule deinit from subdirectory' '
>  	git submodule update --init &&
>  	git config submodule.example.foo bar &&

^ permalink raw reply	[relevance 3%]

* Re: [PATCH] Revert "Merge branch 'sb/submodule-core-worktree'" (was Re: Old submodules broken in 2.19rc1 and 2.19rc2)
  2018-09-08  2:04         ` Junio C Hamano
@ 2018-09-08 18:39           ` Johannes Sixt
  2018-09-10 17:11             ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Johannes Sixt @ 2018-09-08 18:39 UTC (permalink / raw)
  To: Junio C Hamano, Jonathan Nieder; +Cc: Stefan Beller, allan.jensen, git

Am 08.09.2018 um 04:04 schrieb Junio C Hamano:
> Jonathan Nieder <jrnieder@gmail.com> writes:
> 
>> It is late in the release cycle, so revert the whole 3-patch series.
>> We can try again later for 2.20.
>>
>> Reported-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
>> Helped-by: Stefan Beller <sbeller@google.com>
>> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
>> ---
>> Stefan Beller wrote:
>>> Jonathan Nieder wrote:
>>
>>>> I think we
>>>> should revert e98317508c0 in "master" (for 2.19) and keep making use
>>>> of that 'second try' in "next" (for 2.20).
>>>
>>> Actually I'd rather revert the whole topic leading up to
>>> 7e25437d35a (Merge branch 'sb/submodule-core-worktree', 2018-07-18)
>>> as the last patch in there doesn't work well without e98317508c0 IIRC.
>>>
>>> And having only the first patch would bring an inconsistent state as
>>> then different commands behave differently w.r.t. setting core.worktree.
>>
>> Like this (generated using "git revert -m1)?
> 
> OK.  Thanks for taking care of it.

Please don't forget to remove the corresponding release notes entry.

diff --git a/Documentation/RelNotes/2.19.0.txt b/Documentation/RelNotes/2.19.0.txt
index bcbfbc2041..834454ffb9 100644
--- a/Documentation/RelNotes/2.19.0.txt
+++ b/Documentation/RelNotes/2.19.0.txt
@@ -296,12 +296,6 @@ Fixes since v2.18
    to the submodule was changed in the range of commits in the
    superproject, sometimes showing "(null)".  This has been corrected.
 
- * "git submodule" did not correctly adjust core.worktree setting that
-   indicates whether/where a submodule repository has its associated
-   working tree across various state transitions, which has been
-   corrected.
-   (merge 984cd77ddb sb/submodule-core-worktree later to maint).
-
  * Bugfix for "rebase -i" corner case regression.
    (merge a9279c6785 pw/rebase-i-keep-reword-after-conflict later to maint).
 

^ permalink raw reply	[relevance 11%]

* Re: [PATCH] git-mv: allow submodules and fsmonitor to work together
  2018-09-06 20:34             ` [PATCH] git-mv: allow submodules and fsmonitor to work together Stefan Beller
@ 2018-09-10 15:58               ` Ben Peart
  2018-09-10 16:29                 ` [PATCH v1] " Ben Peart
  0 siblings, 1 reply; 200+ results
From: Ben Peart @ 2018-09-10 15:58 UTC (permalink / raw)
  To: Stefan Beller, git; +Cc: Ben.Peart, avarab, gitster



On 9/6/2018 4:34 PM, Stefan Beller wrote:
> It was reported that
> 
>    GIT_FSMONITOR_TEST=$PWD/t7519/fsmonitor-all ./t7411-submodule-config.sh
> 
> breaks as the .gitmodules file is modified and staged after the fsmonitor
> considers it clean. Mark the .gitmodules file to be not clean before
> staging.
> 
> Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> Inspired-by: Ben Peart <benpeart@microsoft.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
> 
> I am not quite sure if this is the correct approach and handling of the
> fsmonitor API, but it unbreaks the test.
> 
>> Just naively adding mark_fsmonitor_invalid doesn't work, as then ...
> 
> Adding it before the staging, works.
> 
> Please double check!

I took a look at this bug/patch and wondered why add_file_to_index() 
wasn't properly handling the .gitmodules file.  On investigation, I 
chased it down to what looks like a faulty test in 
is_staging_gitmodules_ok().

I believe the following is a better patch for this bug:

diff --git a/submodule.c b/submodule.c
index 50cbf5f13e..1e7194af28 100644
--- a/submodule.c
+++ b/submodule.c
@@ -65,8 +65,7 @@ int is_staging_gitmodules_ok(struct index_state *istate)
         if ((pos >= 0) && (pos < istate->cache_nr)) {
                 struct stat st;
                 if (lstat(GITMODULES_FILE, &st) == 0 &&
-                   ie_match_stat(istate, istate->cache[pos], &st,
-                                 CE_MATCH_IGNORE_FSMONITOR) & DATA_CHANGED)
+                   ie_match_stat(istate, istate->cache[pos], &st, 0) & 
DATA_CHANGED)
                         return 0;
         }

Please double check but I just don't understand why the .gitmodules file 
should force the fsmonitor data to be ignored.  This flag was added to 
enable proper behavior in the preload_thread() logic and I don't believe 
it is appropriate here.

Ben

> 
> Thanks,
> Stefan
> 
>   submodule.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/submodule.c b/submodule.c
> index 50cbf5f13ed..56b0d5fe24e 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -22,6 +22,7 @@
>   #include "worktree.h"
>   #include "parse-options.h"
>   #include "object-store.h"
> +#include "fsmonitor.h"
>   
>   static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
>   static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
> @@ -149,6 +150,15 @@ int remove_path_from_gitmodules(const char *path)
>   
>   void stage_updated_gitmodules(struct index_state *istate)
>   {
> +	struct cache_entry *ce;
> +	int pos;
> +
> +	pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));
> +	ce = (0 <= pos) ? istate->cache[pos] : NULL;
> +
> +	if (ce)
> +		mark_fsmonitor_invalid(istate, ce);
> +
>   	if (add_file_to_index(istate, GITMODULES_FILE, 0))
>   		die(_("staging updated .gitmodules failed"));
>   }
> 

^ permalink raw reply	[relevance 8%]

* [PATCH v1] git-mv: allow submodules and fsmonitor to work together
  2018-09-10 15:58               ` Ben Peart
@ 2018-09-10 16:29                 ` " Ben Peart
  2018-09-10 17:07                   ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Ben Peart @ 2018-09-10 16:29 UTC (permalink / raw)
  To: peartben; +Cc: Ben Peart, avarab, git, gitster, sbeller, Ben Peart

It was reported that

   GIT_FSMONITOR_TEST=$PWD/t7519/fsmonitor-all ./t7411-submodule-config.sh

breaks as the fsmonitor data is out of sync with the state of the .gitmodules
file. Update is_staging_gitmodules_ok() so that it no longer tells
ie_match_stat() to ignore refreshing the fsmonitor data.

Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Ben Peart <benpeart@microsoft.com>
---

Notes:
    Base Ref: v2.19.0-rc2
    Web-Diff: https://github.com/benpeart/git/commit/ed30e1a885
    Checkout: git fetch https://github.com/benpeart/git fsmonitor-t7411-v1 && git checkout ed30e1a885

 submodule.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/submodule.c b/submodule.c
index 50cbf5f13e..1e7194af28 100644
--- a/submodule.c
+++ b/submodule.c
@@ -65,8 +65,7 @@ int is_staging_gitmodules_ok(struct index_state *istate)
 	if ((pos >= 0) && (pos < istate->cache_nr)) {
 		struct stat st;
 		if (lstat(GITMODULES_FILE, &st) == 0 &&
-		    ie_match_stat(istate, istate->cache[pos], &st,
-				  CE_MATCH_IGNORE_FSMONITOR) & DATA_CHANGED)
+		    ie_match_stat(istate, istate->cache[pos], &st, 0) & DATA_CHANGED)
 			return 0;
 	}
 

base-commit: c05048d43925ab8edcb36663752c2b4541911231
-- 
2.18.0.windows.1


^ permalink raw reply	[relevance 11%]

* Re: [PATCH v1] git-mv: allow submodules and fsmonitor to work together
  2018-09-10 16:29                 ` [PATCH v1] " Ben Peart
@ 2018-09-10 17:07                   ` Stefan Beller
  2018-09-10 19:38                     ` Ben Peart
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-10 17:07 UTC (permalink / raw)
  To: Ben Peart
  Cc: Ben Peart, Ben Peart, Ævar Arnfjörð Bjarmason,
	git, Junio C Hamano

On Mon, Sep 10, 2018 at 9:29 AM Ben Peart <benpeart@microsoft.com> wrote:
>
> It was reported that
>
>    GIT_FSMONITOR_TEST=$PWD/t7519/fsmonitor-all ./t7411-submodule-config.sh
>
> breaks as the fsmonitor data is out of sync with the state of the .gitmodules
> file. Update is_staging_gitmodules_ok() so that it no longer tells
> ie_match_stat() to ignore refreshing the fsmonitor data.

Wondering how this came to be,
7da9aba4178 (submodule: used correct index in is_staging_gitmodules_ok,
2017-12-12) last touched this line, but is unrelated as the fsmonitor
behavior was
there before.

Before that, we have 883e248b8a0 (fsmonitor: teach git to optionally utilize a
file system monitor to speed up detecting new or changed files., 2017-09-22)
that was written by you, who knows the fsmonitor better than I do (or Brandon
who wrote the commit referenced above).

Looking through the archive, it seems that we might have more such hidden
gems?

https://public-inbox.org/git/f50825a4-fa15-9f28-a079-853e78ee8e2e@gmail.com/

Anyway, I think this is a better fix than what I proposed for sure.

Thanks for looking into this!

Stefan

>
> Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> Helped-by: Stefan Beller <sbeller@google.com>
> Signed-off-by: Ben Peart <benpeart@microsoft.com>
> ---
>
> Notes:
>     Base Ref: v2.19.0-rc2
>     Web-Diff: https://github.com/benpeart/git/commit/ed30e1a885
>     Checkout: git fetch https://github.com/benpeart/git fsmonitor-t7411-v1 && git checkout ed30e1a885
>
>  submodule.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/submodule.c b/submodule.c
> index 50cbf5f13e..1e7194af28 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -65,8 +65,7 @@ int is_staging_gitmodules_ok(struct index_state *istate)
>         if ((pos >= 0) && (pos < istate->cache_nr)) {
>                 struct stat st;
>                 if (lstat(GITMODULES_FILE, &st) == 0 &&
> -                   ie_match_stat(istate, istate->cache[pos], &st,
> -                                 CE_MATCH_IGNORE_FSMONITOR) & DATA_CHANGED)
> +                   ie_match_stat(istate, istate->cache[pos], &st, 0) & DATA_CHANGED)
>                         return 0;
>         }
>
>
> base-commit: c05048d43925ab8edcb36663752c2b4541911231
> --
> 2.18.0.windows.1
>

^ permalink raw reply	[relevance 7%]

* Re: [PATCH] Revert "Merge branch 'sb/submodule-core-worktree'" (was Re: Old submodules broken in 2.19rc1 and 2.19rc2)
  2018-09-08 18:39           ` Johannes Sixt
@ 2018-09-10 17:11             ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-10 17:11 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Junio C Hamano, Jonathan Nieder, allan.jensen, git

> >> Like this (generated using "git revert -m1)?
> >
> > OK.  Thanks for taking care of it.

Yes that looks good to me, thanks!

>
> Please don't forget to remove the corresponding release notes entry.

Makes sense, too.

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH v1] git-mv: allow submodules and fsmonitor to work together
  2018-09-10 17:07                   ` Stefan Beller
@ 2018-09-10 19:38                     ` Ben Peart
  0 siblings, 0 replies; 200+ results
From: Ben Peart @ 2018-09-10 19:38 UTC (permalink / raw)
  To: Stefan Beller, Ben Peart
  Cc: Ben Peart, Ævar Arnfjörð Bjarmason, git, Junio C Hamano



On 9/10/2018 1:07 PM, Stefan Beller wrote:
> On Mon, Sep 10, 2018 at 9:29 AM Ben Peart <benpeart@microsoft.com> wrote:
>>
>> It was reported that
>>
>>     GIT_FSMONITOR_TEST=$PWD/t7519/fsmonitor-all ./t7411-submodule-config.sh
>>
>> breaks as the fsmonitor data is out of sync with the state of the .gitmodules
>> file. Update is_staging_gitmodules_ok() so that it no longer tells
>> ie_match_stat() to ignore refreshing the fsmonitor data.
> 
> Wondering how this came to be,
> 7da9aba4178 (submodule: used correct index in is_staging_gitmodules_ok,
> 2017-12-12) last touched this line, but is unrelated as the fsmonitor
> behavior was
> there before.
> 
> Before that, we have 883e248b8a0 (fsmonitor: teach git to optionally utilize a
> file system monitor to speed up detecting new or changed files., 2017-09-22)
> that was written by you, who knows the fsmonitor better than I do (or Brandon
> who wrote the commit referenced above).
> 
> Looking through the archive, it seems that we might have more such hidden
> gems?

Fortunately, the only one left is the one in preload_index() which is 
what the flag was created to handle so I think we're ok.

> 
> https://public-inbox.org/git/f50825a4-fa15-9f28-a079-853e78ee8e2e@gmail.com/
> 
> Anyway, I think this is a better fix than what I proposed for sure.
> 
> Thanks for looking into this!
> 
> Stefan
> 
>>
>> Reported-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>> Helped-by: Stefan Beller <sbeller@google.com>
>> Signed-off-by: Ben Peart <benpeart@microsoft.com>
>> ---
>>
>> Notes:
>>      Base Ref: v2.19.0-rc2
>>      Web-Diff: https://github.com/benpeart/git/commit/ed30e1a885
>>      Checkout: git fetch https://github.com/benpeart/git fsmonitor-t7411-v1 && git checkout ed30e1a885
>>
>>   submodule.c | 3 +--
>>   1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> diff --git a/submodule.c b/submodule.c
>> index 50cbf5f13e..1e7194af28 100644
>> --- a/submodule.c
>> +++ b/submodule.c
>> @@ -65,8 +65,7 @@ int is_staging_gitmodules_ok(struct index_state *istate)
>>          if ((pos >= 0) && (pos < istate->cache_nr)) {
>>                  struct stat st;
>>                  if (lstat(GITMODULES_FILE, &st) == 0 &&
>> -                   ie_match_stat(istate, istate->cache[pos], &st,
>> -                                 CE_MATCH_IGNORE_FSMONITOR) & DATA_CHANGED)
>> +                   ie_match_stat(istate, istate->cache[pos], &st, 0) & DATA_CHANGED)
>>                          return 0;
>>          }
>>
>>
>> base-commit: c05048d43925ab8edcb36663752c2b4541911231
>> --
>> 2.18.0.windows.1
>>

^ permalink raw reply	[relevance 5%]

* [ANNOUNCE] Git v2.19.0
@ 2018-09-10 20:11 Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-09-10 20:11 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

The latest feature release Git v2.19.0 is now available at the
usual places.  It is comprised of 769 non-merge commits since
v2.18.0, contributed by 72 people, 16 of which are new faces.

The tarballs are found at:

    https://www.kernel.org/pub/software/scm/git/

The following public repositories all have a copy of the 'v2.19.0'
tag and the 'master' branch that the tag points at:

  url = https://kernel.googlesource.com/pub/scm/git/git
  url = git://repo.or.cz/alt-git.git
  url = https://github.com/gitster/git

New contributors whose contributions weren't in v2.18.0 are as follows.
Welcome to the Git development community!

  Aleksandr Makarov, Andrei Rybak, Chen Bin, Henning Schild,
  Isabella Stephens, Josh Steadmon, Jules Maselbas, Kana Natsuno,
  Marc Strapetz, Masaya Suzuki, Nicholas Guriev, Raphaël Hertzog,
  Samuel Maftoul, Sebastian Kisela, Vladimir Parfinenko, and
  William Chargin.

Returning contributors who helped this release are as follows.
Thanks for your continued support.

  Aaron Schrab, Ævar Arnfjörð Bjarmason, Alban Gruin, Alejandro
  R. Sedeño, Alexander Shopov, Anthony Sottile, Antonio Ospite,
  Beat Bolli, Ben Peart, Brandon Williams, brian m. carlson,
  Christian Couder, Christopher Díaz Riveros, Derrick Stolee,
  Dimitriy Ryazantcev, Elia Pinto, Elijah Newren, Eric Sunshine,
  Han-Wen Nienhuys, Jameson Miller, Jean-Noël Avila, Jeff
  Hostetler, Jeff King, Jiang Xin, Johannes Schindelin, Johannes
  Sixt, Jonathan Nieder, Jonathan Tan, Junio C Hamano, Kim Gybels,
  Kirill Smelkov, Kyle Meyer, Luis Marsano, Łukasz Stelmach,
  Luke Diamand, Martin Ågren, Max Kirillov, Michael Barabanov,
  Mike Hommey, Nguyễn Thái Ngọc Duy, Olga Telezhnaya, Peter
  Krefting, Phillip Wood, Prathamesh Chavan, Ralf Thielow, Ramsay
  Jones, René Scharfe, Stefan Beller, SZEDER Gábor, Taylor Blau,
  Thomas Rast, Tobias Klauser, Todd Zullinger, Trần Ngọc Quân,
  Ville Skyttä, and Xiaolong Ye.

----------------------------------------------------------------

Git 2.19 Release Notes
======================

Updates since v2.18
-------------------

UI, Workflows & Features

 * "git diff" compares the index and the working tree.  For paths
   added with intent-to-add bit, the command shows the full contents
   of them as added, but the paths themselves were not marked as new
   files.  They are now shown as new by default.

   "git apply" learned the "--intent-to-add" option so that an
   otherwise working-tree-only application of a patch will add new
   paths to the index marked with the "intent-to-add" bit.

 * "git grep" learned the "--column" option that gives not just the
   line number but the column number of the hit.

 * The "-l" option in "git branch -l" is an unfortunate short-hand for
   "--create-reflog", but many users, both old and new, somehow expect
   it to be something else, perhaps "--list".  This step warns when "-l"
   is used as a short-hand for "--create-reflog" and warns about the
   future repurposing of the it when it is used.

 * The userdiff pattern for .php has been updated.

 * The content-transfer-encoding of the message "git send-email" sends
   out by default was 8bit, which can cause trouble when there is an
   overlong line to bust RFC 5322/2822 limit.  A new option 'auto' to
   automatically switch to quoted-printable when there is such a line
   in the payload has been introduced and is made the default.

 * "git checkout" and "git worktree add" learned to honor
   checkout.defaultRemote when auto-vivifying a local branch out of a
   remote tracking branch in a repository with multiple remotes that
   have tracking branches that share the same names.
   (merge 8d7b558bae ab/checkout-default-remote later to maint).

 * "git grep" learned the "--only-matching" option.

 * "git rebase --rebase-merges" mode now handles octopus merges as
   well.

 * Add a server-side knob to skip commits in exponential/fibbonacci
   stride in an attempt to cover wider swath of history with a smaller
   number of iterations, potentially accepting a larger packfile
   transfer, instead of going back one commit a time during common
   ancestor discovery during the "git fetch" transaction.
   (merge 42cc7485a2 jt/fetch-negotiator-skipping later to maint).

 * A new configuration variable core.usereplacerefs has been added,
   primarily to help server installations that want to ignore the
   replace mechanism altogether.

 * Teach "git tag -s" etc. a few configuration variables (gpg.format
   that can be set to "openpgp" or "x509", and gpg.<format>.program
   that is used to specify what program to use to deal with the format)
   to allow x.509 certs with CMS via "gpgsm" to be used instead of
   openpgp via "gnupg".

 * Many more strings are prepared for l10n.

 * "git p4 submit" learns to ask its own pre-submit hook if it should
   continue with submitting.

 * The test performed at the receiving end of "git push" to prevent
   bad objects from entering repository can be customized via
   receive.fsck.* configuration variables; we now have gained a
   counterpart to do the same on the "git fetch" side, with
   fetch.fsck.* configuration variables.

 * "git pull --rebase=interactive" learned "i" as a short-hand for
   "interactive".

 * "git instaweb" has been adjusted to run better with newer Apache on
   RedHat based distros.

 * "git range-diff" is a reimplementation of "git tbdiff" that lets us
   compare individual patches in two iterations of a topic.

 * The sideband code learned to optionally paint selected keywords at
   the beginning of incoming lines on the receiving end.

 * "git branch --list" learned to take the default sort order from the
   'branch.sort' configuration variable, just like "git tag --list"
   pays attention to 'tag.sort'.

 * "git worktree" command learned "--quiet" option to make it less
   verbose.


Performance, Internal Implementation, Development Support etc.

 * The bulk of "git submodule foreach" has been rewritten in C.

 * The in-core "commit" object had an all-purpose "void *util" field,
   which was tricky to use especially in library-ish part of the
   code.  All of the existing uses of the field has been migrated to a
   more dedicated "commit-slab" mechanism and the field is eliminated.

 * A less often used command "git show-index" has been modernized.
   (merge fb3010c31f jk/show-index later to maint).

 * The conversion to pass "the_repository" and then "a_repository"
   throughout the object access API continues.

 * Continuing with the idea to programatically enumerate various
   pieces of data required for command line completion, teach the
   codebase to report the list of configuration variables
   subcommands care about to help complete them.

 * Separate "rebase -p" codepath out of "rebase -i" implementation to
   slim down the latter and make it easier to manage.

 * Make refspec parsing codepath more robust.

 * Some flaky tests have been fixed.

 * Continuing with the idea to programmatically enumerate various
   pieces of data required for command line completion, the codebase
   has been taught to enumerate options prefixed with "--no-" to
   negate them.

 * Build and test procedure for netrc credential helper (in contrib/)
   has been updated.

 * Remove unused function definitions and declarations from ewah
   bitmap subsystem.

 * Code preparation to make "git p4" closer to be usable with Python 3.

 * Tighten the API to make it harder to misuse in-tree .gitmodules
   file, even though it shares the same syntax with configuration
   files, to read random configuration items from it.

 * "git fast-import" has been updated to avoid attempting to create
   delta against a zero-byte-long string, which is pointless.

 * The codebase has been updated to compile cleanly with -pedantic
   option.
   (merge 2b647a05d7 bb/pedantic later to maint).

 * The character display width table has been updated to match the
   latest Unicode standard.
   (merge 570951eea2 bb/unicode-11-width later to maint).

 * test-lint now looks for broken use of "VAR=VAL shell_func" in test
   scripts.

 * Conversion from uchar[40] to struct object_id continues.

 * Recent "security fix" to pay attention to contents of ".gitmodules"
   while accepting "git push" was a bit overly strict than necessary,
   which has been adjusted.

 * "git fsck" learns to make sure the optional commit-graph file is in
   a sane state.

 * "git diff --color-moved" feature has further been tweaked.

 * Code restructuring and a small fix to transport protocol v2 during
   fetching.

 * Parsing of -L[<N>][,[<M>]] parameters "git blame" and "git log"
   take has been tweaked.

 * lookup_commit_reference() and friends have been updated to find
   in-core object for a specific in-core repository instance.

 * Various glitches in the heuristics of merge-recursive strategy have
   been documented in new tests.

 * "git fetch" learned a new option "--negotiation-tip" to limit the
   set of commits it tells the other end as "have", to reduce wasted
   bandwidth and cycles, which would be helpful when the receiving
   repository has a lot of refs that have little to do with the
   history at the remote it is fetching from.

 * For a large tree, the index needs to hold many cache entries
   allocated on heap.  These cache entries are now allocated out of a
   dedicated memory pool to amortize malloc(3) overhead.

 * Tests to cover various conflicting cases have been added for
   merge-recursive.

 * Tests to cover conflict cases that involve submodules have been
   added for merge-recursive.

 * Look for broken "&&" chains that are hidden in subshell, many of
   which have been found and corrected.

 * The singleton commit-graph in-core instance is made per in-core
   repository instance.

 * "make DEVELOPER=1 DEVOPTS=pedantic" allows developers to compile
   with -pedantic option, which may catch more problematic program
   constructs and potential bugs.

 * Preparatory code to later add json output for telemetry data has
   been added.

 * Update the way we use Coccinelle to find out-of-style code that
   need to be modernised.

 * It is too easy to misuse system API functions such as strcat();
   these selected functions are now forbidden in this codebase and
   will cause a compilation failure.

 * Add a script (in contrib/) to help users of VSCode work better with
   our codebase.

 * The Travis CI scripts were taught to ship back the test data from
   failed tests.
   (merge aea8879a6a sg/travis-retrieve-trash-upon-failure later to maint).

 * The parse-options machinery learned to refrain from enclosing
   placeholder string inside a "<bra" and "ket>" pair automatically
   without PARSE_OPT_LITERAL_ARGHELP.  Existing help text for option
   arguments that are not formatted correctly have been identified and
   fixed.
   (merge 5f0df44cd7 rs/parse-opt-lithelp later to maint).

 * Noiseword "extern" has been removed from function decls in the
   header files.

 * A few atoms like %(objecttype) and %(objectsize) in the format
   specifier of "for-each-ref --format=<format>" can be filled without
   getting the full contents of the object, but just with the object
   header.  These cases have been optimized by calling
   oid_object_info() API (instead of reading and inspecting the data).

 * The end result of documentation update has been made to be
   inspected more easily to help developers.

 * The API to iterate over all objects learned to optionally list
   objects in the order they appear in packfiles, which helps locality
   of access if the caller accesses these objects while as objects are
   enumerated.

 * Improve built-in facility to catch broken &&-chain in the tests.

 * The more library-ish parts of the codebase learned to work on the
   in-core index-state instance that is passed in by their callers,
   instead of always working on the singleton "the_index" instance.

 * A test prerequisite defined by various test scripts with slightly
   different semantics has been consolidated into a single copy and
   made into a lazily defined one.
   (merge 6ec633059a wc/make-funnynames-shared-lazy-prereq later to maint).

 * After a partial clone, repeated fetches from promisor remote would
   have accumulated many packfiles marked with .promisor bit without
   getting them coalesced into fewer packfiles, hurting performance.
   "git repack" now learned to repack them.

 * Partially revert the support for multiple hash functions to regain
   hash comparison performance; we'd think of a way to do this better
   in the next cycle.

 * "git help --config" (which is used in command line completion)
   missed the configuration variables not described in the main
   config.txt file but are described in another file that is included
   by it, which has been corrected.

 * The test linter code has learned that the end of here-doc mark
   "EOF" can be quoted in a double-quote pair, not just in a
   single-quote pair.


Fixes since v2.18
-----------------

 * "git remote update" can take both a single remote nickname and a
   nickname for remote groups, and the completion script (in contrib/)
   has been taught about it.
   (merge 9cd4382ad5 ls/complete-remote-update-names later to maint).

 * "git fetch --shallow-since=<cutoff>" that specifies the cut-off
   point that is newer than the existing history used to end up
   grabbing the entire history.  Such a request now errors out.
   (merge e34de73c56 nd/reject-empty-shallow-request later to maint).

 * Fix for 2.17-era regression around `core.safecrlf`.
   (merge 6cb09125be as/safecrlf-quiet-fix later to maint).

 * The recent addition of "partial clone" experimental feature kicked
   in when it shouldn't, namely, when there is no partial-clone filter
   defined even if extensions.partialclone is set.
   (merge cac1137dc4 jh/partial-clone later to maint).

 * "git send-pack --signed" (hence "git push --signed" over the http
   transport) did not read user ident from the config mechanism to
   determine whom to sign the push certificate as, which has been
   corrected.
   (merge d067d98887 ms/send-pack-honor-config later to maint).

 * "git fetch-pack --all" used to unnecessarily fail upon seeing an
   annotated tag that points at an object other than a commit.
   (merge c12c9df527 jk/fetch-all-peeled-fix later to maint).

 * When user edits the patch in "git add -p" and the user's editor is
   set to strip trailing whitespaces indiscriminately, an empty line
   that is unchanged in the patch would become completely empty
   (instead of a line with a sole SP on it).  The code introduced in
   Git 2.17 timeframe failed to parse such a patch, but now it learned
   to notice the situation and cope with it.
   (merge f4d35a6b49 pw/add-p-recount later to maint).

 * The code to try seeing if a fetch is necessary in a submodule
   during a fetch with --recurse-submodules got confused when the path
   to the submodule was changed in the range of commits in the
   superproject, sometimes showing "(null)".  This has been corrected.

 * Bugfix for "rebase -i" corner case regression.
   (merge a9279c6785 pw/rebase-i-keep-reword-after-conflict later to maint).

 * Recently added "--base" option to "git format-patch" command did
   not correctly generate prereq patch ids.
   (merge 15b76c1fb3 xy/format-patch-prereq-patch-id-fix later to maint).

 * POSIX portability fix in Makefile to fix a glitch introduced a few
   releases ago.
   (merge 6600054e9b dj/runtime-prefix later to maint).

 * "git filter-branch" when used with the "--state-branch" option
   still attempted to rewrite the commits whose filtered result is
   known from the previous attempt (which is recorded on the state
   branch); the command has been corrected not to waste cycles doing
   so.
   (merge 709cfe848a mb/filter-branch-optim later to maint).

 * Clarify that setting core.ignoreCase to deviate from reality would
   not turn a case-incapable filesystem into a case-capable one.
   (merge 48294b512a ms/core-icase-doc later to maint).

 * "fsck.skipList" did not prevent a blob object listed there from
   being inspected for is contents (e.g. we recently started to
   inspect the contents of ".gitmodules" for certain malicious
   patterns), which has been corrected.
   (merge fb16287719 rj/submodule-fsck-skip later to maint).

 * "git checkout --recurse-submodules another-branch" did not report
   in which submodule it failed to update the working tree, which
   resulted in an unhelpful error message.
   (merge ba95d4e4bd sb/submodule-move-head-error-msg later to maint).

 * "git rebase" behaved slightly differently depending on which one of
   the three backends gets used; this has been documented and an
   effort to make them more uniform has begun.
   (merge b00bf1c9a8 en/rebase-consistency later to maint).

 * The "--ignore-case" option of "git for-each-ref" (and its friends)
   did not work correctly, which has been fixed.
   (merge e674eb2528 jk/for-each-ref-icase later to maint).

 * "git fetch" failed to correctly validate the set of objects it
   received when making a shallow history deeper, which has been
   corrected.
   (merge cf1e7c0770 jt/connectivity-check-after-unshallow later to maint).

 * Partial clone support of "git clone" has been updated to correctly
   validate the objects it receives from the other side.  The server
   side has been corrected to send objects that are directly
   requested, even if they may match the filtering criteria (e.g. when
   doing a "lazy blob" partial clone).
   (merge a7e67c11b8 jt/partial-clone-fsck-connectivity later to maint).

 * Handling of an empty range by "git cherry-pick" was inconsistent
   depending on how the range ended up to be empty, which has been
   corrected.
   (merge c5e358d073 jk/empty-pick-fix later to maint).

 * "git reset --merge" (hence "git merge ---abort") and "git reset --hard"
   had trouble working correctly in a sparsely checked out working
   tree after a conflict, which has been corrected.
   (merge b33fdfc34c mk/merge-in-sparse-checkout later to maint).

 * Correct a broken use of "VAR=VAL shell_func" in a test.
   (merge 650161a277 jc/t3404-one-shot-export-fix later to maint).

 * "git rev-parse ':/substring'" did not consider the history leading
   only to HEAD when looking for a commit with the given substring,
   when the HEAD is detached.  This has been fixed.
   (merge 6b3351e799 wc/find-commit-with-pattern-on-detached-head later to maint).

 * Build doc update for Windows.
   (merge ede8d89bb1 nd/command-list later to maint).

 * core.commentchar is now honored when preparing the list of commits
   to replay in "rebase -i".

 * "git pull --rebase" on a corrupt HEAD caused a segfault.  In
   general we substitute an empty tree object when running the in-core
   equivalent of the diff-index command, and the codepath has been
   corrected to do so as well to fix this issue.
   (merge 3506dc9445 jk/has-uncommitted-changes-fix later to maint).

 * httpd tests saw occasional breakage due to the way its access log
   gets inspected by the tests, which has been updated to make them
   less flaky.
   (merge e8b3b2e275 sg/httpd-test-unflake later to maint).

 * Tests to cover more D/F conflict cases have been added for
   merge-recursive.

 * "git gc --auto" opens file descriptors for the packfiles before
   spawning "git repack/prune", which would upset Windows that does
   not want a process to work on a file that is open by another
   process.  The issue has been worked around.
   (merge 12e73a3ce4 kg/gc-auto-windows-workaround later to maint).

 * The recursive merge strategy did not properly ensure there was no
   change between HEAD and the index before performing its operation,
   which has been corrected.
   (merge 55f39cf755 en/dirty-merge-fixes later to maint).

 * "git rebase" started exporting GIT_DIR environment variable and
   exposing it to hook scripts when part of it got rewritten in C.
   Instead of matching the old scripted Porcelains' behaviour,
   compensate by also exporting GIT_WORK_TREE environment as well to
   lessen the damage.  This can harm existing hooks that want to
   operate on different repository, but the current behaviour is
   already broken for them anyway.
   (merge ab5e67d751 bc/sequencer-export-work-tree-as-well later to maint).

 * "git send-email" when using in a batched mode that limits the
   number of messages sent in a single SMTP session lost the contents
   of the variable used to choose between tls/ssl, unable to send the
   second and later batches, which has been fixed.
   (merge 636f3d7ac5 jm/send-email-tls-auth-on-batch later to maint).

 * The lazy clone support had a few places where missing but promised
   objects were not correctly tolerated, which have been fixed.

 * One of the "diff --color-moved" mode "dimmed_zebra" that was named
   in an unusual way has been deprecated and replaced by
   "dimmed-zebra".
   (merge e3f2f5f9cd es/diff-color-moved-fix later to maint).

 * The wire-protocol v2 relies on the client to send "ref prefixes" to
   limit the bandwidth spent on the initial ref advertisement.  "git
   clone" when learned to speak v2 forgot to do so, which has been
   corrected.
   (merge 402c47d939 bw/clone-ref-prefixes later to maint).

 * "git diff --histogram" had a bad memory usage pattern, which has
   been rearranged to reduce the peak usage.
   (merge 79cb2ebb92 sb/histogram-less-memory later to maint).

 * Code clean-up to use size_t/ssize_t when they are the right type.
   (merge 7726d360b5 jk/size-t later to maint).

 * The wire-protocol v2 relies on the client to send "ref prefixes" to
   limit the bandwidth spent on the initial ref advertisement.  "git
   fetch $remote branch:branch" that asks tags that point into the
   history leading to the "branch" automatically followed sent to
   narrow prefix and broke the tag following, which has been fixed.
   (merge 2b554353a5 jt/tag-following-with-proto-v2-fix later to maint).

 * When the sparse checkout feature is in use, "git cherry-pick" and
   other mergy operations lost the skip_worktree bit when a path that
   is excluded from checkout requires content level merge, which is
   resolved as the same as the HEAD version, without materializing the
   merge result in the working tree, which made the path appear as
   deleted.  This has been corrected by preserving the skip_worktree
   bit (and not materializing the file in the working tree).
   (merge 2b75fb601c en/merge-recursive-skip-fix later to maint).

 * The "author-script" file "git rebase -i" creates got broken when
   we started to move the command away from shell script, which is
   getting fixed now.
   (merge 5522bbac20 es/rebase-i-author-script-fix later to maint).

 * The automatic tree-matching in "git merge -s subtree" was broken 5
   years ago and nobody has noticed since then, which is now fixed.
   (merge 2ec4150713 jk/merge-subtree-heuristics later to maint).

 * "git fetch $there refs/heads/s" ought to fetch the tip of the
   branch 's', but when "refs/heads/refs/heads/s", i.e. a branch whose
   name is "refs/heads/s" exists at the same time, fetched that one
   instead by mistake.  This has been corrected to honor the usual
   disambiguation rules for abbreviated refnames.
   (merge 60650a48c0 jt/refspec-dwim-precedence-fix later to maint).

 * Futureproofing a helper function that can easily be misused.
   (merge 65bb21e77e es/want-color-fd-defensive later to maint).

 * The http-backend (used for smart-http transport) used to slurp the
   whole input until EOF, without paying attention to CONTENT_LENGTH
   that is supplied in the environment and instead expecting the Web
   server to close the input stream.  This has been fixed.
   (merge eebfe40962 mk/http-backend-content-length later to maint).

 * "git merge --abort" etc. did not clean things up properly when
   there were conflicted entries in the index in certain order that
   are involved in D/F conflicts.  This has been corrected.
   (merge ad3762042a en/abort-df-conflict-fixes later to maint).

 * "git diff --indent-heuristic" had a bad corner case performance.
   (merge 301ef85401 sb/indent-heuristic-optim later to maint).

 * The "--exec" option to "git rebase --rebase-merges" placed the exec
   commands at wrong places, which has been corrected.

 * "git verify-tag" and "git verify-commit" have been taught to use
   the exit status of underlying "gpg --verify" to signal bad or
   untrusted signature they found.
   (merge 4e5dc9ca17 jc/gpg-status later to maint).

 * "git mergetool" stopped and gave an extra prompt to continue after
   the last path has been handled, which did not make much sense.
   (merge d651a54b8a ng/mergetool-lose-final-prompt later to maint).

 * Among the three codepaths we use O_APPEND to open a file for
   appending, one used for writing GIT_TRACE output requires O_APPEND
   implementation that behaves sensibly when multiple processes are
   writing to the same file.  POSIX emulation used in the Windows port
   has been updated to improve in this area.
   (merge d641097589 js/mingw-o-append later to maint).

 * "git pull --rebase -v" in a repository with a submodule barfed as
   an intermediate process did not understand what "-v(erbose)" flag
   meant, which has been fixed.
   (merge e84c3cf3dc sb/pull-rebase-submodule later to maint).

 * Recent update to "git config" broke updating variable in a
   subsection, which has been corrected.
   (merge bff7df7a87 sb/config-write-fix later to maint).

 * When "git rebase -i" is told to squash two or more commits into
   one, it labeled the log message for each commit with its number.
   It correctly called the first one "1st commit", but the next one
   was "commit #1", which was off-by-one.  This has been corrected.
   (merge dd2e36ebac pw/rebase-i-squash-number-fix later to maint).

 * "git rebase -i", when a 'merge <branch>' insn in its todo list
   fails, segfaulted, which has been (minimally) corrected.
   (merge bc9238bb09 pw/rebase-i-merge-segv-fix later to maint).

 * "git cherry-pick --quit" failed to remove CHERRY_PICK_HEAD even
   though we won't be in a cherry-pick session after it returns, which
   has been corrected.
   (merge 3e7dd99208 nd/cherry-pick-quit-fix later to maint).

 * In a recent update in 2.18 era, "git pack-objects" started
   producing a larger than necessary packfiles by missing
   opportunities to use large deltas.  This has been corrected.

 * The meaning of the possible values the "core.checkStat"
   configuration variable can take were not adequately documented,
   which has been fixed.
   (merge 9bf5d4c4e2 nd/config-core-checkstat-doc later to maint).

 * Recent "git rebase -i" update started to write bogusly formatted
   author-script, with a matching broken reading code.  These are
   fixed.

 * Recent addition of "directory rename" heuristics to the
   merge-recursive backend makes the command susceptible to false
   positives and false negatives.  In the context of "git am -3",
   which does not know about surrounding unmodified paths and thus
   cannot inform the merge machinery about the full trees involved,
   this risk is particularly severe.  As such, the heuristic is
   disabled for "git am -3" to keep the machinery "more stupid but
   predictable".

 * "git merge-base" in 2.19-rc1 has performance regression when the
   (experimental) commit-graph feature is in use, which has been
   mitigated.

 * Code cleanup, docfix, build fix, etc.
   (merge aee9be2ebe sg/update-ref-stdin-cleanup later to maint).
   (merge 037714252f jc/clean-after-sanity-tests later to maint).
   (merge 5b26c3c941 en/merge-recursive-cleanup later to maint).
   (merge 0dcbc0392e bw/config-refer-to-gitsubmodules-doc later to maint).
   (merge bb4d000e87 bw/protocol-v2 later to maint).
   (merge 928f0ab4ba vs/typofixes later to maint).
   (merge d7f590be84 en/rebase-i-microfixes later to maint).
   (merge 81d395cc85 js/rebase-recreate-merge later to maint).
   (merge 51d1863168 tz/exclude-doc-smallfixes later to maint).
   (merge a9aa3c0927 ds/commit-graph later to maint).
   (merge 5cf8e06474 js/enhanced-version-info later to maint).
   (merge 6aaded5509 tb/config-default later to maint).
   (merge 022d2ac1f3 sb/blame-color later to maint).
   (merge 5a06a20e0c bp/test-drop-caches-for-windows later to maint).
   (merge dd61cc1c2e jk/ui-color-always-to-auto later to maint).
   (merge 1e83b9bfdd sb/trailers-docfix later to maint).
   (merge ab29f1b329 sg/fast-import-dump-refs-on-checkpoint-fix later to maint).
   (merge 6a8ad880f0 jn/subtree-test-fixes later to maint).
   (merge ffbd51cc60 nd/pack-objects-threading-doc later to maint).
   (merge e9dac7be60 es/mw-to-git-chain-fix later to maint).
   (merge fe583c6c7a rs/remote-mv-leakfix later to maint).
   (merge 69885ab015 en/t3031-title-fix later to maint).
   (merge 8578037bed nd/config-blame-sort later to maint).
   (merge 8ad169c4ba hn/config-in-code-comment later to maint).
   (merge b7446fcfdf ar/t4150-am-scissors-test-fix later to maint).
   (merge a8132410ee js/typofixes later to maint).
   (merge 388d0ff6e5 en/update-index-doc later to maint).
   (merge e05aa688dd jc/update-index-doc later to maint).
   (merge 10c600172c sg/t5310-empty-input-fix later to maint).
   (merge 5641eb9465 jh/partial-clone-doc later to maint).
   (merge 2711b1ad5e ab/submodule-relative-url-tests later to maint).
   (merge ce528de023 ab/unconditional-free-and-null later to maint).
   (merge bbc072f5d8 rs/opt-updates later to maint).
   (merge 69d846f053 jk/use-compat-util-in-test-tool later to maint).
   (merge 1820703045 js/larger-timestamps later to maint).
   (merge c8b35b95e1 sg/t4051-fix later to maint).
   (merge 30612cb670 sg/t0020-conversion-fix later to maint).
   (merge 15da753709 sg/t7501-thinkofix later to maint).
   (merge 79b04f9b60 sg/t3903-missing-fix later to maint).
   (merge 2745817028 sg/t3420-autostash-fix later to maint).
   (merge 7afb0d6777 sg/test-rebase-editor-fix later to maint).
   (merge 6c6ce21baa es/freebsd-iconv-portability later to maint).

----------------------------------------------------------------

Changes since v2.18.0 are as follows:

Aaron Schrab (1):
      sequencer: use configured comment character

Alban Gruin (4):
      rebase: introduce a dedicated backend for --preserve-merges
      rebase: strip unused code in git-rebase--preserve-merges.sh
      rebase: use the new git-rebase--preserve-merges.sh
      rebase: remove -p code from git-rebase--interactive.sh

Alejandro R. Sedeño (1):
      Makefile: tweak sed invocation

Aleksandr Makarov (1):
      for-each-ref: consistently pass WM_IGNORECASE flag

Alexander Shopov (1):
      l10n: bg.po: Updated Bulgarian translation (3958t)

Andrei Rybak (2):
      Documentation: fix --color option formatting
      t4150: fix broken test for am --scissors

Anthony Sottile (1):
      config.c: fix regression for core.safecrlf false

Antonio Ospite (6):
      config: move config_from_gitmodules to submodule-config.c
      submodule-config: add helper function to get 'fetch' config from .gitmodules
      submodule-config: add helper to get 'update-clone' config from .gitmodules
      submodule-config: make 'config_from_gitmodules' private
      submodule-config: pass repository as argument to config_from_gitmodules
      submodule-config: reuse config_from_gitmodules in repo_read_gitmodules

Beat Bolli (10):
      builtin/config: work around an unsized array forward declaration
      unicode: update the width tables to Unicode 11
      connect.h: avoid forward declaration of an enum
      refs/refs-internal.h: avoid forward declaration of an enum
      convert.c: replace "\e" escapes with "\033".
      sequencer.c: avoid empty statements at top level
      string-list.c: avoid conversion from void * to function pointer
      utf8.c: avoid char overflow
      Makefile: add a DEVOPTS flag to get pedantic compilation
      packfile: ensure that enum object_type is defined

Ben Peart (3):
      convert log_ref_write_fd() to use strbuf
      handle lower case drive letters on Windows
      t3507: add a testcase showing failure with sparse checkout

Brandon Williams (15):
      commit: convert commit_graft_pos() to handle arbitrary repositories
      commit: convert register_commit_graft to handle arbitrary repositories
      commit: convert read_graft_file to handle arbitrary repositories
      test-pkt-line: add unpack-sideband subcommand
      docs: link to gitsubmodules
      upload-pack: implement ref-in-want
      upload-pack: test negotiation with changing repository
      fetch: refactor the population of peer ref OIDs
      fetch: refactor fetch_refs into two functions
      fetch: refactor to make function args narrower
      fetch-pack: put shallow info in output parameter
      fetch-pack: implement ref-in-want
      clone: send ref-prefixes when using protocol v2
      fetch-pack: mark die strings for translation
      pack-protocol: mention and point to docs for protocol v2

Chen Bin (1):
      git-p4: add the `p4-pre-submit` hook

Christian Couder (1):
      t9104: kosherly remove remote refs

Christopher Díaz Riveros (1):
      l10n: es.po v2.19.0 round 2

Derrick Stolee (46):
      ref-filter: fix outdated comment on in_commit_list
      commit: add generation number to struct commit
      commit-graph: compute generation numbers
      commit: use generations in paint_down_to_common()
      commit-graph: always load commit-graph information
      ref-filter: use generation number for --contains
      commit: use generation numbers for in_merge_bases()
      commit: add short-circuit to paint_down_to_common()
      commit: use generation number in remove_redundant()
      merge: check config before loading commits
      commit-graph.txt: update design document
      commit-graph: fix UX issue when .lock file exists
      ewah/bitmap.c: delete unused 'bitmap_clear()'
      ewah/bitmap.c: delete unused 'bitmap_each_bit()'
      ewah_bitmap: delete unused 'ewah_and()'
      ewah_bitmap: delete unused 'ewah_and_not()'
      ewah_bitmap: delete unused 'ewah_not()'
      ewah_bitmap: delete unused 'ewah_or()'
      ewah_io: delete unused 'ewah_serialize()'
      t5318-commit-graph.sh: use core.commitGraph
      commit-graph: UNLEAK before die()
      commit-graph: fix GRAPH_MIN_SIZE
      commit-graph: parse commit from chosen graph
      commit: force commit to parse from object database
      commit-graph: load a root tree from specific graph
      commit-graph: add 'verify' subcommand
      commit-graph: verify catches corrupt signature
      commit-graph: verify required chunks are present
      commit-graph: verify corrupt OID fanout and lookup
      commit-graph: verify objects exist
      commit-graph: verify root tree OIDs
      commit-graph: verify parent list
      commit-graph: verify generation number
      commit-graph: verify commit date
      commit-graph: test for corrupted octopus edge
      commit-graph: verify contents match checksum
      fsck: verify commit-graph
      commit-graph: use string-list API for input
      commit-graph: add '--reachable' option
      gc: automatically write commit-graph files
      commit-graph: update design document
      commit-graph: fix documentation inconsistencies
      coccinelle: update commit.cocci
      commit: use timestamp_t for author_date_slab
      config: fix commit-graph related config docs
      commit: don't use generation numbers if not needed

Dimitriy Ryazantcev (1):
      l10n: ru.po: update Russian translation

Elia Pinto (1):
      worktree: add --quiet option

Elijah Newren (66):
      t6036, t6042: use test_create_repo to keep tests independent
      t6036, t6042: use test_line_count instead of wc -l
      t6036, t6042: prefer test_path_is_file, test_path_is_missing
      t6036, t6042: prefer test_cmp to sequences of test
      t6036: prefer test_when_finished to manual cleanup in following test
      merge-recursive: fix miscellaneous grammar error in comment
      merge-recursive: fix numerous argument alignment issues
      merge-recursive: align labels with their respective code blocks
      merge-recursive: clarify the rename_dir/RENAME_DIR meaning
      merge-recursive: rename conflict_rename_*() family of functions
      merge-recursive: add pointer about unduly complex looking code
      git-rebase.txt: document incompatible options
      git-rebase.sh: update help messages a bit
      t3422: new testcases for checking when incompatible options passed
      git-rebase: error out when incompatible options passed
      git-rebase.txt: address confusion between --no-ff vs --force-rebase
      directory-rename-detection.txt: technical docs on abilities and limitations
      git-rebase.txt: document behavioral differences between modes
      t3401: add directory rename testcases for rebase and am
      git-rebase: make --allow-empty-message the default
      t3418: add testcase showing problems with rebase -i and strategy options
      Fix use of strategy options with interactive rebases
      git-rebase--merge: modernize "git-$cmd" to "git $cmd"
      apply: fix grammar error in comment
      t5407: fix test to cover intended arguments
      read-cache.c: move index_has_changes() from merge.c
      index_has_changes(): avoid assuming operating on the_index
      t6044: verify that merges expected to abort actually abort
      t6036: add a failed conflict detection case with symlink modify/modify
      t6036: add a failed conflict detection case with symlink add/add
      t6036: add a failed conflict detection case with submodule modify/modify
      t6036: add a failed conflict detection case with submodule add/add
      t6036: add a failed conflict detection case with conflicting types
      t6042: add testcase covering rename/add/delete conflict type
      t6042: add testcase covering rename/rename(2to1)/delete/delete conflict
      t6042: add testcase covering long chains of rename conflicts
      t6036: add lots of detail for directory/file conflicts in recursive case
      t6036: add a failed conflict detection case: regular files, different modes
      t6044: add a testcase for index matching head, when head doesn't match HEAD
      merge-recursive: make sure when we say we abort that we actually abort
      merge-recursive: fix assumption that head tree being merged is HEAD
      t6044: add more testcases with staged changes before a merge is invoked
      merge-recursive: enforce rule that index matches head before merging
      merge: fix misleading pre-merge check documentation
      t7405: add a file/submodule conflict
      t7405: add a directory/submodule conflict
      t7405: verify 'merge --abort' works after submodule/path conflicts
      merge-recursive: preserve skip_worktree bit when necessary
      t1015: demonstrate directory/file conflict recovery failures
      read-cache: fix directory/file conflict handling in read_index_unmerged()
      t3031: update test description to mention desired behavior
      t7406: fix call that was failing for the wrong reason
      t7406: simplify by using diff --name-only instead of diff --raw
      t7406: avoid having git commands upstream of a pipe
      t7406: prefer test_* helper functions to test -[feds]
      t7406: avoid using test_must_fail for commands other than git
      git-update-index.txt: reword possibly confusing example
      Add missing includes and forward declarations
      alloc: make allocate_alloc_state and clear_alloc_state more consistent
      Move definition of enum branch_track from cache.h to branch.h
      urlmatch.h: fix include guard
      compat/precompose_utf8.h: use more common include guard style
      Remove forward declaration of an enum
      t3401: add another directory rename testcase for rebase and am
      merge-recursive: add ability to turn off directory rename detection
      am: avoid directory rename detection when calling recursive merge machinery

Eric Sunshine (55):
      t: use test_might_fail() instead of manipulating exit code manually
      t: use test_write_lines() instead of series of 'echo' commands
      t: use sane_unset() rather than 'unset' with broken &&-chain
      t: drop unnecessary terminating semicolon in subshell
      t/lib-submodule-update: fix "absorbing" test
      t5405: use test_must_fail() instead of checking exit code manually
      t5406: use write_script() instead of birthing shell script manually
      t5505: modernize and simplify hard-to-digest test
      t6036: fix broken "merge fails but has appropriate contents" tests
      t7201: drop pointless "exit 0" at end of subshell
      t7400: fix broken "submodule add/reconfigure --force" test
      t7810: use test_expect_code() instead of hand-rolled comparison
      t9001: fix broken "invoke hook" test
      t9814: simplify convoluted check that command correctly errors out
      t0000-t0999: fix broken &&-chains
      t1000-t1999: fix broken &&-chains
      t2000-t2999: fix broken &&-chains
      t3000-t3999: fix broken &&-chains
      t3030: fix broken &&-chains
      t4000-t4999: fix broken &&-chains
      t5000-t5999: fix broken &&-chains
      t6000-t6999: fix broken &&-chains
      t7000-t7999: fix broken &&-chains
      t9000-t9999: fix broken &&-chains
      t9119: fix broken &&-chains
      t6046/t9833: fix use of "VAR=VAL cmd" with a shell function
      t/check-non-portable-shell: stop being so polite
      t/check-non-portable-shell: make error messages more compact
      t/check-non-portable-shell: detect "FOO=bar shell_func"
      t/test-lib: teach --chain-lint to detect broken &&-chains in subshells
      t/Makefile: add machinery to check correctness of chainlint.sed
      t/chainlint: add chainlint "basic" test cases
      t/chainlint: add chainlint "whitespace" test cases
      t/chainlint: add chainlint "one-liner" test cases
      t/chainlint: add chainlint "nested subshell" test cases
      t/chainlint: add chainlint "loop" and "conditional" test cases
      t/chainlint: add chainlint "cuddled" test cases
      t/chainlint: add chainlint "complex" test cases
      t/chainlint: add chainlint "specialized" test cases
      diff: --color-moved: rename "dimmed_zebra" to "dimmed-zebra"
      mw-to-git/t9360: fix broken &&-chain
      t/chainlint.sed: drop extra spaces from regex character class
      sequencer: fix "rebase -i --root" corrupting author header
      sequencer: fix "rebase -i --root" corrupting author header timezone
      sequencer: fix "rebase -i --root" corrupting author header timestamp
      sequencer: don't die() on bogus user-edited timestamp
      color: protect against out-of-bounds reads and writes
      chainlint: match arbitrary here-docs tags rather than hard-coded names
      chainlint: match 'quoted' here-doc tags
      chainlint: recognize multi-line $(...) when command cuddled with "$("
      chainlint: let here-doc and multi-line string commence on same line
      chainlint: recognize multi-line quoted strings more robustly
      chainlint: add test of pathological case which triggered false positive
      chainlint: match "quoted" here-doc tags
      config.mak.uname: resolve FreeBSD iconv-related compilation warning

Han-Wen Nienhuys (2):
      config: document git config getter return value
      sideband: highlight keywords in remote sideband output

Henning Schild (9):
      builtin/receive-pack: use check_signature from gpg-interface
      gpg-interface: make parse_gpg_output static and remove from interface header
      gpg-interface: add new config to select how to sign a commit
      t/t7510: check the validation of the new config gpg.format
      gpg-interface: introduce an abstraction for multiple gpg formats
      gpg-interface: do not hardcode the key string len anymore
      gpg-interface: introduce new config to select per gpg format program
      gpg-interface: introduce new signature format "x509" using gpgsm
      gpg-interface t: extend the existing GPG tests with GPGSM

Isabella Stephens (2):
      blame: prevent error if range ends past end of file
      log: prevent error if line range ends past end of file

Jameson Miller (8):
      read-cache: teach refresh_cache_entry to take istate
      read-cache: teach make_cache_entry to take object_id
      block alloc: add lifecycle APIs for cache_entry structs
      mem-pool: only search head block for available space
      mem-pool: add life cycle management functions
      mem-pool: fill out functionality
      block alloc: allocate cache entries from mem_pool
      block alloc: add validations around cache_entry lifecyle

Jean-Noël Avila (3):
      i18n: fix mistakes in translated strings
      l10n: fr.po v2.19.0 rnd 1
      l10n: fr.po v2.19.0 rnd 2

Jeff Hostetler (1):
      json_writer: new routines to create JSON data

Jeff King (50):
      make show-index a builtin
      show-index: update documentation for index v2
      fetch-pack: don't try to fetch peel values with --all
      ewah: drop ewah_deserialize function
      ewah: drop ewah_serialize_native function
      t3200: unset core.logallrefupdates when testing reflog creation
      t: switch "branch -l" to "branch --create-reflog"
      branch: deprecate "-l" option
      config: turn die_on_error into caller-facing enum
      config: add CONFIG_ERROR_SILENT handler
      config: add options parameter to git_config_from_mem
      fsck: silence stderr when parsing .gitmodules
      t6300: add a test for --ignore-case
      ref-filter: avoid backend filtering with --ignore-case
      t5500: prettify non-commit tag tests
      sequencer: handle empty-set cases consistently
      sequencer: don't say BUG on bogus input
      has_uncommitted_changes(): fall back to empty tree
      fsck: split ".gitmodules too large" error from parse failure
      fsck: downgrade gitmodulesParse default to "info"
      blame: prefer xsnprintf to strcpy for colors
      check_replace_refs: fix outdated comment
      check_replace_refs: rename to read_replace_refs
      add core.usereplacerefs config option
      reencode_string: use st_add/st_mult helpers
      reencode_string: use size_t for string lengths
      strbuf: use size_t for length in intermediate variables
      strbuf_readlink: use ssize_t
      pass st.st_size as hint for strbuf_readlink()
      strbuf_humanise: use unsigned variables
      automatically ban strcpy()
      banned.h: mark strcat() as banned
      banned.h: mark sprintf() as banned
      banned.h: mark strncpy() as banned
      score_trees(): fix iteration over trees with missing entries
      add a script to diff rendered documentation
      t5552: suppress upload-pack trace output
      for_each_*_object: store flag definitions in a single location
      for_each_*_object: take flag arguments as enum
      for_each_*_object: give more comprehensive docstrings
      for_each_packed_object: support iterating in pack-order
      t1006: test cat-file --batch-all-objects with duplicates
      cat-file: rename batch_{loose,packed}_object callbacks
      cat-file: support "unordered" output for --batch-all-objects
      cat-file: use oidset check-and-insert
      cat-file: split batch "buf" into two variables
      cat-file: use a single strbuf for all output
      for_each_*_object: move declarations to object-store.h
      test-tool.h: include git-compat-util.h
      hashcmp: assert constant hash size

Jiang Xin (4):
      l10n: zh_CN: review for git 2.18.0
      l10n: git.pot: v2.19.0 round 1 (382 new, 30 removed)
      l10n: git.pot: v2.19.0 round 2 (3 new, 5 removed)
      l10n: zh_CN: for git v2.19.0 l10n round 1 to 2

Johannes Schindelin (41):
      Makefile: fix the "built from commit" code
      merge: allow reading the merge commit message from a file
      rebase --rebase-merges: add support for octopus merges
      rebase --rebase-merges: adjust man page for octopus support
      vcbuild/README: update to accommodate for missing common-cmds.h
      t7406: avoid failures solely due to timing issues
      contrib: add a script to initialize VS Code configuration
      vscode: hard-code a couple defines
      cache.h: extract enum declaration from inside a struct declaration
      mingw: define WIN32 explicitly
      vscode: only overwrite C/C++ settings
      vscode: wrap commit messages at column 72 by default
      vscode: use 8-space tabs, no trailing ws, etc for Git's source code
      vscode: add a dictionary for cSpell
      vscode: let cSpell work on commit messages, too
      pull --rebase=<type>: allow single-letter abbreviations for the type
      t3430: demonstrate what -r, --autosquash & --exec should do
      git-compat-util.h: fix typo
      remote-curl: remove spurious period
      rebase --exec: make it work with --rebase-merges
      linear-assignment: a function to solve least-cost assignment problems
      Introduce `range-diff` to compare iterations of a topic branch
      range-diff: first rudimentary implementation
      range-diff: improve the order of the shown commits
      range-diff: also show the diff between patches
      range-diff: right-trim commit messages
      range-diff: indent the diffs just like tbdiff
      range-diff: suppress the diff headers
      range-diff: adjust the output of the commit pairs
      range-diff: do not show "function names" in hunk headers
      range-diff: use color for the commit pairs
      color: add the meta color GIT_COLOR_REVERSE
      diff: add an internal option to dual-color diffs of diffs
      range-diff: offer to dual-color the diffs
      range-diff --dual-color: skip white-space warnings
      range-diff: populate the man page
      completion: support `git range-diff`
      range-diff: left-pad patch numbers
      range-diff: make --dual-color the default mode
      range-diff: use dim/bold cues to improve dual color mode
      chainlint: fix for core.autocrlf=true

Johannes Sixt (1):
      mingw: enable atomic O_APPEND

Jonathan Nieder (12):
      object: add repository argument to grow_object_hash
      object: move grafts to object parser
      commit: add repository argument to commit_graft_pos
      commit: add repository argument to register_commit_graft
      commit: add repository argument to read_graft_file
      commit: add repository argument to prepare_commit_graft
      commit: add repository argument to lookup_commit_graft
      subtree test: add missing && to &&-chain
      subtree test: simplify preparation of expected results
      doc hash-function-transition: pick SHA-256 as NewHash
      partial-clone: render design doc using asciidoc
      Revert "Merge branch 'sb/submodule-core-worktree'"

Jonathan Tan (28):
      list-objects: check if filter is NULL before using
      fetch-pack: split up everything_local()
      fetch-pack: clear marks before re-marking
      fetch-pack: directly end negotiation if ACK ready
      fetch-pack: use ref adv. to prune "have" sent
      fetch-pack: make negotiation-related vars local
      fetch-pack: move common check and marking together
      fetch-pack: introduce negotiator API
      pack-bitmap: remove bitmap_git global variable
      pack-bitmap: add free function
      fetch-pack: write shallow, then check connectivity
      fetch-pack: support negotiation tip whitelist
      upload-pack: send refs' objects despite "filter"
      clone: check connectivity even if clone is partial
      revision: tolerate promised targets of tags
      tag: don't warn if target is missing but promised
      negotiator/skipping: skip commits during fetch
      commit-graph: refactor preparing commit graph
      object-store: add missing include
      commit-graph: add missing forward declaration
      commit-graph: add free_commit_graph
      commit-graph: store graph in struct object_store
      commit-graph: add repo arg to graph readers
      t5702: test fetch with multiple refspecs at a time
      fetch: send "refs/tags/" prefix upon CLI refspecs
      fetch-pack: unify ref in and out param
      repack: refactor setup of pack-objects cmd
      repack: repack promisor objects if -a or -A is set

Josh Steadmon (1):
      protocol-v2 doc: put HTTP headers after request

Jules Maselbas (1):
      send-email: fix tls AUTH when sending batch

Junio C Hamano (23):
      tests: clean after SANITY tests
      ewah: delete unused 'rlwit_discharge_empty()'
      Prepare to start 2.19 cycle
      First batch for 2.19 cycle
      Second batch for 2.19 cycle
      fixup! connect.h: avoid forward declaration of an enum
      fixup! refs/refs-internal.h: avoid forward declaration of an enum
      t3404: fix use of "VAR=VAL cmd" with a shell function
      Third batch for 2.19 cycle
      Fourth batch for 2.19 cycle
      remote: make refspec follow the same disambiguation rule as local refs
      Fifth batch for 2.19 cycle
      update-index: there no longer is `apply --index-info`
      gpg-interface: propagate exit status from gpg back to the callers
      Sixth batch for 2.19 cycle
      config.txt: clarify core.checkStat
      Seventh batch for 2.19 cycle
      sideband: do not read beyond the end of input
      Git 2.19-rc0
      Getting ready for -rc1
      Git 2.19-rc1
      Git 2.19-rc2
      Git 2.19

Kana Natsuno (2):
      t4018: add missing test cases for PHP
      userdiff: support new keywords in PHP hunk header

Kim Gybels (1):
      gc --auto: release pack files before auto packing

Kirill Smelkov (1):
      fetch-pack: test explicitly that --all can fetch tag references pointing to non-commits

Kyle Meyer (1):
      range-diff: update stale summary of --no-dual-color

Luis Marsano (2):
      git-credential-netrc: use in-tree Git.pm for tests
      git-credential-netrc: fix exit status when tests fail

Luke Diamand (6):
      git-p4: python3: replace <> with !=
      git-p4: python3: replace dict.has_key(k) with "k in dict"
      git-p4: python3: remove backticks
      git-p4: python3: basestring workaround
      git-p4: python3: use print() function
      git-p4: python3: fix octal constants

Marc Strapetz (1):
      Documentation: declare "core.ignoreCase" as internal variable

Martin Ågren (1):
      refspec: initalize `refspec_item` in `valid_fetch_refspec()`

Masaya Suzuki (2):
      builtin/send-pack: populate the default configs
      doc: fix want-capability separator

Max Kirillov (5):
      http-backend: cleanup writing to child process
      http-backend: respect CONTENT_LENGTH as specified by rfc3875
      unpack-trees: do not fail reset because of unmerged skipped entry
      http-backend: respect CONTENT_LENGTH for receive-pack
      http-backend: allow empty CONTENT_LENGTH

Michael Barabanov (1):
      filter-branch: skip commits present on --state-branch

Mike Hommey (1):
      fast-import: do not call diff_delta() with empty buffer

Nguyễn Thái Ngọc Duy (100):
      commit-slab.h: code split
      commit-slab: support shared commit-slab
      blame: use commit-slab for blame suspects instead of commit->util
      describe: use commit-slab for commit names instead of commit->util
      shallow.c: use commit-slab for commit depth instead of commit->util
      sequencer.c: use commit-slab to mark seen commits
      sequencer.c: use commit-slab to associate todo items to commits
      revision.c: use commit-slab for show_source
      bisect.c: use commit-slab for commit weight instead of commit->util
      name-rev: use commit-slab for rev-name instead of commit->util
      show-branch: use commit-slab for commit-name instead of commit->util
      show-branch: note about its object flags usage
      log: use commit-slab in prepare_bases() instead of commit->util
      merge: use commit-slab in merge remote desc instead of commit->util
      commit.h: delete 'util' field in struct commit
      diff: ignore --ita-[in]visible-in-index when diffing worktree-to-tree
      diff: turn --ita-invisible-in-index on by default
      t2203: add a test about "diff HEAD" case
      apply: add --intent-to-add
      parse-options: option to let --git-completion-helper show negative form
      completion: suppress some -no- options
      Add and use generic name->id mapping code for color slot parsing
      grep: keep all colors in an array
      fsck: factor out msg_id_info[] lazy initialization code
      help: add --config to list all available config
      fsck: produce camelCase config key names
      advice: keep config name in camelCase in advice_config[]
      am: move advice.amWorkDir parsing back to advice.c
      completion: drop the hard coded list of config vars
      completion: keep other config var completion in camelCase
      completion: support case-insensitive config vars
      log-tree: allow to customize 'grafted' color
      completion: complete general config vars in two steps
      upload-pack: reject shallow requests that would return nothing
      completion: collapse extra --no-.. options
      pack-objects: fix performance issues on packing large deltas
      Update messages in preparation for i18n
      archive-tar.c: mark more strings for translation
      archive-zip.c: mark more strings for translation
      builtin/config.c: mark more strings for translation
      builtin/grep.c: mark strings for translation
      builtin/pack-objects.c: mark more strings for translation
      builtin/replace.c: mark more strings for translation
      commit-graph.c: mark more strings for translation
      config.c: mark more strings for translation
      connect.c: mark more strings for translation
      convert.c: mark more strings for translation
      dir.c: mark more strings for translation
      environment.c: mark more strings for translation
      exec-cmd.c: mark more strings for translation
      object.c: mark more strings for translation
      pkt-line.c: mark more strings for translation
      refs.c: mark more strings for translation
      refspec.c: mark more strings for translation
      replace-object.c: mark more strings for translation
      sequencer.c: mark more strings for translation
      sha1-file.c: mark more strings for translation
      transport.c: mark more strings for translation
      transport-helper.c: mark more strings for translation
      pack-objects: document about thread synchronization
      apply.h: drop extern on func declaration
      attr.h: drop extern from function declaration
      blame.h: drop extern on func declaration
      cache-tree.h: drop extern from function declaration
      convert.h: drop 'extern' from function declaration
      diffcore.h: drop extern from function declaration
      diff.h: remove extern from function declaration
      line-range.h: drop extern from function declaration
      rerere.h: drop extern from function declaration
      repository.h: drop extern from function declaration
      revision.h: drop extern from function declaration
      submodule.h: drop extern from function declaration
      config.txt: reorder blame stuff to keep config keys sorted
      Makefile: add missing dependency for command-list.h
      diff.c: move read_index() code back to the caller
      cache-tree: wrap the_index based wrappers with #ifdef
      attr: remove an implicit dependency on the_index
      convert.c: remove an implicit dependency on the_index
      dir.c: remove an implicit dependency on the_index in pathspec code
      preload-index.c: use the right index instead of the_index
      ls-files: correct index argument to get_convert_attr_ascii()
      unpack-trees: remove 'extern' on function declaration
      unpack-trees: add a note about path invalidation
      unpack-trees: don't shadow global var the_index
      unpack-trees: convert clear_ce_flags* to avoid the_index
      unpack-trees: avoid the_index in verify_absent()
      pathspec.c: use the right index instead of the_index
      submodule.c: use the right index instead of the_index
      entry.c: use the right index instead of the_index
      attr: remove index from git_attr_set_direction()
      grep: use the right index instead of the_index
      archive.c: avoid access to the_index
      archive-*.c: use the right repository
      resolve-undo.c: use the right index instead of the_index
      apply.c: pass struct apply_state to more functions
      apply.c: make init_apply_state() take a struct repository
      apply.c: remove implicit dependency on the_index
      blame.c: remove implicit dependency on the_index
      cherry-pick: fix --quit not deleting CHERRY_PICK_HEAD
      generate-cmdlist.sh: collect config from all config.txt files

Nicholas Guriev (1):
      mergetool: don't suggest to continue after last file

Olga Telezhnaya (5):
      ref-filter: add info_source to valid_atom
      ref-filter: fill empty fields with empty values
      ref-filter: initialize eaten variable
      ref-filter: merge get_obj and get_object
      ref-filter: use oid_object_info() to get object

Peter Krefting (2):
      l10n: sv.po: Update Swedish translation(3608t0f0u)
      l10n: sv.po: Update Swedish translation (3958t0f0u)

Phillip Wood (7):
      add -p: fix counting empty context lines in edited patches
      sequencer: do not squash 'reword' commits when we hit conflicts
      sequencer: handle errors from read_author_ident()
      sequencer: fix quoting in write_author_script
      rebase -i: fix numbering in squash message
      t3430: add conflicting commit
      rebase -i: fix SIGSEGV when 'merge <branch>' fails

Prathamesh Chavan (4):
      submodule foreach: correct '$path' in nested submodules from a subdirectory
      submodule foreach: document '$sm_path' instead of '$path'
      submodule foreach: document variable '$displaypath'
      submodule: port submodule subcommand 'foreach' from shell to C

Ralf Thielow (1):
      l10n: de.po: translate 108 new messages

Ramsay Jones (3):
      fsck: check skiplist for object in fsck_blob()
      t6036: fix broken && chain in sub-shell
      t5562: avoid non-portable "export FOO=bar" construct

Raphaël Hertzog (1):
      l10n: fr: fix a message seen in git bisect

René Scharfe (10):
      remote: clear string_list after use in mv()
      add, update-index: fix --chmod argument help
      difftool: remove angular brackets from argument help
      pack-objects: specify --index-version argument help explicitly
      send-pack: specify --force-with-lease argument help explicitly
      shortlog: correct option help for -w
      parse-options: automatically infer PARSE_OPT_LITERAL_ARGHELP
      checkout-index: improve argument help for --stage
      remote: improve argument help for add --mirror
      parseopt: group literal string alternatives in argument help

SZEDER Gábor (30):
      update-ref --stdin: use skip_prefix()
      t7510-signed-commit: use 'test_must_fail'
      tests: make forging GPG signed commits and tags more robust
      t5541: clean up truncating access log
      t/lib-httpd: add the strip_access_log() helper function
      t/lib-httpd: avoid occasional failures when checking access.log
      t5608: fix broken &&-chain
      t9300: wait for background fast-import process to die after killing it
      travis-ci: run Coccinelle static analysis with two parallel jobs
      travis-ci: fail if Coccinelle static analysis found something to transform
      coccinelle: mark the 'coccicheck' make target as .PHONY
      coccinelle: use $(addsuffix) in 'coccicheck' make target
      coccinelle: exclude sha1dc source files from static analysis
      coccinelle: put sane filenames into output patches
      coccinelle: extract dedicated make target to clean Coccinelle's results
      travis-ci: include the trash directories of failed tests in the trace log
      t5318: use 'test_cmp_bin' to compare commit-graph files
      t5318: avoid unnecessary command substitutions
      t5310-pack-bitmaps: fix bogus 'pack-objects to file can use bitmap' test
      tests: use 'test_must_be_empty' instead of '! test -s'
      tests: use 'test_must_be_empty' instead of 'test ! -s'
      tests: use 'test_must_be_empty' instead of 'test_cmp /dev/null <out>'
      tests: use 'test_must_be_empty' instead of 'test_cmp <empty> <out>'
      t7501-commit: drop silly command substitution
      t0020-crlf: check the right file
      t4051-diff-function-context: read the right file
      t6018-rev-list-glob: fix 'empty stdin' test
      t3903-stash: don't try to grep non-existing file
      t3420-rebase-autostash: don't try to grep non-existing files
      t/lib-rebase.sh: support explicit 'pick' commands in 'fake_editor.sh'

Samuel Maftoul (1):
      branch: support configuring --sort via .gitconfig

Sebastian Kisela (2):
      git-instaweb: support Fedora/Red Hat apache module path
      git-instaweb: fix apache2 config with apache >= 2.4

Stefan Beller (87):
      repository: introduce parsed objects field
      object: add repository argument to create_object
      alloc: add repository argument to alloc_blob_node
      alloc: add repository argument to alloc_tree_node
      alloc: add repository argument to alloc_commit_node
      alloc: add repository argument to alloc_tag_node
      alloc: add repository argument to alloc_object_node
      alloc: add repository argument to alloc_report
      alloc: add repository argument to alloc_commit_index
      object: allow grow_object_hash to handle arbitrary repositories
      object: allow create_object to handle arbitrary repositories
      alloc: allow arbitrary repositories for alloc functions
      object-store: move object access functions to object-store.h
      shallow: add repository argument to set_alternate_shallow_file
      shallow: add repository argument to register_shallow
      shallow: add repository argument to check_shallow_file_for_update
      shallow: add repository argument to is_repository_shallow
      cache: convert get_graft_file to handle arbitrary repositories
      path.c: migrate global git_path_* to take a repository argument
      shallow: migrate shallow information into the object parser
      commit: allow prepare_commit_graft to handle arbitrary repositories
      commit: allow lookup_commit_graft to handle arbitrary repositories
      refs/packed-backend.c: close fd of empty file
      submodule--helper: plug mem leak in print_default_remote
      sequencer.c: plug leaks in do_pick_commit
      submodule: fix NULL correctness in renamed broken submodules
      t5526: test recursive submodules when fetching moved submodules
      submodule: unset core.worktree if no working tree is present
      submodule: ensure core.worktree is set after update
      submodule deinit: unset core.worktree
      submodule.c: report the submodule that an error occurs in
      sequencer.c: plug mem leak in git_sequencer_config
      .mailmap: merge different spellings of names
      object: add repository argument to parse_object
      object: add repository argument to lookup_object
      object: add repository argument to parse_object_buffer
      object: add repository argument to object_as_type
      blob: add repository argument to lookup_blob
      tree: add repository argument to lookup_tree
      commit: add repository argument to lookup_commit_reference_gently
      commit: add repository argument to lookup_commit_reference
      commit: add repository argument to lookup_commit
      commit: add repository argument to parse_commit_buffer
      commit: add repository argument to set_commit_buffer
      commit: add repository argument to get_cached_commit_buffer
      tag: add repository argument to lookup_tag
      tag: add repository argument to parse_tag_buffer
      tag: add repository argument to deref_tag
      object: allow object_as_type to handle arbitrary repositories
      object: allow lookup_object to handle arbitrary repositories
      blob: allow lookup_blob to handle arbitrary repositories
      tree: allow lookup_tree to handle arbitrary repositories
      commit: allow lookup_commit to handle arbitrary repositories
      tag: allow lookup_tag to handle arbitrary repositories
      tag: allow parse_tag_buffer to handle arbitrary repositories
      commit.c: allow parse_commit_buffer to handle arbitrary repositories
      commit-slabs: remove realloc counter outside of slab struct
      commit.c: migrate the commit buffer to the parsed object store
      commit.c: allow set_commit_buffer to handle arbitrary repositories
      commit.c: allow get_cached_commit_buffer to handle arbitrary repositories
      object.c: allow parse_object_buffer to handle arbitrary repositories
      object.c: allow parse_object to handle arbitrary repositories
      tag.c: allow deref_tag to handle arbitrary repositories
      commit.c: allow lookup_commit_reference_gently to handle arbitrary repositories
      commit.c: allow lookup_commit_reference to handle arbitrary repositories
      xdiff/xdiff.h: remove unused flags
      xdiff/xdiffi.c: remove unneeded function declarations
      t4015: avoid git as a pipe input
      diff.c: do not pass diff options as keydata to hashmap
      diff.c: adjust hash function signature to match hashmap expectation
      diff.c: add a blocks mode for moved code detection
      diff.c: decouple white space treatment from move detection algorithm
      diff.c: factor advance_or_nullify out of mark_color_as_moved
      diff.c: add white space mode to move detection that allows indent changes
      diff.c: offer config option to control ws handling in move detection
      xdiff/xhistogram: pass arguments directly to fall_back_to_classic_diff
      xdiff/xhistogram: factor out memory cleanup into free_index()
      xdiff/xhistogram: move index allocation into find_lcs
      Documentation/git-interpret-trailers: explain possible values
      xdiff/histogram: remove tail recursion
      t1300: document current behavior of setting options
      xdiff: reduce indent heuristic overhead
      config: fix case sensitive subsection names on writing
      git-config: document accidental multi-line setting in deprecated syntax
      git-submodule.sh: accept verbose flag in cmd_update to be non-quiet
      t7410: update to new style
      builtin/submodule--helper: remove stray new line

Taylor Blau (9):
      Documentation/config.txt: camel-case lineNumber for consistency
      grep.c: expose {,inverted} match column in match_line()
      grep.[ch]: extend grep_opt to allow showing matched column
      grep.c: display column number of first match
      builtin/grep.c: add '--column' option to 'git-grep(1)'
      grep.c: add configuration variables to show matched option
      contrib/git-jump/git-jump: jump to exact location
      grep.c: extract show_line_header()
      grep.c: teach 'git grep --only-matching'

Thomas Rast (1):
      range-diff: add tests

Tobias Klauser (1):
      git-rebase--preserve-merges: fix formatting of todo help message

Todd Zullinger (4):
      git-credential-netrc: minor whitespace cleanup in test script
      git-credential-netrc: make "all" default target of Makefile
      gitignore.txt: clarify default core.excludesfile path
      dir.c: fix typos in core.excludesfile comment

Trần Ngọc Quân (1):
      l10n: vi.po(3958t): updated Vietnamese translation v2.19.0 round 2

Ville Skyttä (1):
      Documentation: spelling and grammar fixes

Vladimir Parfinenko (1):
      rebase: fix documentation formatting

William Chargin (2):
      sha1-name.c: for ":/", find detached HEAD commits
      t: factor out FUNNYNAMES as shared lazy prereq

Xiaolong Ye (1):
      format-patch: clear UNINTERESTING flag before prepare_bases

brian m. carlson (21):
      send-email: add an auto option for transfer encoding
      send-email: accept long lines with suitable transfer encoding
      send-email: automatically determine transfer-encoding
      docs: correct RFC specifying email line length
      sequencer: pass absolute GIT_WORK_TREE to exec commands
      cache: update object ID functions for the_hash_algo
      tree-walk: replace hard-coded constants with the_hash_algo
      hex: switch to using the_hash_algo
      commit: express tree entry constants in terms of the_hash_algo
      strbuf: allocate space with GIT_MAX_HEXSZ
      sha1-name: use the_hash_algo when parsing object names
      refs/files-backend: use the_hash_algo for writing refs
      builtin/update-index: convert to using the_hash_algo
      builtin/update-index: simplify parsing of cacheinfo
      builtin/fmt-merge-msg: make hash independent
      builtin/merge: switch to use the_hash_algo
      builtin/merge-recursive: make hash independent
      diff: switch GIT_SHA1_HEXSZ to use the_hash_algo
      log-tree: switch GIT_SHA1_HEXSZ to the_hash_algo->hexsz
      sha1-file: convert constants to uses of the_hash_algo
      pretty: switch hard-coded constants to the_hash_algo

Ævar Arnfjörð Bjarmason (45):
      checkout tests: index should be clean after dwim checkout
      checkout.h: wrap the arguments to unique_tracking_name()
      checkout.c: introduce an *_INIT macro
      checkout.c: change "unique" member to "num_matches"
      checkout: pass the "num_matches" up to callers
      builtin/checkout.c: use "ret" variable for return
      checkout: add advice for ambiguous "checkout <branch>"
      checkout & worktree: introduce checkout.defaultRemote
      refspec: s/refspec_item_init/&_or_die/g
      refspec: add back a refspec_item_init() function
      doc hash-function-transition: note the lack of a changelog
      receive.fsck.<msg-id> tests: remove dead code
      config doc: don't describe *.fetchObjects twice
      config doc: unify the description of fsck.* and receive.fsck.*
      config doc: elaborate on what transfer.fsckObjects does
      config doc: elaborate on fetch.fsckObjects security
      transfer.fsckObjects tests: untangle confusing setup
      fetch: implement fetch.fsck.*
      fsck: test & document {fetch,receive}.fsck.* config fallback
      fsck: add stress tests for fsck.skipList
      fsck: test and document unknown fsck.<msg-id> values
      tests: make use of the test_must_be_empty function
      tests: make use of the test_must_be_empty function
      fetch tests: change "Tag" test tag to "testTag"
      push tests: remove redundant 'git push' invocation
      push tests: fix logic error in "push" test assertion
      push tests: add more testing for forced tag pushing
      push tests: assert re-pushing annotated tags
      negotiator: unknown fetch.negotiationAlgorithm should error out
      fetch doc: cross-link two new negotiation options
      sha1dc: update from upstream
      push: use PARSE_OPT_LITERAL_ARGHELP instead of unbalanced brackets
      fetch tests: correct a comment "remove it" -> "remove them"
      pull doc: fix a long-standing grammar error
      submodule: add more exhaustive up-path testing
      refactor various if (x) FREE_AND_NULL(x) to just FREE_AND_NULL(x)
      t2024: mark test using "checkout -p" with PERL prerequisite
      tests: fix and add lint for non-portable head -c N
      tests: fix and add lint for non-portable seq
      tests: fix comment syntax in chainlint.sed for AIX sed
      tests: use shorter labels in chainlint.sed for AIX sed
      tests: fix version-specific portability issue in Perl JSON
      tests: fix and add lint for non-portable grep --file
      tests: fix non-portable "${var:-"str"}" construct
      tests: fix non-portable iconv invocation

Łukasz Stelmach (1):
      completion: complete remote names too


^ permalink raw reply	[relevance 3%]

* Re: [PATCH 06/11] submodule.c: sort changed_submodule_names before searching it
  2018-09-06 18:03   ` Junio C Hamano
@ 2018-09-11 18:31     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-11 18:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Thu, Sep 6, 2018 at 11:03 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > Instead of sorting it after we created an unsorted list, we could insert
> > correctly into the list.
>
> It is unclear what problem you are solving, especially with
> subjunctive "could" there.  We are creating an unsorted list and
> then sorting it and you see it as a problem because it is just as
> easy and efficient to do the insertion sort while building up the
> list?  (don't react and answer without reading all the way to the
> end; I think I know what is going on).
>
> > As the unsorted append is in order of cache entry
> > names, this is already sorted if names were equal to paths for submodules.
>
> That may be a statement of a fact, but it is unclear how that fact
> relates to what the code is doing before this patch, or what the
> code updated by this patch is doing.
>
> > As submodule names are often the same as their path, the input is sorted
> > pretty well already, so let's just do the sort afterwards.
>
> It is unclear what (performance?) trade-off this senttence is trying
> to make.  It sounds as if it is claiming this:
>
>         We can string_list_insert() to maintain sorted-ness of the
>         list as we find new items, or we can string_list_append() to
>         build an unsorted list and sort it at the end just once.
>
>         To pick which one is more appropriate, we notice the fact
>         that we discover new items more or less in the already
>         sorted order.  That makes "append then sort" more
>         appropriate.
>
> But is that reasoning sensible?
>
> I'd imagine that append-then-sort would always be more efficient
> than insert-at-the-right-place-as-we-go, and the reason why we
> sometimes would need to do the latter is when we need to look up
> elements in the middle of building the list (e.g. we may want to
> de-dup, which requires us to look up a name from the ones we
> collected so far).

If we come across a (mostly) sorted list, then the insert-at-the-right-place
we'd come across the best case of insertion sort which is O(n), which
sounds better than append-then-sort as our sorting is a merge sort,
which has O(n log n) even in its best case (and needs to copy stuff
into a temp buffer and back).

By having the submodules named after its path, I strongly suspect
we have a mostly sorted list in nearly all cases except some really
interesting corner cases out there.

> And in this application, calculate_changed_submodule_paths()
> discover paths by calling collect_changed_submodules() which finds a
> mapping <submodule name, oid of commits> into a list sorted by
> submodule name, and then goes through that list and builds a list of
> submodules paths (which could be different from submodule names) by
> appending.  Only after this list is fully built, get_next_submodule()
> gets called, so making the latter use string_list_lookup() that assumes
> a sorted list is safe if we built the list by append-then-sort (iow,
> sortedness while building the list does not matter).
>
> Having analysed all that, I find it somewhat iffy that _append() is
> used there in the calculate_changed_submodule_paths() function.

Note that this is fixed in the later patch
"submodule.c: do not copy around submodule list"

>  It
> would cause the resulting changed_submodule_names list to hold the
> same name twice (or more),

This would be possible if there is a submodule at path A and another
submodule (at a different path) named "A", as we'll try hard to collect
names, but are also okay with path as we want to keep supporting the
historical use case of submodules.

> but I do not know if that would pose a
> problem to the consumer of the list.  Using "accumulate then sort
> before calling look-up" would not change it as string_list_sort()
> would not dedup, so I do not think this patch would introduce a new
> problem, though.

Yes, that is true, so we'd want to extend the message above to
mention the potential duplicates.

Thanks,
Stefan

^ permalink raw reply	[relevance 8%]

* Re: 2.19.0.rc2.windows.1: stash fails with dirty submodule
      [irrelevant] ` <20180908003514.GC225427@aiede.svl.corp.google.com>
@ 2018-09-11 22:24   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-11 22:24 UTC (permalink / raw)
  To: Jonathan Nieder
  Cc: Thomas Braun, git, Philip Oakley, git-for-windows, Johannes Schindelin

On Fri, Sep 7, 2018 at 5:35 PM Jonathan Nieder <jrnieder@gmail.com> wrote:
>
> Hi,
>
> Thomas Braun wrote:
>
> > I'm using git with stash and rebase builtins.
> >
> > $ git --version --build-options
> >
> > git version 2.19.0.rc2.windows.1
> [...]
> > mkdir test
> > cd test
> > git init
> > echo 1 > file
> > git add file
> > git commit file -m "message"
> > git submodule add ./ mysubmod
> > git commit -m "Add submodule"
> > echo 2 > mysubmod/file
> > git checkout -b mybranch
> > git rebase -i --autosquash master
> [...]
> > fatal: Unexpected stash response: ''
> >
> > and that used to work with older git versions.
>
> Thanks for reporting.  I'm cc-ing Dscho, who has been looking for
> reports of issues with the new experimental stash and rebase code[2].

(It tests fine on my machine and I have no Windows machine at hand,
so ...)
This finally gave me an opportunity to play around with gitgitgadget
and its integrated CI for all major OS, see
https://github.com/gitgitgadget/git/pull/38
which is just the bug report put into our test suite.

^ permalink raw reply	[relevance 5%]

* [PATCH 0/9] fetch: make sure submodule oids are fetched
@ 2018-09-11 23:49 Stefan Beller
  2018-09-11 23:49 ` [PATCH 3/9] submodule.c: fix indentation Stefan Beller
                   ` (7 more replies)
  0 siblings, 8 replies; 200+ results
From: Stefan Beller @ 2018-09-11 23:49 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

Currently when git-fetch is asked to recurse into submodules, it dispatches
a plain "git-fetch -C <submodule-dir>" (and some submodule related options
such as prefix and recusing strategy, but) without any information of the
remote or the tip that should be fetched.

This works surprisingly well in some workflows, not so well in others,
which this series aims to fix.

The first patches provide new basic functionality and do some refactoring;
the interesting part is in the two last patches.

This was discussed in
https://public-inbox.org/git/20180808221752.195419-1-sbeller@google.com/
and I think I addressed all feedback so far.

Thanks,
Stefan

Stefan Beller (9):
  string-list: add string_list_{pop, last} functions
  sha1-array: provide oid_array_filter
  submodule.c: fix indentation
  submodule.c: sort changed_submodule_names before searching it
  submodule: move global changed_submodule_names into fetch submodule
    struct
  submodule.c: do not copy around submodule list
  submodule: fetch in submodules git directory instead of in worktree
  fetch: retry fetching submodules if sha1 were not fetched
  builtin/fetch: check for submodule updates for non branch fetches

 builtin/fetch.c             |  14 +--
 sha1-array.c                |  18 ++++
 sha1-array.h                |   5 +
 string-list.c               |  14 +++
 string-list.h               |  11 +++
 submodule.c                 | 189 ++++++++++++++++++++++++++++--------
 t/t5526-fetch-submodules.sh |  23 ++++-
 7 files changed, 227 insertions(+), 47 deletions(-)

-- 
2.19.0.397.gdd90340f6a-goog


^ permalink raw reply	[relevance 10%]

* [PATCH 3/9] submodule.c: fix indentation
  2018-09-11 23:49 [PATCH 0/9] fetch: make sure submodule oids are fetched Stefan Beller
@ 2018-09-11 23:49 ` Stefan Beller
  2018-09-12 18:02   ` Junio C Hamano
  2018-09-11 23:49 ` [PATCH 4/9] submodule.c: sort changed_submodule_names before searching it Stefan Beller
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-11 23:49 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

The submodule subsystem is really bad at staying within 80 characters.
Fix it while we are here.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index a2b266fbfae..d29dfa3d1f5 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1244,7 +1244,8 @@ static int get_next_submodule(struct child_process *cp,
 		if (!submodule) {
 			const char *name = default_name_or_path(ce->name);
 			if (name) {
-				default_submodule.path = default_submodule.name = name;
+				default_submodule.path = name;
+				default_submodule.name = name;
 				submodule = &default_submodule;
 			}
 		}
@@ -1254,8 +1255,10 @@ static int get_next_submodule(struct child_process *cp,
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule || !unsorted_string_list_lookup(&changed_submodule_names,
-							 submodule->name))
+			if (!submodule ||
+			    !unsorted_string_list_lookup(
+					&changed_submodule_names,
+					submodule->name))
 				continue;
 			default_argv = "on-demand";
 			break;
-- 
2.19.0.397.gdd90340f6a-goog


^ permalink raw reply	[relevance 26%]

* [PATCH 4/9] submodule.c: sort changed_submodule_names before searching it
  2018-09-11 23:49 [PATCH 0/9] fetch: make sure submodule oids are fetched Stefan Beller
  2018-09-11 23:49 ` [PATCH 3/9] submodule.c: fix indentation Stefan Beller
@ 2018-09-11 23:49 ` Stefan Beller
  2018-09-12 18:18   ` Junio C Hamano
  2018-09-11 23:49 ` [PATCH 5/9] submodule: move global changed_submodule_names into fetch submodule struct Stefan Beller
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-11 23:49 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

We can string_list_insert() to maintain sorted-ness of the
list as we find new items, or we can string_list_append() to
build an unsorted list and sort it at the end just once.

To pick which one is more appropriate, we notice the fact
that we discover new items more or less in the already
sorted order.  That makes "append then sort" more
appropriate.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/submodule.c b/submodule.c
index d29dfa3d1f5..c6eff7699f3 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1256,7 +1256,7 @@ static int get_next_submodule(struct child_process *cp,
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
 			if (!submodule ||
-			    !unsorted_string_list_lookup(
+			    !string_list_lookup(
 					&changed_submodule_names,
 					submodule->name))
 				continue;
@@ -1350,6 +1350,7 @@ int fetch_populated_submodules(struct repository *r,
 	/* default value, "--submodule-prefix" and its value are added later */
 
 	calculate_changed_submodule_paths();
+	string_list_sort(&changed_submodule_names);
 	run_processes_parallel(max_parallel_jobs,
 			       get_next_submodule,
 			       fetch_start_failure,
-- 
2.19.0.397.gdd90340f6a-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 5/9] submodule: move global changed_submodule_names into fetch submodule struct
  2018-09-11 23:49 [PATCH 0/9] fetch: make sure submodule oids are fetched Stefan Beller
  2018-09-11 23:49 ` [PATCH 3/9] submodule.c: fix indentation Stefan Beller
  2018-09-11 23:49 ` [PATCH 4/9] submodule.c: sort changed_submodule_names before searching it Stefan Beller
@ 2018-09-11 23:49 ` Stefan Beller
  2018-09-11 23:49 ` [PATCH 6/9] submodule.c: do not copy around submodule list Stefan Beller
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-11 23:49 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

The `changed_submodule_names` are only used for fetching, so let's make it
part of the struct that is passed around for fetching submodules.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/submodule.c b/submodule.c
index c6eff7699f3..3520dd76bdf 100644
--- a/submodule.c
+++ b/submodule.c
@@ -24,7 +24,7 @@
 #include "object-store.h"
 
 static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
-static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
+
 static int initialized_fetch_ref_tips;
 static struct oid_array ref_tips_before_fetch;
 static struct oid_array ref_tips_after_fetch;
@@ -1110,7 +1110,22 @@ void check_for_new_submodule_commits(struct object_id *oid)
 	oid_array_append(&ref_tips_after_fetch, oid);
 }
 
-static void calculate_changed_submodule_paths(void)
+struct submodule_parallel_fetch {
+	int count;
+	struct argv_array args;
+	struct repository *r;
+	const char *prefix;
+	int command_line_option;
+	int default_option;
+	int quiet;
+	int result;
+
+	struct string_list changed_submodule_names;
+};
+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
+
+static void calculate_changed_submodule_paths(
+	struct submodule_parallel_fetch *spf)
 {
 	struct argv_array argv = ARGV_ARRAY_INIT;
 	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
@@ -1148,7 +1163,8 @@ static void calculate_changed_submodule_paths(void)
 			continue;
 
 		if (!submodule_has_commits(path, commits))
-			string_list_append(&changed_submodule_names, name->string);
+			string_list_append(&spf->changed_submodule_names,
+					   name->string);
 	}
 
 	free_submodules_oids(&changed_submodules);
@@ -1185,18 +1201,6 @@ int submodule_touches_in_range(struct object_id *excl_oid,
 	return ret;
 }
 
-struct submodule_parallel_fetch {
-	int count;
-	struct argv_array args;
-	struct repository *r;
-	const char *prefix;
-	int command_line_option;
-	int default_option;
-	int quiet;
-	int result;
-};
-#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0}
-
 static int get_fetch_recurse_config(const struct submodule *submodule,
 				    struct submodule_parallel_fetch *spf)
 {
@@ -1257,7 +1261,7 @@ static int get_next_submodule(struct child_process *cp,
 		case RECURSE_SUBMODULES_ON_DEMAND:
 			if (!submodule ||
 			    !string_list_lookup(
-					&changed_submodule_names,
+					&spf->changed_submodule_names,
 					submodule->name))
 				continue;
 			default_argv = "on-demand";
@@ -1349,8 +1353,8 @@ int fetch_populated_submodules(struct repository *r,
 	argv_array_push(&spf.args, "--recurse-submodules-default");
 	/* default value, "--submodule-prefix" and its value are added later */
 
-	calculate_changed_submodule_paths();
-	string_list_sort(&changed_submodule_names);
+	calculate_changed_submodule_paths(&spf);
+	string_list_sort(&spf.changed_submodule_names);
 	run_processes_parallel(max_parallel_jobs,
 			       get_next_submodule,
 			       fetch_start_failure,
@@ -1359,7 +1363,7 @@ int fetch_populated_submodules(struct repository *r,
 
 	argv_array_clear(&spf.args);
 out:
-	string_list_clear(&changed_submodule_names, 1);
+	string_list_clear(&spf.changed_submodule_names, 1);
 	return spf.result;
 }
 
-- 
2.19.0.397.gdd90340f6a-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 6/9] submodule.c: do not copy around submodule list
  2018-09-11 23:49 [PATCH 0/9] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (2 preceding siblings ...)
  2018-09-11 23:49 ` [PATCH 5/9] submodule: move global changed_submodule_names into fetch submodule struct Stefan Beller
@ 2018-09-11 23:49 ` Stefan Beller
  2018-09-12  2:25   ` Ramsay Jones
  2018-09-11 23:49 ` [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree Stefan Beller
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-11 23:49 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

'calculate_changed_submodule_paths' uses a local list to compute the
changed submodules, and then produces the result by copying appropriate
items into the result list.

Instead use the result list directly and prune items afterwards
using string_list_remove_empty_items.

By doin so we'll have access to the util pointer for longer that
contains the commits that we need to fetch, which will be
useful in a later patch.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/submodule.c b/submodule.c
index 3520dd76bdf..00a9a3c6b12 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1128,8 +1128,7 @@ static void calculate_changed_submodule_paths(
 	struct submodule_parallel_fetch *spf)
 {
 	struct argv_array argv = ARGV_ARRAY_INIT;
-	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
-	const struct string_list_item *name;
+	struct string_list_item *name;
 
 	/* No need to check if there are no submodules configured */
 	if (!submodule_from_path(the_repository, NULL, NULL))
@@ -1146,9 +1145,9 @@ static void calculate_changed_submodule_paths(
 	 * Collect all submodules (whether checked out or not) for which new
 	 * commits have been recorded upstream in "changed_submodule_names".
 	 */
-	collect_changed_submodules(&changed_submodules, &argv);
+	collect_changed_submodules(&spf->changed_submodule_names, &argv);
 
-	for_each_string_list_item(name, &changed_submodules) {
+	for_each_string_list_item(name, &spf->changed_submodule_names) {
 		struct oid_array *commits = name->util;
 		const struct submodule *submodule;
 		const char *path = NULL;
@@ -1162,12 +1161,14 @@ static void calculate_changed_submodule_paths(
 		if (!path)
 			continue;
 
-		if (!submodule_has_commits(path, commits))
-			string_list_append(&spf->changed_submodule_names,
-					   name->string);
+		if (submodule_has_commits(path, commits)) {
+			oid_array_clear(commits);
+			*name->string = '\0';
+		}
 	}
 
-	free_submodules_oids(&changed_submodules);
+	string_list_remove_empty_items(&spf->changed_submodule_names, 1);
+
 	argv_array_clear(&argv);
 	oid_array_clear(&ref_tips_before_fetch);
 	oid_array_clear(&ref_tips_after_fetch);
@@ -1363,7 +1364,7 @@ int fetch_populated_submodules(struct repository *r,
 
 	argv_array_clear(&spf.args);
 out:
-	string_list_clear(&spf.changed_submodule_names, 1);
+	free_submodules_oids(&spf.changed_submodule_names);
 	return spf.result;
 }
 
-- 
2.19.0.397.gdd90340f6a-goog


^ permalink raw reply	[relevance 17%]

* [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree
  2018-09-11 23:49 [PATCH 0/9] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (3 preceding siblings ...)
  2018-09-11 23:49 ` [PATCH 6/9] submodule.c: do not copy around submodule list Stefan Beller
@ 2018-09-11 23:49 ` Stefan Beller
  2018-09-12 18:36   ` Junio C Hamano
  2018-09-11 23:49 ` [PATCH 8/9] fetch: retry fetching submodules if sha1 were not fetched Stefan Beller
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-11 23:49 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

This patch started as a refactoring to make 'get_next_submodule' more
readable, but upon doing so, I realized that git-fetch actually doesn't
need to be run in the worktree. So let's run it in the git dir instead.

That should pave the way towards fetching submodules that are currently
not checked out.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 submodule.c                 | 43 ++++++++++++++++++++++++++-----------
 t/t5526-fetch-submodules.sh |  7 +++++-
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/submodule.c b/submodule.c
index 00a9a3c6b12..1e6781504f0 100644
--- a/submodule.c
+++ b/submodule.c
@@ -481,6 +481,12 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_GIT_DIR_ENVIRONMENT);
 }
 
+static void prepare_submodule_repo_env_in_gitdir(struct argv_array *out)
+{
+	prepare_submodule_repo_env_no_git_dir(out);
+	argv_array_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT);
+}
+
 /* Helper function to display the submodule header line prior to the full
  * summary output. If it can locate the submodule objects directory it will
  * attempt to lookup both the left and right commits and put them into the
@@ -1227,6 +1233,27 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+static const char *get_submodule_git_dir(struct repository *r, const char *path)
+{
+	struct repository subrepo;
+	const char *ret;
+
+	if (repo_submodule_init(&subrepo, r, path)) {
+		/* no entry in .gitmodules? */
+		struct strbuf gitdir = STRBUF_INIT;
+		strbuf_repo_worktree_path(&gitdir, r, "%s/.git", path);
+		if (repo_init(&subrepo, gitdir.buf, NULL)) {
+			strbuf_release(&gitdir);
+			return NULL;
+		}
+	}
+
+	ret = xstrdup(subrepo.gitdir);
+	repo_clear(&subrepo);
+
+	return ret;
+}
+
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
@@ -1234,8 +1261,6 @@ static int get_next_submodule(struct child_process *cp,
 	struct submodule_parallel_fetch *spf = data;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
-		struct strbuf submodule_path = STRBUF_INIT;
-		struct strbuf submodule_git_dir = STRBUF_INIT;
 		struct strbuf submodule_prefix = STRBUF_INIT;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *git_dir, *default_argv;
@@ -1274,16 +1299,12 @@ static int get_next_submodule(struct child_process *cp,
 			continue;
 		}
 
-		strbuf_repo_worktree_path(&submodule_path, spf->r, "%s", ce->name);
-		strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
 		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
-		git_dir = read_gitfile(submodule_git_dir.buf);
-		if (!git_dir)
-			git_dir = submodule_git_dir.buf;
-		if (is_directory(git_dir)) {
+		git_dir = get_submodule_git_dir(spf->r, ce->name);
+		if (git_dir) {
 			child_process_init(cp);
-			cp->dir = strbuf_detach(&submodule_path, NULL);
-			prepare_submodule_repo_env(&cp->env_array);
+			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+			cp->dir = git_dir;
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
@@ -1295,8 +1316,6 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_push(&cp->args, submodule_prefix.buf);
 			ret = 1;
 		}
-		strbuf_release(&submodule_path);
-		strbuf_release(&submodule_git_dir);
 		strbuf_release(&submodule_prefix);
 		if (ret) {
 			spf->count++;
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 6c2f9b2ba26..42692219a1a 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -566,7 +566,12 @@ test_expect_success 'fetching submodule into a broken repository' '
 
 	test_must_fail git -C dst status &&
 	test_must_fail git -C dst diff &&
-	test_must_fail git -C dst fetch --recurse-submodules
+
+	# git-fetch cannot find the git directory of the submodule,
+	# so it will do nothing, successfully, as it cannot distinguish between
+	# this broken submodule and a submodule that was just set active but
+	# not cloned yet
+	git -C dst fetch --recurse-submodules
 '
 
 test_expect_success "fetch new commits when submodule got renamed" '
-- 
2.19.0.397.gdd90340f6a-goog


^ permalink raw reply	[relevance 28%]

* [PATCH 8/9] fetch: retry fetching submodules if sha1 were not fetched
  2018-09-11 23:49 [PATCH 0/9] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (4 preceding siblings ...)
  2018-09-11 23:49 ` [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree Stefan Beller
@ 2018-09-11 23:49 ` Stefan Beller
  2018-09-12 19:03   ` Junio C Hamano
  2018-09-11 23:49 ` [PATCH 9/9] builtin/fetch: check for submodule updates for non branch fetches Stefan Beller
  2018-09-17 21:35 ` [PATCHv2 0/9] fetch: make sure submodule oids are fetched Stefan Beller
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-11 23:49 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

Currently when git-fetch is asked to recurse into submodules, it dispatches
a plain "git-fetch -C <submodule-dir>" (and some submodule related options
such as prefix and recusing strategy, but) without any information of the
remote or the tip that should be fetched.

This works surprisingly well in some workflows (such as using submodules
as a third party library), while not so well in other scenarios, such
as in a Gerrit topic-based workflow, that can tie together changes
(potentially across repositories) on the server side. One of the parts
of such a Gerrit workflow is to download a change when wanting to examine
it, and you'd want to have its submodule changes that are in the same
topic downloaded as well. However these submodule changes reside in their
own repository in their own ref (refs/changes/<int>).

Retry fetching a submodule if the object id that the superproject points
to, cannot be found.

This doesn't support fetching to FETCH_HEAD yet, but only into a local
branch. To make fetching into FETCH_HEAD work, we need some refactoring
in builtin/fetch.c to adjust the calls to 'check_for_new_submodule_commits'
that is coming in the next patch.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/fetch.c             |  9 ++--
 submodule.c                 | 87 ++++++++++++++++++++++++++++++++++++-
 t/t5526-fetch-submodules.sh | 16 +++++++
 3 files changed, 104 insertions(+), 8 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 61bec5d213d..95c44bf6ffa 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -700,8 +700,7 @@ static int update_local_ref(struct ref *ref,
 			what = _("[new ref]");
 		}
 
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
+		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
 			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref(msg, ref, 0);
 		format_display(display, r ? '!' : '*', what,
@@ -716,8 +715,7 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "..");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
+		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
 			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("fast-forward", ref, 1);
 		format_display(display, r ? '!' : ' ', quickref.buf,
@@ -731,8 +729,7 @@ static int update_local_ref(struct ref *ref,
 		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
 		strbuf_addstr(&quickref, "...");
 		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
-		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
-		    (recurse_submodules != RECURSE_SUBMODULES_ON))
+		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
 			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("forced-update", ref, 1);
 		format_display(display, r ? '!' : '+', quickref.buf,
diff --git a/submodule.c b/submodule.c
index 1e6781504f0..a75146e89cf 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1127,8 +1127,11 @@ struct submodule_parallel_fetch {
 	int result;
 
 	struct string_list changed_submodule_names;
+	struct string_list retry;
 };
-#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \
+		  STRING_LIST_INIT_DUP, \
+		  STRING_LIST_INIT_NODUP}
 
 static void calculate_changed_submodule_paths(
 	struct submodule_parallel_fetch *spf)
@@ -1259,8 +1262,10 @@ static int get_next_submodule(struct child_process *cp,
 {
 	int ret = 0;
 	struct submodule_parallel_fetch *spf = data;
+	struct string_list_item *it;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
+		int recurse_config;
 		struct strbuf submodule_prefix = STRBUF_INIT;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *git_dir, *default_argv;
@@ -1280,7 +1285,9 @@ static int get_next_submodule(struct child_process *cp,
 			}
 		}
 
-		switch (get_fetch_recurse_config(submodule, spf))
+		recurse_config = get_fetch_recurse_config(submodule, spf);
+
+		switch (recurse_config)
 		{
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
@@ -1319,9 +1326,50 @@ static int get_next_submodule(struct child_process *cp,
 		strbuf_release(&submodule_prefix);
 		if (ret) {
 			spf->count++;
+			if (submodule != &default_submodule)
+				/* discard const-ness: */
+				*task_cb = (void*)submodule;
 			return 1;
 		}
 	}
+
+retry_next:
+
+	if (spf->retry.nr) {
+		struct strbuf submodule_prefix = STRBUF_INIT;
+		const struct submodule *sub;
+
+		it = string_list_last(&spf->retry);
+		sub = submodule_from_name(spf->r, &null_oid,
+					  it->string);
+
+		child_process_init(cp);
+		cp->dir = get_submodule_git_dir(spf->r, sub->path);
+		if (!cp->dir) {
+			string_list_pop(&spf->retry, 0);
+			goto retry_next;
+		}
+		prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+		cp->git_cmd = 1;
+
+		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, sub->path);
+		argv_array_init(&cp->args);
+		argv_array_pushv(&cp->args, spf->args.argv);
+		argv_array_push(&cp->args, "on-demand");
+		argv_array_push(&cp->args, "--submodule-prefix");
+		argv_array_push(&cp->args, submodule_prefix.buf);
+
+		/* NEEDSWORK: have get_default_remote from s--h */
+		argv_array_push(&cp->args, "origin");
+		oid_array_for_each_unique(it->util,
+					  append_oid_to_argv, &cp->args);
+
+		*task_cb = NULL; /* make sure we do not recurse forever */
+		strbuf_release(&submodule_prefix);
+		string_list_pop(&spf->retry, 0);
+		return 1;
+	}
+
 	return 0;
 }
 
@@ -1335,14 +1383,49 @@ static int fetch_start_failure(struct strbuf *err,
 	return 0;
 }
 
+static int commit_exists_in_sub(const struct object_id *oid, void *data)
+{
+	struct repository *subrepo = data;
+
+	enum object_type type = oid_object_info(subrepo, oid, NULL);
+
+	return type != OBJ_COMMIT;
+}
+
 static int fetch_finish(int retvalue, struct strbuf *err,
 			void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
+	struct submodule *sub = task_cb;
+	struct repository subrepo;
 
 	if (retvalue)
 		spf->result = 1;
 
+	if (!sub)
+		return 0;
+
+	if (repo_submodule_init(&subrepo, spf->r, sub->path) < 0)
+		warning(_("Could not get submodule repository for submodule '%s' in repository '%s'"),
+			  sub->path, spf->r->worktree);
+	else {
+		struct string_list_item *it;
+		struct oid_array *commits;
+
+		it = string_list_lookup(&spf->changed_submodule_names, sub->name);
+		if (!it)
+			return 0;
+
+		commits = it->util;
+		oid_array_filter(commits,
+				 commit_exists_in_sub,
+				 &subrepo);
+
+		if (commits->nr)
+			string_list_append(&spf->retry, sub->name)
+				->util = commits;
+	}
+
 	return 0;
 }
 
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 42692219a1a..af12c50e7dd 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -605,4 +605,20 @@ test_expect_success "fetch new commits when submodule got renamed" '
 	test_cmp expect actual
 '
 
+test_expect_success "fetch new commits on-demand when they are not reachable" '
+	git checkout --detach &&
+	C=$(git -C submodule commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/1 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	git commit -m "updated submodule outside of refs/heads" &&
+	D=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/2 $D &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules --recurse-submodules-default on-demand origin refs/changes/2:refs/heads/my_branch &&
+		git -C submodule cat-file -t $C &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
 test_done
-- 
2.19.0.397.gdd90340f6a-goog


^ permalink raw reply	[relevance 19%]

* [PATCH 9/9] builtin/fetch: check for submodule updates for non branch fetches
  2018-09-11 23:49 [PATCH 0/9] fetch: make sure submodule oids are fetched Stefan Beller
                   ` (5 preceding siblings ...)
  2018-09-11 23:49 ` [PATCH 8/9] fetch: retry fetching submodules if sha1 were not fetched Stefan Beller
@ 2018-09-11 23:49 ` Stefan Beller
  2018-09-12 19:20   ` Junio C Hamano
  2018-09-17 21:35 ` [PATCHv2 0/9] fetch: make sure submodule oids are fetched Stefan Beller
  7 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-09-11 23:49 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

For Gerrit users that use submodules the invocation of fetch without a
branch is their main use case.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/fetch.c             | 5 ++++-
 t/t5526-fetch-submodules.sh | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 95c44bf6ffa..ea6ecd123e7 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -887,11 +887,14 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
 				rc |= update_local_ref(ref, what, rm, &note,
 						       summary_width);
 				free(ref);
-			} else
+			} else {
+				check_for_new_submodule_commits(&rm->old_oid);
 				format_display(&note, '*',
 					       *kind ? kind : "branch", NULL,
 					       *what ? what : "HEAD",
 					       "FETCH_HEAD", summary_width);
+			}
+
 			if (note.len) {
 				if (verbosity >= 0 && !shown_url) {
 					fprintf(stderr, _("From %.*s\n"),
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index af12c50e7dd..a509eabb044 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -615,7 +615,7 @@ test_expect_success "fetch new commits on-demand when they are not reachable" '
 	git update-ref refs/changes/2 $D &&
 	(
 		cd downstream &&
-		git fetch --recurse-submodules --recurse-submodules-default on-demand origin refs/changes/2:refs/heads/my_branch &&
+		git fetch --recurse-submodules origin refs/changes/2 &&
 		git -C submodule cat-file -t $C &&
 		git checkout --recurse-submodules FETCH_HEAD
 	)
-- 
2.19.0.397.gdd90340f6a-goog


^ permalink raw reply	[relevance 24%]

* Re: [PATCH 6/9] submodule.c: do not copy around submodule list
  2018-09-11 23:49 ` [PATCH 6/9] submodule.c: do not copy around submodule list Stefan Beller
@ 2018-09-12  2:25   ` Ramsay Jones
  0 siblings, 0 replies; 200+ results
From: Ramsay Jones @ 2018-09-12  2:25 UTC (permalink / raw)
  To: Stefan Beller, git



On 12/09/18 00:49, Stefan Beller wrote:
> 'calculate_changed_submodule_paths' uses a local list to compute the
> changed submodules, and then produces the result by copying appropriate
> items into the result list.
> 
> Instead use the result list directly and prune items afterwards
> using string_list_remove_empty_items.
> 
> By doin so we'll have access to the util pointer for longer that

s/doin/doing/

ATB,
Ramsay Jones

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 3/9] submodule.c: fix indentation
  2018-09-11 23:49 ` [PATCH 3/9] submodule.c: fix indentation Stefan Beller
@ 2018-09-12 18:02   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-09-12 18:02 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> The submodule subsystem is really bad at staying within 80 characters.
> Fix it while we are here.

Makes sense.  Thanks.

>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/submodule.c b/submodule.c
> index a2b266fbfae..d29dfa3d1f5 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1244,7 +1244,8 @@ static int get_next_submodule(struct child_process *cp,
>  		if (!submodule) {
>  			const char *name = default_name_or_path(ce->name);
>  			if (name) {
> -				default_submodule.path = default_submodule.name = name;
> +				default_submodule.path = name;
> +				default_submodule.name = name;
>  				submodule = &default_submodule;
>  			}
>  		}
> @@ -1254,8 +1255,10 @@ static int get_next_submodule(struct child_process *cp,
>  		default:
>  		case RECURSE_SUBMODULES_DEFAULT:
>  		case RECURSE_SUBMODULES_ON_DEMAND:
> -			if (!submodule || !unsorted_string_list_lookup(&changed_submodule_names,
> -							 submodule->name))
> +			if (!submodule ||
> +			    !unsorted_string_list_lookup(
> +					&changed_submodule_names,
> +					submodule->name))
>  				continue;
>  			default_argv = "on-demand";
>  			break;

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 4/9] submodule.c: sort changed_submodule_names before searching it
  2018-09-11 23:49 ` [PATCH 4/9] submodule.c: sort changed_submodule_names before searching it Stefan Beller
@ 2018-09-12 18:18   ` Junio C Hamano
  2018-09-12 19:06     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-09-12 18:18 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> We can string_list_insert() to maintain sorted-ness of the
> list as we find new items, or we can string_list_append() to
> build an unsorted list and sort it at the end just once.
>
> To pick which one is more appropriate, we notice the fact
> that we discover new items more or less in the already
> sorted order.  That makes "append then sort" more
> appropriate.

Sorry, but I still do not get the math you are implying in the
second paragraph.  Are you saying that append-then-sort is efficient
when items being appended is already sorted?  That depends on the
sorting algorithm used, so the logic is incomplete unless you say
"given that we use X for sorting,...", I think.

Do we really discover new items in sorted order, by the way?  In a
single diff invocation made inside collect_changed_submodules() for
one commit in the superproject's history, we will grab changed paths
in the pathname order (i.e. sorted); if the superproject's tip commit
touches the submodules at paths A and Z, we will discover these two
paths in sorted order.

But because we are walking the superproject's history to collect all
paths that have been affected in that function, and repeatedly
calling diff as we discover commit in the superproject's history, I
am not sure how well the resulting set of paths would be sorted.

The tip commit in superproject's history may have modified the
submodule at path X, the parent of that commit may have touched the
submodule at path M, and its parent may have touched the submodule
at path A.  Don't we end up grabbing these paths in that discoverd
order, i.e. X, M and A?

I still think changing it from "insert as we find an item, keeping
the list sorted" to "append all and then sort before we start
looking things up from the result" makes sense, but I do not think
the "we find things in sorted order" is either true, or it would
affect the choice between the two.  A justification to choose the
latter I can think of that makes sense is that we don't have to pay
cost to keep the list sorted while building it because we do not do
any look-up while building the list.

> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/submodule.c b/submodule.c
> index d29dfa3d1f5..c6eff7699f3 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1256,7 +1256,7 @@ static int get_next_submodule(struct child_process *cp,
>  		case RECURSE_SUBMODULES_DEFAULT:
>  		case RECURSE_SUBMODULES_ON_DEMAND:
>  			if (!submodule ||
> -			    !unsorted_string_list_lookup(
> +			    !string_list_lookup(
>  					&changed_submodule_names,
>  					submodule->name))
>  				continue;
> @@ -1350,6 +1350,7 @@ int fetch_populated_submodules(struct repository *r,
>  	/* default value, "--submodule-prefix" and its value are added later */
>  
>  	calculate_changed_submodule_paths();
> +	string_list_sort(&changed_submodule_names);
>  	run_processes_parallel(max_parallel_jobs,
>  			       get_next_submodule,
>  			       fetch_start_failure,

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree
  2018-09-11 23:49 ` [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree Stefan Beller
@ 2018-09-12 18:36   ` Junio C Hamano
  2018-09-13 19:29     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-09-12 18:36 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> This patch started as a refactoring to make 'get_next_submodule' more
> readable, but upon doing so, I realized that git-fetch actually doesn't
> need to be run in the worktree. So let's run it in the git dir instead.

It may be clear to the author but not clear to the reader of the
above paragraph that "worktree", "fetch" and "git dir" all refer to
the recursively invoked operation that updates the submodules
repository.  s/git-fetch/"git fetch" for the submodule/ should be
sufficient to help the readers.

> That should pave the way towards fetching submodules that are currently
> not checked out.

Very good.

> +static void prepare_submodule_repo_env_in_gitdir(struct argv_array *out)
> +{
> +	prepare_submodule_repo_env_no_git_dir(out);
> +	argv_array_pushf(out, "%s=.", GIT_DIR_ENVIRONMENT);
> +}
> +
>  /* Helper function to display the submodule header line prior to the full
>   * summary output. If it can locate the submodule objects directory it will
>   * attempt to lookup both the left and right commits and put them into the
> @@ -1227,6 +1233,27 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
>  	return spf->default_option;
>  }
>  
> +static const char *get_submodule_git_dir(struct repository *r, const char *path)
> +{
> +	struct repository subrepo;
> +	const char *ret;
> +
> +	if (repo_submodule_init(&subrepo, r, path)) {
> +		/* no entry in .gitmodules? */
> +		struct strbuf gitdir = STRBUF_INIT;
> +		strbuf_repo_worktree_path(&gitdir, r, "%s/.git", path);
> +		if (repo_init(&subrepo, gitdir.buf, NULL)) {
> +			strbuf_release(&gitdir);
> +			return NULL;
> +		}

This is for the modern "absorbed" layout?  Do we get a notice and
encouragement to migrate from the historical layout, or there is no
need to (e.g. the migration happens automatically in some other
codepaths)?

> +	}
> +
> +	ret = xstrdup(subrepo.gitdir);
> +	repo_clear(&subrepo);
> +
> +	return ret;
> +}

Returned value from this function is xstrdup()'ed so the caller
owns, not borrows.  There is no need to return "const char *" from
this function.  Also the caller needs to free it once done.

>  static int get_next_submodule(struct child_process *cp,
>  			      struct strbuf *err, void *data, void **task_cb)
>  {
> @@ -1234,8 +1261,6 @@ static int get_next_submodule(struct child_process *cp,
>  	struct submodule_parallel_fetch *spf = data;
>  
>  	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
> -		struct strbuf submodule_path = STRBUF_INIT;
> -		struct strbuf submodule_git_dir = STRBUF_INIT;
>  		struct strbuf submodule_prefix = STRBUF_INIT;
>  		const struct cache_entry *ce = spf->r->index->cache[spf->count];
>  		const char *git_dir, *default_argv;
> @@ -1274,16 +1299,12 @@ static int get_next_submodule(struct child_process *cp,
>  			continue;
>  		}
>  
> -		strbuf_repo_worktree_path(&submodule_path, spf->r, "%s", ce->name);
> -		strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
>  		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
> -		git_dir = read_gitfile(submodule_git_dir.buf);
> -		if (!git_dir)
> -			git_dir = submodule_git_dir.buf;
> -		if (is_directory(git_dir)) {

In the old code, git_dir came from read_gitfile() which borrowed.

> +		git_dir = get_submodule_git_dir(spf->r, ce->name);

In the new code, we own it, so we'd eventually need to get rid of
it.  How does it happen?

> +		if (git_dir) {
>  			child_process_init(cp);
> -			cp->dir = strbuf_detach(&submodule_path, NULL);
> -			prepare_submodule_repo_env(&cp->env_array);
> +			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
> +			cp->dir = git_dir;

Does cp now own it and cp->dir gets freed once run_processes_parallel()
is done with this task?  Or is cp->dir simply leaking?  The old code
gave the result of strbuf_detach(), so even if cp->dir is leaking,
the leak is not new in this patch.

>  			cp->git_cmd = 1;
>  			if (!spf->quiet)
>  				strbuf_addf(err, "Fetching submodule %s%s\n",
> @@ -1295,8 +1316,6 @@ static int get_next_submodule(struct child_process *cp,
>  			argv_array_push(&cp->args, submodule_prefix.buf);
>  			ret = 1;
>  		}
> -		strbuf_release(&submodule_path);
> -		strbuf_release(&submodule_git_dir);

But if it is a leak, it is easily plugged by freeing git_dir here, I
think.

Thanks.


>  		strbuf_release(&submodule_prefix);
>  		if (ret) {
>  			spf->count++;
> diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
> index 6c2f9b2ba26..42692219a1a 100755
> --- a/t/t5526-fetch-submodules.sh
> +++ b/t/t5526-fetch-submodules.sh
> @@ -566,7 +566,12 @@ test_expect_success 'fetching submodule into a broken repository' '
>  
>  	test_must_fail git -C dst status &&
>  	test_must_fail git -C dst diff &&
> -	test_must_fail git -C dst fetch --recurse-submodules
> +
> +	# git-fetch cannot find the git directory of the submodule,
> +	# so it will do nothing, successfully, as it cannot distinguish between
> +	# this broken submodule and a submodule that was just set active but
> +	# not cloned yet
> +	git -C dst fetch --recurse-submodules
>  '
>  
>  test_expect_success "fetch new commits when submodule got renamed" '

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 8/9] fetch: retry fetching submodules if sha1 were not fetched
  2018-09-11 23:49 ` [PATCH 8/9] fetch: retry fetching submodules if sha1 were not fetched Stefan Beller
@ 2018-09-12 19:03   ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-09-12 19:03 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> Retry fetching a submodule if the object id that the superproject points
> to, cannot be found.

By object name?  By attempting to fetch all refs?  Or by doing
something else?  Fetching by the exact object name is the most
efficient approach, but the server side may not be prepared to
serve such a request, and that is why spelling it out here would
help the readers.

> This doesn't support fetching to FETCH_HEAD yet, but only into a local
> branch.

It is not clear if this sentence is talking about the fetch done at
the superproject level, or what happens in a submodule repository
when this "retrying" happens.  Assuming that it is the former,
perhaps

    This retrying does not happen when the "git fetch" done at the
    superproject is not storing the fetched results in remote
    tracking branches (i.e. instead just recording them to
    FETCH_HEAD) in this step.

would help the readers understand what you are trying to say.

> To make fetching into FETCH_HEAD work, we need some refactoring
> in builtin/fetch.c to adjust the calls to 'check_for_new_submodule_commits'
> that is coming in the next patch.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  builtin/fetch.c             |  9 ++--
>  submodule.c                 | 87 ++++++++++++++++++++++++++++++++++++-
>  t/t5526-fetch-submodules.sh | 16 +++++++
>  3 files changed, 104 insertions(+), 8 deletions(-)
>
> diff --git a/builtin/fetch.c b/builtin/fetch.c
> index 61bec5d213d..95c44bf6ffa 100644
> --- a/builtin/fetch.c
> +++ b/builtin/fetch.c
> @@ -700,8 +700,7 @@ static int update_local_ref(struct ref *ref,
>  			what = _("[new ref]");
>  		}
>  
> -		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
> -		    (recurse_submodules != RECURSE_SUBMODULES_ON))
> +		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
>  			check_for_new_submodule_commits(&ref->new_oid);
>  		r = s_update_ref(msg, ref, 0);
>  		format_display(display, r ? '!' : '*', what,
> @@ -716,8 +715,7 @@ static int update_local_ref(struct ref *ref,
>  		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
>  		strbuf_addstr(&quickref, "..");
>  		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
> -		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
> -		    (recurse_submodules != RECURSE_SUBMODULES_ON))
> +		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
>  			check_for_new_submodule_commits(&ref->new_oid);
>  		r = s_update_ref("fast-forward", ref, 1);
>  		format_display(display, r ? '!' : ' ', quickref.buf,
> @@ -731,8 +729,7 @@ static int update_local_ref(struct ref *ref,
>  		strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
>  		strbuf_addstr(&quickref, "...");
>  		strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
> -		if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
> -		    (recurse_submodules != RECURSE_SUBMODULES_ON))
> +		if (recurse_submodules != RECURSE_SUBMODULES_OFF)
>  			check_for_new_submodule_commits(&ref->new_oid);
>  		r = s_update_ref("forced-update", ref, 1);
>  		format_display(display, r ? '!' : '+', quickref.buf,

All of these used to react to any value set to recurse-submodules
that is not off or on (i.e. on-demand, default, none), but now
unless the value is explicitly set to off, we call into the check.
It is not immediately clear how that change is linked to the
retrying.  "When set to 'on', we did not check for new commits, but
now we do" can be read from the patch text but not the reasoning
behind it.

What was the reason why we didn't call "check-for-new" when recurse
is set to "on"?  Is it because "we are going to recurse anyway, so
there is no need to check to decide if we need to fetch in
submodule"?  And the reason why we now need to call when we are set
to recurse anyway is because check-for-new now learns much more than
just "do we need to cd there and run git-fetch? yes/no?"

The answers to these two questions would help readers in the log
message.

> diff --git a/submodule.c b/submodule.c
> index 1e6781504f0..a75146e89cf 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1127,8 +1127,11 @@ struct submodule_parallel_fetch {
>  	int result;
>  
>  	struct string_list changed_submodule_names;
> +	struct string_list retry;
>  };
> -#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
> +#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, \
> +		  STRING_LIST_INIT_DUP, \
> +		  STRING_LIST_INIT_NODUP}
>  
>  static void calculate_changed_submodule_paths(
>  	struct submodule_parallel_fetch *spf)
> @@ -1259,8 +1262,10 @@ static int get_next_submodule(struct child_process *cp,
>  {
>  	int ret = 0;
>  	struct submodule_parallel_fetch *spf = data;
> +	struct string_list_item *it;
>  
>  	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
> +		int recurse_config;
>  		struct strbuf submodule_prefix = STRBUF_INIT;
>  		const struct cache_entry *ce = spf->r->index->cache[spf->count];
>  		const char *git_dir, *default_argv;
> @@ -1280,7 +1285,9 @@ static int get_next_submodule(struct child_process *cp,
>  			}
>  		}
>  
> -		switch (get_fetch_recurse_config(submodule, spf))
> +		recurse_config = get_fetch_recurse_config(submodule, spf);
> +
> +		switch (recurse_config)
>  		{
>  		default:
>  		case RECURSE_SUBMODULES_DEFAULT:
> @@ -1319,9 +1326,50 @@ static int get_next_submodule(struct child_process *cp,
>  		strbuf_release(&submodule_prefix);
>  		if (ret) {
>  			spf->count++;
> +			if (submodule != &default_submodule)
> +				/* discard const-ness: */
> +				*task_cb = (void*)submodule;
>  			return 1;
>  		}
>  	}
> +
> +retry_next:
> +
> +	if (spf->retry.nr) {
> +		struct strbuf submodule_prefix = STRBUF_INIT;
> +		const struct submodule *sub;
> +
> +		it = string_list_last(&spf->retry);
> +		sub = submodule_from_name(spf->r, &null_oid,
> +					  it->string);
> +
> +		child_process_init(cp);
> +		cp->dir = get_submodule_git_dir(spf->r, sub->path);
> +		if (!cp->dir) {
> +			string_list_pop(&spf->retry, 0);
> +			goto retry_next;
> +		}
> +		prepare_submodule_repo_env_in_gitdir(&cp->env_array);
> +		cp->git_cmd = 1;
> +
> +		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, sub->path);
> +		argv_array_init(&cp->args);
> +		argv_array_pushv(&cp->args, spf->args.argv);
> +		argv_array_push(&cp->args, "on-demand");
> +		argv_array_push(&cp->args, "--submodule-prefix");
> +		argv_array_push(&cp->args, submodule_prefix.buf);
> +
> +		/* NEEDSWORK: have get_default_remote from s--h */
> +		argv_array_push(&cp->args, "origin");
> +		oid_array_for_each_unique(it->util,
> +					  append_oid_to_argv, &cp->args);
> +
> +		*task_cb = NULL; /* make sure we do not recurse forever */
> +		strbuf_release(&submodule_prefix);
> +		string_list_pop(&spf->retry, 0);
> +		return 1;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -1335,14 +1383,49 @@ static int fetch_start_failure(struct strbuf *err,
>  	return 0;
>  }
>  
> +static int commit_exists_in_sub(const struct object_id *oid, void *data)
> +{
> +	struct repository *subrepo = data;
> +
> +	enum object_type type = oid_object_info(subrepo, oid, NULL);
> +
> +	return type != OBJ_COMMIT;
> +}

Is this checking if the 'oid' exists as a comit in the submodule
repository?  It smells to me that it is checking the opposite.
Shouldn't the function be named "commit_missing_from_submodule()" or
something like that?

>  static int fetch_finish(int retvalue, struct strbuf *err,
>  			void *cb, void *task_cb)
>  {
>  	struct submodule_parallel_fetch *spf = cb;
> +	struct submodule *sub = task_cb;
> +	struct repository subrepo;
>  
>  	if (retvalue)
>  		spf->result = 1;
>  
> +	if (!sub)
> +		return 0;
> +
> +	if (repo_submodule_init(&subrepo, spf->r, sub->path) < 0)
> +		warning(_("Could not get submodule repository for submodule '%s' in repository '%s'"),
> +			  sub->path, spf->r->worktree);
> +	else {
> +		struct string_list_item *it;
> +		struct oid_array *commits;
> +
> +		it = string_list_lookup(&spf->changed_submodule_names, sub->name);
> +		if (!it)
> +			return 0;

OK, so after a fetch, if we have missing commits, we append to the
spf->retry list, which will be looked at in the function we looked
at earlier.

> +		commits = it->util;
> +		oid_array_filter(commits,
> +				 commit_exists_in_sub,
> +				 &subrepo);
> +
> +		if (commits->nr)
> +			string_list_append(&spf->retry, sub->name)
> +				->util = commits;
> +	}
> +
>  	return 0;
>  }
>  
> diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
> index 42692219a1a..af12c50e7dd 100755
> --- a/t/t5526-fetch-submodules.sh
> +++ b/t/t5526-fetch-submodules.sh
> @@ -605,4 +605,20 @@ test_expect_success "fetch new commits when submodule got renamed" '
>  	test_cmp expect actual
>  '
>  
> +test_expect_success "fetch new commits on-demand when they are not reachable" '
> +	git checkout --detach &&
> +	C=$(git -C submodule commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
> +	git -C submodule update-ref refs/changes/1 $C &&
> +	git update-index --cacheinfo 160000 $C submodule &&
> +	git commit -m "updated submodule outside of refs/heads" &&
> +	D=$(git rev-parse HEAD) &&
> +	git update-ref refs/changes/2 $D &&
> +	(
> +		cd downstream &&
> +		git fetch --recurse-submodules --recurse-submodules-default on-demand origin refs/changes/2:refs/heads/my_branch &&
> +		git -C submodule cat-file -t $C &&
> +		git checkout --recurse-submodules FETCH_HEAD
> +	)
> +'
> +
>  test_done

^ permalink raw reply	[relevance 6%]

* Re: [PATCH 4/9] submodule.c: sort changed_submodule_names before searching it
  2018-09-12 18:18   ` Junio C Hamano
@ 2018-09-12 19:06     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-09-12 19:06 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Wed, Sep 12, 2018 at 11:18 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > We can string_list_insert() to maintain sorted-ness of the
> > list as we find new items, or we can string_list_append() to
> > build an unsorted list and sort it at the end just once.
> >
> > To pick which one is more appropriate, we notice the fact
> > that we discover new items more or less in the already
> > sorted order.  That makes "append then sort" more
> > appropriate.
>
> Sorry, but I still do not get the math you are implying in the
> second paragraph.  Are you saying that append-then-sort is efficient
> when items being appended is already sorted?  That depends on the
> sorting algorithm used, so the logic is incomplete unless you say
> "given that we use X for sorting,...", I think.
>
> Do we really discover new items in sorted order, by the way?  In a
> single diff invocation made inside collect_changed_submodules() for
> one commit in the superproject's history, we will grab changed paths
> in the pathname order (i.e. sorted); if the superproject's tip commit
> touches the submodules at paths A and Z, we will discover these two
> paths in sorted order.
>
> But because we are walking the superproject's history to collect all
> paths that have been affected in that function, and repeatedly
> calling diff as we discover commit in the superproject's history, I
> am not sure how well the resulting set of paths would be sorted.
>
> The tip commit in superproject's history may have modified the
> submodule at path X, the parent of that commit may have touched the
> submodule at path M, and its parent may have touched the submodule
> at path A.  Don't we end up grabbing these paths in that discoverd
> order, i.e. X, M and A?

That is true.

>
> I still think changing it from "insert as we find an item, keeping
> the list sorted" to "append all and then sort before we start
> looking things up from the result" makes sense, but I do not think
> the "we find things in sorted order" is either true, or it would
> affect the choice between the two.  A justification to choose the
> latter I can think of that makes sense is that we don't have to pay
> cost to keep the list sorted while building it because we do not do
> any look-up while building the list.

ok.

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 0/1] contrib: Add script to show uncovered "new" lines
      [irrelevant] <pull.40.git.gitgitgadget@gmail.com>
@ 2018-09-12 19:14 ` Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-09-12 19:14 UTC (permalink / raw)
  To: Derrick Stolee via GitGitGadget, git; +Cc: peff, Junio C Hamano

On 9/12/2018 12:45 PM, Derrick Stolee via GitGitGadget wrote:
> For example, I ran this against the 'jch' branch (d3c0046)
> versus 'next' (dd90340)

As another example, I ran this against the 'pu' branch (4c416a53) versus 
'jch' (d3c0046) and got the following output, submitted here without 
commentary:

builtin/bisect--helper.c
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 
43)             free((void *) terms->term_good);
3d3237b0e6b     (Pranit Bauva   2017-10-27 15:06:37 +0000 
162)            if (get_oid_commit(commit, &oid))
3d3237b0e6b     (Pranit Bauva   2017-10-27 15:06:37 +0000 
163)                    return error(_("'%s' is not a valid commit"), 
commit);
3d3237b0e6b     (Pranit Bauva   2017-10-27 15:06:37 +0000 
164)            strbuf_addstr(&branch, commit);
3d3237b0e6b     (Pranit Bauva   2017-10-27 15:06:37 +0000 
172)                    error(_("Could not check out original HEAD '%s'. 
Try "
3d3237b0e6b     (Pranit Bauva   2017-10-27 15:06:37 +0000 
174)                    strbuf_release(&branch);
3d3237b0e6b     (Pranit Bauva   2017-10-27 15:06:37 +0000 
175)                    argv_array_clear(&argv);
3d3237b0e6b     (Pranit Bauva   2017-10-27 15:06:37 +0000 
176)                    return -1;
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 
215)            error(_("Bad bisect_write argument: %s"), state);
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 
216)            goto fail;
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 
220)            error(_("couldn't get the oid of the rev '%s'"), rev);
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 
221)            goto fail;
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 
226)            goto fail;
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 
230)            error_errno(_("couldn't open the file '%s'"), 
git_path_bisect_log());
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 
231)            goto fail;
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 242)fail:
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 243)    retval 
= -1;
a919f328ba3     (Pranit Bauva   2017-10-27 15:06:37 +0000 
323)            yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO);
a919f328ba3     (Pranit Bauva   2017-10-27 15:06:37 +0000 
324)            if (starts_with(yesno, "N") || starts_with(yesno, "n"))
a919f328ba3     (Pranit Bauva   2017-10-27 15:06:37 +0000 
327)            goto finish;
a919f328ba3     (Pranit Bauva   2017-10-27 15:06:37 +0000 
336)            error(_("You need to start by \"git bisect start\". You "
a919f328ba3     (Pranit Bauva   2017-10-27 15:06:37 +0000 
341)            goto fail;
a919f328ba3     (Pranit Bauva   2017-10-27 15:06:37 +0000 345)fail:
35f7ca528ae     (Pranit Bauva   2017-10-27 15:06:37 +0000 
387)            return error(_("--bisect-term requires exactly one 
argument"));
35f7ca528ae     (Pranit Bauva   2017-10-27 15:06:37 +0000 
400)                    error(_("BUG: invalid argument %s for 'git 
bisect terms'.\n"
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
416)            return -1;
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
419)            goto fail;
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
423)            goto fail;
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 427)fail:
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 428)    retval 
= -1;
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
466)                    no_checkout = 1;
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
488)                     !one_of(arg, "--term-good", "--term-bad", NULL)) {
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
489)                    return error(_("unrecognised option: '%s'"), arg);
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
523)            if (get_oid("HEAD", &head_oid))
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
524)                    return error(_("Bad HEAD - I need a HEAD"));
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
539)                            error(_("checking out '%s' failed. Try 
'git "
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
559)                            return error(_("won't bisect on 
cg-seek'ed tree"));
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
562)                    return error(_("Bad HEAD - strange symbolic ref"));
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
570)            return -1;
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
588)                    goto fail;
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
598)                    goto fail;
5dfeec316b8     (Pranit Bauva   2017-10-27 15:06:37 +0000 
606)            goto fail;
3d3237b0e6b     (Pranit Bauva   2017-10-27 15:06:37 +0000 
686)                    return error(_("--bisect-reset requires either 
no argument or a commit"));
0b1f0fd910c     (Pranit Bauva   2017-10-27 15:06:37 +0000 
690)                    return error(_("--bisect-write requires either 4 
or 5 arguments"));
20edf353b72     (Pranit Bauva   2017-10-27 15:06:37 +0000 
697)                    return error(_("--check-and-set-terms requires 3 
arguments"));
a919f328ba3     (Pranit Bauva   2017-10-27 15:06:37 +0000 
703)                    return error(_("--bisect-next-check requires 2 
or 3 arguments"));
builtin/blame.c
74e8221b523     (Linus Torvalds 2018-07-07 15:02:35 -0700 922)    case 
DATE_HUMAN:
74e8221b523     (Linus Torvalds 2018-07-07 15:02:35 -0700 
924)            blame_date_width = sizeof("Thu Oct 19 16:00");
74e8221b523     (Linus Torvalds 2018-07-07 15:02:35 -0700 
925)            break;
builtin/gc.c
3029970275b     (Jonathan Nieder        2018-07-16 23:57:40 -0700       
461)            ret = error_errno(_("cannot stat '%s'"), gc_log_path);
3029970275b     (Jonathan Nieder        2018-07-16 23:57:40 -0700       
470)            ret = error_errno(_("cannot read '%s'"), gc_log_path);
fec2ed21871     (Jonathan Nieder        2018-07-16 23:54:16 -0700       
495)            die(FAILED_RUN, pack_refs_cmd.argv[0]);
fec2ed21871     (Jonathan Nieder        2018-07-16 23:54:16 -0700       
498)            die(FAILED_RUN, reflog.argv[0]);
3029970275b     (Jonathan Nieder        2018-07-16 23:57:40 -0700       
585)                            exit(128);
fec2ed21871     (Jonathan Nieder        2018-07-16 23:54:16 -0700       
637)                    die(FAILED_RUN, repack.argv[0]);
fec2ed21871     (Jonathan Nieder        2018-07-16 23:54:16 -0700       
647)                            die(FAILED_RUN, prune.argv[0]);
fec2ed21871     (Jonathan Nieder        2018-07-16 23:54:16 -0700       
654)                    die(FAILED_RUN, prune_worktrees.argv[0]);
fec2ed21871     (Jonathan Nieder        2018-07-16 23:54:16 -0700       
658)            die(FAILED_RUN, rerere.argv[0]);
builtin/rebase--interactive.c
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
24)             return error(_("no HEAD?"));
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
51)             return error_errno(_("could not create temporary %s"), 
path_state_dir());
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
57)             return error_errno(_("could not mark as interactive"));
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
77)             return -1;
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
81)             return -1;
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
87)             free(revisions);
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
88)             free(shortrevisions);
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
90)             return -1;
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
98)             free(revisions);
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
99)             free(shortrevisions);
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
101)            return error_errno(_("could not open %s"), 
rebase_path_todo());
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
106)            argv_array_push(&make_script_args, restrict_revision);
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
114)            error(_("could not generate todo list"));
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 205) 
usage_with_options(builtin_rebase_interactive_usage, options);
93420467efe     (Alban Gruin    2018-08-28 14:10:42 +0200 
219)            warning(_("--[no-]rebase-cousins has no effect without "
adb4f8f6b72     (Alban Gruin    2018-08-28 14:10:43 +0200 
225)                    die(_("a base commit must be provided with 
--upstream or --onto"));
b3fe2e1f8cb     (Alban Gruin    2018-08-28 14:10:45 +0200 259)    case 
REARRANGE_SQUASH:
b3fe2e1f8cb     (Alban Gruin    2018-08-28 14:10:45 +0200 
260)            ret = rearrange_squash();
b3fe2e1f8cb     (Alban Gruin    2018-08-28 14:10:45 +0200 
261)            break;
b3fe2e1f8cb     (Alban Gruin    2018-08-28 14:10:45 +0200 262)    case 
ADD_EXEC:
b3fe2e1f8cb     (Alban Gruin    2018-08-28 14:10:45 +0200 
263)            ret = sequencer_add_exec_commands(cmd);
b3fe2e1f8cb     (Alban Gruin    2018-08-28 14:10:45 +0200 
264)            break;
adb4f8f6b72     (Alban Gruin    2018-08-28 14:10:43 +0200 265)    default:
adb4f8f6b72     (Alban Gruin    2018-08-28 14:10:43 +0200 
266)            BUG("invalid command '%d'", command);
builtin/rebase.c
55071ea248e     (Pratik Karki   2018-08-07 01:16:09 +0545 61)     
strbuf_trim(&out);
55071ea248e     (Pratik Karki   2018-08-07 01:16:09 +0545 62)     ret = 
!strcmp("true", out.buf);
55071ea248e     (Pratik Karki   2018-08-07 01:16:09 +0545 63)     
strbuf_release(&out);
002ee2fe682     (Pratik Karki   2018-09-04 14:59:57 -0700 114)    case 
REBASE_AM:
002ee2fe682     (Pratik Karki   2018-09-04 14:59:57 -0700 
115)            die(_("%s requires an interactive rebase"), option);
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
148)            return error_errno(_("could not read '%s'"), path);
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
162)            return -1;
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
167)            return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
178)                    return -1;
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 179)    } else 
if (read_one(state_dir_path("head", opts), &buf))
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
180)            return -1;
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
182)            return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
186)            return -1;
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
188)            opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a59     (Pratik Karki   2018-09-04 14:59:50 -0700 
196)            opts->signoff = 1;
73d51ed0a59     (Pratik Karki   2018-09-04 14:59:50 -0700 
197)            opts->flags |= REBASE_FORCE;
ead98c111b8     (Pratik Karki   2018-09-04 14:59:52 -0700 
204)                    return -1;
28a02c5a790     (Pratik Karki   2018-09-04 15:00:00 -0700 
219)                    return -1;
399a505296a     (Pratik Karki   2018-09-04 15:00:11 -0700 
227)                    return -1;
399a505296a     (Pratik Karki   2018-09-04 15:00:11 -0700 
235)                    return -1;
7debdaa4ad1     (Pratik Karki   2018-09-04 15:00:02 -0700 
255)            return error(_("Could not read '%s'"), path);
7debdaa4ad1     (Pratik Karki   2018-09-04 15:00:02 -0700 
271)                    res = error(_("Cannot store %s"), autostash.buf);
7debdaa4ad1     (Pratik Karki   2018-09-04 15:00:02 -0700 
275)                    return res;
b2263c13613     (Johannes Schindelin    2018-08-29 07:31:17 -0700       
373) argv_array_pushf(&child.args,
b2263c13613     (Johannes Schindelin    2018-08-29 07:31:17 -0700       
375) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 479)    case 
REBASE_INTERACTIVE:
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
480)            backend = "git-rebase--interactive";
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
481)            backend_func = "git_rebase__interactive";
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
482)            break;
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 491)    default:
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
492)            BUG("Unhandled rebase type %d", opts->type);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
509)            struct strbuf dir = STRBUF_INIT;
7debdaa4ad1     (Pratik Karki   2018-09-04 15:00:02 -0700 
511)            apply_autostash(opts);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
512)            strbuf_addstr(&dir, opts->state_dir);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
513)            remove_dir_recursively(&dir, 0);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
514)            strbuf_release(&dir);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
515)            die("Nothing to do");
d4c569f8f4c     (Pratik Karki   2018-09-04 14:27:20 -0700 
542)            BUG("Not a fully qualified branch: '%s'", switch_to_branch);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
545)            return -1;
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
549)                    rollback_lock_file(&lock);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
550)                    return error(_("could not determine HEAD 
revision"));
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
567)            rollback_lock_file(&lock);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
568)            return error(_("could not read index"));
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
572)            error(_("failed to find tree of %s"), oid_to_hex(oid));
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
573)            rollback_lock_file(&lock);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
574)            free((void *)desc.buffer);
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
575)            return -1;
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
588)            ret = error(_("could not write index"));
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
592)            return ret;
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 608)    } else 
if (old_orig)
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
609)            delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7d     (Pratik Karki   2018-09-04 14:27:13 -0700 
637)                    opts->flags &= !REBASE_DIFFSTAT;
9a48a615b47     (Pratik Karki   2018-09-04 14:27:16 -0700 
671)                    return 1;
9a48a615b47     (Pratik Karki   2018-09-04 14:27:16 -0700 
687)            return 0;
55071ea248e     (Pratik Karki   2018-08-07 01:16:09 +0545 
894)            const char *path = mkpath("%s/git-legacy-rebase",
55071ea248e     (Pratik Karki   2018-08-07 01:16:09 +0545 
897)            if (sane_execvp(path, (char **)argv) < 0)
55071ea248e     (Pratik Karki   2018-08-07 01:16:09 +0545 
898)                    die_errno(_("could not exec %s"), path);
55071ea248e     (Pratik Karki   2018-08-07 01:16:09 +0545 
900)                    BUG("sane_execvp() returned???");
0eabf4b95ca     (Pratik Karki   2018-08-08 20:51:22 +0545 
916)            die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a99     (Pratik Karki   2018-09-04 14:27:07 -0700 
953)            usage_with_options(builtin_rebase_usage,
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
973)                    die(_("Cannot read HEAD"));
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
977)                    die(_("could not read index"));
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 
991)                    exit(1);
122420c2953     (Pratik Karki   2018-08-08 20:51:17 +0545 
1003)                   die(_("could not discard worktree changes"));
122420c2953     (Pratik Karki   2018-08-08 20:51:17 +0545 
1005)                   exit(1);
5e5d96197ca     (Pratik Karki   2018-08-08 20:51:18 +0545 
1016)                   exit(1);
5e5d96197ca     (Pratik Karki   2018-08-08 20:51:18 +0545 
1019)                   die(_("could not move back to %s"),
5a61494539b     (Pratik Karki   2018-08-08 20:51:19 +0545 
1029)                   die(_("could not remove '%s'"), options.state_dir);
f95736288a3     (Pratik Karki   2018-08-08 20:51:16 +0545 1042)   default:
51e9ea6da76     (Pratik Karki   2018-08-08 20:51:20 +0545 
1043)           BUG("action: %d", action);
c54dacb50ea     (Pratik Karki   2018-09-04 14:27:18 -0700 
1048)           const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50ea     (Pratik Karki   2018-09-04 14:27:18 -0700 
1049)           const char *state_dir_base =
c54dacb50ea     (Pratik Karki   2018-09-04 14:27:18 -0700 
1050)                   last_slash ? last_slash + 1 : options.state_dir;
c54dacb50ea     (Pratik Karki   2018-09-04 14:27:18 -0700 
1051)           const char *cmd_live_rebase =
c54dacb50ea     (Pratik Karki   2018-09-04 14:27:18 -0700 
1053)           strbuf_reset(&buf);
c54dacb50ea     (Pratik Karki   2018-09-04 14:27:18 -0700 
1054)           strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50ea     (Pratik Karki   2018-09-04 14:27:18 -0700 
1055)           die(_("It seems that there is already a %s directory, and\n"
53f9e5be94e     (Pratik Karki   2018-09-04 14:59:56 -0700 
1079)           strbuf_addstr(&options.git_am_opt, " --ignore-date");
53f9e5be94e     (Pratik Karki   2018-09-04 14:59:56 -0700 
1080)           options.flags |= REBASE_FORCE;
c7ee2134d42     (Pratik Karki   2018-09-04 15:00:01 -0700 
1092)           strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
0073df2bd31     (Pratik Karki   2018-09-04 15:00:07 -0700 
1124)           else if (strcmp("no-rebase-cousins", rebase_merges))
0073df2bd31     (Pratik Karki   2018-09-04 15:00:07 -0700 
1125)                   die(_("Unknown mode: %s"), rebase_merges);
399a505296a     (Pratik Karki   2018-09-04 15:00:11 -0700 
1146)           case REBASE_AM:
399a505296a     (Pratik Karki   2018-09-04 15:00:11 -0700 
1147)                   die(_("--strategy requires --merge or 
--interactive"));
399a505296a     (Pratik Karki   2018-09-04 15:00:11 -0700 
1156)           default:
399a505296a     (Pratik Karki   2018-09-04 15:00:11 -0700 
1157)                   BUG("unhandled rebase type (%d)", options.type);
6dc73173f6c     (Pratik Karki   2018-08-08 21:21:33 +0545 
1165)           strbuf_addstr(&options.git_format_patch_opt, " --progress");
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 1173)   case 
REBASE_AM:
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
1174)           options.state_dir = apply_dir();
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
1175)           break;
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
1252)                   die(_("invalid upstream '%s'"), 
options.upstream_name);
bfa5147095f     (Pratik Karki   2018-09-04 15:00:12 -0700 
1258)                           die(_("Could not create new root commit"));
e65123a71d0     (Pratik Karki   2018-09-04 14:27:21 -0700 
1308)                   die(_("fatal: no such branch/commit '%s'"),
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
1316)                   die(_("No such ref: %s"), "HEAD");
ac7f467fef8     (Pratik Karki   2018-08-07 01:16:11 +0545 
1328)                   die(_("Could not resolve HEAD to a revision"));
e65123a71d0     (Pratik Karki   2018-09-04 14:27:21 -0700 
1330)           BUG("unexpected number of arguments left to parse");
e0333e5c63f     (Pratik Karki   2018-09-04 14:27:14 -0700 
1341)           die(_("could not read index"));
7debdaa4ad1     (Pratik Karki   2018-09-04 15:00:02 -0700 
1368)                           die(_("Cannot autostash"));
7debdaa4ad1     (Pratik Karki   2018-09-04 15:00:02 -0700 
1371)                           die(_("Unexpected stash response: '%s'"),
7debdaa4ad1     (Pratik Karki   2018-09-04 15:00:02 -0700 
1377)                           die(_("Could not create directory for 
'%s'"),
7debdaa4ad1     (Pratik Karki   2018-09-04 15:00:02 -0700 
1383)                           die(_("could not reset --hard"));
e65123a71d0     (Pratik Karki   2018-09-04 14:27:21 -0700 
1427)                                   ret = !!error(_("could not parse 
'%s'"),
e65123a71d0     (Pratik Karki   2018-09-04 14:27:21 -0700 
1429)                                   goto cleanup;
e65123a71d0     (Pratik Karki   2018-09-04 14:27:21 -0700 
1438)                                   ret = !!error(_("could not 
switch to "
1ed9c14ff25     (Pratik Karki   2018-09-04 14:27:17 -0700 
1448)                            resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff25     (Pratik Karki   2018-09-04 14:27:17 -0700 
1449)                           puts(_("HEAD is up to date."));
9a48a615b47     (Pratik Karki   2018-09-04 14:27:16 -0700 
1458)                    resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b47     (Pratik Karki   2018-09-04 14:27:16 -0700 
1459)                   puts(_("HEAD is up to date, rebase forced."));
builtin/rev-list.c
0eee403f2f7     (Matthew DeVore 2018-09-04 11:05:47 -0700 
227)            die("unexpected missing %s object '%s'",
0eee403f2f7     (Matthew DeVore 2018-09-04 11:05:47 -0700 
228)                type_name(obj->type), oid_to_hex(&obj->oid));
builtin/stash.c
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
130)            free_stash_info(info);
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
131)            error(_("'%s' is not a stash-like commit"), revision);
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
132)            exit(128);
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
165)                    free_stash_info(info);
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
166)                    fprintf_ln(stderr, _("No stash entries found."));
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
167)                    return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 201)    
default: /* Invalid or ambiguous */
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
202)            free_stash_info(info);
31f109a3618     (Joel Teichroeb 2018-08-31 00:40:37 +0300 
229)            return error(_("git stash clear with parameters is 
unimplemented"));
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
244)            return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
252)            return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
265)            return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
268)            return error(_("unable to write new index file"));
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
374)            remove_path(stash_index_path.buf);
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
375)            return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
402)            return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
405)            return error(_("Cannot apply a stash in the middle of a 
merge"));
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
415)                            strbuf_release(&out);
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
416)                            return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
422)                            return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
427)                            return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
434)            return error(_("Could not restore untracked files from 
stash"));
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
465)                    return -1;
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
470)                    strbuf_release(&out);
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
475)                    strbuf_release(&out);
93871263d18     (Joel Teichroeb 2018-08-31 00:40:36 +0300 
476)                    return -1;
31f109a3618     (Joel Teichroeb 2018-08-31 00:40:37 +0300 
551)            return error(_("%s: Could not drop stash entry"),
b3513da4bd9     (Joel Teichroeb 2018-08-31 00:40:39 +0300 
623)            printf_ln(_("The stash entry is kept in case you need it 
again."));
8ceb24b2c38     (Paul-Sebastian Ungureanu       2018-08-31 00:40:41 
+0300       754)            free_stash_info(&info);
129f0b0a009     (Paul-Sebastian Ungureanu       2018-08-31 00:40:48 
+0300       755) usage_with_options(git_stash_show_usage, options);
0ac06fb81f2     (Paul-Sebastian Ungureanu       2018-08-31 00:40:43 
+0300       808)            fprintf_ln(stderr, _("\"git stash store\" 
requires one <commit> argument"));
0ac06fb81f2     (Paul-Sebastian Ungureanu       2018-08-31 00:40:43 
+0300       809)            return -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       884)            return 1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       925)            ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       926)            goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       931)            ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       932)            goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       937)            ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       938)            goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       966)            ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       967)            goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       978)            ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       979)            goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       984)            ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       985)            goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       992)            ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       993)            goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1018)           ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1019)           goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1031)           ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1032)           goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1037)           ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1038)           goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1049)           ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1050)           goto done;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1055)           ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1056)           goto done;
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1089)                   fprintf_ln(stderr, _("You do not 
have the initial commit yet"));
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1110)           if (!quiet)
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1111)                   fprintf_ln(stderr, _("Cannot save 
the current index state"));
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1112)           ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1113)           *stash_msg = NULL;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1114)           goto done;
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1119)                   if (!quiet)
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1120) fprintf_ln(stderr, _("Cannot save the untracked files"));
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1121)                   ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1122)                   *stash_msg = NULL;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1123)                   goto done;
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1131)                   if (!quiet)
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1132) fprintf_ln(stderr, _("Cannot save the current worktree 
state"));
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1133)                   goto done;
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1139)                   if (!quiet)
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1140) fprintf_ln(stderr, _("Cannot save the current worktree 
state"));
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1141)                   ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1142)                   *stash_msg = NULL;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1143)                   goto done;
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1166)           if (!quiet)
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1167)                   fprintf_ln(stderr, _("Cannot record 
working tree state"));
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1168)           ret = -1;
f6f191b3f25     (Paul-Sebastian Ungureanu       2018-08-31 00:40:44 
+0300       1169)           goto done;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1251)           return -1;
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1260)           if (!quiet)
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1261)                   fprintf_ln(stderr, _("Cannot 
initialize stash"));
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1262)           return -1;
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1272)           if (!quiet)
8002b9e6264     (Paul-Sebastian Ungureanu       2018-08-31 00:40:46 
+0300       1273)                   fprintf_ln(stderr, _("Cannot save 
the current status"));
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1274)           ret = -1;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1275)           goto done;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1292)                           ret = -1;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1311)                           ret = -1;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1312)                           goto done;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1321)                           ret = -1;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1322)                           goto done;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1330)                           ret = -1;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1339)                           ret = -1;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1350)                           ret = -1;
48c061fa443     (Paul-Sebastian Ungureanu       2018-08-31 00:40:45 
+0300       1359)