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: 
* Re: What's cooking in git.git (Oct 2018, #02; Sat, 13)
      [irrelevant]   ` <xmqqd0seac9y.fsf@gitster-ct.c.googlers.com>
@ 2018-10-15 17:32     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-15 17:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Fri, Oct 12, 2018 at 6:03 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> >> * sb/submodule-recursive-fetch-gets-the-tip (2018-10-11) 9 commits
> >>  . builtin/fetch: check for submodule updates for non branch fetches
> >>  . fetch: retry fetching submodules if needed objects were not fetched
> >>  . submodule: fetch in submodules git directory instead of in worktree
> >>  . repository: repo_submodule_init to take a submodule struct
> >>  . submodule.c: do not copy around submodule list
> >>  . submodule.c: move global changed_submodule_names into fetch submodule struct
> >>  . submodule.c: sort changed_submodule_names before searching it
> >>  . submodule.c: fix indentation
> >>  . sha1-array: provide oid_array_filter
> >>
> >>  "git fetch --recurse-submodules" may not fetch the necessary commit
> >>  that is bound to the superproject, which is getting corrected.
> >>
> >>  Ejected for now, as it has fallouts in places like t/helper/.
> >
> > This is the first time I hear about that, I'll look into that.
> > The tipmost commit there is also shoddy, I'll redo that.
>
> This is the first time I saw the breakage with this series, but I
> would not be suprised, as this was rerolled recently.  Who knows
> what got changed in this series and in other topics---any new
> interaction can arise and that is a normal part of distributed
> development.

I performed the same merge last week, and the range-diff indicates,
that your version of next was further ahead than mine.

The breakage itself comes from

t/helper/test-submodule-nested-repo-config.c: In function
‘cmd__submodule_nested_repo_config’:
t/helper/test-submodule-nested-repo-config.c:20:54: warning: passing
argument 3 of ‘repo_submodule_init’ from incompatible pointer type
[-Wincompatible-pointer-types]
  if (repo_submodule_init(&submodule, the_repository, argv[1])) {
                                                      ^~~~
In file included from ./cache.h:17:0,
                 from ./submodule-config.h:4,
                 from t/helper/test-submodule-nested-repo-config.c:2:
./repository.h:126:5: note: expected ‘const struct submodule *’ but
argument is of type ‘const char *’
 int repo_submodule_init(struct repository *subrepo,
     ^~~~~~~~~~~~~~~~~~~

which is introduced by
commit c369da44610acc5e56213b8784d4250ae619fdb9
  (origin/ao/submodule-wo-gitmodules-checked-out)
Author: Antonio Ospite <ao2@ao2.it>
Date:   2018-10-05 15:06

    t/helper: add test-submodule-nested-repo-config

    Add a test tool to exercise config_from_gitmodules(), in particular for
    the case of nested submodules.

    Add also a test to document that reading the submoudles config of nested
    submodules does not work yet when the .gitmodules file is not in the
    working tree but it still in the index.

    This is because the git API does not always make it possible access the
    object store  of an arbitrary repository (see get_oid() usage in
    config_from_gitmodules()).

    When this git limitation gets fixed the aforementioned use case will be
    supported too.

    Signed-off-by: Antonio Ospite <ao2@ao2.it>
    Signed-off-by: Junio C Hamano <gitster@pobox.com>

My resend will take that into account, building on Antonios series.

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* [PATCH] submodule helper: convert relative URL to absolute URL if needed
      [irrelevant] <20181012215314.44266-1-sbeller@google.com>
@ 2018-10-16  0:19 ` Stefan Beller
  2018-10-16  0:33   ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-16  0:19 UTC (permalink / raw)
  To: sbeller, gitster; +Cc: git, jrnieder

The submodule helper update_clone called by "git submodule update",
clones submodules if needed. As submodules used to have the URL indicating
if they were active, the step to resolve relative URLs was done in the
"submodule init" step. Nowadays submodules can be configured active without
calling an explicit init, e.g. via configuring submodule.active.

When trying to obtain submodules that are set active this way, we'll
fallback to the URL found in the .gitmodules, which may be relative to the
superproject, but we do not resolve it, yet:

    git clone https://gerrit.googlesource.com/gerrit
    cd gerrit && grep url .gitmodules
	url = ../plugins/codemirror-editor
	...
    git config submodule.active .
    git submodule update
fatal: repository '../plugins/codemirror-editor' does not exist
fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
Failed to clone 'plugins/codemirror-editor'. Retry scheduled
[...]
fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
Failed to clone 'plugins/codemirror-editor' a second time, aborting
[...]

To resolve the issue, factor out the function that resolves the relative
URLs in "git submodule init" (in the submodule helper in the init_submodule
function) and call it at the appropriate place in the update_clone helper.

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

Jonathan wrote:
> Ah, this is moved code. I should have used --color-moved. ;-)

Yes, any cleanup should go on top.

I extended the commit message and made sure not to leak memory.

When rerolling origin/xxx/sb-submodule-recursive-fetch-gets-the-tip-in-pu,
there will be conflicts with this series, but I can work with that.

 builtin/submodule--helper.c | 48 ++++++++++++++++++++++++-------------
 t/t7400-submodule-basic.sh  | 24 +++++++++++++++++++
 2 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index f6fb8991f3..03f5e0d03e 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -584,6 +584,27 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+
+static char *compute_submodule_clone_url(const char *rel_url)
+{
+	char *remoteurl, *relurl;
+	char *remote = get_default_remote();
+	struct strbuf remotesb = STRBUF_INIT;
+
+	strbuf_addf(&remotesb, "remote.%s.url", remote);
+	free(remote);
+
+	if (git_config_get_string(remotesb.buf, &remoteurl)) {
+		warning(_("could not lookup configuration '%s'. Assuming this repository is its own authoritative upstream."), remotesb.buf);
+		remoteurl = xgetcwd();
+	}
+	relurl = relative_url(remoteurl, rel_url, NULL);
+	strbuf_release(&remotesb);
+	free(remoteurl);
+
+	return relurl;
+}
+
 struct init_cb {
 	const char *prefix;
 	unsigned int flags;
@@ -634,21 +655,9 @@ static void init_submodule(const char *path, const char *prefix,
 		/* Possibly a url relative to parent */
 		if (starts_with_dot_dot_slash(url) ||
 		    starts_with_dot_slash(url)) {
-			char *remoteurl, *relurl;
-			char *remote = get_default_remote();
-			struct strbuf remotesb = STRBUF_INIT;
-			strbuf_addf(&remotesb, "remote.%s.url", remote);
-			free(remote);
-
-			if (git_config_get_string(remotesb.buf, &remoteurl)) {
-				warning(_("could not lookup configuration '%s'. Assuming this repository is its own authoritative upstream."), remotesb.buf);
-				remoteurl = xgetcwd();
-			}
-			relurl = relative_url(remoteurl, url, NULL);
-			strbuf_release(&remotesb);
-			free(remoteurl);
-			free(url);
-			url = relurl;
+			char *to_free = url;
+			url = compute_submodule_clone_url(url);
+			free(to_free);
 		}
 
 		if (git_config_set_gently(sb.buf, url))
@@ -1562,8 +1571,13 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 
 	strbuf_reset(&sb);
 	strbuf_addf(&sb, "submodule.%s.url", sub->name);
-	if (repo_config_get_string_const(the_repository, sb.buf, &url))
-		url = sub->url;
+	if (repo_config_get_string_const(the_repository, sb.buf, &url)) {
+		if (starts_with_dot_slash(sub->url) ||
+		    starts_with_dot_dot_slash(sub->url))
+			url = compute_submodule_clone_url(sub->url);
+		else
+			url = sub->url;
+	}
 
 	strbuf_reset(&sb);
 	strbuf_addf(&sb, "%s/.git", ce->name);
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index c0ffc1022a..76a7cb0af7 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -1224,6 +1224,30 @@ test_expect_success 'submodule update and setting submodule.<name>.active' '
 	test_cmp expect actual
 '
 
+test_expect_success 'clone active submodule without submodule url set' '
+	test_when_finished "rm -rf test/test" &&
+	mkdir test &&
+	# another dir breaks accidental relative paths still being correct
+	git clone file://"$pwd"/multisuper test/test &&
+	(
+		cd test/test &&
+		git config submodule.active "." &&
+
+		# do not pass --init flag, as the submodule is already active:
+		git submodule update &&
+		git submodule status >actual_raw &&
+
+		cut -c 1,43- actual_raw >actual &&
+		cat >expect <<-\EOF &&
+		 sub0 (test2)
+		 sub1 (test2)
+		 sub2 (test2)
+		 sub3 (test2)
+		EOF
+		test_cmp expect actual
+	)
+'
+
 test_expect_success 'clone --recurse-submodules with a pathspec works' '
 	test_when_finished "rm -rf multisuper_clone" &&
 	cat >expected <<-\EOF &&
-- 
2.19.0


^ permalink raw reply	[relevance 22%]

* Re: [PATCH] submodule helper: convert relative URL to absolute URL if needed
  2018-10-16  0:19 ` [PATCH] submodule helper: convert relative URL to absolute URL if needed Stefan Beller
@ 2018-10-16  0:33   ` Jonathan Nieder
  2018-10-16  5:15     ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-10-16  0:33 UTC (permalink / raw)
  To: Stefan Beller; +Cc: gitster, git, Jaewoong Jung

Hi,

Stefan Beller wrote:

> The submodule helper update_clone called by "git submodule update",
> clones submodules if needed. As submodules used to have the URL indicating
> if they were active, the step to resolve relative URLs was done in the
> "submodule init" step. Nowadays submodules can be configured active without
> calling an explicit init, e.g. via configuring submodule.active.
>
> When trying to obtain submodules that are set active this way, we'll
> fallback to the URL found in the .gitmodules, which may be relative to the
> superproject, but we do not resolve it, yet:
> 
>     git clone https://gerrit.googlesource.com/gerrit
>     cd gerrit && grep url .gitmodules
> 	url = ../plugins/codemirror-editor
> 	...
>     git config submodule.active .
>     git submodule update
> fatal: repository '../plugins/codemirror-editor' does not exist
> fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
> Failed to clone 'plugins/codemirror-editor'. Retry scheduled
> [...]
> fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
> Failed to clone 'plugins/codemirror-editor' a second time, aborting
> [...]

Thanks.

"git log" and other tools have the ability to rewrap lines and will get
confused by this transcript.  Can you indent it to unconfuse them?

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

Please also credit the bug reporter:

Reported-by: Jaewoong Jung <jungjw@google.com>

[...]
> --- a/builtin/submodule--helper.c
> +++ b/builtin/submodule--helper.c
> @@ -584,6 +584,27 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
>  	return 0;
>  }
>  
> +

nit: inconsistent vertical whitespace (extra blank line?)

> +static char *compute_submodule_clone_url(const char *rel_url)
> +{
> +	char *remoteurl, *relurl;
> +	char *remote = get_default_remote();
> +	struct strbuf remotesb = STRBUF_INIT;
> +
> +	strbuf_addf(&remotesb, "remote.%s.url", remote);
> +	free(remote);
> +
> +	if (git_config_get_string(remotesb.buf, &remoteurl)) {
> +		warning(_("could not lookup configuration '%s'. Assuming this repository is its own authoritative upstream."), remotesb.buf);
> +		remoteurl = xgetcwd();
> +	}
> +	relurl = relative_url(remoteurl, rel_url, NULL);
> +	strbuf_release(&remotesb);
> +	free(remoteurl);
> +
> +	return relurl;
> +}

I think this would be easier to read with all the release commands
together:

	...

	free(remote);
	free(remoteurl);
	strbuf_release(&remotesb);
	return relurl;

[...]
> @@ -634,21 +655,9 @@ static void init_submodule(const char *path, const char *prefix,
[...]
> -			relurl = relative_url(remoteurl, url, NULL);
> -			strbuf_release(&remotesb);
> -			free(remoteurl);
> -			free(url);
> -			url = relurl;
> +			char *to_free = url;
> +			url = compute_submodule_clone_url(url);
> +			free(to_free);

I still think this would be easier to read with a style that makes
the ownership passing clearer:

			char *oldurl = url;
			url = compute_submodule_clone_url(oldurl);
			free(oldurl);

With whatever subset of the above tweaks makes sense,
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>

Thanks.

^ permalink raw reply	[relevance 4%]

* Re: [PATCH] submodule helper: convert relative URL to absolute URL if needed
  2018-10-16  0:33   ` Jonathan Nieder
@ 2018-10-16  5:15     ` Junio C Hamano
  2018-10-16 17:27       ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-10-16  5:15 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Stefan Beller, git, Jaewoong Jung

Jonathan Nieder <jrnieder@gmail.com> writes:

>>     git config submodule.active .
>>     git submodule update
>> fatal: repository '../plugins/codemirror-editor' does not exist
>> fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
>> Failed to clone 'plugins/codemirror-editor'. Retry scheduled
>> [...]
>> fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
>> Failed to clone 'plugins/codemirror-editor' a second time, aborting
>> [...]
>
> Thanks.
>
> "git log" and other tools have the ability to rewrap lines and will get
> confused by this transcript.  Can you indent it to unconfuse them?
>
>> Signed-off-by: Stefan Beller <sbeller@google.com>
>
> Please also credit the bug reporter:
>
> Reported-by: Jaewoong Jung <jungjw@google.com>
>
> ...
> nit: inconsistent vertical whitespace (extra blank line?)
> ...
> I think this would be easier to read with all the release commands
> together:
> ...

All good points.

^ permalink raw reply	[relevance 2%]

* [PATCH] submodule helper: convert relative URL to absolute URL if needed
  2018-10-16  5:15     ` Junio C Hamano
@ 2018-10-16 17:27       ` Stefan Beller
  2018-10-16 21:05         ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-16 17:27 UTC (permalink / raw)
  To: gitster; +Cc: git, jrnieder, jungjw, sbeller

The submodule helper update_clone called by "git submodule update",
clones submodules if needed. As submodules used to have the URL indicating
if they were active, the step to resolve relative URLs was done in the
"submodule init" step. Nowadays submodules can be configured active without
calling an explicit init, e.g. via configuring submodule.active.

When trying to obtain submodules that are set active this way, we'll
fallback to the URL found in the .gitmodules, which may be relative to the
superproject, but we do not resolve it, yet:

    git clone https://gerrit.googlesource.com/gerrit
    cd gerrit && grep url .gitmodules
	url = ../plugins/codemirror-editor
	...
    git config submodule.active .
    git submodule update
    fatal: repository '../plugins/codemirror-editor' does not exist
    fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
    Failed to clone 'plugins/codemirror-editor'. Retry scheduled
    [...]
    fatal: clone of '../plugins/codemirror-editor' into submodule path '/tmp/gerrit/plugins/codemirror-editor' failed
    Failed to clone 'plugins/codemirror-editor' a second time, aborting
    [...]

To resolve the issue, factor out the function that resolves the relative
URLs in "git submodule init" (in the submodule helper in the init_submodule
function) and call it at the appropriate place in the update_clone helper.

Reported-by: Jaewoong Jung <jungjw@google.com>
Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/submodule--helper.c | 51 ++++++++++++++++++++++++-------------
 t/t7400-submodule-basic.sh  | 24 +++++++++++++++++
 2 files changed, 58 insertions(+), 17 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index f6fb8991f3..13c2e4b556 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -584,6 +584,26 @@ static int module_foreach(int argc, const char **argv, const char *prefix)
 	return 0;
 }
 
+static char *compute_submodule_clone_url(const char *rel_url)
+{
+	char *remoteurl, *relurl;
+	char *remote = get_default_remote();
+	struct strbuf remotesb = STRBUF_INIT;
+
+	strbuf_addf(&remotesb, "remote.%s.url", remote);
+	if (git_config_get_string(remotesb.buf, &remoteurl)) {
+		warning(_("could not look up configuration '%s'. Assuming this repository is its own authoritative upstream."), remotesb.buf);
+		remoteurl = xgetcwd();
+	}
+	relurl = relative_url(remoteurl, rel_url, NULL);
+
+	free(remote);
+	free(remoteurl);
+	strbuf_release(&remotesb);
+
+	return relurl;
+}
+
 struct init_cb {
 	const char *prefix;
 	unsigned int flags;
@@ -634,21 +654,9 @@ static void init_submodule(const char *path, const char *prefix,
 		/* Possibly a url relative to parent */
 		if (starts_with_dot_dot_slash(url) ||
 		    starts_with_dot_slash(url)) {
-			char *remoteurl, *relurl;
-			char *remote = get_default_remote();
-			struct strbuf remotesb = STRBUF_INIT;
-			strbuf_addf(&remotesb, "remote.%s.url", remote);
-			free(remote);
-
-			if (git_config_get_string(remotesb.buf, &remoteurl)) {
-				warning(_("could not lookup configuration '%s'. Assuming this repository is its own authoritative upstream."), remotesb.buf);
-				remoteurl = xgetcwd();
-			}
-			relurl = relative_url(remoteurl, url, NULL);
-			strbuf_release(&remotesb);
-			free(remoteurl);
-			free(url);
-			url = relurl;
+			char *oldurl = url;
+			url = compute_submodule_clone_url(oldurl);
+			free(oldurl);
 		}
 
 		if (git_config_set_gently(sb.buf, url))
@@ -1514,6 +1522,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 	struct strbuf sb = STRBUF_INIT;
 	const char *displaypath = NULL;
 	int needs_cloning = 0;
+	int need_free_url = 0;
 
 	if (ce_stage(ce)) {
 		if (suc->recursive_prefix)
@@ -1562,8 +1571,14 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 
 	strbuf_reset(&sb);
 	strbuf_addf(&sb, "submodule.%s.url", sub->name);
-	if (repo_config_get_string_const(the_repository, sb.buf, &url))
-		url = sub->url;
+	if (repo_config_get_string_const(the_repository, sb.buf, &url)) {
+		if (starts_with_dot_slash(sub->url) ||
+		    starts_with_dot_dot_slash(sub->url)) {
+			url = compute_submodule_clone_url(sub->url);
+			need_free_url = 1;
+		} else
+			url = sub->url;
+	}
 
 	strbuf_reset(&sb);
 	strbuf_addf(&sb, "%s/.git", ce->name);
@@ -1608,6 +1623,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
 cleanup:
 	strbuf_reset(&displaypath_sb);
 	strbuf_reset(&sb);
+	if (need_free_url)
+		free((void*)url);
 
 	return needs_cloning;
 }
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index c0ffc1022a..76a7cb0af7 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -1224,6 +1224,30 @@ test_expect_success 'submodule update and setting submodule.<name>.active' '
 	test_cmp expect actual
 '
 
+test_expect_success 'clone active submodule without submodule url set' '
+	test_when_finished "rm -rf test/test" &&
+	mkdir test &&
+	# another dir breaks accidental relative paths still being correct
+	git clone file://"$pwd"/multisuper test/test &&
+	(
+		cd test/test &&
+		git config submodule.active "." &&
+
+		# do not pass --init flag, as the submodule is already active:
+		git submodule update &&
+		git submodule status >actual_raw &&
+
+		cut -c 1,43- actual_raw >actual &&
+		cat >expect <<-\EOF &&
+		 sub0 (test2)
+		 sub1 (test2)
+		 sub2 (test2)
+		 sub3 (test2)
+		EOF
+		test_cmp expect actual
+	)
+'
+
 test_expect_success 'clone --recurse-submodules with a pathspec works' '
 	test_when_finished "rm -rf multisuper_clone" &&
 	cat >expected <<-\EOF &&
-- 
2.19.0


^ permalink raw reply	[relevance 22%]

* [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip
@ 2018-10-16 18:13 Stefan Beller
  2018-10-16 18:13 ` [PATCH 2/9] submodule.c: fix indentation Stefan Beller
                   ` (9 more replies)
  0 siblings, 10 replies; 200+ results
From: Stefan Beller @ 2018-10-16 18:13 UTC (permalink / raw)
  To: gitster; +Cc: git, Stefan Beller

This is based on ao/submodule-wo-gitmodules-checked-out.

This resends origin/sb/submodule-recursive-fetch-gets-the-tip, resolving
the issues pointed out via origin/xxx/sb-submodule-recursive-fetch-gets-the-tip-in-pu
by basing this series on origin/ao/submodule-wo-gitmodules-checked-out

A range-diff below shows how picking a different base changed the patches,
apart from that no further adjustments have been made.

Thanks,
Stefan

Stefan Beller (9):
  sha1-array: provide oid_array_filter
  submodule.c: fix indentation
  submodule.c: sort changed_submodule_names before searching it
  submodule.c: move global changed_submodule_names into fetch submodule
    struct
  submodule.c: do not copy around submodule list
  repository: repo_submodule_init to take a submodule struct
  submodule: fetch in submodules git directory instead of in worktree
  fetch: retry fetching submodules if needed objects were not fetched
  builtin/fetch: check for submodule updates for non branch fetches

 Documentation/technical/api-oid-array.txt    |   5 +
 builtin/fetch.c                              |  14 +-
 builtin/grep.c                               |  17 +-
 builtin/ls-files.c                           |  12 +-
 repository.c                                 |  27 +-
 repository.h                                 |  11 +-
 sha1-array.c                                 |  17 ++
 sha1-array.h                                 |   3 +
 submodule.c                                  | 275 +++++++++++++++----
 t/helper/test-submodule-nested-repo-config.c |   8 +-
 t/t5526-fetch-submodules.sh                  |  23 +-
 11 files changed, 315 insertions(+), 97 deletions(-)

git range-diff origin/xxx/sb-submodule-recursive-fetch-gets-the-tip-in-pu...
[...]
585:  ac1f98a0df <   -:  ---------- doc: move git-rev-parse from porcelain to plumbing
586:  7cf1a0fbef =   1:  a035323c49 sha1-array: provide oid_array_filter
587:  01077381d0 =   2:  30ed20b4f0 submodule.c: fix indentation
588:  4b0cdf5899 =   3:  cd590ea88d submodule.c: sort changed_submodule_names before searching it
589:  78e5099ecc !   4:  ce959811ba submodule.c: move global changed_submodule_names into fetch submodule struct
    @@ -12,7 +12,7 @@
     --- a/submodule.c
     +++ b/submodule.c
     @@
    - #include "commit-reach.h"
    + #include "object-store.h"
      
      static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
     -static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
590:  d813f18bb3 =   5:  151f9a8ad4 submodule.c: do not copy around submodule list
591:  a077d63af7 !   6:  3a97743fa2 repository: repo_submodule_init to take a submodule struct
    @@ -15,7 +15,6 @@
         Also move its documentation into the header file.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
     diff --git a/builtin/grep.c b/builtin/grep.c
     --- a/builtin/grep.c
    @@ -31,12 +30,16 @@
     +
      	int hit;
      
    - 	if (!is_submodule_active(superproject, path))
    + 	/*
    +@@
      		return 0;
    + 	}
      
    --	if (repo_submodule_init(&submodule, superproject, path))
    -+	if (repo_submodule_init(&subrepo, superproject, sub))
    +-	if (repo_submodule_init(&submodule, superproject, path)) {
    ++	if (repo_submodule_init(&subrepo, superproject, sub)) {
    + 		grep_read_unlock();
      		return 0;
    + 	}
      
     -	repo_read_gitmodules(&submodule);
     +	repo_read_gitmodules(&subrepo);
    @@ -44,9 +47,9 @@
      	/*
      	 * NEEDSWORK: This adds the submodule's object directory to the list of
     @@
    + 	 * store is no longer global and instead is a member of the repository
      	 * object.
      	 */
    - 	grep_read_lock();
     -	add_to_alternates_memory(submodule.objects->objectdir);
     +	add_to_alternates_memory(subrepo.objects->objectdir);
      	grep_read_unlock();
    @@ -100,19 +103,6 @@
      
      static void show_ce(struct repository *repo, struct dir_struct *dir,
     
    -diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
    ---- a/builtin/submodule--helper.c
    -+++ b/builtin/submodule--helper.c
    -@@
    - 	if (!sub)
    - 		BUG("We could get the submodule handle before?");
    - 
    --	if (repo_submodule_init(&subrepo, the_repository, path))
    -+	if (repo_submodule_init(&subrepo, the_repository, sub))
    - 		die(_("could not get a repository handle for submodule '%s'"), path);
    - 
    - 	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
    -
     diff --git a/repository.c b/repository.c
     --- a/repository.c
     +++ b/repository.c
    @@ -197,3 +187,32 @@
      void repo_clear(struct repository *repo);
      
      /*
    +
    +diff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c
    +--- a/t/helper/test-submodule-nested-repo-config.c
    ++++ b/t/helper/test-submodule-nested-repo-config.c
    +@@
    + 
    + int cmd__submodule_nested_repo_config(int argc, const char **argv)
    + {
    +-	struct repository submodule;
    ++	struct repository subrepo;
    ++	const struct submodule *sub;
    + 
    + 	if (argc < 3)
    + 		die_usage(argc, argv, "Wrong number of arguments.");
    + 
    + 	setup_git_directory();
    + 
    +-	if (repo_submodule_init(&submodule, the_repository, argv[1])) {
    ++	sub = submodule_from_path(the_repository, &null_oid, argv[1]);
    ++	if (repo_submodule_init(&subrepo, the_repository, sub)) {
    + 		die_usage(argc, argv, "Submodule not found.");
    + 	}
    + 
    + 	/* Read the config of _child_ submodules. */
    +-	print_config_from_gitmodules(&submodule, argv[2]);
    ++	print_config_from_gitmodules(&subrepo, argv[2]);
    + 
    + 	submodule_free(the_repository);
    + 
592:  780f6c1a92 =   7:  4e8ad61f8d submodule: fetch in submodules git directory instead of in worktree
593:  a530535912 =   8:  24bac00db7 fetch: retry fetching submodules if needed objects were not fetched
594:  a72bde3a8a =   9:  e031182e44 builtin/fetch: check for submodule updates for non branch fetches
[...]

^ permalink raw reply	[relevance 9%]

* [PATCH 2/9] submodule.c: fix indentation
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
@ 2018-10-16 18:13 ` Stefan Beller
  2018-10-16 18:13 ` [PATCH 3/9] submodule.c: sort changed_submodule_names before searching it Stefan Beller
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-16 18:13 UTC (permalink / raw)
  To: gitster; +Cc: git, 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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 submodule.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index 2b7082b2db..e145ebbb16 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1258,7 +1258,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;
 			}
 		}
@@ -1268,8 +1269,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


^ permalink raw reply	[relevance 26%]

* [PATCH 3/9] submodule.c: sort changed_submodule_names before searching it
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
  2018-10-16 18:13 ` [PATCH 2/9] submodule.c: fix indentation Stefan Beller
@ 2018-10-16 18:13 ` Stefan Beller
  2018-10-16 18:13 ` [PATCH 4/9] submodule.c: move global changed_submodule_names into fetch submodule struct Stefan Beller
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-16 18:13 UTC (permalink / raw)
  To: gitster; +Cc: git, 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.

As we do not rely on the sortedness while building the
list, we pick the "append and sort at the end" as it
has better worst case execution times.

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

diff --git a/submodule.c b/submodule.c
index e145ebbb16..9fbfcfcfe1 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1270,7 +1270,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;
@@ -1364,6 +1364,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


^ permalink raw reply	[relevance 17%]

* [PATCH 4/9] submodule.c: move global changed_submodule_names into fetch submodule struct
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
  2018-10-16 18:13 ` [PATCH 2/9] submodule.c: fix indentation Stefan Beller
  2018-10-16 18:13 ` [PATCH 3/9] submodule.c: sort changed_submodule_names before searching it Stefan Beller
@ 2018-10-16 18:13 ` Stefan Beller
      [irrelevant]   ` <20181017212624.196598-1-jonathantanmy@google.com>
  2018-10-16 18:13 ` [PATCH 5/9] submodule.c: do not copy around submodule list Stefan Beller
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-16 18:13 UTC (permalink / raw)
  To: gitster; +Cc: git, 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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 submodule.c | 42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/submodule.c b/submodule.c
index 9fbfcfcfe1..6b4cee82bf 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;
@@ -1124,7 +1124,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;
@@ -1162,7 +1177,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);
@@ -1199,18 +1215,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)
 {
@@ -1271,7 +1275,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";
@@ -1363,8 +1367,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,
@@ -1373,7 +1377,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


^ permalink raw reply	[relevance 17%]

* [PATCH 5/9] submodule.c: do not copy around submodule list
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (2 preceding siblings ...)
  2018-10-16 18:13 ` [PATCH 4/9] submodule.c: move global changed_submodule_names into fetch submodule struct Stefan Beller
@ 2018-10-16 18:13 ` Stefan Beller
  2018-10-16 18:13 ` [PATCH 6/9] repository: repo_submodule_init to take a submodule struct Stefan Beller
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-16 18:13 UTC (permalink / raw)
  To: gitster; +Cc: git, 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 doing 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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 submodule.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/submodule.c b/submodule.c
index 6b4cee82bf..cbefe5f54d 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1142,8 +1142,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))
@@ -1160,9 +1159,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;
@@ -1176,12 +1175,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);
@@ -1377,7 +1378,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


^ permalink raw reply	[relevance 17%]

* [PATCH 6/9] repository: repo_submodule_init to take a submodule struct
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (3 preceding siblings ...)
  2018-10-16 18:13 ` [PATCH 5/9] submodule.c: do not copy around submodule list Stefan Beller
@ 2018-10-16 18:13 ` Stefan Beller
  2018-10-16 18:13 ` [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree Stefan Beller
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-16 18:13 UTC (permalink / raw)
  To: gitster; +Cc: git, Stefan Beller

When constructing a struct repository for a submodule for some revision
of the superproject where the submodule is not contained in the index,
it may not be present in the working tree currently either. In that
siutation giving a 'path' argument is not useful. Upgrade the
repo_submodule_init function to take a struct submodule instead.

While we are at it, overhaul the repo_submodule_init function by renaming
the submodule repository struct, which is to be initialized, to a name
that is not confused with the struct submodule as easily.

Also move its documentation into the header file.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/grep.c                               | 17 +++++++-----
 builtin/ls-files.c                           | 12 +++++----
 repository.c                                 | 27 ++++++++------------
 repository.h                                 | 11 ++++++--
 t/helper/test-submodule-nested-repo-config.c |  8 +++---
 5 files changed, 41 insertions(+), 34 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 7da8fef31a..ba7634258a 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -418,7 +418,10 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 			  const struct object_id *oid,
 			  const char *filename, const char *path)
 {
-	struct repository submodule;
+	struct repository subrepo;
+	const struct submodule *sub = submodule_from_path(superproject,
+							  &null_oid, path);
+
 	int hit;
 
 	/*
@@ -434,12 +437,12 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 		return 0;
 	}
 
-	if (repo_submodule_init(&submodule, superproject, path)) {
+	if (repo_submodule_init(&subrepo, superproject, sub)) {
 		grep_read_unlock();
 		return 0;
 	}
 
-	repo_read_gitmodules(&submodule);
+	repo_read_gitmodules(&subrepo);
 
 	/*
 	 * NEEDSWORK: This adds the submodule's object directory to the list of
@@ -451,7 +454,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 	 * store is no longer global and instead is a member of the repository
 	 * object.
 	 */
-	add_to_alternates_memory(submodule.objects->objectdir);
+	add_to_alternates_memory(subrepo.objects->objectdir);
 	grep_read_unlock();
 
 	if (oid) {
@@ -476,14 +479,14 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 
 		init_tree_desc(&tree, data, size);
 		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
-				object->type == OBJ_COMMIT, &submodule);
+				object->type == OBJ_COMMIT, &subrepo);
 		strbuf_release(&base);
 		free(data);
 	} else {
-		hit = grep_cache(opt, &submodule, pathspec, 1);
+		hit = grep_cache(opt, &subrepo, pathspec, 1);
 	}
 
-	repo_clear(&submodule);
+	repo_clear(&subrepo);
 	return hit;
 }
 
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 7f9919a362..4d1649c1b3 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -206,17 +206,19 @@ static void show_files(struct repository *repo, struct dir_struct *dir);
 static void show_submodule(struct repository *superproject,
 			   struct dir_struct *dir, const char *path)
 {
-	struct repository submodule;
+	struct repository subrepo;
+	const struct submodule *sub = submodule_from_path(superproject,
+							  &null_oid, path);
 
-	if (repo_submodule_init(&submodule, superproject, path))
+	if (repo_submodule_init(&subrepo, superproject, sub))
 		return;
 
-	if (repo_read_index(&submodule) < 0)
+	if (repo_read_index(&subrepo) < 0)
 		die("index file corrupt");
 
-	show_files(&submodule, dir);
+	show_files(&subrepo, dir);
 
-	repo_clear(&submodule);
+	repo_clear(&subrepo);
 }
 
 static void show_ce(struct repository *repo, struct dir_struct *dir,
diff --git a/repository.c b/repository.c
index 5dd1486718..aabe64ee5d 100644
--- a/repository.c
+++ b/repository.c
@@ -166,30 +166,23 @@ int repo_init(struct repository *repo,
 	return -1;
 }
 
-/*
- * Initialize 'submodule' as the submodule given by 'path' in parent repository
- * 'superproject'.
- * Return 0 upon success and a non-zero value upon failure.
- */
-int repo_submodule_init(struct repository *submodule,
+int repo_submodule_init(struct repository *subrepo,
 			struct repository *superproject,
-			const char *path)
+			const struct submodule *sub)
 {
-	const struct submodule *sub;
 	struct strbuf gitdir = STRBUF_INIT;
 	struct strbuf worktree = STRBUF_INIT;
 	int ret = 0;
 
-	sub = submodule_from_path(superproject, &null_oid, path);
 	if (!sub) {
 		ret = -1;
 		goto out;
 	}
 
-	strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path);
-	strbuf_repo_worktree_path(&worktree, superproject, "%s", path);
+	strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", sub->path);
+	strbuf_repo_worktree_path(&worktree, superproject, "%s", sub->path);
 
-	if (repo_init(submodule, gitdir.buf, worktree.buf)) {
+	if (repo_init(subrepo, gitdir.buf, worktree.buf)) {
 		/*
 		 * If initilization fails then it may be due to the submodule
 		 * not being populated in the superproject's worktree.  Instead
@@ -201,16 +194,16 @@ int repo_submodule_init(struct repository *submodule,
 		strbuf_repo_git_path(&gitdir, superproject,
 				     "modules/%s", sub->name);
 
-		if (repo_init(submodule, gitdir.buf, NULL)) {
+		if (repo_init(subrepo, gitdir.buf, NULL)) {
 			ret = -1;
 			goto out;
 		}
 	}
 
-	submodule->submodule_prefix = xstrfmt("%s%s/",
-					      superproject->submodule_prefix ?
-					      superproject->submodule_prefix :
-					      "", path);
+	subrepo->submodule_prefix = xstrfmt("%s%s/",
+					    superproject->submodule_prefix ?
+					    superproject->submodule_prefix :
+					    "", sub->path);
 
 out:
 	strbuf_release(&gitdir);
diff --git a/repository.h b/repository.h
index 9f16c42c1e..a9c7a5baa5 100644
--- a/repository.h
+++ b/repository.h
@@ -116,9 +116,16 @@ void repo_set_worktree(struct repository *repo, const char *path);
 void repo_set_hash_algo(struct repository *repo, int algo);
 void initialize_the_repository(void);
 int repo_init(struct repository *r, const char *gitdir, const char *worktree);
-int repo_submodule_init(struct repository *submodule,
+
+/*
+ * Initialize the repository 'subrepo' as the submodule given by the
+ * struct submodule 'sub' in parent repository 'superproject'.
+ * Return 0 upon success and a non-zero value upon failure.
+ */
+struct submodule;
+int repo_submodule_init(struct repository *subrepo,
 			struct repository *superproject,
-			const char *path);
+			const struct submodule *sub);
 void repo_clear(struct repository *repo);
 
 /*
diff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c
index a31e2a9bea..bc97929bbc 100644
--- a/t/helper/test-submodule-nested-repo-config.c
+++ b/t/helper/test-submodule-nested-repo-config.c
@@ -10,19 +10,21 @@ static void die_usage(int argc, const char **argv, const char *msg)
 
 int cmd__submodule_nested_repo_config(int argc, const char **argv)
 {
-	struct repository submodule;
+	struct repository subrepo;
+	const struct submodule *sub;
 
 	if (argc < 3)
 		die_usage(argc, argv, "Wrong number of arguments.");
 
 	setup_git_directory();
 
-	if (repo_submodule_init(&submodule, the_repository, argv[1])) {
+	sub = submodule_from_path(the_repository, &null_oid, argv[1]);
+	if (repo_submodule_init(&subrepo, the_repository, sub)) {
 		die_usage(argc, argv, "Submodule not found.");
 	}
 
 	/* Read the config of _child_ submodules. */
-	print_config_from_gitmodules(&submodule, argv[2]);
+	print_config_from_gitmodules(&subrepo, argv[2]);
 
 	submodule_free(the_repository);
 
-- 
2.19.0


^ permalink raw reply	[relevance 26%]

* [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (4 preceding siblings ...)
  2018-10-16 18:13 ` [PATCH 6/9] repository: repo_submodule_init to take a submodule struct Stefan Beller
@ 2018-10-16 18:13 ` Stefan Beller
      [irrelevant]   ` <20181017225811.66554-1-jonathantanmy@google.com>
  2018-10-16 18:13 ` [PATCH 8/9] fetch: retry fetching submodules if needed objects were not fetched Stefan Beller
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-16 18:13 UTC (permalink / raw)
  To: gitster; +Cc: git, Stefan Beller

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

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

This patch leaks the cp->dir in get_next_submodule, as any further
callback in run_processes_parallel doesn't have access to the child
process any more. In an early iteration of this patch, the function
get_submodule_repo_for directly returned the string containing the
git directory, which would be a better design choice for this patch.

However the next patch both fixes the memory leak of cp->dir and also has
a use case for using the full repository handle of the submodule, so
it makes sense to introduce the get_submodule_repo_for here already.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 submodule.c                 | 51 +++++++++++++++++++++++++++----------
 t/t5526-fetch-submodules.sh |  7 ++++-
 2 files changed, 44 insertions(+), 14 deletions(-)

diff --git a/submodule.c b/submodule.c
index cbefe5f54d..30c06507e3 100644
--- a/submodule.c
+++ b/submodule.c
@@ -495,6 +495,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
@@ -1241,6 +1247,29 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+static struct repository *get_submodule_repo_for(struct repository *r,
+						 const struct submodule *sub)
+{
+	struct repository *ret = xmalloc(sizeof(*ret));
+
+	if (repo_submodule_init(ret, r, sub)) {
+		/*
+		 * No entry in .gitmodules? Technically not a submodule,
+		 * but historically we supported repositories that happen to be
+		 * in-place where a gitlink is. Keep supporting them.
+		 */
+		struct strbuf gitdir = STRBUF_INIT;
+		strbuf_repo_worktree_path(&gitdir, r, "%s/.git", sub->path);
+		if (repo_init(ret, gitdir.buf, NULL)) {
+			strbuf_release(&gitdir);
+			return NULL;
+		}
+		strbuf_release(&gitdir);
+	}
+
+	return ret;
+}
+
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
@@ -1248,12 +1277,11 @@ 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;
+		const char *default_argv;
 		const struct submodule *submodule;
+		struct repository *repo;
 		struct submodule default_submodule = SUBMODULE_INIT;
 
 		if (!S_ISGITLINK(ce->ce_mode))
@@ -1288,16 +1316,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)) {
+		repo = get_submodule_repo_for(spf->r, submodule);
+		if (repo) {
 			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 = xstrdup(repo->gitdir);
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
@@ -1307,10 +1331,11 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_push(&cp->args, default_argv);
 			argv_array_push(&cp->args, "--submodule-prefix");
 			argv_array_push(&cp->args, submodule_prefix.buf);
+
+			repo_clear(repo);
+			free(repo);
 			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 6c2f9b2ba2..42692219a1 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


^ permalink raw reply	[relevance 28%]

* [PATCH 8/9] fetch: retry fetching submodules if needed objects were not fetched
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (5 preceding siblings ...)
  2018-10-16 18:13 ` [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree Stefan Beller
@ 2018-10-16 18:13 ` Stefan Beller
      [irrelevant]   ` <20181018003954.139498-1-jonathantanmy@google.com>
  2018-10-16 18:13 ` [PATCH 9/9] builtin/fetch: check for submodule updates for non branch fetches Stefan Beller
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-16 18:13 UTC (permalink / raw)
  To: gitster; +Cc: git, Stefan Beller

Currently when git-fetch is asked to recurse into submodules, it dispatches
a plain "git-fetch -C <submodule-dir>" (with 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 by object name if the object id that the
superproject points to, cannot be found.

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. A later patch will fix this.

builtin/fetch used to only inspect submodules when they were fetched
"on-demand", as in either on/off case it was clear whether the submodule
needs to be fetched. However to know whether we need to try fetching the
object ids, we need to identify the object names, which is done in this
function check_for_new_submodule_commits(), so we'll also run that code
in case the submodule recursion is set to "on".

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/fetch.c             |   9 +-
 submodule.c                 | 185 ++++++++++++++++++++++++++++++------
 t/t5526-fetch-submodules.sh |  16 ++++
 3 files changed, 177 insertions(+), 33 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 61bec5d213..95c44bf6ff 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 30c06507e3..7246b776f3 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1141,8 +1141,12 @@ struct submodule_parallel_fetch {
 	int result;
 
 	struct string_list changed_submodule_names;
+	struct get_next_submodule_task **retry;
+	int retry_nr, retry_alloc;
 };
-#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, \
+		  NULL, 0, 0}
 
 static void calculate_changed_submodule_paths(
 	struct submodule_parallel_fetch *spf)
@@ -1247,6 +1251,56 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+struct get_next_submodule_task {
+	struct repository *repo;
+	const struct submodule *sub;
+	unsigned free_sub : 1; /* Do we need to free the submodule? */
+	struct oid_array *commits;
+};
+
+static const struct submodule *get_default_submodule(const char *path)
+{
+	struct submodule *ret = NULL;
+	const char *name = default_name_or_path(path);
+
+	if (!name)
+		return NULL;
+
+	ret = xmalloc(sizeof(*ret));
+	memset(ret, 0, sizeof(*ret));
+	ret->path = name;
+	ret->name = name;
+
+	return (const struct submodule *) ret;
+}
+
+static struct get_next_submodule_task *get_next_submodule_task_create(
+	struct repository *r, const char *path)
+{
+	struct get_next_submodule_task *task = xmalloc(sizeof(*task));
+	memset(task, 0, sizeof(*task));
+
+	task->sub = submodule_from_path(r, &null_oid, path);
+	if (!task->sub) {
+		task->sub = get_default_submodule(path);
+		task->free_sub = 1;
+	}
+
+	return task;
+}
+
+static void get_next_submodule_task_release(struct get_next_submodule_task *p)
+{
+	if (p->free_sub)
+		free((void*)p->sub);
+	p->free_sub = 0;
+	p->sub = NULL;
+
+	if (p->repo)
+		repo_clear(p->repo);
+	FREE_AND_NULL(p->repo);
+}
+
 static struct repository *get_submodule_repo_for(struct repository *r,
 						 const struct submodule *sub)
 {
@@ -1273,39 +1327,35 @@ static struct repository *get_submodule_repo_for(struct repository *r,
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
-	int ret = 0;
 	struct submodule_parallel_fetch *spf = data;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
-		struct strbuf submodule_prefix = STRBUF_INIT;
+		int recurse_config;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *default_argv;
-		const struct submodule *submodule;
-		struct repository *repo;
-		struct submodule default_submodule = SUBMODULE_INIT;
+		struct get_next_submodule_task *task;
 
 		if (!S_ISGITLINK(ce->ce_mode))
 			continue;
 
-		submodule = submodule_from_path(spf->r, &null_oid, ce->name);
-		if (!submodule) {
-			const char *name = default_name_or_path(ce->name);
-			if (name) {
-				default_submodule.path = name;
-				default_submodule.name = name;
-				submodule = &default_submodule;
-			}
+		task = get_next_submodule_task_create(spf->r, ce->name);
+
+		if (!task->sub) {
+			free(task);
+			continue;
 		}
 
-		switch (get_fetch_recurse_config(submodule, spf))
+		recurse_config = get_fetch_recurse_config(task->sub, spf);
+
+		switch (recurse_config)
 		{
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule ||
+			if (!task->sub ||
 			    !string_list_lookup(
 					&spf->changed_submodule_names,
-					submodule->name))
+					task->sub->name))
 				continue;
 			default_argv = "on-demand";
 			break;
@@ -1316,12 +1366,12 @@ static int get_next_submodule(struct child_process *cp,
 			continue;
 		}
 
-		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
-		repo = get_submodule_repo_for(spf->r, submodule);
-		if (repo) {
+		task->repo = get_submodule_repo_for(spf->r, task->sub);
+		if (task->repo) {
+			struct strbuf submodule_prefix = STRBUF_INIT;
 			child_process_init(cp);
 			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
-			cp->dir = xstrdup(repo->gitdir);
+			cp->dir = task->repo->gitdir;
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
@@ -1330,18 +1380,51 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_pushv(&cp->args, spf->args.argv);
 			argv_array_push(&cp->args, default_argv);
 			argv_array_push(&cp->args, "--submodule-prefix");
+
+			strbuf_addf(&submodule_prefix, "%s%s/",
+						       spf->prefix,
+						       task->sub->path);
 			argv_array_push(&cp->args, submodule_prefix.buf);
 
-			repo_clear(repo);
-			free(repo);
-			ret = 1;
-		}
-		strbuf_release(&submodule_prefix);
-		if (ret) {
 			spf->count++;
+			*task_cb = task;
+
+			strbuf_release(&submodule_prefix);
 			return 1;
+		} else {
+			get_next_submodule_task_release(task);
+			free(task);
 		}
 	}
+
+	if (spf->retry_nr) {
+		struct get_next_submodule_task *task = spf->retry[spf->retry_nr - 1];
+		struct strbuf submodule_prefix = STRBUF_INIT;
+		spf->retry_nr--;
+
+		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, task->sub->path);
+
+		child_process_init(cp);
+		prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+		cp->git_cmd = 1;
+		cp->dir = task->repo->gitdir;
+
+		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(task->commits,
+					  append_oid_to_argv, &cp->args);
+
+		*task_cb = task;
+		strbuf_release(&submodule_prefix);
+		return 1;
+	}
+
 	return 0;
 }
 
@@ -1349,20 +1432,68 @@ static int fetch_start_failure(struct strbuf *err,
 			       void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
+	struct get_next_submodule_task *task = task_cb;
 
 	spf->result = 1;
 
+	get_next_submodule_task_release(task);
 	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 get_next_submodule_task *task = task_cb;
+	const struct submodule *sub;
+
+	struct string_list_item *it;
+	struct oid_array *commits;
 
 	if (retvalue)
 		spf->result = 1;
 
+	if (!task)
+		return 0;
+
+	sub = task->sub;
+	if (!sub)
+		goto out;
+
+	it = string_list_lookup(&spf->changed_submodule_names, sub->name);
+	if (!it)
+		goto out;
+
+	commits = it->util;
+	oid_array_filter(commits,
+			 commit_exists_in_sub,
+			 task->repo);
+
+	/* Are there commits that do not exist? */
+	if (commits->nr) {
+		/* We already tried fetching them, do not try again. */
+		if (task->commits)
+			return 0;
+
+		task->commits = commits;
+		ALLOC_GROW(spf->retry, spf->retry_nr + 1, spf->retry_alloc);
+		spf->retry[spf->retry_nr] = task;
+		spf->retry_nr++;
+		return 0;
+	}
+
+out:
+	get_next_submodule_task_release(task);
+
 	return 0;
 }
 
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 42692219a1..af12c50e7d 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


^ permalink raw reply	[relevance 25%]

* [PATCH 9/9] builtin/fetch: check for submodule updates for non branch fetches
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (6 preceding siblings ...)
  2018-10-16 18:13 ` [PATCH 8/9] fetch: retry fetching submodules if needed objects were not fetched Stefan Beller
@ 2018-10-16 18:13 ` Stefan Beller
  2018-10-18  2:30 ` [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Junio C Hamano
  2018-10-18  7:30 ` Junio C Hamano
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-16 18:13 UTC (permalink / raw)
  To: gitster; +Cc: git, Stefan Beller

Gerrit, the code review tool, has a different workflow than our mailing
list based approach. Usually users upload changes to a Gerrit server and
continuous integration and testing happens by bots. Sometimes however a
user wants to checkout a change locally and look at it locally. For this
use case, Gerrit offers a command line snippet to copy and paste to your
terminal, which looks like

  git fetch https://<host>/gerrit refs/changes/<id> &&
  git checkout FETCH_HEAD

For Gerrit changes that contain changing submodule gitlinks, it would be
easy to extend both the fetch and checkout with the '--recurse-submodules'
flag, such that this command line snippet would produce the state of a
change locally.

However the functionality added in the previous patch, which would
ensure that we fetch the objects in the submodule that the gitlink pointed
at, only works for remote tracking branches so far, not for FETCH_HEAD.

Make sure that fetching a superproject to its FETCH_HEAD, also respects
the existence checks for objects in the submodule recursion.

Signed-off-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.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 95c44bf6ff..ea6ecd123e 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 af12c50e7d..a509eabb04 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


^ permalink raw reply	[relevance 22%]

* Re: [PATCH 17/19] submodule: use submodule repos for object lookup
      [irrelevant] ` <20181011224052.191281-1-jonathantanmy@google.com>
@ 2018-10-16 19:30   ` Stefan Beller
      [irrelevant]     ` <20181016231343.189184-1-jonathantanmy@google.com>
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-16 19:30 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: git

On Thu, Oct 11, 2018 at 3:41 PM Jonathan Tan <jonathantanmy@google.com> wrote:
>
> > +/*
> > + * Initialize 'out' based on the provided submodule path.
> > + *
> > + * Unlike repo_submodule_init, this tolerates submodules not present
> > + * in .gitmodules. NEEDSWORK: The repo_submodule_init behavior is
> > + * preferrable. This function exists only to preserve historical behavior.
>
> What do you mean by "The repo_submodule_init behavior is preferable"? If
> we need to preserve historical behavior, then it seems that the most
> preferable one is something that meets our needs (like open_submodule()
> in this patch).
>
> > +static int open_submodule(struct repository *out, const char *path)
> > +{
> > +     struct strbuf sb = STRBUF_INIT;
> > +
> > +     if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
> > +             strbuf_release(&sb);
> > +             return -1;
> > +     }
> > +
> > +     out->submodule_prefix = xstrdup(path);
>
> Do we need to set submodule_prefix?
>
> > @@ -507,7 +533,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
> >       else if (is_null_oid(two))
> >               message = "(submodule deleted)";
> >
> > -     if (add_submodule_odb(path)) {
> > +     if (open_submodule(sub, path) < 0) {
>
> This function, as a side effect, writes the open repository to "sub" for
> its caller to use. I think it's better if its callers open "sub" and
> then pass it to show_submodule_header() if successful. If opening the
> submodule is expected to fail sometimes (like it seems here), then we
> can allow callers to also pass NULL, and document what happens when NULL
> is passed.

Thanks for the review of the whole series!

I have redone this series, addressing all your comments. I addressed
this comment differently than suggested, and put the submodule
repository argument at the end of the parameter list, such that it
goes with all the other arguments to be filled in.

I was about to resend the series, but test-merged with the other
submodule series in flight (origin/sb/submodule-recursive-fetch-gets-the-tip)
which had some conflicts that I can easily resolve by rebasing on top.

It conflicts a lot when merging to next, due to the latest patch
("Apply semantic patches from previous patches"), so I am not sure
how to proceed properly. Maybe we'd omit that patch and
run 'make coccicheck' on next to apply the semantic patches
there instead.

^ permalink raw reply	[relevance 8%]

* Re: [PATCH] submodule helper: convert relative URL to absolute URL if needed
  2018-10-16 17:27       ` Stefan Beller
@ 2018-10-16 21:05         ` Jonathan Nieder
  0 siblings, 0 replies; 200+ results
From: Jonathan Nieder @ 2018-10-16 21:05 UTC (permalink / raw)
  To: Stefan Beller; +Cc: gitster, git, jungjw

Stefan Beller wrote:

> Reported-by: Jaewoong Jung <jungjw@google.com>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  builtin/submodule--helper.c | 51 ++++++++++++++++++++++++-------------
>  t/t7400-submodule-basic.sh  | 24 +++++++++++++++++
>  2 files changed, 58 insertions(+), 17 deletions(-)

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

Thanks for your patient work.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 17/19] submodule: use submodule repos for object lookup
      [irrelevant]     ` <20181016231343.189184-1-jonathantanmy@google.com>
@ 2018-10-16 23:16       ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-16 23:16 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: git

On Tue, Oct 16, 2018 at 4:13 PM Jonathan Tan <jonathantanmy@google.com> wrote:
>
> > Thanks for the review of the whole series!
> >
> > I have redone this series, addressing all your comments. I addressed
> > this comment differently than suggested, and put the submodule
> > repository argument at the end of the parameter list, such that it
> > goes with all the other arguments to be filled in.
>
> Sounds good.

Actually I changed my mind on that after figuring out how to free
the submodule repository appropriately and went with your original suggestion.

>
> > I was about to resend the series, but test-merged with the other
> > submodule series in flight (origin/sb/submodule-recursive-fetch-gets-the-tip)
> > which had some conflicts that I can easily resolve by rebasing on top.
>
> I presume you are talking about [1]? Maybe consider rebasing that one on
> top of this instead, since this is just a refactoring whereas
> submodule-recursive-fetch-gets-the-tip changes functionality, from what
> I understand of patches 8 and 9.

From my understanding, that series is further along than this one,
so I would not want to mix up their order.

Currently I am rebasing this on top of select topics from next,
(ds/reachable) as that are the other conflicts that I'd have to deal with.

> [1] https://public-inbox.org/git/20181016181327.107186-1-sbeller@google.com/
>
> > It conflicts a lot when merging to next, due to the latest patch
> > ("Apply semantic patches from previous patches"), so I am not sure
> > how to proceed properly. Maybe we'd omit that patch and
> > run 'make coccicheck' on next to apply the semantic patches
> > there instead.
>
> Omitting the patch sounds good to me. For me, just stating that you have
> excluded any coccinelle-generated patches in order to ease merging into
> the various branches is sufficient, and people can test the coccinelle
> patches included by running "make coccicheck" then "patch -p1
> <contrib/coccinelle/the_repository.cocci.patch".

ok.

Thanks,
Stefan

^ permalink raw reply	[relevance 8%]

* [PATCH 00/19] Bring more repository handles into our code base
@ 2018-10-16 23:35 Stefan Beller
  2018-10-16 23:35 ` [PATCH 18/19] submodule: use submodule repos for object lookup Stefan Beller
                   ` (3 more replies)
  0 siblings, 4 replies; 200+ results
From: Stefan Beller @ 2018-10-16 23:35 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

This rerolls sb/more-repo-in-api.
It applies on nd/the-index merged with ds/reachable and is available via
    git fetch https://github.com/stefanbeller/git object-store-final-3

I addressed all of Jonathans comments, see range-diff below;
the last patch (applying the semantic patches) has been omitted as that
would produce a lot of merge conflicts. Without that patch, this merges
cleanly to next.

As for when to apply the semantic patches, I wondered if we would prefer a dirty merge
(created via "make coccicheck && git apply contrib/coccinelle/the_repository.cocci.patch")
of the semantic patches, or if we'd actually trickle in the changes over some time?

Thanks,
Stefan

An earlier RFC was sent out at
https://public-inbox.org/git/20181011211754.31369-1-sbeller@google.com/ and said:
    This applies on nd/the-index (b3c7eef9b05) and is the logical continuation of
    the object store series, which I sent over the last year.
    
    The previous series did take a very slow and pedantic approach,
    using a #define trick, see cfc62fc98c for details, but it turns out,
    that it doesn't work:
       When changing the signature of widely used functions, it burdens the
       maintainer in resolving the semantic conflicts.
       
       In the orginal approach this was called a feature, as then we can ensure
       that not bugs creep into the code base during the merge window (while such
       a refactoring series wanders from pu to master). It turns out this
       was not well received and was just burdensome.
       
       The #define trick doesn't buy us much to begin with when dealing with
       non-merge-conflicts.  For example, see deref_tag at tag.c:68, which got
       the repository argument in 286d258d4f (tag.c: allow deref_tag to handle
       arbitrary repositories, 2018-06-28) but lost its property of working on any
       repository while 8c4cc32689 (tag: don't warn if target is missing but
       promised, 2018-07-12) was in flight simultaneously.
       
       Another example of failure of this approach is seen in patch 5, which
       shows that the pedantry was missed.
            
    This series takes another approach as it doesn't change the signature of
    functions, but introduces new functions that can deal with arbitrary 
    repositories, keeping the old function signature around using a shallow wrapper.
    
    Additionally each patch adds a semantic patch, that would port from the old to
    the new function. These semantic patches are all applied in the very last patch,
    but we could omit applying the last patch if it causes too many merge conflicts
    and trickl in the semantic patches over time when there are no merge conflicts.
    
    
    The original goal of all these refactoring series was to remove add_submodule_odb 
    in submodule.c, which was partially reached with this series. I'll investigate the
    remaining calls in another series, but it shows we're close to be done with these
    large refactorings as far as I am concerned.
    
    Thanks,
    Stefan
    

Stefan Beller (19):
  sha1_file: allow read_object to read objects in arbitrary repositories
  packfile: allow has_packed_and_bad to handle arbitrary repositories
  object-store: allow read_object_file_extended to read from arbitrary
    repositories
  object-store: prepare read_object_file to deal with arbitrary
    repositories
  object-store: prepare has_{sha1, object}_file[_with_flags] to handle
    arbitrary repositories
  object: parse_object to honor its repository argument
  commit: allow parse_commit* to handle arbitrary repositories
  commit-reach.c: allow paint_down_to_common to handle arbitrary
    repositories
  commit-reach.c: allow merge_bases_many to handle arbitrary
    repositories
  commit-reach.c: allow remove_redundant to handle arbitrary
    repositories
  commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary
    repositories
  commit-reach: prepare get_merge_bases to handle arbitrary repositories
  commit-reach: prepare in_merge_bases[_many] to handle arbitrary
    repositories
  commit: prepare get_commit_buffer to handle arbitrary repositories
  commit: prepare repo_unuse_commit_buffer to handle arbitrary
    repositories
  commit: prepare logmsg_reencode to handle arbitrary repositories
  pretty: prepare format_commit_message to handle arbitrary repositories
  submodule: use submodule repos for object lookup
  submodule: don't add submodule as odb for push

 commit-reach.c                          |  73 +++++++-----
 commit-reach.h                          |  38 +++++--
 commit.c                                |  32 ++++--
 commit.h                                |  39 ++++++-
 contrib/coccinelle/the_repository.cocci | 144 ++++++++++++++++++++++++
 object-store.h                          |  35 ++++--
 object.c                                |   6 +-
 packfile.c                              |   5 +-
 packfile.h                              |   2 +-
 pretty.c                                |  28 ++---
 pretty.h                                |   7 +-
 sha1-file.c                             |  34 +++---
 streaming.c                             |   2 +-
 submodule.c                             |  78 ++++++++++---
 14 files changed, 402 insertions(+), 121 deletions(-)
 create mode 100644 contrib/coccinelle/the_repository.cocci

 git range-diff origin/sb/more-repo-in-api...

 -:  ---------- >  1:  5227c38566 commit-reach: move walk methods from commit.c
 -:  ---------- >  2:  6404355657 commit.h: remove method declarations
 -:  ---------- >  3:  1d614d41e5 commit-reach: move ref_newer from remote.c
 -:  ---------- >  4:  920f93ca1c commit-reach: move commit_contains from ref-filter
 -:  ---------- >  5:  f044bb49ad upload-pack: make reachable() more generic
 -:  ---------- >  6:  921bf7734f upload-pack: refactor ok_to_give_up()
 -:  ---------- >  7:  118be5785e upload-pack: generalize commit date cutoff
 -:  ---------- >  8:  ba3ca1edce commit-reach: move can_all_from_reach_with_flags
 -:  ---------- >  9:  ab176ac4ae test-reach: create new test tool for ref_newer
 -:  ---------- > 10:  5cd52de326 test-reach: test in_merge_bases
 -:  ---------- > 11:  6255232ec1 test-reach: test is_descendant_of
 -:  ---------- > 12:  324dec0191 test-reach: test get_merge_bases_many
 -:  ---------- > 13:  0c89f715d0 test-reach: test reduce_heads
 -:  ---------- > 14:  1792bc1250 test-reach: test can_all_from_reach_with_flags
 -:  ---------- > 15:  1fee124257 test-reach: test commit_contains
 -:  ---------- > 16:  1e3497a24c commit-reach: replace ref_newer logic
 -:  ---------- > 17:  4fbcca4eff commit-reach: make can_all_from_reach... linear
 -:  ---------- > 18:  6cc017431c commit-reach: use can_all_from_reach
 -:  ---------- > 19:  6621c83874 commit-reach: correct accidental #include of C file
 -:  ---------- > 20:  b67f6b26e3 commit-reach: properly peel tags
 -:  ---------- > 21:  4067a64672 commit-reach: fix memory and flag leaks
 1:  2c13c6101f = 22:  14c12a5350 sha1_file: allow read_object to read objects in arbitrary repositories
 2:  82848c2571 = 23:  f978950604 packfile: allow has_packed_and_bad to handle arbitrary repositories
 3:  717023d801 = 24:  852f6696d1 object-store: allow read_object_file_extended to read from arbitrary repositories
 4:  fab6bdfad0 ! 25:  b185b88ad8 object-store: prepare read_object_file to deal with arbitrary repositories
    @@ -9,7 +9,7 @@
     
         Introduce repo_read_object_file which takes the repository argument, and
         hide the original read_object_file as a macro behind
    -    NO_THE_REPOSITORY_COMPATIBILITY_MACROS, which we planned for in
    +    NO_THE_REPOSITORY_COMPATIBILITY_MACROS, similar to
         e675765235 (diff.c: remove implicit dependency on the_index, 2018-09-21)
     
         Add a coccinelle patch to convert existing callers, but do not apply
 -:  ---------- > 26:  009d6f350b object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories
 5:  9e34d76c53 ! 27:  df2feb2baf object: parse_object to honor its repository argument
    @@ -12,6 +12,17 @@
     diff --git a/object.c b/object.c
     --- a/object.c
     +++ b/object.c
    +@@
    + 	if (obj && obj->parsed)
    + 		return obj;
    + 
    +-	if ((obj && obj->type == OBJ_BLOB && has_object_file(oid)) ||
    +-	    (!obj && has_object_file(oid) &&
    ++	if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) ||
    ++	    (!obj && repo_has_object_file(r, oid) &&
    + 	     oid_object_info(r, oid, NULL) == OBJ_BLOB)) {
    + 		if (check_object_signature(repl, NULL, 0, NULL) < 0) {
    + 			error(_("sha1 mismatch %s"), oid_to_hex(oid));
     @@
      		return lookup_object(r, oid->hash);
      	}
 6:  9cb7efc7b2 ! 28:  18b7073c25 commit: allow parse_commit* to handle arbitrary repositories
    @@ -97,9 +97,10 @@
     --- a/contrib/coccinelle/the_repository.cocci
     +++ b/contrib/coccinelle/the_repository.cocci
     @@
    - + repo_read_object_file(the_repository,
    -   E, F, G)
    - 
    + - has_object_file_with_flags(
    + + repo_has_object_file_with_flags(the_repository,
    +   E)
    ++
     +@@
     +expression E;
     +expression F;
    @@ -123,4 +124,3 @@
     +- parse_commit(
     ++ repo_parse_commit(the_repository,
     +  E)
    -+
 7:  fcab4a4000 ! 29:  48f8999e95 commit.c: allow paint_down_to_common to handle arbitrary repositories
    @@ -1,15 +1,14 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit.c: allow paint_down_to_common to handle arbitrary repositories
    +    commit-reach.c: allow paint_down_to_common to handle arbitrary repositories
     
         As the function is file local and not widely used, migrate it all at once.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    -diff --git a/commit.c b/commit.c
    ---- a/commit.c
    -+++ b/commit.c
    +diff --git a/commit-reach.c b/commit-reach.c
    +--- a/commit-reach.c
    ++++ b/commit-reach.c
     @@
      }
      
 8:  324422f0d3 ! 30:  b84d32c972 commit.c: allow merge_bases_many to handle arbitrary repositories
    @@ -1,13 +1,12 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit.c: allow merge_bases_many to handle arbitrary repositories
    +    commit-reach.c: allow merge_bases_many to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    -diff --git a/commit.c b/commit.c
    ---- a/commit.c
    -+++ b/commit.c
    +diff --git a/commit-reach.c b/commit-reach.c
    +--- a/commit-reach.c
    ++++ b/commit-reach.c
     @@
      	return result;
      }
 9:  9c43e74d6c ! 31:  cd0e595b8d commit.c: allow remove_redundant to handle arbitrary repositories
    @@ -1,13 +1,12 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit.c: allow remove_redundant to handle arbitrary repositories
    +    commit-reach.c: allow remove_redundant to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    -diff --git a/commit.c b/commit.c
    ---- a/commit.c
    -+++ b/commit.c
    +diff --git a/commit-reach.c b/commit-reach.c
    +--- a/commit-reach.c
    ++++ b/commit-reach.c
     @@
      	return ret;
      }
10:  e5c2e2fa8e ! 32:  40ebd46acd commit: allow get_merge_bases_many_0 to handle arbitrary repositories
    @@ -1,13 +1,12 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit: allow get_merge_bases_many_0 to handle arbitrary repositories
    +    commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    -diff --git a/commit.c b/commit.c
    ---- a/commit.c
    -+++ b/commit.c
    +diff --git a/commit-reach.c b/commit-reach.c
    +--- a/commit-reach.c
    ++++ b/commit-reach.c
     @@
      	return filled;
      }
11:  27d4669ccb ! 33:  151cc8cd9b commit: prepare get_merge_bases to handle arbitrary repositories
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit: prepare get_merge_bases to handle arbitrary repositories
    +    commit-reach: prepare get_merge_bases to handle arbitrary repositories
     
         Similarly to previous patches, the get_merge_base functions are used
         often in the code base, which makes migrating them hard.
    @@ -9,11 +9,10 @@
         functions behind a wrapper macro.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    -diff --git a/commit.c b/commit.c
    ---- a/commit.c
    -+++ b/commit.c
    +diff --git a/commit-reach.c b/commit-reach.c
    +--- a/commit-reach.c
    ++++ b/commit-reach.c
     @@
      	return result;
      }
    @@ -53,16 +52,21 @@
      
      /*
     
    -diff --git a/commit.h b/commit.h
    ---- a/commit.h
    -+++ b/commit.h
    +diff --git a/commit-reach.h b/commit-reach.h
    +--- a/commit-reach.h
    ++++ b/commit-reach.h
     @@
    - int register_commit_graft(struct repository *r, struct commit_graft *, int);
    - struct commit_graft *lookup_commit_graft(struct repository *r, const struct object_id *oid);
    + struct contains_cache;
    + struct ref_filter;
      
    --extern struct commit_list *get_merge_bases(struct commit *rev1, struct commit *rev2);
    --extern struct commit_list *get_merge_bases_many(struct commit *one, int n, struct commit **twos);
    --extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
    +-struct commit_list *get_merge_bases_many(struct commit *one,
    +-					 int n,
    +-					 struct commit **twos);
    +-struct commit_list *get_merge_bases_many_dirty(struct commit *one,
    +-					       int n,
    +-					       struct commit **twos);
    +-struct commit_list *get_merge_bases(struct commit *one, struct commit *two);
    +-struct commit_list *get_octopus_merge_bases(struct commit_list *in);
     -
     +struct commit_list *repo_get_merge_bases(struct repository *r,
     +					 struct commit *rev1,
    @@ -71,7 +75,7 @@
     +					      struct commit *one, int n,
     +					      struct commit **twos);
      /* To be used only when object flags after this call no longer matter */
    --extern struct commit_list *get_merge_bases_many_dirty(struct commit *one, int n, struct commit **twos);
    +-struct commit_list *get_merge_bases_many_dirty(struct commit *one, int n, struct commit **twos);
     +struct commit_list *repo_get_merge_bases_many_dirty(struct repository *r,
     +						    struct commit *one, int n,
     +						    struct commit **twos);
    @@ -80,18 +84,20 @@
     +#define get_merge_bases_many(one, n, two) repo_get_merge_bases_many(the_repository, one, n, two)
     +#define get_merge_bases_many_dirty(one, n, twos) repo_get_merge_bases_many_dirty(the_repository, one, n, twos)
     +#endif
    -+extern struct commit_list *get_octopus_merge_bases(struct commit_list *in);
    ++
    ++struct commit_list *get_octopus_merge_bases(struct commit_list *in);
      
    - /* largest positive number a signed 32-bit integer can contain */
    - #define INFINITE_DEPTH 0x7fffffff
    + int is_descendant_of(struct commit *commit, struct commit_list *with_commit);
    + int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);
     
     diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
     --- a/contrib/coccinelle/the_repository.cocci
     +++ b/contrib/coccinelle/the_repository.cocci
     @@
    + - parse_commit(
      + repo_parse_commit(the_repository,
        E)
    - 
    ++
     +@@
     +expression E;
     +expression F;
13:  977359ec86 ! 34:  b508acf4fd commit: prepare in_merge_bases[_many] to handle arbitrary repositories
    @@ -1,13 +1,12 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit: prepare in_merge_bases[_many] to handle arbitrary repositories
    +    commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    -diff --git a/commit.c b/commit.c
    ---- a/commit.c
    -+++ b/commit.c
    +diff --git a/commit-reach.c b/commit-reach.c
    +--- a/commit-reach.c
    ++++ b/commit-reach.c
     @@
      /*
       * Is "commit" an ancestor of one of the "references"?
    @@ -53,33 +52,36 @@
      
      struct commit_list *reduce_heads(struct commit_list *heads)
     
    -diff --git a/commit.h b/commit.h
    ---- a/commit.h
    -+++ b/commit.h
    +diff --git a/commit-reach.h b/commit-reach.h
    +--- a/commit-reach.h
    ++++ b/commit-reach.h
     @@
    - extern struct trace_key trace_shallow;
    + struct commit_list *get_octopus_merge_bases(struct commit_list *in);
      
    - int is_descendant_of(struct commit *, struct commit_list *);
    --int in_merge_bases(struct commit *, struct commit *);
    --int in_merge_bases_many(struct commit *, int, struct commit **);
    -+int repo_in_merge_bases(struct repository *r, struct commit *, struct commit *);
    -+int repo_in_merge_bases_many(struct repository *r, struct commit *, int, struct commit **);
    + int is_descendant_of(struct commit *commit, struct commit_list *with_commit);
    +-int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);
    +-int in_merge_bases(struct commit *commit, struct commit *reference);
    ++int repo_in_merge_bases(struct repository *r,
    ++			struct commit *commit,
    ++			struct commit *reference);
    ++int repo_in_merge_bases_many(struct repository *r,
    ++			     struct commit *commit,
    ++			     int nr_reference, struct commit **reference);
     +#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
     +#define in_merge_bases(c1, c2) repo_in_merge_bases(the_repository, c1, c2)
     +#define in_merge_bases_many(c1, n, cs) repo_in_merge_bases_many(the_repository, c1, n, cs)
     +#endif
      
    - extern int interactive_add(int argc, const char **argv, const char *prefix, int patch);
    - extern int run_add_interactive(const char *revision, const char *patch_mode,
    + /*
    +  * Takes a list of commits and returns a new list where those
     
     diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
     --- a/contrib/coccinelle/the_repository.cocci
     +++ b/contrib/coccinelle/the_repository.cocci
     @@
    - - get_commit_buffer(
    - + repo_get_commit_buffer(the_repository,
    -   E, F);
    -+
    + + repo_get_merge_bases_many_dirty(the_repository,
    +   E, F, G);
    + 
     +@@
     +expression E;
     +expression F;
12:  044bf2917c ! 35:  c825f2703c commit: prepare get_commit_buffer to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit: prepare get_commit_buffer to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
     diff --git a/commit.c b/commit.c
     --- a/commit.c
    @@ -50,9 +49,10 @@
     --- a/contrib/coccinelle/the_repository.cocci
     +++ b/contrib/coccinelle/the_repository.cocci
     @@
    - + repo_get_merge_bases_many_dirty(the_repository,
    + - in_merge_bases_many(
    + + repo_in_merge_bases_many(the_repository,
        E, F, G);
    - 
    ++
     +@@
     +expression E;
     +expression F;
14:  65771970b9 ! 36:  bea6ff2e6d commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
     diff --git a/commit.c b/commit.c
     --- a/commit.c
    @@ -46,9 +45,10 @@
     --- a/contrib/coccinelle/the_repository.cocci
     +++ b/contrib/coccinelle/the_repository.cocci
     @@
    + - get_commit_buffer(
      + repo_get_commit_buffer(the_repository,
        E, F);
    - 
    ++
     +@@
     +expression E;
     +expression F;
    @@ -56,7 +56,3 @@
     +- unuse_commit_buffer(
     ++ repo_unuse_commit_buffer(the_repository,
     +  E, F);
    -+
    - @@
    - expression E;
    - expression F;
15:  ddef24685d ! 37:  11ea084cd2 commit: prepare logmsg_reencode to handle arbitrary repositories
    @@ -28,9 +28,9 @@
     --- a/contrib/coccinelle/the_repository.cocci
     +++ b/contrib/coccinelle/the_repository.cocci
     @@
    - - in_merge_bases_many(
    - + repo_in_merge_bases_many(the_repository,
    -   E, F, G);
    + - unuse_commit_buffer(
    + + repo_unuse_commit_buffer(the_repository,
    +   E, F);
     +
     +@@
     +expression E;
16:  8612153e23 = 38:  9f50edd155 pretty: prepare format_commit_message to handle arbitrary repositories
17:  eba296fc18 ! 39:  1a4a392233 submodule: use submodule repos for object lookup
    @@ -7,7 +7,6 @@
         are not added to the main object store.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
     diff --git a/submodule.c b/submodule.c
     --- a/submodule.c
    @@ -35,12 +34,15 @@
      			 DEFAULT_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
    +- * left and right pointers.
     +/*
     + * Initialize 'out' based on the provided submodule path.
     + *
     + * Unlike repo_submodule_init, this tolerates submodules not present
    -+ * in .gitmodules. NEEDSWORK: The repo_submodule_init behavior is
    -+ * preferrable. This function exists only to preserve historical behavior.
    ++ * in .gitmodules. This function exists only to preserve historical behavior,
     + *
     + * Returns 0 on success, -1 when the submodule is not present.
     + */
    @@ -54,28 +56,38 @@
     +	}
     +
     +	out->submodule_prefix = xstrdup(path);
    ++	out->submodule_prefix = xstrfmt("%s%s/",
    ++					the_repository->submodule_prefix ?
    ++					the_repository->submodule_prefix :
    ++					"", path);
     +
     +	strbuf_release(&sb);
     +	return 0;
     +}
     +
    - /* 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
    -  * left and right pointers.
    ++/*
    ++ * Helper function to display the submodule header line prior to the full
    ++ * summary output.
    ++ *
    ++ * If it can locate the submodule git directory it will create a repository
    ++ * handle for the submodule and lookup both the left and right commits and
    ++ * put them into the left and right pointers.
       */
     -static void show_submodule_header(struct diff_options *o, const char *path,
    -+static void show_submodule_header(struct diff_options *o, struct repository *sub,
    ++static void show_submodule_header(struct diff_options *o,
     +		const char *path,
      		struct object_id *one, struct object_id *two,
      		unsigned dirty_submodule,
    ++		struct repository *sub,
      		struct commit **left, struct commit **right,
    + 		struct commit_list **merge_bases)
    + {
     @@
      	else if (is_null_oid(two))
      		message = "(submodule deleted)";
      
     -	if (add_submodule_odb(path)) {
    -+	if (open_submodule(sub, path) < 0) {
    ++	if (!sub) {
      		if (!message)
      			message = "(commits not present)";
      		goto output_header;
    @@ -103,30 +115,63 @@
      	struct rev_info rev;
      	struct commit *left = NULL, *right = NULL;
      	struct commit_list *merge_bases = NULL;
    -+	struct repository sub;
    ++	struct repository subrepo, *sub = &subrepo;
    ++
    ++	if (open_submodule(&subrepo, path) < 0)
    ++		sub = NULL;
      
    --	show_submodule_header(o, path, one, two, dirty_submodule,
    -+	show_submodule_header(o, &sub, path, one, two, dirty_submodule,
    - 			      &left, &right, &merge_bases);
    + 	show_submodule_header(o, path, one, two, dirty_submodule,
    +-			      &left, &right, &merge_bases);
    ++			      sub, &left, &right, &merge_bases);
      
      	/*
    + 	 * If we don't have both a left and a right pointer, there is no
    + 	 * reason to try and display a summary. The header line should contain
    + 	 * all the information the user needs.
    + 	 */
    +-	if (!left || !right)
    ++	if (!left || !right || !sub)
    + 		goto out;
    + 
    + 	/* Treat revision walker failure the same as missing commits */
     @@
      		goto out;
      	}
      
     -	print_submodule_summary(&rev, o);
    -+	print_submodule_summary(&sub, &rev, o);
    ++	print_submodule_summary(sub, &rev, o);
      
      out:
      	if (merge_bases)
    + 		free_commit_list(merge_bases);
    + 	clear_commit_marks(left, ~0);
    + 	clear_commit_marks(right, ~0);
    ++	if (sub)
    ++		repo_clear(sub);
    + }
    + 
    + void show_submodule_inline_diff(struct diff_options *o, const char *path,
     @@
      	struct commit_list *merge_bases = NULL;
      	struct child_process cp = CHILD_PROCESS_INIT;
      	struct strbuf sb = STRBUF_INIT;
    -+	struct repository sub;
    ++	struct repository subrepo, *sub = &subrepo;
    ++
    ++	if (open_submodule(&subrepo, path) < 0)
    ++		sub = NULL;
      
    --	show_submodule_header(o, path, one, two, dirty_submodule,
    -+	show_submodule_header(o, &sub, path, one, two, dirty_submodule,
    - 			      &left, &right, &merge_bases);
    + 	show_submodule_header(o, path, one, two, dirty_submodule,
    +-			      &left, &right, &merge_bases);
    ++			      sub, &left, &right, &merge_bases);
      
      	/* We need a valid left and right commit to display a difference */
    + 	if (!(left || is_null_oid(one)) ||
    +@@
    + 		clear_commit_marks(left, ~0);
    + 	if (right)
    + 		clear_commit_marks(right, ~0);
    ++	if (sub)
    ++		repo_clear(sub);
    + }
    + 
    + int should_update_submodules(void)
18:  4b2033017a ! 40:  1ce2d0a867 submodule: don't add submodule as odb for push
    @@ -2,20 +2,13 @@
     
         submodule: don't add submodule as odb for push
     
    -    The submodule was added as an alternative in eb21c732d6 (push: teach
    -    --recurse-submodules the on-demand option, 2012-03-29), but was
    -    not explained, why.
    -
    -    In similar code, submodule_has_commits, the submodule is added as an
    -    alternative to perform a quick check if we need to dive into the submodule.
    -
    -    However in push_submodule
    -    (a) for_each_remote_ref_submodule will also provide the quick check and
    -    (b) after that we don't need to have submodule objects around, as all
    -        further code is to spawn a separate process.
    +    In push_submodule(), because we do not actually need access to objects
    +    in the submodule, do not invoke add_submodule_odb().
    +    (for_each_remote_ref_submodule() does not require access to those
    +    objects, and the actual push is done by spawning another process,
    +    which handles object access by itself.)
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
     diff --git a/submodule.c b/submodule.c
     --- a/submodule.c
19:  c74af1496b <  -:  ---------- Apply semantic patches from previous patches

^ permalink raw reply	[relevance 7%]

* [PATCH 18/19] submodule: use submodule repos for object lookup
  2018-10-16 23:35 [PATCH 00/19] Bring more repository handles into our code base Stefan Beller
@ 2018-10-16 23:35 ` Stefan Beller
  2018-10-25  9:14   ` SZEDER Gábor
  2018-10-31 13:38   ` Derrick Stolee
  2018-10-16 23:35 ` [PATCH 19/19] submodule: don't add submodule as odb for push Stefan Beller
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 200+ results
From: Stefan Beller @ 2018-10-16 23:35 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

This converts the 'show_submodule_header' function to use
the repository API properly, such that the submodule objects
are not added to the main object store.

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

diff --git a/submodule.c b/submodule.c
index 4ee69cc014..7305ae2e10 100644
--- a/submodule.c
+++ b/submodule.c
@@ -444,7 +444,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
 	return prepare_revision_walk(rev);
 }
 
-static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
+static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
 {
 	static const char format[] = "  %m %s";
 	struct strbuf sb = STRBUF_INIT;
@@ -455,7 +455,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
 		ctx.date_mode = rev->date_mode;
 		ctx.output_encoding = get_log_output_encoding();
 		strbuf_setlen(&sb, 0);
-		format_commit_message(commit, format, &sb, &ctx);
+		repo_format_commit_message(r, commit, format, &sb,
+				      &ctx);
 		strbuf_addch(&sb, '\n');
 		if (commit->object.flags & SYMMETRIC_LEFT)
 			diff_emit_submodule_del(o, sb.buf);
@@ -482,14 +483,46 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_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
- * left and right pointers.
+/*
+ * Initialize 'out' based on the provided submodule path.
+ *
+ * Unlike repo_submodule_init, this tolerates submodules not present
+ * in .gitmodules. This function exists only to preserve historical behavior,
+ *
+ * Returns 0 on success, -1 when the submodule is not present.
+ */
+static int open_submodule(struct repository *out, const char *path)
+{
+	struct strbuf sb = STRBUF_INIT;
+
+	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
+		strbuf_release(&sb);
+		return -1;
+	}
+
+	out->submodule_prefix = xstrdup(path);
+	out->submodule_prefix = xstrfmt("%s%s/",
+					the_repository->submodule_prefix ?
+					the_repository->submodule_prefix :
+					"", path);
+
+	strbuf_release(&sb);
+	return 0;
+}
+
+/*
+ * Helper function to display the submodule header line prior to the full
+ * summary output.
+ *
+ * If it can locate the submodule git directory it will create a repository
+ * handle for the submodule and lookup both the left and right commits and
+ * put them into the left and right pointers.
  */
-static void show_submodule_header(struct diff_options *o, const char *path,
+static void show_submodule_header(struct diff_options *o,
+		const char *path,
 		struct object_id *one, struct object_id *two,
 		unsigned dirty_submodule,
+		struct repository *sub,
 		struct commit **left, struct commit **right,
 		struct commit_list **merge_bases)
 {
@@ -508,7 +541,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	else if (is_null_oid(two))
 		message = "(submodule deleted)";
 
-	if (add_submodule_odb(path)) {
+	if (!sub) {
 		if (!message)
 			message = "(commits not present)";
 		goto output_header;
@@ -518,8 +551,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	 * Attempt to lookup the commit references, and determine if this is
 	 * a fast forward or fast backwards update.
 	 */
-	*left = lookup_commit_reference(the_repository, one);
-	*right = lookup_commit_reference(the_repository, two);
+	*left = lookup_commit_reference(sub, one);
+	*right = lookup_commit_reference(sub, two);
 
 	/*
 	 * Warn about missing commits in the submodule project, but only if
@@ -529,7 +562,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	     (!is_null_oid(two) && !*right))
 		message = "(commits not present)";
 
-	*merge_bases = get_merge_bases(*left, *right);
+	*merge_bases = repo_get_merge_bases(sub, *left, *right);
 	if (*merge_bases) {
 		if ((*merge_bases)->item == *left)
 			fast_forward = 1;
@@ -563,16 +596,20 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 	struct rev_info rev;
 	struct commit *left = NULL, *right = NULL;
 	struct commit_list *merge_bases = NULL;
+	struct repository subrepo, *sub = &subrepo;
+
+	if (open_submodule(&subrepo, path) < 0)
+		sub = NULL;
 
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/*
 	 * If we don't have both a left and a right pointer, there is no
 	 * reason to try and display a summary. The header line should contain
 	 * all the information the user needs.
 	 */
-	if (!left || !right)
+	if (!left || !right || !sub)
 		goto out;
 
 	/* Treat revision walker failure the same as missing commits */
@@ -581,13 +618,15 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 		goto out;
 	}
 
-	print_submodule_summary(&rev, o);
+	print_submodule_summary(sub, &rev, o);
 
 out:
 	if (merge_bases)
 		free_commit_list(merge_bases);
 	clear_commit_marks(left, ~0);
 	clear_commit_marks(right, ~0);
+	if (sub)
+		repo_clear(sub);
 }
 
 void show_submodule_inline_diff(struct diff_options *o, const char *path,
@@ -599,9 +638,13 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 	struct commit_list *merge_bases = NULL;
 	struct child_process cp = CHILD_PROCESS_INIT;
 	struct strbuf sb = STRBUF_INIT;
+	struct repository subrepo, *sub = &subrepo;
+
+	if (open_submodule(&subrepo, path) < 0)
+		sub = NULL;
 
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/* We need a valid left and right commit to display a difference */
 	if (!(left || is_null_oid(one)) ||
@@ -662,6 +705,8 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 		clear_commit_marks(left, ~0);
 	if (right)
 		clear_commit_marks(right, ~0);
+	if (sub)
+		repo_clear(sub);
 }
 
 int should_update_submodules(void)
-- 
2.19.0


^ permalink raw reply	[relevance 20%]

* [PATCH 19/19] submodule: don't add submodule as odb for push
  2018-10-16 23:35 [PATCH 00/19] Bring more repository handles into our code base Stefan Beller
  2018-10-16 23:35 ` [PATCH 18/19] submodule: use submodule repos for object lookup Stefan Beller
@ 2018-10-16 23:35 ` Stefan Beller
  2018-10-19 20:39   ` Jonathan Tan
  2018-10-17 12:41 ` [PATCH 00/19] Bring more repository handles into our code base Derrick Stolee
      [irrelevant] ` <20181022173935.GG30222@szeder.dev>
  3 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-16 23:35 UTC (permalink / raw)
  To: git; +Cc: jonathantanmy, Stefan Beller

In push_submodule(), because we do not actually need access to objects
in the submodule, do not invoke add_submodule_odb().
(for_each_remote_ref_submodule() does not require access to those
objects, and the actual push is done by spawning another process,
which handles object access by itself.)

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

diff --git a/submodule.c b/submodule.c
index 7305ae2e10..e623e6bf7f 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1024,9 +1024,6 @@ static int push_submodule(const char *path,
 			  const struct string_list *push_options,
 			  int dry_run)
 {
-	if (add_submodule_odb(path))
-		return 1;
-
 	if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
 		struct child_process cp = CHILD_PROCESS_INIT;
 		argv_array_push(&cp.args, "push");
-- 
2.19.0


^ permalink raw reply	[relevance 14%]

* [PATCH] builtin/submodule--helper: remove debugging leftover tracing
@ 2018-10-16 23:45 Stefan Beller
  2018-10-17  2:52 ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-16 23:45 UTC (permalink / raw)
  To: gitster; +Cc: git, Stefan Beller

I noticed 74d4731da1 (submodule--helper: replace connect-gitdir-workingtree
by ensure-core-worktree, 2018-08-13) had two leftover debugging statements
when reading The coverage report [1]. Remove them.

https://public-inbox.org/git/e30a9c05-87d8-1f2b-182c-6d6a5fefe43c@gmail.com/

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

To be applied on (or squashed into the tip of)
  sb/submodule-update-in-c

 builtin/submodule--helper.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 5c9d1fb496..c7d3841ffc 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1459,7 +1459,6 @@ static void determine_submodule_update_strategy(struct repository *r,
 	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);
@@ -1468,7 +1467,6 @@ static void determine_submodule_update_strategy(struct repository *r,
 			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
-- 
2.19.0


^ permalink raw reply	[relevance 18%]

* Re: [PATCH] builtin/submodule--helper: remove debugging leftover tracing
  2018-10-16 23:45 [PATCH] builtin/submodule--helper: remove debugging leftover tracing Stefan Beller
@ 2018-10-17  2:52 ` Jonathan Nieder
  0 siblings, 0 replies; 200+ results
From: Jonathan Nieder @ 2018-10-17  2:52 UTC (permalink / raw)
  To: Stefan Beller; +Cc: gitster, git

Stefan Beller wrote:

> I noticed 74d4731da1 (submodule--helper: replace connect-gitdir-workingtree
> by ensure-core-worktree, 2018-08-13) had two leftover debugging statements
> when reading The coverage report [1]. Remove them.
>
> https://public-inbox.org/git/e30a9c05-87d8-1f2b-182c-6d6a5fefe43c@gmail.com/
>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  builtin/submodule--helper.c | 2 --
>  1 file changed, 2 deletions(-)

Doh.  Glad you caught it!

Is there some reference for The Coverage Report other than the mailing
list?  E.g. I suspect a reference to

	make coverage-test
	make coverage-report

would be useful to readers finding this commit later.

> To be applied on (or squashed into the tip of)
>   sb/submodule-update-in-c

Looks like that's already in "master", so not a candidate for
squashing.

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

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 00/19] Bring more repository handles into our code base
  2018-10-16 23:35 [PATCH 00/19] Bring more repository handles into our code base Stefan Beller
  2018-10-16 23:35 ` [PATCH 18/19] submodule: use submodule repos for object lookup Stefan Beller
  2018-10-16 23:35 ` [PATCH 19/19] submodule: don't add submodule as odb for push Stefan Beller
@ 2018-10-17 12:41 ` Derrick Stolee
  2018-10-17 17:53   ` Stefan Beller
      [irrelevant] ` <20181022173935.GG30222@szeder.dev>
  3 siblings, 1 reply; 200+ results
From: Derrick Stolee @ 2018-10-17 12:41 UTC (permalink / raw)
  To: Stefan Beller, git; +Cc: jonathantanmy

On 10/16/2018 7:35 PM, Stefan Beller wrote:
>              
>      This series takes another approach as it doesn't change the signature of
>      functions, but introduces new functions that can deal with arbitrary
>      repositories, keeping the old function signature around using a shallow wrapper.
I think this is a good direction, and the changes look good to me.

>      Additionally each patch adds a semantic patch, that would port from the old to
>      the new function. These semantic patches are all applied in the very last patch,
>      but we could omit applying the last patch if it causes too many merge conflicts
>      and trickl in the semantic patches over time when there are no merge conflicts.

The semantic patches are a good idea. At some point in the future, we 
can submit a series that applies the patches to any leftover calls and 
removes the old callers. We can hopefully rely on review (and the 
semantic patches warning that there is work to do) to prevent new 
callers from being introduced in future topics. That doesn't count 
topics that come around while this one isn't merged down.

I had one high-level question: How are we testing that these "arbitrary 
repository" changes are safe? I just remember the issue we had with the 
commit-graph code relying on arbitrary repositories, but then adding a 
reference to the replace objects broke the code (because replace-objects 
wasn't using arbitrary repos correctly, but the commit-graph was tested 
with arbitrary repositories using "test-tool repository"). It would be 
nice to introduce more method calls in t/helper/test-repository.c that 
help us know these are safe conversions. Otherwise, we are essentially 
waiting until we try to take submodule things in-process and find out 
what breaks. As we discovered with the refstore, we can't just ensure 
that all references to the_repository are removed.

Thanks,
-Stolee

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 00/19] Bring more repository handles into our code base
  2018-10-17 12:41 ` [PATCH 00/19] Bring more repository handles into our code base Derrick Stolee
@ 2018-10-17 17:53   ` Stefan Beller
      [irrelevant]     ` <20181018183758.81186-1-sbeller@google.com>
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-17 17:53 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: git, Jonathan Tan

On Wed, Oct 17, 2018 at 5:41 AM Derrick Stolee <stolee@gmail.com> wrote:
>
> On 10/16/2018 7:35 PM, Stefan Beller wrote:
> >
> >      This series takes another approach as it doesn't change the signature of
> >      functions, but introduces new functions that can deal with arbitrary
> >      repositories, keeping the old function signature around using a shallow wrapper.
> I think this is a good direction, and the changes look good to me.
>
> >      Additionally each patch adds a semantic patch, that would port from the old to
> >      the new function. These semantic patches are all applied in the very last patch,
> >      but we could omit applying the last patch if it causes too many merge conflicts
> >      and trickl in the semantic patches over time when there are no merge conflicts.
>
> The semantic patches are a good idea. At some point in the future, we
> can submit a series that applies the patches to any leftover calls and
> removes the old callers. We can hopefully rely on review (and the
> semantic patches warning that there is work to do) to prevent new
> callers from being introduced in future topics. That doesn't count
> topics that come around while this one isn't merged down.

For those topics still in flight, I added re-defines, e.g.

#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS
#define get_merge_bases(r1, r2)
repo_get_merge_bases(the_repository, r1, r2)
#endif

so the base function still keeps working, and we can cleanup
multiple times, until eventually, we can get rid of the base function.

> I had one high-level question: How are we testing that these "arbitrary
> repository" changes are safe?

I did the bare minimum in conversions in this series, such that the
submodule code tests successfully. So if we'd revert some parts,
the submodule tests would break.



> I just remember the issue we had with the
> commit-graph code relying on arbitrary repositories, but then adding a
> reference to the replace objects broke the code (because replace-objects
> wasn't using arbitrary repos correctly, but the commit-graph was tested
> with arbitrary repositories using "test-tool repository"). It would be
> nice to introduce more method calls in t/helper/test-repository.c that
> help us know these are safe conversions.

Or instead we could accelerate the long term plan of removing a
hard coded the_repository and have each cmd builtin take an additional
repository pointer from the init code, such that we'd bring all of Git to
work on arbitrary repositories. Then the standard test suite should be
okay, as there is no special case for the_repository any more.

> Otherwise, we are essentially
> waiting until we try to take submodule things in-process and find out
> what breaks. As we discovered with the refstore, we can't just ensure
> that all references to the_repository are removed.

Yes, that is correct. We had a similar case with partial clone,
as laid out in the cover letter for the RFC.

I'll explore both the test tool approach as well as
repository-fication of the code base.

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (7 preceding siblings ...)
  2018-10-16 18:13 ` [PATCH 9/9] builtin/fetch: check for submodule updates for non branch fetches Stefan Beller
@ 2018-10-18  2:30 ` Junio C Hamano
  2018-10-18  7:30 ` Junio C Hamano
  9 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-10-18  2:30 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> This is based on ao/submodule-wo-gitmodules-checked-out.

Thanks.  I had an impression that we were not entirely happy with
the topic and are expecting a reroll, but let's hope that the part
we expect to be updated won't have much overlaps.

> A range-diff below shows how picking a different base changed the patches,
> apart from that no further adjustments have been made.

Thanks.  Let's see how well this plays together with other topics in 'pu'.q

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip
  2018-10-16 18:13 [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (8 preceding siblings ...)
  2018-10-18  2:30 ` [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip Junio C Hamano
@ 2018-10-18  7:30 ` Junio C Hamano
  2018-10-18 18:00   ` Stefan Beller
  9 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-10-18  7:30 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

> This is based on ao/submodule-wo-gitmodules-checked-out.
>
> This resends origin/sb/submodule-recursive-fetch-gets-the-tip, resolving
> the issues pointed out via origin/xxx/sb-submodule-recursive-fetch-gets-the-tip-in-pu
> by basing this series on origin/ao/submodule-wo-gitmodules-checked-out

Applying this round to the result of merging ao/submodule-* to
'master' requires this to work, it seems, as you've introduced a
call to repo-init thing in the meantime with another topic.

Subject: [PATCH] fixup! repository: repo_submodule_init to take a submodule struct

---
 builtin/submodule--helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 5f8a804a6e..015aa1471f 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2037,7 +2037,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
 	if (!sub)
 		BUG("We could get the submodule handle before?");
 
-	if (repo_submodule_init(&subrepo, the_repository, path))
+	if (repo_submodule_init(&subrepo, the_repository, sub))
 		die(_("could not get a repository handle for submodule '%s'"), path);
 
 	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
-- 
2.19.1-450-ga4b8ab5363


^ permalink raw reply	[relevance 15%]

* Re: [PATCH 0/9] Resending sb/submodule-recursive-fetch-gets-the-tip
  2018-10-18  7:30 ` Junio C Hamano
@ 2018-10-18 18:00   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-18 18:00 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Thu, Oct 18, 2018 at 12:30 AM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> > This is based on ao/submodule-wo-gitmodules-checked-out.
> >
> > This resends origin/sb/submodule-recursive-fetch-gets-the-tip, resolving
> > the issues pointed out via origin/xxx/sb-submodule-recursive-fetch-gets-the-tip-in-pu
> > by basing this series on origin/ao/submodule-wo-gitmodules-checked-out
>
> Applying this round to the result of merging ao/submodule-* to
> 'master' requires this to work, it seems, as you've introduced a
> call to repo-init thing in the meantime with another topic.

Unfortunately, yes, sb/submodule-update-in-c had one such call.

> > This is based on ao/submodule-wo-gitmodules-checked-out.
> Thanks.  I had an impression that we were not entirely happy with
> the topic and are expecting a reroll, but let's hope that the part
> we expect to be updated won't have much overlaps.

I slowly came to the realization that this topic might be ripped up
into 2 or more topics, as some of the cleanups seem to be orthogonal.

^ permalink raw reply	[relevance 7%]

* [RFC PATCH 1/2] repository: have get_the_repository() to remove the_repository dependency
      [irrelevant]     ` <20181018183758.81186-1-sbeller@google.com>
@ 2018-10-18 18:37       ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-18 18:37 UTC (permalink / raw)
  To: sbeller; +Cc: git, jonathantanmy, stolee

The struct 'the_repo' contains all data that of the main repository.
As we move more and more globals into this struct, the usual way of
accessing these is using 'the_repository', which can be used as a drop in
replacement for accessing the migrated globals.

However during the migration of globals into the repository object, it is
not clear if some code path rely on the_repository or can work on an
arbitrary repository (as we'd eventually want for submodules) due to the
excessive use of the_repository throughout the code base.

To address this, introduce a function 'get_the_repository(void)' which
will return the main repository and set the_repository to NULL when the
environment variable GIT_NO_THE_REPOSITORY is set.

This function is to be strictly used only at the beginning of builtin
command to assign it to a local repository pointer that we'll use to
pass through the code base.

By having the possibility to set the_repository to NULL, we'll get
a segfault when we try to access the_repository instead of using the
handle that we pass around.

This approach let's us have the_repository in the setup code, which
in its current form is not yet able to transition into a world where
the repository handle is passed around and only test the passing around
of the repository handle for later stage code.

Eventually in the future the setup code will produce the repository
handle and each 'cmd_foo(int argc, char **argv)' builtin would get the
repository via an additional parameter.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 repository.c | 10 ++++++++++
 repository.h | 13 ++++++++++++-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/repository.c b/repository.c
index 5dd1486718..aaaababb88 100644
--- a/repository.c
+++ b/repository.c
@@ -20,6 +20,16 @@ void initialize_the_repository(void)
 	repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
 }
 
+struct repository *get_the_repository(void)
+{
+	struct repository *r = the_repository;
+
+	if (getenv("GIT_NO_THE_REPOSITORY"))
+		the_repository = NULL;
+
+	return r;
+}
+
 static void expand_base_dir(char **out, const char *in,
 			    const char *base_dir, const char *def_in)
 {
diff --git a/repository.h b/repository.h
index 9f16c42c1e..26f5d64f68 100644
--- a/repository.h
+++ b/repository.h
@@ -114,13 +114,24 @@ void repo_set_gitdir(struct repository *repo, const char *root,
 		     const struct set_gitdir_args *extra_args);
 void repo_set_worktree(struct repository *repo, const char *path);
 void repo_set_hash_algo(struct repository *repo, int algo);
-void initialize_the_repository(void);
 int repo_init(struct repository *r, const char *gitdir, const char *worktree);
 int repo_submodule_init(struct repository *submodule,
 			struct repository *superproject,
 			const char *path);
 void repo_clear(struct repository *repo);
 
+/*
+ * Initializes the repository 'the_repository', which is used in the transition
+ * phase of moving globals into the repository struct.
+ */
+void initialize_the_repository(void);
+
+/*
+ * To be called once; after the call use only returned repository, and do not
+ * use the_repository any more
+ */
+struct repository *get_the_repository(void);
+
 /*
  * Populates the repository's index from its index_file, an index struct will
  * be allocated if needed.
-- 
2.19.0


^ permalink raw reply	[relevance 8%]

* Re: [PATCH 4/9] submodule.c: move global changed_submodule_names into fetch submodule struct
      [irrelevant]   ` <20181017212624.196598-1-jonathantanmy@google.com>
@ 2018-10-18 19:09     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-18 19:09 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: Junio C Hamano, git

On Wed, Oct 17, 2018 at 2:26 PM Jonathan Tan <jonathantanmy@google.com> wrote:
>
> > 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.
>
> Keep the titles of commit messages to 50 characters or under.

renamed

>
> > +static void calculate_changed_submodule_paths(
> > +     struct submodule_parallel_fetch *spf)
>
> Instead of taking the entire struct, could this just take the list of
> changed submodule names instead?

I think so, done.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH v2 19/24] submodule.c: remove implicit dependency on the_index
      [irrelevant]         ` <20181019164237.GA24740@sigill.intra.peff.net>
@ 2018-10-19 16:57           ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-19 16:57 UTC (permalink / raw)
  To: Jeff King; +Cc: Duy Nguyen, git

> >
> > Yeah. Killing the_index is just the first small step (didn't look that
> > small when I started). Now it's all about the_repository ;-) and we
> > have like 400 references of it just in library code.
>
> I suspect it is much worse than that, even. There are many spots that
> likely are relying on global data that _should_ be in the repository
> struct but aren't yet. I don't think there's even an easy way to count
> those. ;)

This is a very interesting part of the discussion,
please note the series "RFC Bring the_repository into cmd_foo"[1]
as that proposes one way how to deal with this, exposing the
repository/index changes into the existing test suite.

[1] https://public-inbox.org/git/20181018183758.81186-1-sbeller@google.com/

I'll read on.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH/WIP 00/19] Kill the_index, final part
      [irrelevant] <20181019145237.16079-1-pclouds@gmail.com>
@ 2018-10-19 17:38 ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-19 17:38 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

On Fri, Oct 19, 2018 at 7:52 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
>
> Stefan I see you start removing more references of the_repository in
> another series (haven't really looked at it yet) so this is just heads
> up so we could coordinate if needed. Still WIP, not really ready for
> review yet.

I'll take a brief look anyway, otherwise you wouldn't have put in on
a mailing list :-P

Yes, coordination would be good; stolee brought up a good point
regarding testing these changes. Killing of the index in itself can be
just tested by checking if behavior stays the same, but killing of
the_repository is a slightly different beast, as it relates to submodules,
which means any global state that is still around, need to go into
the repository struct (we might have missed some there, whereas
the index struct has been around for a long time).

> This series removes use of the_index outside builtin/ and t/helper/.
> The only the_index reference left is in repository.c. The macro
> NO_THE_REPOSITORY_COMPATIBILITY_MACROS is now flipped to
> USE_THE_INDEX_COMPATIBILITY_MACROS. "the_index" is forbidden by
> default.

Wow, that is really cool. Looking forward for the patches. :-)

> After this I think we can start pushing the_repository outside library
> code. Then perhaps clean them up in builtin code too and you can
> finally get rid of it. But I don't think that'll happen in a year's
> time.

That sounds realistic.

Stefan

^ permalink raw reply	[relevance 4%]

* Re: [PATCH] submodule.c: remove some of the_repository references
      [irrelevant] ` <20181019173443.25760-1-pclouds@gmail.com>
@ 2018-10-19 17:46   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-19 17:46 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git, Jeff King, Junio C Hamano

On Fri, Oct 19, 2018 at 10:34 AM Nguyễn Thái Ngọc Duy <pclouds@gmail.com> wrote:
>
>
>  struct collect_changed_submodules_cb_data {
> +       struct repository *repo;

This slightly overlaps with sb/submodule-recursive-fetch-gets-the-tip,
but we can have this patch on its own as I have to rebuild that
series, will build on top of this.

The patch looks good,
Stefan

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 19/19] submodule: don't add submodule as odb for push
  2018-10-16 23:35 ` [PATCH 19/19] submodule: don't add submodule as odb for push Stefan Beller
@ 2018-10-19 20:39   ` Jonathan Tan
  0 siblings, 0 replies; 200+ results
From: Jonathan Tan @ 2018-10-19 20:39 UTC (permalink / raw)
  To: sbeller; +Cc: git, jonathantanmy

> In push_submodule(), because we do not actually need access to objects
> in the submodule, do not invoke add_submodule_odb().
> (for_each_remote_ref_submodule() does not require access to those
> objects, and the actual push is done by spawning another process,
> which handles object access by itself.)

The code looks good - my analysis is the same as that in my review of
the previous version [1].

Can you mention, in the commit message, the tests that exercise the
functionality here (and say that they still pass)?

[1] https://public-inbox.org/git/20181011230028.200488-1-jonathantanmy@google.com/
> 
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>  submodule.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/submodule.c b/submodule.c
> index 7305ae2e10..e623e6bf7f 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -1024,9 +1024,6 @@ static int push_submodule(const char *path,
>  			  const struct string_list *push_options,
>  			  int dry_run)
>  {
> -	if (add_submodule_odb(path))
> -		return 1;
> -
>  	if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
>  		struct child_process cp = CHILD_PROCESS_INIT;
>  		argv_array_push(&cp.args, "push");
> -- 
> 2.19.0
> 

^ permalink raw reply	[relevance 3%]

* Re: Bug with "git mv" and submodules, and with "git submodule add something --force"
      [irrelevant] <c4792c95-9a19-fd0e-9171-fded095b78a6@jku.at>
@ 2018-10-19 20:40 ` Stefan Beller
  2018-10-19 20:58   ` Jonathan Nieder
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-19 20:40 UTC (permalink / raw)
  To: juergen.vogl; +Cc: git

On Fri, Oct 19, 2018 at 5:43 AM Juergen Vogl <juergen.vogl@jku.at> wrote:
>
> Hi there,
>
> tested on both, git 2.18 and git 2.19.1:
>
> moving a file with `git mv` from a project to a submodule results in an
> **undefined state** of the local repository.

Luckily we do have a submodule in git.git itself, so we can
try it out here as well (I'll use a separate worktree to not
hose my main repo):

  git worktree add ../testgit && cd ../testgit
  git checkout v2.19.1 && make install
  git --version
  git version 2.19.1
  git submodule update --init
  Cloning into '/home/sbeller/testgit/sha1collisiondetection'...
  Submodule path 'sha1collisiondetection': checked out
'232357eb2ea0397388254a4b188333a227bf5b10'
  git mv cache.h sha1collisiondetection/
  git status
HEAD detached at v2.19.1
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

deleted:    sha1collisiondetection
renamed:    cache.h -> sha1collisiondetection/cache.h

Untracked files:
  (use "git add <file>..." to include in what will be committed)

sha1collisiondetection/.gitignore
sha1collisiondetection/.travis.yml
sha1collisiondetection/LICENSE.txt
sha1collisiondetection/Makefile
sha1collisiondetection/README.md
sha1collisiondetection/lib/
sha1collisiondetection/src/
sha1collisiondetection/test/
sha1collisiondetection/vs2015/

> It breaks up the submodule (it's still in .gitmodules, but not
> accessable via `git submodule`), and is not reversible on local repository.

This seems like what I just did. However reversing can be done via:

  git checkout -f
  git status
HEAD detached at v2.19.1
nothing to commit, working tree clean
  git submodule status
232357eb2ea0397388254a4b188333a227bf5b10 sha1collisiondetection
(stable-v1.0.3-31-g232357e)

So I think it's just "git-mv" that doesn't respect submodule
boundaries, which we would want to address.

The man page of git mv
(https://git-scm.com/docs/git-mv)
actually has a short note about submodules, but that is about
moving *a* submodule not about moving things in and out.

Maybe for now we can do with just an update of the documentation/bugs
section and say we cannot move files in and out of submodules?



>
> Either `git mv submodule/file .`

which is just running the command in reverse, (i.e. swapping
destination and target),
  git mv cache.h sha1collisiondetection/
  git mv sha1collisiondetection/cache.h cache.h
  git status
HEAD detached at v2.19.1
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

deleted:    sha1collisiondetection

Untracked files:
  (use "git add <file>..." to include in what will be committed)

sha1collisiondetection/

which seems like the submodule is gone,

> nor deleting the folder works. For the
> locale repo the submodule is gone.

Yup, that seems to be the case.

> But: trying to add it with `git
> submodule add` also do not work and results in an error message (with
> and without `--force` flag):

Would checkout out a state where the submodule still exists
(such as HEAD) and then running "git submodule update --init"
fix it instead?

>
> $ git submodule add git@github.com:-----------/wiki-public.git public
> --force
> A git directory for 'public' is found locally with remote(s):
>   origin        git@github.com:-----------/wiki-public.git
> If you want to reuse this local git directory instead of cloning again from
>   git@github.com:-----------/wiki-public.git
> use the '--force' option. If the local git directory is not the correct repo
> or you are unsure what this means choose another name with the '--name'
> option.
>
> Therefore, it's in a undefined, broken state.
>
>
> Another bug I've got by testing upper line:
> * --force will be used as folder name * when used in `git submodule add
> git@github.com:someone/some.git --force`:

Yes, the order of arguments is important, the options
(such as --force) goes before the URL and path.

> /usr/libexec/git-core/git-submodule: line 273: cd: --: invalid option
> cd: usage: cd [-L|-P] [dir]
> Unable to checkout submodule '--force'

Gah! We'd need to escape the path after the options,
i.e. cd -- --force
would cd into that directory, but I am unsure if that
is accepted by all shells.

Thanks,
Stefan

^ permalink raw reply	[relevance 8%]

* Re: Bug with "git mv" and submodules, and with "git submodule add something --force"
  2018-10-19 20:40 ` Bug with "git mv" and submodules, and with "git submodule add something --force" Stefan Beller
@ 2018-10-19 20:58   ` Jonathan Nieder
  2018-10-22  2:52     ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Jonathan Nieder @ 2018-10-19 20:58 UTC (permalink / raw)
  To: Stefan Beller; +Cc: juergen.vogl, git

Stefan Beller wrote:

> Maybe for now we can do with just an update of the documentation/bugs
> section and say we cannot move files in and out of submodules?

I think we have some existing logic to prevent "git add"-ing a file
within a submodule to the superproject, for example.

So "git mv" should learn the same trick.  And perhaps the trick needs
to be moved down a layer (e.g. into the index API).  Hints?

Thanks,
Jonathan

^ permalink raw reply	[relevance 8%]

* Re: Bug with "git mv" and submodules, and with "git submodule add something --force"
  2018-10-19 20:58   ` Jonathan Nieder
@ 2018-10-22  2:52     ` Junio C Hamano
  2018-10-22 21:52       ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-10-22  2:52 UTC (permalink / raw)
  To: Jonathan Nieder; +Cc: Stefan Beller, juergen.vogl, git

Jonathan Nieder <jrnieder@gmail.com> writes:

> Stefan Beller wrote:
>
>> Maybe for now we can do with just an update of the documentation/bugs
>> section and say we cannot move files in and out of submodules?
>
> I think we have some existing logic to prevent "git add"-ing a file
> within a submodule to the superproject, for example.

There is die_path_inside_submodule() that sanity-checks the pathspec
and rejects.  But I think that is done primarily to give an error
message and not strictly necesary for correctness.

The real safety of "git add" is its call to dir.c::fill_directory();
it collects untracked paths that match the pathspec so that they can
be added as new paths, but because it won't cross the module
boundary, you won't get such a path in the index to begin with.

> So "git mv" should learn the same trick.  And perhaps the trick needs
> to be moved down a layer (e.g. into the index API).  Hints?

You would want to be able to remove a submodule and replace it with
a directory, but you can probably do it in two steps, i.e.

	git reset --hard
	git rm --cached sha1collisiondetection
	echo Now a regular dir >sha1collisiondetection/READ.ME
	find sha1collisiondetection ! -type d -print0 | 
	git update-index --add --stdin -z

So from that point of view, forbidding (starting from the same state
of our project) this sequence:

	git reset --hard
	echo Now a regular dir >sha1collisiondetection/READ.ME
	find sha1collisiondetection ! -type d -print0 | 
	git update-index --add --remove --stdin -z

that would nuke the submodule and replace it with a directory within
which there are files would be OK.  Making the latter's default
rejection overridable with ADD_CACHE_OK_TO_REPLACE would also be
fine.


^ permalink raw reply	[relevance 5%]

* Bug with "git mv" and submodules, and with "git submodule add something --force"
  2018-10-22  2:52     ` Junio C Hamano
@ 2018-10-22 21:52       ` Stefan Beller
  2018-10-24  7:18         ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-22 21:52 UTC (permalink / raw)
  To: gitster; +Cc: git, jrnieder, juergen.vogl, sbeller

On Sun, Oct 21, 2018 at 7:52 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Jonathan Nieder <jrnieder@gmail.com> writes:
>
> > Stefan Beller wrote:
> >
> >> Maybe for now we can do with just an update of the documentation/bugs
> >> section and say we cannot move files in and out of submodules?
> >
> > I think we have some existing logic to prevent "git add"-ing a file
> > within a submodule to the superproject, for example.
>
> There is die_path_inside_submodule() that sanity-checks the pathspec
> and rejects.  But I think that is done primarily to give an error
> message and not strictly necesary for correctness.

c08397e3aa (pathspec: remove PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE
flag, 2017-05-11) seems to be relevant here, as that factors out the
warning.

> The real safety of "git add" is its call to dir.c::fill_directory();
> it collects untracked paths that match the pathspec so that they can
> be added as new paths, but because it won't cross the module
> boundary, you won't get such a path in the index to begin with.

It would not cross the boundary and fail silently as it would
treat a path into the submodule as a no-op.

> > So "git mv" should learn the same trick.  And perhaps the trick needs
> > to be moved down a layer (e.g. into the index API).  Hints?

Yeah, I think we'd want to teach git-mv about that trick.

Unfortunately git-mv is one of the last remainders of not
properly using pathspecs, and die_path_inside_submodule
expects a pathspec. :-/

> You would want to be able to remove a submodule and replace it with
> a directory, but you can probably do it in two steps, i.e.
>
>         git reset --hard
>         git rm --cached sha1collisiondetection
>         echo Now a regular dir >sha1collisiondetection/READ.ME
>         find sha1collisiondetection ! -type d -print0 |
>         git update-index --add --stdin -z

    "Ignoring path sha1collisiondetection/.git"

Nice!

>
> So from that point of view, forbidding (starting from the same state
> of our project) this sequence:
>
>         git reset --hard
>         echo Now a regular dir >sha1collisiondetection/READ.ME
>         find sha1collisiondetection ! -type d -print0 |
>         git update-index --add --remove --stdin -z
>
> that would nuke the submodule and replace it with a directory within
> which there are files would be OK.  Making the latter's default
> rejection overridable with ADD_CACHE_OK_TO_REPLACE would also be
> fine.

I am having trouble of relating these commands to the original git-mv
across submodule boundaries.

Moving files from the submodule out to the superproject, seems
to fail properly, though having a less-than-optimal error message:

$ git mv sha1collisiondetection/LICENSE.txt .
fatal: not under version control, source=sha1collisiondetection/LICENSE.txt, destination=LICENSE.txt

and moving things inside was the original report, below is a proof of concept
that would yield

./git mv -v cache.h sha1collisiondetection/
fatal: moving across submodule boundaries not supported, source=cache.h, destination=sha1collisiondetection/cache.h

--8<--
Subject: [WIP/PATCH] builtin/mv.c: disallow moving across submodule boundaries

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/mv.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/builtin/mv.c b/builtin/mv.c
index 80bb967a63..9ec4b2f0a3 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -172,7 +172,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 	/* Checking */
 	for (i = 0; i < argc; i++) {
 		const char *src = source[i], *dst = destination[i];
-		int length, src_is_dir;
+		int length, src_is_dir, pos;
 		const char *bad = NULL;
 
 		if (show_only)
@@ -243,6 +243,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 		else
 			string_list_insert(&src_for_dst, dst);
 
+		pos = cache_name_pos(dst, strlen(dst));
+		if (pos < 0) {
+			pos = -(pos + 1);
+			if (!S_ISGITLINK(active_cache[pos]->ce_mode))
+				bad = _("moving across submodule boundaries not supported");
+		}
+
 		if (!bad)
 			continue;
 		if (!ignore_errors)
-- 
2.19.0


^ permalink raw reply	[relevance 13%]

* Re: [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree
      [irrelevant]   ` <20181017225811.66554-1-jonathantanmy@google.com>
@ 2018-10-23 18:26     ` Stefan Beller
      [irrelevant]       ` <20181023225536.61508-1-jonathantanmy@google.com>
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-23 18:26 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: Junio C Hamano, git

On Wed, Oct 17, 2018 at 3:58 PM Jonathan Tan <jonathantanmy@google.com> wrote:
>
> > This patch started as a refactoring to make 'get_next_submodule' more
> > readable, but upon doing so, I realized that "git fetch" of the submodule
> > actually doesn't need to be run in the submodules worktree. So let's run
> > it in its git dir instead.
>
> The commit message needs to be updated, I think - this patch does
> significantly more than fetching in the gitdir.

From my point of view, it is not significant, but refactoring.
I'll think how to write a better commit message.

> > This patch leaks the cp->dir in get_next_submodule, as any further
> > callback in run_processes_parallel doesn't have access to the child
> > process any more.
>
> The cp->dir is already leaked - probably better to write "cp->dir in
> get_next_submodule() is still leaked, but this will be fixed in a
> subsequent patch".

... which fails to mention the reason why (as it is hard to do given
the current design) but is more concise.

> > +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);
>
> Why does GIT_DIR need to be set? Is it to avoid subcommands recursively
> checking the parent directories in case the CWD is a malformed Git
> repository? If yes, maybe it's worth adding a comment.

It is copying the structure from prepare_submodule_repo_env,
specifically 10f5c52656 (submodule: avoid auto-discovery in
prepare_submodule_repo_env(), 2016-09-01), which sounds
appealing (and brings real benefits for the working directory),
but I have not thought about this protection for the git dir.

Maybe another approach is to not set the cwd for the child process
and instead point GIT_DIR_ENVIRONMENT only to the right
directory.

Then the use of GIT_DIR_ENVIRONMENT is obvious and
is not just for protection of corner cases.

However I think this protection is really valuable for the
.git dir as well as the submodule may be broken and we do not
want to end up in an infinite loop (as the discovery would find
the superproject which then tries to recurse, again, into the
submodule with the broken git dir)

When adding the comment here, we'd also want to have
the comment in prepare_submodule_repo_env, which
could be its own preparation commit.

> > +static struct repository *get_submodule_repo_for(struct repository *r,
> > +                                              const struct submodule *sub)
> > +{
> > +     struct repository *ret = xmalloc(sizeof(*ret));
> > +
> > +     if (repo_submodule_init(ret, r, sub)) {
> > +             /*
> > +              * No entry in .gitmodules? Technically not a submodule,
> > +              * but historically we supported repositories that happen to be
> > +              * in-place where a gitlink is. Keep supporting them.
> > +              */
> > +             struct strbuf gitdir = STRBUF_INIT;
> > +             strbuf_repo_worktree_path(&gitdir, r, "%s/.git", sub->path);
> > +             if (repo_init(ret, gitdir.buf, NULL)) {
> > +                     strbuf_release(&gitdir);
> > +                     return NULL;
> > +             }
> > +             strbuf_release(&gitdir);
> > +     }
> > +
> > +     return ret;
> > +}
>
> This is the significant thing that this patch does more - an unskipped
> submodule is now something that either passes the checks in
> repo_submodule_init() or the checks in repo_init(), which seems to be
> stricter than the current check that ".git" points to a directory or is
> one. This means that we skip certain broken repositories, and this
> necessitates a change in the test.

I see. However there is no change in function, the check in repo_init
(or repo_submodule_init) is less strict than the check in the child process.
So if there are broken submodule repositories, the difference of this
patch is the layer at which it is caught, i.e. we would not spawn a child
that fails, but skip the submodule.

Thinking of that, maybe we need to announce that in get_next_submodule

>
> I think we should be more particular about what we're allowed to skip -
> in particular, maybe if we're planning to skip this submodule, its
> corresponding directory in the worktree (if one exists) needs to be
> empty.

If the working tree directory is empty for that submodule, it means
it is likely not initialized. But why would we use that as a signal to
skip the submodule?



> > -                     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 = xstrdup(repo->gitdir);
>
> Here is where the functionality change (fetch in ".git") described in
> the commit message occurs.

True.

Thanks for the review, I'll try to split up this commit a bit more and
explain each part on its own.

^ permalink raw reply	[relevance 8%]

* Re: git pull defaults for recursesubmodules
      [irrelevant] <CAGshahkvn3fcyuqtD-WQE9tn+7rSad84+mtA_cfkz+t42xqPdw@mail.gmail.com>
@ 2018-10-23 21:57 ` Stefan Beller
  2018-10-24  5:32   ` Tommi Vainikainen
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-23 21:57 UTC (permalink / raw)
  To: tvainika; +Cc: git

On Tue, Oct 23, 2018 at 2:04 PM Tommi Vainikainen <tvainika@gmail.com> wrote:
>
> I configured my local git to fetch with recurseSubmodules = on-demand,
> which I found the most convenient setting. However then I noticed that
> I mostly use git pull actually to fetch from remotes, but git pull
> does not utilize any recurseSubmoddules setting now, or at least I
> could not find such.
>
> I would expect that if git-config has fetch.recurseSubmodules set,
> also git pull should use this setting, or at least similar option such
> as pull.recurseSubmodules should be available. I'd prefer sharing
> fetch.recurseSubmodules setting here.
>
> I've attached a minimal patch, which I believe implements this
> configuration usage, and a test case to show my expected behavior for
> git pull.

This makes sense to me and the patch looks good to me.
It is unclear to me if this is a regression or an oversight of
of a6d7eb2c7a (pull: optionally rebase submodules (remote
submodule changes only), 2017-06-23)

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 8/9] fetch: retry fetching submodules if needed objects were not fetched
      [irrelevant]   ` <20181018003954.139498-1-jonathantanmy@google.com>
@ 2018-10-23 22:37     ` Stefan Beller
      [irrelevant]       ` <20181023233756.190026-1-jonathantanmy@google.com>
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-23 22:37 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: Junio C Hamano, git

On Wed, Oct 17, 2018 at 5:40 PM Jonathan Tan <jonathantanmy@google.com> wrote:
>
> > Currently when git-fetch is asked to recurse into submodules, it dispatches
> > a plain "git-fetch -C <submodule-dir>" (with 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>).
>
> It seems that the pertinent situation is when, in the superproject, you
> fetch a commit (which may be the target of a ref, or an ancestor of the
> target of a ref) that points to a submodule commit that was not fetched
> by the default refspec-less fetch that you describe in the first
> paragraph. I would just describe it as follows:
>
>   But this default fetch is not sufficient, as a newly fetched commit in
>   the superproject could point to a commit in the submodule that is not
>   in the default refspec. This is common in workflows like Gerrit's.
>   When fetching a Gerrit change under review (from refs/changes/??), the
>   commits in that change likely point to submodule commits that have not
>   been merged to a branch yet.

Makes sense.

> Another thing you need to clarify is what happens if the fetch-by-commit
> fails. Right now, it seems that it will make the whole thing fail, which
> might be a surprising change in behavior.

But a positive surprise, I would assume?

> The test stores the result in a normal branch, not a remote tracking
> branch. Is storing in a normal branch required?

In the test we fetch from another repository, such that in the
repository-under-test this will show up in a remote tracking branch?

> Also, do you know why this is required? A naive reading of the patch
> leads me to believe that this should work even if merely fetching to
> FETCH_HEAD.

See the next patch, check_for_new_submodule_commits() is missing
for FETCH_HEAD.

>
> > +struct get_next_submodule_task {
> > +     struct repository *repo;
> > +     const struct submodule *sub;
> > +     unsigned free_sub : 1; /* Do we need to free the submodule? */
> > +     struct oid_array *commits;
> > +};
>
> Firstly, I don't think "commits" needs to be a pointer.
>
> Document at least "commits". As far as I can tell, if NULL (or empty if
> you take my suggestion), this means that this task is the first pass for
> this particular submodule and the fetch needs to be done using the
> default refspec. Otherwise, this task is the second pass for this
> particular submodule and the fetch needs to be done passing the
> contained OIDs.

Makes sense. I think I'll make it a non-pointer, but will introduce another
flag or counter for the phase.

>
> > +static const struct submodule *get_default_submodule(const char *path)
> > +{
> > +     struct submodule *ret = NULL;
> > +     const char *name = default_name_or_path(path);
> > +
> > +     if (!name)
> > +             return NULL;
> > +
> > +     ret = xmalloc(sizeof(*ret));
> > +     memset(ret, 0, sizeof(*ret));
> > +     ret->path = name;
> > +     ret->name = name;
> > +
> > +     return (const struct submodule *) ret;
> > +}
>
> What is a "default" submodule and why would you need one?

s/default/artificial/. Such a submodule is a submodule that has no
config in the .gitmodules file and its name == path.
We need to keep those around for historic reasons AFAICT, c.f.
c68f837576 (implement fetching of moved submodules, 2017-10-16)

> > +             task = get_next_submodule_task_create(spf->r, ce->name);
> > +
> > +             if (!task->sub) {
> > +                     free(task);
> > +                     continue;
> >               }
>
> Will task->sub ever be NULL?

Yes, if we fall back to these "default" submodule and just try if it
can be handled
as a submodule, but it cannot be handled as such,
get_next_submodule_task_create has

    task->sub = submodule_from_path(r, &null_oid, path);
    if (!task->sub) {
        task->sub = get_default_submodule(path);

and get_default_submodule can return NULL.


>
> > +     if (spf->retry_nr) {
> > +             struct get_next_submodule_task *task = spf->retry[spf->retry_nr - 1];
> > +             struct strbuf submodule_prefix = STRBUF_INIT;
> > +             spf->retry_nr--;
> > +
> > +             strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, task->sub->path);
> > +
> > +             child_process_init(cp);
> > +             prepare_submodule_repo_env_in_gitdir(&cp->env_array);
> > +             cp->git_cmd = 1;
> > +             cp->dir = task->repo->gitdir;
> > +
> > +             argv_array_init(&cp->args);
> > +             argv_array_pushv(&cp->args, spf->args.argv);
> > +             argv_array_push(&cp->args, "on-demand");
>
> This means that we need to trust that the last entry in spf->args can
> take an "on-demand" parameter. Could we supply that argument here
> explicitly instead?
>
> > +             argv_array_push(&cp->args, "--submodule-prefix");
> > +             argv_array_push(&cp->args, submodule_prefix.buf);
> > +
> > +             /* NEEDSWORK: have get_default_remote from s--h */
>
> What is s--h?

builtin/submodule--helper, will clarify

>
> > +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;
> > +}
>
> Shouldn't the function name be commit_missing_in_sub?

yes.

>
> >  static int fetch_finish(int retvalue, struct strbuf *err,
> >                       void *cb, void *task_cb)
> >  {
> >       struct submodule_parallel_fetch *spf = cb;
> > +     struct get_next_submodule_task *task = task_cb;
> > +     const struct submodule *sub;
> > +
> > +     struct string_list_item *it;
> > +     struct oid_array *commits;
> >
> >       if (retvalue)
> >               spf->result = 1;
> >
> > +     if (!task)
> > +             return 0;
>
> When will task be NULL?
>
> > +
> > +     sub = task->sub;
> > +     if (!sub)
> > +             goto out;
>
> Same as above - when will sub be NULL?
>
> > +     it = string_list_lookup(&spf->changed_submodule_names, sub->name);
> > +     if (!it)
> > +             goto out;
>
> And "it" as well.

I'll add comments.

>
> > +     commits = it->util;
> > +     oid_array_filter(commits,
> > +                      commit_exists_in_sub,
> > +                      task->repo);
> > +
> > +     /* Are there commits that do not exist? */
> > +     if (commits->nr) {
> > +             /* We already tried fetching them, do not try again. */
> > +             if (task->commits)
> > +                     return 0;
>
> Clearer and more efficient if the check for task->commits was first
> before all the filtering.
>
> > +test_expect_success "fetch new commits on-demand when they are not reachable" '
>
> "not reachable" confused me - they are indeed reachable, just not from
> the default refspec.

Makes sense

>
> > +     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
> > +     )
> > +'
>
> For maximum test coverage, I think this test should involve 2
> submodules:
>
>  B   C  E   F
>   \ /    \ /
>    A      D
>
> and the upstream superproject having:
>
>   G -> H -> I
>
> The downstream superproject already has G, and is fetching I. In H, the
> submodule gitlinks point to B and E respectively, and in I, the
> submodule gitlinks point to C and F respectively. This ensures that both
> multiple submodules work, and that submodule commits are also fetched
> for interior superproject commits.

ok.

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 7/9] submodule: fetch in submodules git directory instead of in worktree
      [irrelevant]       ` <20181023225536.61508-1-jonathantanmy@google.com>
@ 2018-10-23 23:01         ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-23 23:01 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: Junio C Hamano, git

On Tue, Oct 23, 2018 at 3:55 PM Jonathan Tan <jonathantanmy@google.com> wrote:
> > When adding the comment here, we'd also want to have
> > the comment in prepare_submodule_repo_env, which
> > could be its own preparation commit.
>
> I agree with the protection. As for the preparation commit, I don't
> think it's always the code author's responsibility to tidy up the
> surrounding code, but since you're adding an identical comment here,
> it's probably worth it to add the comment there too.

Am I the only one who dislikes inconsistent files? ;-)
(ie. clean in one place, not cleaned up in another)
I can see your point. Will add a comment

> > Thinking of that, maybe we need to announce that in get_next_submodule
>
> The consequence of getting caught changes, though. Currently,
> spf->result is set to 1 whenever a child process fails. But in this
> patch, some of these repositories would be entirely skipped, meaning
> that no child process is run, and spf->result is never modified.

Right.

> > If the working tree directory is empty for that submodule, it means
> > it is likely not initialized. But why would we use that as a signal to
> > skip the submodule?
>
> What I meant was: if empty, skip it completely. Otherwise, do the
> repo_submodule_init() and repo_init() thing, and if they both fail, set
> spf->result to 1, preserving existing behavior.

I did it the other way round:

If repo_[submodule_]init fails, see if we have a gitlink in tree and
an empty dir in the FS, to decide if we need to signal failure.

I can switch it around again, but it seemed easier to write as
that puts corner cases away into one else {} case.

^ permalink raw reply	[relevance 5%]

* Re: git pull defaults for recursesubmodules
  2018-10-23 21:57 ` git pull defaults for recursesubmodules Stefan Beller
@ 2018-10-24  5:32   ` Tommi Vainikainen
  0 siblings, 0 replies; 200+ results
From: Tommi Vainikainen @ 2018-10-24  5:32 UTC (permalink / raw)
  To: sbeller; +Cc: git

ke 24. lokak. 2018 klo 0.57 Stefan Beller (sbeller@google.com) kirjoitti:
> On Tue, Oct 23, 2018 at 2:04 PM Tommi Vainikainen <tvainika@gmail.com> wrote:
> > I would expect that if git-config has fetch.recurseSubmodules set,
> > also git pull should use this setting, or at least similar option such
>
> This makes sense to me and the patch looks good to me.
> It is unclear to me if this is a regression or an oversight of
> of a6d7eb2c7a (pull: optionally rebase submodules (remote
> submodule changes only), 2017-06-23)

With my testing, no it was not regression at least from that commit.
It did not work as I expected before that commit.

What was unclear to me is why this config needs to be read as
pull calls fetch, why fetch does not use this configuration as is?
If fetch.prune=1, should git pull command also prune or not during
fetch? There does not seem to be test case for that behavior.

-- 
Tommi Vainikainen

^ permalink raw reply	[relevance 2%]

* Re: Bug with "git mv" and submodules, and with "git submodule add something --force"
  2018-10-22 21:52       ` Stefan Beller
@ 2018-10-24  7:18         ` Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-10-24  7:18 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, jrnieder, juergen.vogl

Stefan Beller <sbeller@google.com> writes:

>> You would want to be able to remove a submodule and replace it with
>> a directory, but you can probably do it in two steps, i.e.
>>
>>         git reset --hard
>>         git rm --cached sha1collisiondetection
>>         echo Now a regular dir >sha1collisiondetection/READ.ME
>>         find sha1collisiondetection ! -type d -print0 |
>>         git update-index --add --stdin -z
>
>     "Ignoring path sha1collisiondetection/.git"
>
> Nice!

There actually is another possible outcome that anybody following
along must be aware of and be careful about: not even .git directory
exist there, i.e. it is possible that the submodule has never been
init'ed.

So, it is not that nice X-<.

^ permalink raw reply	[relevance 8%]

* Re: [PATCH 18/19] submodule: use submodule repos for object lookup
  2018-10-16 23:35 ` [PATCH 18/19] submodule: use submodule repos for object lookup Stefan Beller
@ 2018-10-25  9:14   ` SZEDER Gábor
  2018-10-31 13:38   ` Derrick Stolee
  1 sibling, 0 replies; 200+ results
From: SZEDER Gábor @ 2018-10-25  9:14 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Derrick Stolee, git, jonathantanmy

On Tue, Oct 16, 2018 at 04:35:49PM -0700, Stefan Beller wrote:
> This converts the 'show_submodule_header' function to use
> the repository API properly, such that the submodule objects
> are not added to the main object store.

This patch breaks the test suite with 'GIT_TEST_COMMIT_GRAPH=1', in
particular 't4041-diff-submodule-option.sh' fails with:

  expecting success:
          git diff-index -p --submodule=log HEAD >actual &&
          cat >expected <<-EOF &&
          Submodule sm1 $head2..$head3 (rewind):
            < Add foo3 ($added foo3)
            < Add foo2 ($added foo2)
          EOF
          test_cmp expected actual
  
  + git diff-index -p --submodule=log HEAD
  + cat
  + test_cmp expected actual
  + diff -u expected actual
  --- expected    2018-10-25 09:10:00.541610016 +0000
  +++ actual      2018-10-25 09:10:00.537609885 +0000
  @@ -1,3 +1,5 @@
  -Submodule sm1 30b9670..dafb207 (rewind):
  +Submodule sm1 30b9670...dafb207:
     < Add foo3 (hinzugefügt foo3)
     < Add foo2 (hinzugefügt foo2)
  +  > Add foo1 (hinzugefügt foo1)
  +  < Add foo1 (hinzugefügt foo1)
  error: last command exited with $?=1
  not ok 9 - modified submodule(backward)

and 't4060-diff-submodule-option-diff-format.sh' fails with:

  expecting success:
          git diff-index -p --submodule=diff HEAD >actual &&
          cat >expected <<-EOF &&
          Submodule sm1 $head2..$head3 (rewind):
          diff --git a/sm1/foo2 b/sm1/foo2
          deleted file mode 100644
          index 54b060e..0000000
          --- a/sm1/foo2
          +++ /dev/null
          @@ -1 +0,0 @@
          -foo2
          diff --git a/sm1/foo3 b/sm1/foo3
          deleted file mode 100644
          index c1ec6c6..0000000
          --- a/sm1/foo3
          +++ /dev/null
          @@ -1 +0,0 @@
          -foo3
          EOF
          test_cmp expected actual
  
  + git diff-index -p --submodule=diff HEAD
  + cat
  + test_cmp expected actual
  + diff -u expected actual
  --- expected    2018-10-25 09:10:38.854868800 +0000
  +++ actual      2018-10-25 09:10:38.854868800 +0000
  @@ -1,4 +1,4 @@
  -Submodule sm1 30b9670..dafb207 (rewind):
  +Submodule sm1 30b9670...dafb207:
   diff --git a/sm1/foo2 b/sm1/foo2
   deleted file mode 100644
   index 54b060e..0000000
  error: last command exited with $?=1
  not ok 10 - modified submodule(backward)



^ permalink raw reply	[relevance 8%]

* [PATCH v7 00/10] Make submodules work if .gitmodules is not checked out
@ 2018-10-25 16:18 Antonio Ospite
  2018-10-25 18:49 ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Antonio Ospite @ 2018-10-25 16:18 UTC (permalink / raw)
  To: gitster
  Cc: git, Jonathan Nieder, Stefan Beller, Jeff King,
	SZEDER Gábor, Antonio Ospite

Hi,

this series teaches git to try and read the .gitmodules file from the
index (:.gitmodules) or from the current branch (HEAD:.gitmodules) when
the file is not readily available in the working tree.

This can be used, together with sparse checkouts, to enable submodule
usage with programs like vcsh[1] which manage multiple repositories with
their working trees sharing the same path.

[1] https://github.com/RichiH/vcsh

In the previous series there were some comments about not using the enum
in patch 8, but I decided to leave the code as it was as I still think
that it make sense to use an enum there, and have the default value
unnamed; during the discussion I pointed out that other code in git do
the same.

In this series I am addressing the comments by Stefan Beller about the
tests in patch 9.

If the new tests look OK, I'd say we try moving the series to "next" and
see what happens?

I am available to address any further concerns in follow-up patches.

v6 of the series is here:
https://public-inbox.org/git/20181005130601.15879-1-ao2@ao2.it/

v5 of the series is here:
https://public-inbox.org/git/20180917140940.3839-1-ao2@ao2.it/

v4 of the series is here:
https://public-inbox.org/git/20180824132951.8000-1-ao2@ao2.it/

v3 of the series is here:
https://public-inbox.org/git/20180814110525.17801-1-ao2@ao2.it/

v2 of the series is here:
https://public-inbox.org/git/20180802134634.10300-1-ao2@ao2.it/

v1 of the series, with some background info, is here:
https://public-inbox.org/git/20180514105823.8378-1-ao2@ao2.it/

Changes since v6:

  * Renamed t7416-submodule-sparse-gitmodules.sh to
    t7418-submodule-sparse-gitmodules.sh because t7416 was already
    taken.  This has been already taken care of by Junio in "pu".

  * Improved tests in t7418: now, instead of just testing the return
    value of "git submodule ..." commands when .gitmodules is not in the
    working tree, the actual use case is checked in each test, with pre-
    and post-conditions.

Thank you,
   Antonio

Antonio Ospite (10):
  submodule: add a print_config_from_gitmodules() helper
  submodule: factor out a config_set_in_gitmodules_file_gently function
  t7411: merge tests 5 and 6
  t7411: be nicer to future tests and really clean things up
  submodule--helper: add a new 'config' subcommand
  submodule: use the 'submodule--helper config' command
  t7506: clean up .gitmodules properly before setting up new scenario
  submodule: add a helper to check if it is safe to write to .gitmodules
  submodule: support reading .gitmodules when it's not in the working
    tree
  t/helper: add test-submodule-nested-repo-config

 Makefile                                     |   1 +
 builtin/grep.c                               |  17 ++-
 builtin/submodule--helper.c                  |  40 ++++++
 cache.h                                      |   2 +
 git-submodule.sh                             |  13 +-
 submodule-config.c                           |  68 ++++++++-
 submodule-config.h                           |   2 +
 submodule.c                                  |  28 +++-
 submodule.h                                  |   1 +
 t/helper/test-submodule-nested-repo-config.c |  30 ++++
 t/helper/test-tool.c                         |   1 +
 t/helper/test-tool.h                         |   1 +
 t/t7411-submodule-config.sh                  | 141 +++++++++++++++++--
 t/t7418-submodule-sparse-gitmodules.sh       | 122 ++++++++++++++++
 t/t7506-status-submodule.sh                  |   3 +-
 t/t7814-grep-recurse-submodules.sh           |  16 +++
 16 files changed, 454 insertions(+), 32 deletions(-)
 create mode 100644 t/helper/test-submodule-nested-repo-config.c
 create mode 100755 t/t7418-submodule-sparse-gitmodules.sh

-- 
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: Confusing behavior with ignored submodules and `git commit -a`
      [irrelevant] ` <CAGw6cBvaC+TEOM9Tjdbs5zkz2hzW4649=4rsAo58cNOVHOQS=Q@mail.gmail.com>
@ 2018-10-25 18:26   ` Stefan Beller
  2018-11-15  5:12     ` Michael Forney
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-25 18:26 UTC (permalink / raw)
  To: mforney; +Cc: git

On Thu, Oct 25, 2018 at 11:03 AM Michael Forney <mforney@mforney.org> wrote:
>
> On 2018-03-16, Michael Forney <mforney@mforney.org> wrote:
> > Hi,
> >
> > In the past few months have noticed some confusing behavior with
> > ignored submodules. I finally got around to bisecting this to commit
> > 5556808690ea245708fb80383be5c1afee2fb3eb (add, reset: ensure
> > submodules can be added or reset).

Uh. :(

See the discussion starting at
https://public-inbox.org/git/20170725213928.125998-4-bmwill@google.com/
specifically
https://public-inbox.org/git/xmqqinieq49v.fsf@gitster.mtv.corp.google.com/


> >
> > Here is a demonstration of the problem:
> >
[...]
> > Up to here is all expected.

Makes sense.

> > However, if I go to update `foo.txt` and
> > commit with `git commit -a`, changes to inner get recorded
> > unexpectedly. What's worse is the shortstat output of `git commit -a`,
> > and the diff output of `git show` give no indication that the
> > submodule was changed.

This is really bad. git-status and git-commit share some code,
and we'll populate the commit message with a status output.
So it seems reasonable to expect the status and the commit to match,
i.e. if status tells me there is no change, then commit should not record
the submodule update.

> > $ git commit -a -m 'update foo.txt'
> > [master 6ec564c] update foo.txt
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > $ git show
> > commit 6ec564c15ddae099c71f01750b4c434557525653 (HEAD -> master)
> > Author: Michael Forney <mforney@mforney.org>
> > Date:   Fri Mar 16 20:18:37 2018 -0700
> >
> >     update foo.txt
> >
> > diff --git a/foo.txt b/foo.txt
> > index d00491f..0cfbf08 100644
> > --- a/foo.txt
> > +++ b/foo.txt
> > @@ -1 +1 @@
> > -1
> > +2
> > $
> >
> > There have been a couple occasions where I accidentally pushed local
> > changes to ignored submodules because of this. Since they don't show
> > up in the log output, it is difficult to figure out what actually has
> > gone wrong.

How was it prevented before? Just by git commit -a not picking up the
submodule change?

> >
> > Anyway, since the bisected commit (555680869) only mentions add and
> > reset, I'm assuming that this is a regression and not a deliberate
> > behavior change. The documentation for submodule.<name>.ignore states
> > that the setting should only affect `git status` and the diff family.
> > In terms of my expectations, I would go further and say it should only
> > affect `git status` and diffs against the working tree.
> >
> > I took a brief look through the relevant sources, and it wasn't clear
> > to me how to fix this without accidentally changing the behavior of
> > other subcommands.
> >
> > Any help with this issue is appreciated!

I guess reverting that commit is not a good idea now, as
I would expect something to break.

Maybe looking through the series 614ea03a71
(Merge branch 'bw/submodule-config-cleanup', 2017-08-26)
to understand why it happened in the context would be a good start.

> I accidentally pushed local changes to ignored submodules again due to this.
>
> Can anyone confirm whether this is the intended behavior of ignore? If
> it is, then at least the documentation needs an update saying that
> `commit -a` will commit all submodule changes, even if they are
> ignored.

The docs say "(but it will nonetheless show up in the output of
status and commit when it has been staged)" as well, so that commit
sounds like a regression?

Stefan

^ permalink raw reply	[relevance 7%]

* Re: [PATCH v7 00/10] Make submodules work if .gitmodules is not checked out
  2018-10-25 16:18 [PATCH v7 00/10] Make submodules work if .gitmodules is not checked out Antonio Ospite
@ 2018-10-25 18:49 ` Stefan Beller
  2018-10-26  1:59   ` Junio C Hamano
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-25 18:49 UTC (permalink / raw)
  To: Antonio Ospite
  Cc: Junio C Hamano, git, Jonathan Nieder, Jeff King, SZEDER Gábor

> In this series I am addressing the comments by Stefan Beller about the
> tests in patch 9.
>
> If the new tests look OK, I'd say we try moving the series to "next" and
> see what happens?

Sounds good to me.

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* Re: New semantic patches vs. in-flight topics [was: Re: [PATCH 00/19] Bring more repository handles into our code base]
      [irrelevant]     ` <20181025015910.GJ30222@szeder.dev>
@ 2018-10-25 19:25       ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-25 19:25 UTC (permalink / raw)
  To: SZEDER Gábor; +Cc: Jeff King, git, Jonathan Tan

On Wed, Oct 24, 2018 at 6:59 PM SZEDER Gábor <szeder.dev@gmail.com> wrote:
>
> On Mon, Oct 22, 2018 at 11:54:06AM -0700, Stefan Beller wrote:
>
> > For the sake of a good history, I would think running 'make coccicheck'
> > and applying the resulting patches would be best as part of the (dirty)
> > merge of any topic that proposes new semantic patches, but that would
> > add load to Junio as it would be an extra step during the merge.
> >
> > One could argue that the step of applying such transformations into
> > the dirty merge is cheaper than resolving merge conflicts that are
> > had when the topic includes the transformation.
>
> Please consider that merge commits' have uglier diffs than regular
> commits, and that merge commits cause additional complications when
> 'git bisect' points the finger at them, both of which are exacerbated
> by additional changes squeezed into evil merges.
>
> > >     Consequently, 'make coccicheck' won't run clean and the
> > >     static analysis build job will fail until all those topics reach
> > >     'master', and the remaining transformations are applied on top.
> > >
> > >     This was (and still is!) an issue with the hasheq()/oideq() series
> > >     as well: that series was added on 2018-08-28, and the static
> > >     analysis build job is red on 'pu' ever since.  See the follow-up
> > >     patch e43d2dcce1 (more oideq/hasheq conversions, 2018-10-02), and
> > >     one more follow-up will be necessary after the builtin stash topic
> > >     is merged to 'master'.
> >
> > In my understanding this follow up is a feature, as it helps to avoid
> > merge conflicts with other topics in flight.
>
> I don't see how such a follow up patch helps to avoid merge conflicts.

Well, you merge first (the new topic and the cocci patches), and then
do the transformation. But that is putting a lot more work on Junio
as the way to integrate is not just merge a new topic into the pile of
topics (whether it is pu/next/master), but to first perform a merge
of the topic and the coccinelle patches, apply the transformation
and then merge to the pile, assuming the pile is already transformed
(as it happened in "treewide: apply cocci patch" in next/pu).

> > as 'make coccicheck' is an integral part of your review?
>
> Erm, right, "review" was not the right word here.  Anyway, as it is,
> 'make coccicheck' is an integral part of our automated tests, not only
> on Travis CI but on the upcoming Azure thing as well.  I just try to
> pay attention to its results and the results of a bunch of my
> additional builds, and complain or even send a fix when something goes
> reproducibly wrong.  This has certainly became more cumbersome with
> the permanently failing static analysis build job in the last couple
> of weeks.

I seem to not pay as much attention as I should to these,
mostly because they are unreliable  on the aggregate level (a failure
there most likely means another topic than the one I am interested
broke; except in this case, where we discuss the fallout there via
this topic.)

> > I like the approach of having separate classes of semantic patches:
> > (a) the regular "we need to keep checking these" as they address
> >     undesirable code patterns, which is what we currently have,
> >     and what 'make coccicheck' would complain about.
> > (b) The pending patches as you propose. However I would
> >     argue that we'd not want to include the transformation into
> >     the same patch as then the patch will have merge conflicts.
>
> Since we have a lot of parallel running topics, merge conflicts are
> basically unavoidable anyway.  If the conflicts from the
> transformation are really that severe, then perhaps the whole series
> should be postponed to a calmer, more suitable time.

Merge conflicts of this kind could be avoided, by running the
transformation on both sides before merging (or not running them
on both sides, but only after merging).

So maybe for these larger 'the_repository.pending.cocci' patches
we could get them into the tree and wait until all (most) of the topics
are including that semantic patch in their base, such that application
of the patch is easy whether before or after writing a series
(as the semantic patch is in its base).

Another short term plan would be renaming the_repository.cocci
such that it would break the 'make coccicheck'

> In the case of 'the_repository.cocci', merging its transformations
> into 'pu' resulted in only four conflicts, and I found all four on the
> easy side to resolve.  I don't think it's worth waiting with the
> transformations in this particular case.

I am not worried about the current conflicts, but about those to come
in new series.

>
> >     Ideally we'd have an automated process/bot that would apply
> >     all pending semantic patches onto master and then checks for
> >     conflicts in HEAD..pu, and only sends off the non-conflicting
> >     diffs as a topic.
>
> New semantic patches didn't pop up all that frequently in the past, so
> I'm not sure it's worth investing in such an automation.  Of course
> they can become more frequent in the future, and in that case we might
> want to reconsider it.  Unfortunately, however, Coccinelle's results
> can't be completely trusted, either because our semantic patches or
> because Coccinelle itself are buggy...

For the first, we could just be become better at reviewing the Cocci
patch. ;-) (Well, they are harder to review than usual patches, so
this doesn't surprise me. Also not fully understanding the whole
tool may have impact on reviewability)

>
> >     Then after a couple integration cycles we'd have all pending
> >     changes in, with no conflicts on Junios side.
> >
> > So I think we should add a patch like you post, but we would
> > need to discuss the exact approach how to deal with pending
> > patches. Is it the original dev who should push forward on their
> > own pending patches, or does it become a pooled effort?
>
> Well, it makes sense to me that whoever proposes a change with an
> accompanying new semantic patch should also deal with the necessary
> followups.  However, it doesn't really matter who deals with them, as
> long as somebody deals with them.  I don't think it's much different
> from e.g. sending a followup bugfix to someone else's patch series.

Ok, I plan on resending these patches after I get
origin/sb/submodule-recursive-fetch-gets-the-tip going
resent.

Stefan

^ permalink raw reply	[relevance 4%]

* Re: [PATCH 8/9] fetch: retry fetching submodules if needed objects were not fetched
      [irrelevant]       ` <20181023233756.190026-1-jonathantanmy@google.com>
@ 2018-10-25 21:42         ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-25 21:42 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: Junio C Hamano, git

On Tue, Oct 23, 2018 at 4:38 PM Jonathan Tan <jonathantanmy@google.com> wrote:
>
> > > Another thing you need to clarify is what happens if the fetch-by-commit
> > > fails. Right now, it seems that it will make the whole thing fail, which
> > > might be a surprising change in behavior.
> >
> > But a positive surprise, I would assume?
>
> Whether positive or negative, I think that this needs to be mentioned in
> the commit message.
>
> As for positive or negative, I tend to agree that it's positive - sure,
> some previously successful fetches would now fail, but the results of
> those fetches could not be recursively checked out anyway.
>
> > > The test stores the result in a normal branch, not a remote tracking
> > > branch. Is storing in a normal branch required?
> >
> > In the test we fetch from another repository, such that in the
> > repository-under-test this will show up in a remote tracking branch?

I messed up there. Yes, we need to fetch into a normal branch
such that the logic of check_for_new_submodule_commits triggers
no matter where it is on the remote.

Your experiment below shows that we cannot fetch into FETCH_HEAD:

> If that were true, I would expect that when this line:
>
> > git fetch --recurse-submodules --recurse-submodules-default on-demand origin refs/changes/2:refs/heads/my_branch &&
>
> is replaced by this line:
>
> > git fetch --recurse-submodules --recurse-submodules-default on-demand origin refs/changes/2 &&
>
> then things would still work. The tests pass with the first line (after
> I fixed a type mismatch) but not with the second. (Also I don't think a
> remote-tracking branch is generated here - the output printed doesn't
> indicate so, and refs/changes/2 is not a branch anyway.)

> > > Also, do you know why this is required? A naive reading of the patch
> > > leads me to believe that this should work even if merely fetching to
> > > FETCH_HEAD.
> >
> > See the next patch, check_for_new_submodule_commits() is missing
> > for FETCH_HEAD.
>
> I see in the next patch that there is an "if" branch in
> store_updated_refs() without update_local_ref() in which
> "check_for_new_submodule_commits(&rm->old_oid)" needs to be inserted. I
> think this is a symptom that maybe check_for_new_submodule_commits()
> needs to be extracted from update_local_ref() and put into
> store_updated_refs() instead? In update_local_ref(), it is called on
> ref->new_oid, which is actually the same as rm->old_oid anyway (there is
> an oidcpy earlier).

I'll look into that.

> > > What is a "default" submodule and why would you need one?
> >
> > s/default/artificial/. Such a submodule is a submodule that has no
> > config in the .gitmodules file and its name == path.
> > We need to keep those around for historic reasons AFAICT, c.f.
> > c68f837576 (implement fetching of moved submodules, 2017-10-16)
>
> Ah, OK. I would call it a fake submodule then, and copy over the "No
> entry in .gitmodules?" comment.

"fake submodule" sounds like
http://debuggable.com/posts/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb
which is what I think of when hearing fake submodules.

^ permalink raw reply	[relevance 8%]

* [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip
@ 2018-10-25 23:32 Stefan Beller
  2018-10-25 23:32 ` [PATCH 02/10] submodule.c: fix indentation Stefan Beller
                   ` (9 more replies)
  0 siblings, 10 replies; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, Stefan Beller

Thanks Jonathan for your thoughtful comments,
here is the product of the discussion:
* I split up the patch to fetch in the worktree to be 2 patches,
  each giving motivation on its own.
* the last patch is vastly simplified in code, but takes an extra test
* in [1], you remark "commits" ought not to be a pointer, but I decided against
  that, as we keep the pointed-at value around for the same time span (until
  we're done with that submodule) and we don't need to copy over the pointed-at
  value into the new struct.

[1] https://public-inbox.org/git/20181018003954.139498-1-jonathantanmy@google.com/

This is still based on ao/submodule-wo-gitmodules-checked-out.
previous version
https://public-inbox.org/git/20181016181327.107186-1-sbeller@google.com/

Stefan Beller (10):
  sha1-array: provide oid_array_filter
  submodule.c: fix indentation
  submodule.c: sort changed_submodule_names before searching it
  submodule.c: tighten scope of changed_submodule_names struct
  submodule: store OIDs in changed_submodule_names
  repository: repo_submodule_init to take a submodule struct
  submodule: migrate get_next_submodule to use repository structs
  submodule.c: fetch in submodules git directory instead of in worktree
  fetch: try fetching submodules if needed objects were not fetched
  builtin/fetch: check for submodule updates in any ref update

 Documentation/technical/api-oid-array.txt    |   5 +
 builtin/fetch.c                              |  11 +-
 builtin/grep.c                               |  17 +-
 builtin/ls-files.c                           |  12 +-
 builtin/submodule--helper.c                  |   2 +-
 repository.c                                 |  27 +-
 repository.h                                 |  12 +-
 sha1-array.c                                 |  17 ++
 sha1-array.h                                 |   3 +
 submodule.c                                  | 265 ++++++++++++++++---
 t/helper/test-submodule-nested-repo-config.c |   8 +-
 t/t5526-fetch-submodules.sh                  |  55 ++++
 12 files changed, 346 insertions(+), 88 deletions(-)

  git range-diff origin/sb/submodule-recursive-fetch-gets-the-tip... 

1:  3fbb06aedd ! 1:  0fdb0e2ad9 submodule.c: move global changed_submodule_names into fetch submodule struct
    @@ -1,12 +1,11 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    submodule.c: move global changed_submodule_names into fetch submodule struct
    +    submodule.c: tighten scope of changed_submodule_names struct
     
         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>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
     diff --git a/submodule.c b/submodule.c
     --- a/submodule.c
    @@ -16,7 +15,6 @@
      
      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;
    @@ -25,22 +23,8 @@
      }
      
     -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 string_list *changed_submodule_names)
      {
      	struct argv_array argv = ARGV_ARRAY_INIT;
      	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
    @@ -49,30 +33,23 @@
      
      		if (!submodule_has_commits(path, commits))
     -			string_list_append(&changed_submodule_names, name->string);
    -+			string_list_append(&spf->changed_submodule_names,
    ++			string_list_append(changed_submodule_names,
     +					   name->string);
      	}
      
      	free_submodules_oids(&changed_submodules);
     @@
    - 	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;
    --};
    + 	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}
    --
    ++#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
    + 
      static int get_fetch_recurse_config(const struct submodule *submodule,
      				    struct submodule_parallel_fetch *spf)
    - {
     @@
      		case RECURSE_SUBMODULES_ON_DEMAND:
      			if (!submodule ||
    @@ -88,7 +65,7 @@
      
     -	calculate_changed_submodule_paths();
     -	string_list_sort(&changed_submodule_names);
    -+	calculate_changed_submodule_paths(&spf);
    ++	calculate_changed_submodule_paths(&spf.changed_submodule_names);
     +	string_list_sort(&spf.changed_submodule_names);
      	run_processes_parallel(max_parallel_jobs,
      			       get_next_submodule,
2:  a64a8322a1 ! 2:  a11e6e39a2 submodule.c: do not copy around submodule list
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    submodule.c: do not copy around submodule list
    +    submodule: store OIDs in changed_submodule_names
     
         'calculate_changed_submodule_paths' uses a local list to compute the
         changed submodules, and then produces the result by copying appropriate
    @@ -14,13 +14,13 @@
         useful in a later patch.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
    +    Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
     
     diff --git a/submodule.c b/submodule.c
     --- a/submodule.c
     +++ b/submodule.c
     @@
    - 	struct submodule_parallel_fetch *spf)
    + 	struct string_list *changed_submodule_names)
      {
      	struct argv_array argv = ARGV_ARRAY_INIT;
     -	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
    @@ -34,10 +34,10 @@
      	 * commits have been recorded upstream in "changed_submodule_names".
      	 */
     -	collect_changed_submodules(&changed_submodules, &argv);
    -+	collect_changed_submodules(&spf->changed_submodule_names, &argv);
    ++	collect_changed_submodules(changed_submodule_names, &argv);
      
     -	for_each_string_list_item(name, &changed_submodules) {
    -+	for_each_string_list_item(name, &spf->changed_submodule_names) {
    ++	for_each_string_list_item(name, changed_submodule_names) {
      		struct oid_array *commits = name->util;
      		const struct submodule *submodule;
      		const char *path = NULL;
    @@ -46,7 +46,7 @@
      			continue;
      
     -		if (!submodule_has_commits(path, commits))
    --			string_list_append(&spf->changed_submodule_names,
    +-			string_list_append(changed_submodule_names,
     -					   name->string);
     +		if (submodule_has_commits(path, commits)) {
     +			oid_array_clear(commits);
    @@ -55,7 +55,7 @@
      	}
      
     -	free_submodules_oids(&changed_submodules);
    -+	string_list_remove_empty_items(&spf->changed_submodule_names, 1);
    ++	string_list_remove_empty_items(changed_submodule_names, 1);
     +
      	argv_array_clear(&argv);
      	oid_array_clear(&ref_tips_before_fetch);
3:  9341b92c83 ! 3:  3f4e0d4b8d repository: repo_submodule_init to take a submodule struct
    @@ -5,17 +5,19 @@
         When constructing a struct repository for a submodule for some revision
         of the superproject where the submodule is not contained in the index,
         it may not be present in the working tree currently either. In that
    -    siutation giving a 'path' argument is not useful. Upgrade the
    +    situation giving a 'path' argument is not useful. Upgrade the
         repo_submodule_init function to take a struct submodule instead.
    +    The submodule struct can be obtained via submodule_from_{path, name} or
    +    an artificial submodule struct can be passed in.
     
    -    While we are at it, overhaul the repo_submodule_init function by renaming
    -    the submodule repository struct, which is to be initialized, to a name
    -    that is not confused with the struct submodule as easily.
    +    While we are at it, rename the repository struct in the repo_submodule_init
    +    function, which is to be initialized, to a name that is not confused with
    +    the struct submodule as easily. Perform such renames in similar functions
    +    as well.
     
         Also move its documentation into the header file.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
     diff --git a/builtin/grep.c b/builtin/grep.c
     --- a/builtin/grep.c
    @@ -104,6 +106,19 @@
      
      static void show_ce(struct repository *repo, struct dir_struct *dir,
     
    +diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
    +--- a/builtin/submodule--helper.c
    ++++ b/builtin/submodule--helper.c
    +@@
    + 	if (!sub)
    + 		BUG("We could get the submodule handle before?");
    + 
    +-	if (repo_submodule_init(&subrepo, the_repository, path))
    ++	if (repo_submodule_init(&subrepo, the_repository, sub))
    + 		die(_("could not get a repository handle for submodule '%s'"), path);
    + 
    + 	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
    +
     diff --git a/repository.c b/repository.c
     --- a/repository.c
     +++ b/repository.c
    @@ -178,7 +193,8 @@
     +/*
     + * Initialize the repository 'subrepo' as the submodule given by the
     + * struct submodule 'sub' in parent repository 'superproject'.
    -+ * Return 0 upon success and a non-zero value upon failure.
    ++ * Return 0 upon success and a non-zero value upon failure, which may happen
    ++ * if the submodule is not found, or 'sub' is NULL.
     + */
     +struct submodule;
     +int repo_submodule_init(struct repository *subrepo,
4:  cea909cbd4 ! 4:  b1566069e7 submodule: fetch in submodules git directory instead of in worktree
    @@ -1,44 +1,19 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    submodule: fetch in submodules git directory instead of in worktree
    +    submodule: migrate get_next_submodule to use repository structs
     
    -    This patch started as a refactoring to make 'get_next_submodule' more
    -    readable, but upon doing so, I realized that "git fetch" of the submodule
    -    actually doesn't need to be run in the submodules worktree. So let's run
    -    it in its git dir instead.
    +    We used to recurse into submodules, even if they were broken having
    +    only an objects directory. The child process executed in the submodule
    +    would fail though if the submodule was broken.
     
    -    That should pave the way towards fetching submodules that are currently
    -    not checked out.
    -
    -    This patch leaks the cp->dir in get_next_submodule, as any further
    -    callback in run_processes_parallel doesn't have access to the child
    -    process any more. In an early iteration of this patch, the function
    -    get_submodule_repo_for directly returned the string containing the
    -    git directory, which would be a better design choice for this patch.
    -
    -    However the next patch both fixes the memory leak of cp->dir and also has
    -    a use case for using the full repository handle of the submodule, so
    -    it makes sense to introduce the get_submodule_repo_for here already.
    +    This patch tightens the check upfront, such that we do not need
    +    to spawn a child process to find out if the submodule is broken.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
     diff --git a/submodule.c b/submodule.c
     --- a/submodule.c
     +++ b/submodule.c
    -@@
    - 			 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
     @@
      	return spf->default_option;
      }
    @@ -99,9 +74,8 @@
     +		if (repo) {
      			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 = xstrdup(repo->gitdir);
    + 			prepare_submodule_repo_env(&cp->env_array);
    ++			cp->dir = xstrdup(repo->worktree);
      			cp->git_cmd = 1;
      			if (!spf->quiet)
      				strbuf_addf(err, "Fetching submodule %s%s\n",
    @@ -113,27 +87,17 @@
     +			repo_clear(repo);
     +			free(repo);
      			ret = 1;
    ++		} else {
    ++			/*
    ++			 * An empty directory is normal,
    ++			 * the submodule is not initialized
    ++			 */
    ++			if (S_ISGITLINK(ce->ce_mode) &&
    ++			    !is_empty_dir(ce->name))
    ++				die(_("Could not access submodule '%s'"), ce->name);
      		}
     -		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
    ---- a/t/t5526-fetch-submodules.sh
    -+++ b/t/t5526-fetch-submodules.sh
    -@@
    - 
    - 	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" '
-:  ---------- > 5:  2d98ff1201 submodule.c: fetch in submodules git directory instead of in worktree
5:  9ad0125310 ! 6:  092b9cbcba fetch: retry fetching submodules if needed objects were not fetched
    @@ -1,25 +1,23 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    fetch: retry fetching submodules if needed objects were not fetched
    +    fetch: try fetching submodules if needed objects were not fetched
     
         Currently when git-fetch is asked to recurse into submodules, it dispatches
         a plain "git-fetch -C <submodule-dir>" (with 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>).
    +    But this default fetch is not sufficient, as a newly fetched commit in
    +    the superproject could point to a commit in the submodule that is not
    +    in the default refspec. This is common in workflows like Gerrit's.
    +    When fetching a Gerrit change under review (from refs/changes/??), the
    +    commits in that change likely point to submodule commits that have not
    +    been merged to a branch yet.
     
    -    Retry fetching a submodule by object name if the object id that the
    +    Try fetching a submodule by object id if the object id that the
         superproject points to, cannot be found.
     
    -    This retrying does not happen when the "git fetch" done at the
    +    The try 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. A later patch will fix this.
    @@ -32,7 +30,6 @@
         in case the submodule recursion is set to "on".
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
     diff --git a/builtin/fetch.c b/builtin/fetch.c
     --- a/builtin/fetch.c
    @@ -75,16 +72,16 @@
      	int result;
      
      	struct string_list changed_submodule_names;
    -+	struct get_next_submodule_task **retry;
    -+	int retry_nr, retry_alloc;
    ++	struct get_next_submodule_task **fetch_specific_oids;
    ++	int fetch_specific_oids_nr, fetch_specific_oids_alloc;
      };
     -#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, \
     +		  NULL, 0, 0}
      
    - static void calculate_changed_submodule_paths(
    - 	struct submodule_parallel_fetch *spf)
    + static int get_fetch_recurse_config(const struct submodule *submodule,
    + 				    struct submodule_parallel_fetch *spf)
     @@
      	return spf->default_option;
      }
    @@ -93,6 +90,8 @@
     +	struct repository *repo;
     +	const struct submodule *sub;
     +	unsigned free_sub : 1; /* Do we need to free the submodule? */
    ++
    ++	/* fetch specific oids if set, otherwise fetch default refspec */
     +	struct oid_array *commits;
     +};
     +
    @@ -224,24 +223,29 @@
     -			repo_clear(repo);
     -			free(repo);
     -			ret = 1;
    --		}
    --		strbuf_release(&submodule_prefix);
    --		if (ret) {
    - 			spf->count++;
    ++			spf->count++;
     +			*task_cb = task;
     +
     +			strbuf_release(&submodule_prefix);
    - 			return 1;
    -+		} else {
    ++			return 1;
    + 		} else {
    ++
     +			get_next_submodule_task_release(task);
     +			free(task);
    ++
    + 			/*
    + 			 * An empty directory is normal,
    + 			 * the submodule is not initialized
    +@@
    + 			    !is_empty_dir(ce->name))
    + 				die(_("Could not access submodule '%s'"), ce->name);
      		}
    - 	}
    ++	}
     +
    -+	if (spf->retry_nr) {
    -+		struct get_next_submodule_task *task = spf->retry[spf->retry_nr - 1];
    ++	if (spf->fetch_specific_oids_nr) {
    ++		struct get_next_submodule_task *task = spf->fetch_specific_oids[spf->fetch_specific_oids_nr - 1];
     +		struct strbuf submodule_prefix = STRBUF_INIT;
    -+		spf->retry_nr--;
    ++		spf->fetch_specific_oids_nr--;
     +
     +		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, task->sub->path);
     +
    @@ -262,9 +266,13 @@
     +					  append_oid_to_argv, &cp->args);
     +
     +		*task_cb = task;
    -+		strbuf_release(&submodule_prefix);
    + 		strbuf_release(&submodule_prefix);
    +-		if (ret) {
    +-			spf->count++;
    +-			return 1;
    +-		}
     +		return 1;
    -+	}
    + 	}
     +
      	return 0;
      }
    @@ -326,9 +334,11 @@
     +			return 0;
     +
     +		task->commits = commits;
    -+		ALLOC_GROW(spf->retry, spf->retry_nr + 1, spf->retry_alloc);
    -+		spf->retry[spf->retry_nr] = task;
    -+		spf->retry_nr++;
    ++		ALLOC_GROW(spf->fetch_specific_oids,
    ++			   spf->fetch_specific_oids_nr + 1,
    ++			   spf->fetch_specific_oids_alloc);
    ++		spf->fetch_specific_oids[spf->fetch_specific_oids_nr] = task;
    ++		spf->fetch_specific_oids_nr++;
     +		return 0;
     +	}
     +
    @@ -346,18 +356,33 @@
      	test_cmp expect actual
      '
      
    -+test_expect_success "fetch new commits on-demand when they are not reachable" '
    ++test_expect_success "fetch new submodule commits on-demand outside standard refspec" '
    ++	# add a second submodule and ensure it is around in downstream first
    ++	git clone submodule sub1 &&
    ++	git submodule add ./sub1 &&
    ++	git commit -m "adding a second submodule" &&
    ++	git -C downstream pull &&
    ++	git -C downstream submodule update --init --recursive &&
    ++
     +	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 &&
    ++	test_tick &&
    ++
    ++	D=$(git -C sub1 commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
    ++	git -C sub1 update-ref refs/changes/2 $D &&
    ++	git update-index --cacheinfo 160000 $D sub1 &&
    ++
    ++	git commit -m "updated submodules outside of refs/heads" &&
    ++	E=$(git rev-parse HEAD) &&
    ++	git update-ref refs/changes/2 $E &&
     +	(
     +		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:refs/heads/my_branch &&
     +		git -C submodule cat-file -t $C &&
    ++		git -C sub1 cat-file -t $D &&
     +		git checkout --recurse-submodules FETCH_HEAD
     +	)
     +'
6:  b8db3b45bf < -:  ---------- builtin/fetch: check for submodule updates for non branch fetches
7:  905a4f0d4f < -:  ---------- fixup! repository: repo_submodule_init to take a submodule struct
-:  ---------- > 7:  11bf819782 builtin/fetch: check for submodule updates in any ref update

^ permalink raw reply	[relevance 8%]

* [PATCH 03/10] submodule.c: sort changed_submodule_names before searching it
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
  2018-10-25 23:32 ` [PATCH 02/10] submodule.c: fix indentation Stefan Beller
@ 2018-10-25 23:32 ` Stefan Beller
  2018-10-25 23:32 ` [PATCH 04/10] submodule.c: tighten scope of changed_submodule_names struct Stefan Beller
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, Stefan Beller, Junio C Hamano

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.

As we do not rely on the sortedness while building the
list, we pick the "append and sort at the end" as it
has better worst case execution times.

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

diff --git a/submodule.c b/submodule.c
index e145ebbb16..9fbfcfcfe1 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1270,7 +1270,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;
@@ -1364,6 +1364,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


^ permalink raw reply	[relevance 17%]

* [PATCH 02/10] submodule.c: fix indentation
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
@ 2018-10-25 23:32 ` Stefan Beller
  2018-10-25 23:32 ` [PATCH 03/10] submodule.c: sort changed_submodule_names before searching it Stefan Beller
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, Stefan Beller, Junio C Hamano

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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 submodule.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/submodule.c b/submodule.c
index 2b7082b2db..e145ebbb16 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1258,7 +1258,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;
 			}
 		}
@@ -1268,8 +1269,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


^ permalink raw reply	[relevance 26%]

* [PATCH 04/10] submodule.c: tighten scope of changed_submodule_names struct
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
  2018-10-25 23:32 ` [PATCH 02/10] submodule.c: fix indentation Stefan Beller
  2018-10-25 23:32 ` [PATCH 03/10] submodule.c: sort changed_submodule_names before searching it Stefan Beller
@ 2018-10-25 23:32 ` Stefan Beller
  2018-10-25 23:32 ` [PATCH 05/10] submodule: store OIDs in changed_submodule_names Stefan Beller
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, 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 | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/submodule.c b/submodule.c
index 9fbfcfcfe1..6fb0b9d783 100644
--- a/submodule.c
+++ b/submodule.c
@@ -24,7 +24,6 @@
 #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;
@@ -1124,7 +1123,8 @@ 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)
+static void calculate_changed_submodule_paths(
+	struct string_list *changed_submodule_names)
 {
 	struct argv_array argv = ARGV_ARRAY_INIT;
 	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
@@ -1162,7 +1162,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(changed_submodule_names,
+					   name->string);
 	}
 
 	free_submodules_oids(&changed_submodules);
@@ -1208,8 +1209,10 @@ struct submodule_parallel_fetch {
 	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}
+#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
 
 static int get_fetch_recurse_config(const struct submodule *submodule,
 				    struct submodule_parallel_fetch *spf)
@@ -1271,7 +1274,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";
@@ -1363,8 +1366,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.changed_submodule_names);
+	string_list_sort(&spf.changed_submodule_names);
 	run_processes_parallel(max_parallel_jobs,
 			       get_next_submodule,
 			       fetch_start_failure,
@@ -1373,7 +1376,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


^ permalink raw reply	[relevance 17%]

* [PATCH 05/10] submodule: store OIDs in changed_submodule_names
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (2 preceding siblings ...)
  2018-10-25 23:32 ` [PATCH 04/10] submodule.c: tighten scope of changed_submodule_names struct Stefan Beller
@ 2018-10-25 23:32 ` Stefan Beller
  2018-10-25 23:32 ` [PATCH 06/10] repository: repo_submodule_init to take a submodule struct Stefan Beller
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, 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 doing 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>
Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
---
 submodule.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/submodule.c b/submodule.c
index 6fb0b9d783..e4b494af7b 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1127,8 +1127,7 @@ static void calculate_changed_submodule_paths(
 	struct string_list *changed_submodule_names)
 {
 	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))
@@ -1145,9 +1144,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(changed_submodule_names, &argv);
 
-	for_each_string_list_item(name, &changed_submodules) {
+	for_each_string_list_item(name, changed_submodule_names) {
 		struct oid_array *commits = name->util;
 		const struct submodule *submodule;
 		const char *path = NULL;
@@ -1161,12 +1160,14 @@ static void calculate_changed_submodule_paths(
 		if (!path)
 			continue;
 
-		if (!submodule_has_commits(path, commits))
-			string_list_append(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(changed_submodule_names, 1);
+
 	argv_array_clear(&argv);
 	oid_array_clear(&ref_tips_before_fetch);
 	oid_array_clear(&ref_tips_after_fetch);
@@ -1376,7 +1377,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


^ permalink raw reply	[relevance 17%]

* [PATCH 06/10] repository: repo_submodule_init to take a submodule struct
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (3 preceding siblings ...)
  2018-10-25 23:32 ` [PATCH 05/10] submodule: store OIDs in changed_submodule_names Stefan Beller
@ 2018-10-25 23:32 ` Stefan Beller
      [irrelevant]   ` <20181026191553.108916-1-jonathantanmy@google.com>
  2018-10-25 23:32 ` [PATCH 07/10] submodule: migrate get_next_submodule to use repository structs Stefan Beller
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, Stefan Beller

When constructing a struct repository for a submodule for some revision
of the superproject where the submodule is not contained in the index,
it may not be present in the working tree currently either. In that
situation giving a 'path' argument is not useful. Upgrade the
repo_submodule_init function to take a struct submodule instead.
The submodule struct can be obtained via submodule_from_{path, name} or
an artificial submodule struct can be passed in.

While we are at it, rename the repository struct in the repo_submodule_init
function, which is to be initialized, to a name that is not confused with
the struct submodule as easily. Perform such renames in similar functions
as well.

Also move its documentation into the header file.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/grep.c                               | 17 +++++++-----
 builtin/ls-files.c                           | 12 +++++----
 builtin/submodule--helper.c                  |  2 +-
 repository.c                                 | 27 ++++++++------------
 repository.h                                 | 12 +++++++--
 t/helper/test-submodule-nested-repo-config.c |  8 +++---
 6 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 7da8fef31a..ba7634258a 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -418,7 +418,10 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 			  const struct object_id *oid,
 			  const char *filename, const char *path)
 {
-	struct repository submodule;
+	struct repository subrepo;
+	const struct submodule *sub = submodule_from_path(superproject,
+							  &null_oid, path);
+
 	int hit;
 
 	/*
@@ -434,12 +437,12 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 		return 0;
 	}
 
-	if (repo_submodule_init(&submodule, superproject, path)) {
+	if (repo_submodule_init(&subrepo, superproject, sub)) {
 		grep_read_unlock();
 		return 0;
 	}
 
-	repo_read_gitmodules(&submodule);
+	repo_read_gitmodules(&subrepo);
 
 	/*
 	 * NEEDSWORK: This adds the submodule's object directory to the list of
@@ -451,7 +454,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 	 * store is no longer global and instead is a member of the repository
 	 * object.
 	 */
-	add_to_alternates_memory(submodule.objects->objectdir);
+	add_to_alternates_memory(subrepo.objects->objectdir);
 	grep_read_unlock();
 
 	if (oid) {
@@ -476,14 +479,14 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
 
 		init_tree_desc(&tree, data, size);
 		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
-				object->type == OBJ_COMMIT, &submodule);
+				object->type == OBJ_COMMIT, &subrepo);
 		strbuf_release(&base);
 		free(data);
 	} else {
-		hit = grep_cache(opt, &submodule, pathspec, 1);
+		hit = grep_cache(opt, &subrepo, pathspec, 1);
 	}
 
-	repo_clear(&submodule);
+	repo_clear(&subrepo);
 	return hit;
 }
 
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 7f9919a362..4d1649c1b3 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -206,17 +206,19 @@ static void show_files(struct repository *repo, struct dir_struct *dir);
 static void show_submodule(struct repository *superproject,
 			   struct dir_struct *dir, const char *path)
 {
-	struct repository submodule;
+	struct repository subrepo;
+	const struct submodule *sub = submodule_from_path(superproject,
+							  &null_oid, path);
 
-	if (repo_submodule_init(&submodule, superproject, path))
+	if (repo_submodule_init(&subrepo, superproject, sub))
 		return;
 
-	if (repo_read_index(&submodule) < 0)
+	if (repo_read_index(&subrepo) < 0)
 		die("index file corrupt");
 
-	show_files(&submodule, dir);
+	show_files(&subrepo, dir);
 
-	repo_clear(&submodule);
+	repo_clear(&subrepo);
 }
 
 static void show_ce(struct repository *repo, struct dir_struct *dir,
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 5f8a804a6e..015aa1471f 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -2037,7 +2037,7 @@ static int ensure_core_worktree(int argc, const char **argv, const char *prefix)
 	if (!sub)
 		BUG("We could get the submodule handle before?");
 
-	if (repo_submodule_init(&subrepo, the_repository, path))
+	if (repo_submodule_init(&subrepo, the_repository, sub))
 		die(_("could not get a repository handle for submodule '%s'"), path);
 
 	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
diff --git a/repository.c b/repository.c
index 5dd1486718..aabe64ee5d 100644
--- a/repository.c
+++ b/repository.c
@@ -166,30 +166,23 @@ int repo_init(struct repository *repo,
 	return -1;
 }
 
-/*
- * Initialize 'submodule' as the submodule given by 'path' in parent repository
- * 'superproject'.
- * Return 0 upon success and a non-zero value upon failure.
- */
-int repo_submodule_init(struct repository *submodule,
+int repo_submodule_init(struct repository *subrepo,
 			struct repository *superproject,
-			const char *path)
+			const struct submodule *sub)
 {
-	const struct submodule *sub;
 	struct strbuf gitdir = STRBUF_INIT;
 	struct strbuf worktree = STRBUF_INIT;
 	int ret = 0;
 
-	sub = submodule_from_path(superproject, &null_oid, path);
 	if (!sub) {
 		ret = -1;
 		goto out;
 	}
 
-	strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path);
-	strbuf_repo_worktree_path(&worktree, superproject, "%s", path);
+	strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", sub->path);
+	strbuf_repo_worktree_path(&worktree, superproject, "%s", sub->path);
 
-	if (repo_init(submodule, gitdir.buf, worktree.buf)) {
+	if (repo_init(subrepo, gitdir.buf, worktree.buf)) {
 		/*
 		 * If initilization fails then it may be due to the submodule
 		 * not being populated in the superproject's worktree.  Instead
@@ -201,16 +194,16 @@ int repo_submodule_init(struct repository *submodule,
 		strbuf_repo_git_path(&gitdir, superproject,
 				     "modules/%s", sub->name);
 
-		if (repo_init(submodule, gitdir.buf, NULL)) {
+		if (repo_init(subrepo, gitdir.buf, NULL)) {
 			ret = -1;
 			goto out;
 		}
 	}
 
-	submodule->submodule_prefix = xstrfmt("%s%s/",
-					      superproject->submodule_prefix ?
-					      superproject->submodule_prefix :
-					      "", path);
+	subrepo->submodule_prefix = xstrfmt("%s%s/",
+					    superproject->submodule_prefix ?
+					    superproject->submodule_prefix :
+					    "", sub->path);
 
 out:
 	strbuf_release(&gitdir);
diff --git a/repository.h b/repository.h
index 9f16c42c1e..0e482b7d49 100644
--- a/repository.h
+++ b/repository.h
@@ -116,9 +116,17 @@ void repo_set_worktree(struct repository *repo, const char *path);
 void repo_set_hash_algo(struct repository *repo, int algo);
 void initialize_the_repository(void);
 int repo_init(struct repository *r, const char *gitdir, const char *worktree);
-int repo_submodule_init(struct repository *submodule,
+
+/*
+ * Initialize the repository 'subrepo' as the submodule given by the
+ * struct submodule 'sub' in parent repository 'superproject'.
+ * Return 0 upon success and a non-zero value upon failure, which may happen
+ * if the submodule is not found, or 'sub' is NULL.
+ */
+struct submodule;
+int repo_submodule_init(struct repository *subrepo,
 			struct repository *superproject,
-			const char *path);
+			const struct submodule *sub);
 void repo_clear(struct repository *repo);
 
 /*
diff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c
index a31e2a9bea..bc97929bbc 100644
--- a/t/helper/test-submodule-nested-repo-config.c
+++ b/t/helper/test-submodule-nested-repo-config.c
@@ -10,19 +10,21 @@ static void die_usage(int argc, const char **argv, const char *msg)
 
 int cmd__submodule_nested_repo_config(int argc, const char **argv)
 {
-	struct repository submodule;
+	struct repository subrepo;
+	const struct submodule *sub;
 
 	if (argc < 3)
 		die_usage(argc, argv, "Wrong number of arguments.");
 
 	setup_git_directory();
 
-	if (repo_submodule_init(&submodule, the_repository, argv[1])) {
+	sub = submodule_from_path(the_repository, &null_oid, argv[1]);
+	if (repo_submodule_init(&subrepo, the_repository, sub)) {
 		die_usage(argc, argv, "Submodule not found.");
 	}
 
 	/* Read the config of _child_ submodules. */
-	print_config_from_gitmodules(&submodule, argv[2]);
+	print_config_from_gitmodules(&subrepo, argv[2]);
 
 	submodule_free(the_repository);
 
-- 
2.19.0


^ permalink raw reply	[relevance 27%]

* [PATCH 07/10] submodule: migrate get_next_submodule to use repository structs
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (4 preceding siblings ...)
  2018-10-25 23:32 ` [PATCH 06/10] repository: repo_submodule_init to take a submodule struct Stefan Beller
@ 2018-10-25 23:32 ` Stefan Beller
  2018-10-25 23:32 ` [PATCH 08/10] submodule.c: fetch in submodules git directory instead of in worktree Stefan Beller
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, Stefan Beller

We used to recurse into submodules, even if they were broken having
only an objects directory. The child process executed in the submodule
would fail though if the submodule was broken.

This patch tightens the check upfront, such that we do not need
to spawn a child process to find out if the submodule is broken.

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

diff --git a/submodule.c b/submodule.c
index e4b494af7b..a1a32cab7d 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1240,6 +1240,29 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+static struct repository *get_submodule_repo_for(struct repository *r,
+						 const struct submodule *sub)
+{
+	struct repository *ret = xmalloc(sizeof(*ret));
+
+	if (repo_submodule_init(ret, r, sub)) {
+		/*
+		 * No entry in .gitmodules? Technically not a submodule,
+		 * but historically we supported repositories that happen to be
+		 * in-place where a gitlink is. Keep supporting them.
+		 */
+		struct strbuf gitdir = STRBUF_INIT;
+		strbuf_repo_worktree_path(&gitdir, r, "%s/.git", sub->path);
+		if (repo_init(ret, gitdir.buf, NULL)) {
+			strbuf_release(&gitdir);
+			return NULL;
+		}
+		strbuf_release(&gitdir);
+	}
+
+	return ret;
+}
+
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
@@ -1247,12 +1270,11 @@ 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;
+		const char *default_argv;
 		const struct submodule *submodule;
+		struct repository *repo;
 		struct submodule default_submodule = SUBMODULE_INIT;
 
 		if (!S_ISGITLINK(ce->ce_mode))
@@ -1287,16 +1309,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)) {
+		repo = get_submodule_repo_for(spf->r, submodule);
+		if (repo) {
 			child_process_init(cp);
-			cp->dir = strbuf_detach(&submodule_path, NULL);
 			prepare_submodule_repo_env(&cp->env_array);
+			cp->dir = xstrdup(repo->worktree);
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
@@ -1306,10 +1324,19 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_push(&cp->args, default_argv);
 			argv_array_push(&cp->args, "--submodule-prefix");
 			argv_array_push(&cp->args, submodule_prefix.buf);
+
+			repo_clear(repo);
+			free(repo);
 			ret = 1;
+		} else {
+			/*
+			 * An empty directory is normal,
+			 * the submodule is not initialized
+			 */
+			if (S_ISGITLINK(ce->ce_mode) &&
+			    !is_empty_dir(ce->name))
+				die(_("Could not access submodule '%s'"), ce->name);
 		}
-		strbuf_release(&submodule_path);
-		strbuf_release(&submodule_git_dir);
 		strbuf_release(&submodule_prefix);
 		if (ret) {
 			spf->count++;
-- 
2.19.0


^ permalink raw reply	[relevance 24%]

* [PATCH 08/10] submodule.c: fetch in submodules git directory instead of in worktree
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (5 preceding siblings ...)
  2018-10-25 23:32 ` [PATCH 07/10] submodule: migrate get_next_submodule to use repository structs Stefan Beller
@ 2018-10-25 23:32 ` Stefan Beller
  2018-10-25 23:32 ` [PATCH 09/10] fetch: try fetching submodules if needed objects were not fetched Stefan Beller
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, Stefan Beller

Keep the properties introduced in  10f5c52656 (submodule: avoid
auto-discovery in prepare_submodule_repo_env(), 2016-09-01), by fixating
the git directory of the submodule.

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

diff --git a/submodule.c b/submodule.c
index a1a32cab7d..67813fbe78 100644
--- a/submodule.c
+++ b/submodule.c
@@ -494,6 +494,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
@@ -1313,8 +1319,8 @@ static int get_next_submodule(struct child_process *cp,
 		repo = get_submodule_repo_for(spf->r, submodule);
 		if (repo) {
 			child_process_init(cp);
-			prepare_submodule_repo_env(&cp->env_array);
-			cp->dir = xstrdup(repo->worktree);
+			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+			cp->dir = xstrdup(repo->gitdir);
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
-- 
2.19.0


^ permalink raw reply	[relevance 19%]

* [PATCH 09/10] fetch: try fetching submodules if needed objects were not fetched
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (6 preceding siblings ...)
  2018-10-25 23:32 ` [PATCH 08/10] submodule.c: fetch in submodules git directory instead of in worktree Stefan Beller
@ 2018-10-25 23:32 ` Stefan Beller
      [irrelevant]   ` <20181026204106.132296-1-jonathantanmy@google.com>
  2018-10-25 23:32 ` [PATCH 10/10] builtin/fetch: check for submodule updates in any ref update Stefan Beller
  2018-10-29  3:44 ` [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Junio C Hamano
  9 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, Stefan Beller

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

But this default fetch is not sufficient, as a newly fetched commit in
the superproject could point to a commit in the submodule that is not
in the default refspec. This is common in workflows like Gerrit's.
When fetching a Gerrit change under review (from refs/changes/??), the
commits in that change likely point to submodule commits that have not
been merged to a branch yet.

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

The try 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. A later patch will fix this.

builtin/fetch used to only inspect submodules when they were fetched
"on-demand", as in either on/off case it was clear whether the submodule
needs to be fetched. However to know whether we need to try fetching the
object ids, we need to identify the object names, which is done in this
function check_for_new_submodule_commits(), so we'll also run that code
in case the submodule recursion is set to "on".

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

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 61bec5d213..95c44bf6ff 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 67813fbe78..c978a38c81 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1218,8 +1218,12 @@ struct submodule_parallel_fetch {
 	int result;
 
 	struct string_list changed_submodule_names;
+	struct get_next_submodule_task **fetch_specific_oids;
+	int fetch_specific_oids_nr, fetch_specific_oids_alloc;
 };
-#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, \
+		  NULL, 0, 0}
 
 static int get_fetch_recurse_config(const struct submodule *submodule,
 				    struct submodule_parallel_fetch *spf)
@@ -1246,6 +1250,58 @@ static int get_fetch_recurse_config(const struct submodule *submodule,
 	return spf->default_option;
 }
 
+struct get_next_submodule_task {
+	struct repository *repo;
+	const struct submodule *sub;
+	unsigned free_sub : 1; /* Do we need to free the submodule? */
+
+	/* fetch specific oids if set, otherwise fetch default refspec */
+	struct oid_array *commits;
+};
+
+static const struct submodule *get_default_submodule(const char *path)
+{
+	struct submodule *ret = NULL;
+	const char *name = default_name_or_path(path);
+
+	if (!name)
+		return NULL;
+
+	ret = xmalloc(sizeof(*ret));
+	memset(ret, 0, sizeof(*ret));
+	ret->path = name;
+	ret->name = name;
+
+	return (const struct submodule *) ret;
+}
+
+static struct get_next_submodule_task *get_next_submodule_task_create(
+	struct repository *r, const char *path)
+{
+	struct get_next_submodule_task *task = xmalloc(sizeof(*task));
+	memset(task, 0, sizeof(*task));
+
+	task->sub = submodule_from_path(r, &null_oid, path);
+	if (!task->sub) {
+		task->sub = get_default_submodule(path);
+		task->free_sub = 1;
+	}
+
+	return task;
+}
+
+static void get_next_submodule_task_release(struct get_next_submodule_task *p)
+{
+	if (p->free_sub)
+		free((void*)p->sub);
+	p->free_sub = 0;
+	p->sub = NULL;
+
+	if (p->repo)
+		repo_clear(p->repo);
+	FREE_AND_NULL(p->repo);
+}
+
 static struct repository *get_submodule_repo_for(struct repository *r,
 						 const struct submodule *sub)
 {
@@ -1272,39 +1328,35 @@ static struct repository *get_submodule_repo_for(struct repository *r,
 static int get_next_submodule(struct child_process *cp,
 			      struct strbuf *err, void *data, void **task_cb)
 {
-	int ret = 0;
 	struct submodule_parallel_fetch *spf = data;
 
 	for (; spf->count < spf->r->index->cache_nr; spf->count++) {
-		struct strbuf submodule_prefix = STRBUF_INIT;
+		int recurse_config;
 		const struct cache_entry *ce = spf->r->index->cache[spf->count];
 		const char *default_argv;
-		const struct submodule *submodule;
-		struct repository *repo;
-		struct submodule default_submodule = SUBMODULE_INIT;
+		struct get_next_submodule_task *task;
 
 		if (!S_ISGITLINK(ce->ce_mode))
 			continue;
 
-		submodule = submodule_from_path(spf->r, &null_oid, ce->name);
-		if (!submodule) {
-			const char *name = default_name_or_path(ce->name);
-			if (name) {
-				default_submodule.path = name;
-				default_submodule.name = name;
-				submodule = &default_submodule;
-			}
+		task = get_next_submodule_task_create(spf->r, ce->name);
+
+		if (!task->sub) {
+			free(task);
+			continue;
 		}
 
-		switch (get_fetch_recurse_config(submodule, spf))
+		recurse_config = get_fetch_recurse_config(task->sub, spf);
+
+		switch (recurse_config)
 		{
 		default:
 		case RECURSE_SUBMODULES_DEFAULT:
 		case RECURSE_SUBMODULES_ON_DEMAND:
-			if (!submodule ||
+			if (!task->sub ||
 			    !string_list_lookup(
 					&spf->changed_submodule_names,
-					submodule->name))
+					task->sub->name))
 				continue;
 			default_argv = "on-demand";
 			break;
@@ -1315,12 +1367,12 @@ static int get_next_submodule(struct child_process *cp,
 			continue;
 		}
 
-		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
-		repo = get_submodule_repo_for(spf->r, submodule);
-		if (repo) {
+		task->repo = get_submodule_repo_for(spf->r, task->sub);
+		if (task->repo) {
+			struct strbuf submodule_prefix = STRBUF_INIT;
 			child_process_init(cp);
 			prepare_submodule_repo_env_in_gitdir(&cp->env_array);
-			cp->dir = xstrdup(repo->gitdir);
+			cp->dir = task->repo->gitdir;
 			cp->git_cmd = 1;
 			if (!spf->quiet)
 				strbuf_addf(err, "Fetching submodule %s%s\n",
@@ -1329,12 +1381,22 @@ static int get_next_submodule(struct child_process *cp,
 			argv_array_pushv(&cp->args, spf->args.argv);
 			argv_array_push(&cp->args, default_argv);
 			argv_array_push(&cp->args, "--submodule-prefix");
+
+			strbuf_addf(&submodule_prefix, "%s%s/",
+						       spf->prefix,
+						       task->sub->path);
 			argv_array_push(&cp->args, submodule_prefix.buf);
 
-			repo_clear(repo);
-			free(repo);
-			ret = 1;
+			spf->count++;
+			*task_cb = task;
+
+			strbuf_release(&submodule_prefix);
+			return 1;
 		} else {
+
+			get_next_submodule_task_release(task);
+			free(task);
+
 			/*
 			 * An empty directory is normal,
 			 * the submodule is not initialized
@@ -1343,12 +1405,36 @@ static int get_next_submodule(struct child_process *cp,
 			    !is_empty_dir(ce->name))
 				die(_("Could not access submodule '%s'"), ce->name);
 		}
+	}
+
+	if (spf->fetch_specific_oids_nr) {
+		struct get_next_submodule_task *task = spf->fetch_specific_oids[spf->fetch_specific_oids_nr - 1];
+		struct strbuf submodule_prefix = STRBUF_INIT;
+		spf->fetch_specific_oids_nr--;
+
+		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, task->sub->path);
+
+		child_process_init(cp);
+		prepare_submodule_repo_env_in_gitdir(&cp->env_array);
+		cp->git_cmd = 1;
+		cp->dir = task->repo->gitdir;
+
+		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(task->commits,
+					  append_oid_to_argv, &cp->args);
+
+		*task_cb = task;
 		strbuf_release(&submodule_prefix);
-		if (ret) {
-			spf->count++;
-			return 1;
-		}
+		return 1;
 	}
+
 	return 0;
 }
 
@@ -1356,20 +1442,70 @@ static int fetch_start_failure(struct strbuf *err,
 			       void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
+	struct get_next_submodule_task *task = task_cb;
 
 	spf->result = 1;
 
+	get_next_submodule_task_release(task);
 	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 get_next_submodule_task *task = task_cb;
+	const struct submodule *sub;
+
+	struct string_list_item *it;
+	struct oid_array *commits;
 
 	if (retvalue)
 		spf->result = 1;
 
+	if (!task)
+		return 0;
+
+	sub = task->sub;
+	if (!sub)
+		goto out;
+
+	it = string_list_lookup(&spf->changed_submodule_names, sub->name);
+	if (!it)
+		goto out;
+
+	commits = it->util;
+	oid_array_filter(commits,
+			 commit_exists_in_sub,
+			 task->repo);
+
+	/* Are there commits that do not exist? */
+	if (commits->nr) {
+		/* We already tried fetching them, do not try again. */
+		if (task->commits)
+			return 0;
+
+		task->commits = commits;
+		ALLOC_GROW(spf->fetch_specific_oids,
+			   spf->fetch_specific_oids_nr + 1,
+			   spf->fetch_specific_oids_alloc);
+		spf->fetch_specific_oids[spf->fetch_specific_oids_nr] = task;
+		spf->fetch_specific_oids_nr++;
+		return 0;
+	}
+
+out:
+	get_next_submodule_task_release(task);
+
 	return 0;
 }
 
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 6c2f9b2ba2..5a75b57852 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -600,4 +600,35 @@ test_expect_success "fetch new commits when submodule got renamed" '
 	test_cmp expect actual
 '
 
+test_expect_success "fetch new submodule commits on-demand outside standard refspec" '
+	# add a second submodule and ensure it is around in downstream first
+	git clone submodule sub1 &&
+	git submodule add ./sub1 &&
+	git commit -m "adding a second submodule" &&
+	git -C downstream pull &&
+	git -C downstream submodule update --init --recursive &&
+
+	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 &&
+	test_tick &&
+
+	D=$(git -C sub1 commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
+	git -C sub1 update-ref refs/changes/2 $D &&
+	git update-index --cacheinfo 160000 $D sub1 &&
+
+	git commit -m "updated submodules outside of refs/heads" &&
+	E=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/2 $E &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules origin refs/changes/2:refs/heads/my_branch &&
+		git -C submodule cat-file -t $C &&
+		git -C sub1 cat-file -t $D &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
 test_done
-- 
2.19.0


^ permalink raw reply	[relevance 26%]

* [PATCH 10/10] builtin/fetch: check for submodule updates in any ref update
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (7 preceding siblings ...)
  2018-10-25 23:32 ` [PATCH 09/10] fetch: try fetching submodules if needed objects were not fetched Stefan Beller
@ 2018-10-25 23:32 ` Stefan Beller
  2018-10-29  3:44 ` [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Junio C Hamano
  9 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-25 23:32 UTC (permalink / raw)
  To: jonathantanmy; +Cc: git, Stefan Beller

Gerrit, the code review tool, has a different workflow than our mailing
list based approach. Usually users upload changes to a Gerrit server and
continuous integration and testing happens by bots. Sometimes however a
user wants to checkout a change locally and look at it locally. For this
use case, Gerrit offers a command line snippet to copy and paste to your
terminal, which looks like

  git fetch https://<host>/gerrit refs/changes/<id> &&
  git checkout FETCH_HEAD

For Gerrit changes that contain changing submodule gitlinks, it would be
easy to extend both the fetch and checkout with the '--recurse-submodules'
flag, such that this command line snippet would produce the state of a
change locally.

However the functionality added in the previous patch, which would
ensure that we fetch the objects in the submodule that the gitlink pointed
at, only works for remote tracking branches so far, not for FETCH_HEAD.

Make sure that fetching a superproject to its FETCH_HEAD, also respects
the existence checks for objects in the submodule recursion.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 builtin/fetch.c             |  8 ++------
 t/t5526-fetch-submodules.sh | 24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/builtin/fetch.c b/builtin/fetch.c
index 95c44bf6ff..f39012d7c2 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -700,8 +700,6 @@ static int update_local_ref(struct ref *ref,
 			what = _("[new ref]");
 		}
 
-		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,
 			       r ? _("unable to update local ref") : NULL,
@@ -715,8 +713,6 @@ 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)
-			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("fast-forward", ref, 1);
 		format_display(display, r ? '!' : ' ', quickref.buf,
 			       r ? _("unable to update local ref") : NULL,
@@ -729,8 +725,6 @@ 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)
-			check_for_new_submodule_commits(&ref->new_oid);
 		r = s_update_ref("forced-update", ref, 1);
 		format_display(display, r ? '!' : '+', quickref.buf,
 			       r ? _("unable to update local ref") : _("forced update"),
@@ -826,6 +820,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
 				ref->force = rm->peer_ref->force;
 			}
 
+			if (recurse_submodules != RECURSE_SUBMODULES_OFF)
+				check_for_new_submodule_commits(&rm->old_oid);
 
 			if (!strcmp(rm->name, "HEAD")) {
 				kind = "";
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 5a75b57852..799785783f 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -631,4 +631,28 @@ test_expect_success "fetch new submodule commits on-demand outside standard refs
 	)
 '
 
+test_expect_success 'fetch new submodule commits on-demand in FETCH_HEAD' '
+	# depends on the previous test for setup
+
+	C=$(git -C submodule commit-tree -m "another change outside refs/heads" HEAD^{tree}) &&
+	git -C submodule update-ref refs/changes/1 $C &&
+	git update-index --cacheinfo 160000 $C submodule &&
+	test_tick &&
+
+	D=$(git -C sub1 commit-tree -m "another change outside refs/heads" HEAD^{tree}) &&
+	git -C sub1 update-ref refs/changes/2 $D &&
+	git update-index --cacheinfo 160000 $D sub1 &&
+
+	git commit -m "updated submodules outside of refs/heads" &&
+	E=$(git rev-parse HEAD) &&
+	git update-ref refs/changes/2 $E &&
+	(
+		cd downstream &&
+		git fetch --recurse-submodules origin refs/changes/2 &&
+		git -C submodule cat-file -t $C &&
+		git -C sub1 cat-file -t $D &&
+		git checkout --recurse-submodules FETCH_HEAD
+	)
+'
+
 test_done
-- 
2.19.0


^ permalink raw reply	[relevance 18%]

* Re: [PATCH v7 00/10] Make submodules work if .gitmodules is not checked out
  2018-10-25 18:49 ` Stefan Beller
@ 2018-10-26  1:59   ` Junio C Hamano
  2018-10-26 18:43     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Junio C Hamano @ 2018-10-26  1:59 UTC (permalink / raw)
  To: Stefan Beller
  Cc: Antonio Ospite, git, Jonathan Nieder, Jeff King, SZEDER Gábor

Stefan Beller <sbeller@google.com> writes:

>> In this series I am addressing the comments by Stefan Beller about the
>> tests in patch 9.
>>
>> If the new tests look OK, I'd say we try moving the series to "next" and
>> see what happens?
>
> Sounds good to me.

Which means (1) the plan sounds OK but I didn't look at these new
tests or (2) the new tests look OK and I am happy to see this go to
'next'?

tbdiff tells me that 9/10 is the only patch different from the
previous round, and I vaguely recall that the other patches looked
OK to me (even though I admit I only skimmed them quickly).

Thanks.

^ permalink raw reply	[relevance 5%]

* Re: [PATCH v7 00/10] Make submodules work if .gitmodules is not checked out
  2018-10-26  1:59   ` Junio C Hamano
@ 2018-10-26 18:43     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-26 18:43 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Antonio Ospite, git, Jonathan Nieder, Jeff King, SZEDER Gábor

On Thu, Oct 25, 2018 at 6:59 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Stefan Beller <sbeller@google.com> writes:
>
> >> In this series I am addressing the comments by Stefan Beller about the
> >> tests in patch 9.
> >>
> >> If the new tests look OK, I'd say we try moving the series to "next" and
> >> see what happens?
> >
> > Sounds good to me.
>
> Which means (1) the plan sounds OK but I didn't look at these new
> tests or (2) the new tests look OK and I am happy to see this go to
> 'next'?

I looked at the tests and found it a pleasant read, so I think the plan of
merging it to next and seeing what will happen is a good one.

Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 06/10] repository: repo_submodule_init to take a submodule struct
      [irrelevant]   ` <20181026191553.108916-1-jonathantanmy@google.com>
@ 2018-10-26 22:01     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-26 22:01 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: git

On Fri, Oct 26, 2018 at 12:15 PM Jonathan Tan <jonathantanmy@google.com> wrote:

 [snip]

> The expected pattern.
>
> This patch looks good to me.

I'll take this as a "Reviewed-by"?

Thanks,
Stefan

^ permalink raw reply	[relevance 5%]

* Git Test Coverage Report (Saturday, Oct 27)
@ 2018-10-27 13:27 Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-10-27 13:27 UTC (permalink / raw)
  To: git

In an effort to ensure new code is reasonably covered by the test suite, 
we now have contrib/coverage-diff.sh to combine the gcov output from 
'make coverage-test ; make coverage-report' with the output from 'git 
diff A B' to discover _new_lines of code that are not covered. This 
report ignores lines including "BUG(".

This report takes the output of these results after running on four 
branches:

         pu: a5dda2204a27a14f65171e29307400194b522051
        jch: 280dd2581eb7191db037cf1243dd64fd200455ba
       next: 0250525e6984e0e5e803c7e2e3417279b036f1c9
     master: c670b1f876521c9f7cd40184bf7ed05aad843433
master@{1}: c4df23f7927d8d00e666a3c8d1b3375f1dc8a3c1


Uncovered in pu not in jch
--------------------------
(Note: t4041-diff-submodule-option.sh failed with extra test options, so 
some lines that
would be covered by that test run were not covered.)

builtin/blame.c
a5dda2204a builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    924) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    925) break;

builtin/describe.c
a5dda2204a builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/fsck.c
b29759d89a builtin/fsck.c 613) fprintf(stderr, "Checking %s link\n", 
head_ref_name);
b29759d89a builtin/fsck.c 618) return error("Invalid %s", head_ref_name);

builtin/grep.c
c22b820141 builtin/grep.c  442) grep_read_unlock();

builtin/pack-objects.c
a5dda2204a builtin/pack-objects.c 2852) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/rebase--interactive.c
6424061be4 builtin/rebase--interactive.c   23) return 
error_errno(_("could not read '%s'."), todo_file);
6424061be4 builtin/rebase--interactive.c   28) return 
error_errno(_("could not write '%s'"), todo_file);
7ccfac40bc builtin/rebase--interactive.c   43) return 
error_errno(_("could not read '%s'."), todo_file);
7ccfac40bc builtin/rebase--interactive.c   46) 
todo_list_release(&todo_list);
7ccfac40bc builtin/rebase--interactive.c   47) return error(_("unusable 
todo list: '%s'"), todo_file);
9787d17d40 builtin/rebase--interactive.c  294) ret = 
rearrange_squash_in_todo_file();

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 581) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 617) continue;

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fsck.c
a5dda2204a  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
a5dda2204a  878) repo_read_object_file(the_repository,
a5dda2204a  879)       &tag->object.oid, &type, &size);

http-push.c
a5dda2204a 1635) if (!repo_has_object_file(the_repository, &head_oid))
a5dda2204a 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

merge-recursive.c
4cdc48e412 1585) return -1;
4cdc48e412 1588) return -1;
4cdc48e412 1594) return -1;
4cdc48e412 1596) if (update_file(o, 1, b_oid, b_mode, collide_path))
4cdc48e412 1597) return -1;
4cdc48e412 1664) return -1;
4cdc48e412 1667) return -1;
4cdc48e412 1670) return -1;
b58ae691c0 1703) return -1;
387361a6a7 1738) return -1;
387361a6a7 1786) return -1;
387361a6a7 1795) new_path = unique_path(o, a->path, ci->branch1);
387361a6a7 1796) output(o, 1, _("Refusing to lose untracked file"
387361a6a7 1802) return -1;
387361a6a7 1805) return -1;
387361a6a7 1815) return -1;
387361a6a7 1831) return -1;
387361a6a7 1834) return -1;

midx.c
1dcd9f2043  184) return;

negotiator/default.c
a5dda2204a  71) if (repo_parse_commit(the_repository, commit))

packfile.c
dc7d664335  350) close_midx(o->multi_pack_index);
dc7d664335  351) o->multi_pack_index = NULL;

rebase-interactive.c
b74a37a5a7  26) warning(_("unrecognized setting %s for option "
6424061be4 107) return error_errno(_("could not write '%s''"), todo_file);
6424061be4 110) return error(_("could not copy '%s' to '%s'."), todo_file,
b74a37a5a7 174) goto leave_check;

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
revision.c
a5dda2204a  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
a5dda2204a 1597) repo_unuse_commit_buffer(the_repository, head_commit,
a5dda2204a 3821) repo_unuse_commit_buffer(the_repository,
b5d6062402 4486) strbuf_insert(buf, todo_list->items[insert].offset_in_buf +
b5d6062402 4498) int sequencer_add_exec_commands(const char *commands)
06d8136126 4505) return error_errno(_("could not read '%s'."), todo_file);
b5d6062402 4507) if (todo_list_parse_insn_buffer(todo_list.buf.buf, 
&todo_list)) {
b5d6062402 4512) todo_list_add_exec_commands(&todo_list, commands);
b5d6062402 4513) res = write_message(todo_list.buf.buf, 
todo_list.buf.len, todo_file, 0);
0cce4a2756 4514) todo_list_release(&todo_list);
b5d6062402 4516) return res;
b74a37a5a7 4576) goto out;
b74a37a5a7 4581) goto out;
b8dac44d10 4721) todo_list_release(&new_todo);
009173ed7b 4726) todo_list_release(&new_todo);
009173ed7b 4727) return error_errno(_("could not write '%s'"), todo_file);
9787d17d40 4921) int rearrange_squash_in_todo_file(void)
9787d17d40 4923) const char *todo_file = rebase_path_todo();
9787d17d40 4924) struct todo_list todo_list = TODO_LIST_INIT;
9787d17d40 4925) int res = 0;
9787d17d40 4927) if (strbuf_read_file_or_whine(&todo_list.buf, 
todo_file) < 0)
9787d17d40 4928) return -1;
9787d17d40 4929) if (todo_list_parse_insn_buffer(todo_list.buf.buf, 
&todo_list) < 0) {
9787d17d40 4930) todo_list_release(&todo_list);
9787d17d40 4931) return -1;
9787d17d40 4934) res = todo_list_rearrange_squash(&todo_list);
9787d17d40 4935) if (!res)
9787d17d40 4936) res = rewrite_file(todo_file, todo_list.buf.buf, 
todo_list.buf.len);
9787d17d40 4938) todo_list_release(&todo_list);

setup.c
58b284a2e9  413) return config_error_nonbool(var);

sha1-array.c
7fdf90d541 91) oidcpy(&oids[dst], &oids[src]);

submodule-config.c
bcbc780d14 740) return CONFIG_INVALID_KEY;
45f5ef3d77 755) warning(_("Could not update .gitmodules entry %s"), key);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
060675d4fc 1378) strbuf_release(&gitdir);
183be9660a 1501) struct get_next_submodule_task *task = task_cb;
183be9660a 1505) get_next_submodule_task_release(task);
183be9660a 1532) return 0;
183be9660a 1536) goto out;
183be9660a 1551) return 0;

tree.c
a5dda2204a 108) if (repo_parse_commit(the_repository, commit))

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Alban Gruin      009173ed7: sequencer: change complete_action() to use 
the refactored functions
Alban Gruin      06d813612: sequencer: fix a call to error() in 
transform_todo_file()
Alban Gruin      6424061be: rebase-interactive: rewrite edit_todo_list() 
to handle the initial edit
Alban Gruin      7ccfac40b: rebase--interactive: move 
transform_todo_file() to rebase--interactive.c
Alban Gruin      9787d17d4: sequencer: refactor rearrange_squash() to 
work on a todo_list
Alban Gruin      b5d606240: sequencer: refactor 
sequencer_add_exec_commands() to work on a todo_list
Alban Gruin      b74a37a5a: sequencer: refactor check_todo_list() to 
work on a todo_list
Alban Gruin      b8dac44d1: sequencer: refactor skip_unnecessary_picks() 
to work on a todo_list
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Antonio Ospite      c22b82014: submodule: support reading .gitmodules 
when it's not in the working tree
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      dc7d66433: packfile: close multi-pack-index in 
close_all_packs
Elijah Newren      387361a6a: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      4cdc48e41: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      b58ae691c: merge-recursive: fix rename/add conflict 
handling
Junio C Hamano      a5dda2204: treewide: apply cocci patch
Liam Beguin      0cce4a275: rebase -i -x: add exec commands via the 
rebase--helper
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      b29759d89: fsck: check HEAD and reflog from 
other worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Stefan Beller      060675d4f: submodule: migrate get_next_submodule to 
use repository structs
Stefan Beller      183be9660: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      7fdf90d54: sha1-array: provide oid_array_filter
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup


Uncovered in jch not in next
----------------------------

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/fetch.c
c806111692 builtin/fetch.c  373) continue; /* can this happen??? */

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

revision.c
a63d88e595 2932) return;
a63d88e595 2935) return;
a63d88e595 2941) c->object.flags |= UNINTERESTING;
a63d88e595 2944) return;
a63d88e595 2947) mark_parents_uninteresting(c);
a63d88e595 2970) return;
a63d88e595 2973) return;
a63d88e595 2978) return;
a63d88e595 3042) continue;
f33f8de6af 3090) if (!revs->ignore_missing_links)
f33f8de6af 3091) die("Failed to traverse parents of commit %s",
a63d88e595 3092) oid_to_hex(&commit->object.oid));
a63d88e595 3100) continue;

sequencer.c
08b6ba5cc0  683) np = strchrnul(buf, '\n');
08b6ba5cc0  684) return error(_("unable to parse '%.*s'"),
08b6ba5cc0  695) return error(_("unable to dequote value of '%s'"),
08b6ba5cc0  737) goto finish;
08b6ba5cc0  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
08b6ba5cc0  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
08b6ba5cc0  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
08b6ba5cc0  756) err = error(_("unknown variable '%s'"),
08b6ba5cc0  761) error(_("missing 'GIT_AUTHOR_NAME'"));
08b6ba5cc0  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
08b6ba5cc0  765) error(_("missing 'GIT_AUTHOR_DATE'"));

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      a63d88e59: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f33f8de6a: revision.c: begin refactoring 
--topo-order logic
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Junio C Hamano      c80611169: fetch: replace string-list used as a 
look-up table with a hashmap
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Phillip Wood      08b6ba5cc: add read_author_script() to libgit
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed


Uncovered in next not in master
-------------------------------

apply.c
eccb5a5f3d 4071) return get_oid_hex(p->old_oid_prefix, oid);

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
55071ea248   61) strbuf_trim(&out);
55071ea248   62) ret = !strcmp("true", out.buf);
55071ea248   63) strbuf_release(&out);
002ee2fe68  115) die(_("%s requires an interactive rebase"), option);
f95736288a  148) return error_errno(_("could not read '%s'"), path);
f95736288a  162) return -1;
f95736288a  167) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  178) return -1;
f95736288a  179) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  180) return -1;
f95736288a  182) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  186) return -1;
f95736288a  188) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  196) opts->signoff = 1;
73d51ed0a5  197) opts->flags |= REBASE_FORCE;
ead98c111b  204) return -1;
12026a412c  219) return -1;
ba1905a5fe  227) return -1;
ba1905a5fe  235) return -1;
6defce2b02  255) return error(_("Could not read '%s'"), path);
6defce2b02  271) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  275) return res;
bc24382c2b  373) argv_array_pushf(&child.args,
bc24382c2b  375) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  507) struct strbuf dir = STRBUF_INIT;
6defce2b02  509) apply_autostash(opts);
ac7f467fef  510) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  511) remove_dir_recursively(&dir, 0);
ac7f467fef  512) strbuf_release(&dir);
ac7f467fef  513) die("Nothing to do");
ac7f467fef  543) return -1;
ac7f467fef  547) rollback_lock_file(&lock);
ac7f467fef  548) return error(_("could not determine HEAD revision"));
ac7f467fef  565) rollback_lock_file(&lock);
ac7f467fef  566) return error(_("could not read index"));
ac7f467fef  570) error(_("failed to find tree of %s"), oid_to_hex(oid));
ac7f467fef  571) rollback_lock_file(&lock);
ac7f467fef  572) free((void *)desc.buffer);
ac7f467fef  573) return -1;
ac7f467fef  586) ret = error(_("could not write index"));
ac7f467fef  590) return ret;
ac7f467fef  606) } else if (old_orig)
ac7f467fef  607) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  635) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  669) return 1;
9a48a615b4  685) return 0;
55071ea248  893) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  896) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  897) die_errno(_("could not exec %s"), path);
0eabf4b95c  915) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  952) usage_with_options(builtin_rebase_usage,
f95736288a  972) die(_("Cannot read HEAD"));
f95736288a  976) die(_("could not read index"));
f95736288a  990) exit(1);
122420c295 1002) die(_("could not discard worktree changes"));
122420c295 1004) exit(1);
5e5d96197c 1015) exit(1);
5e5d96197c 1018) die(_("could not move back to %s"),
5a61494539 1028) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1047) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1048) const char *state_dir_base =
c54dacb50e 1049) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1050) const char *cmd_live_rebase =
c54dacb50e 1052) strbuf_reset(&buf);
c54dacb50e 1053) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1054) die(_("It seems that there is already a %s directory, 
and\n"
53f9e5be94 1078) strbuf_addstr(&options.git_am_opt, " --ignore-date");
53f9e5be94 1079) options.flags |= REBASE_FORCE;
7998dbe1ec 1091) strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
3c3588c7d3 1123) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1124) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1146) die(_("--strategy requires --merge or --interactive"));
cda614e489 1164) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1173) options.state_dir = apply_dir();
ac7f467fef 1174) break;
ac7f467fef 1251) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1257) die(_("Could not create new root commit"));
e65123a71d 1307) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1315) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1327) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1340) die(_("could not read index"));
6defce2b02 1367) die(_("Cannot autostash"));
6defce2b02 1370) die(_("Unexpected stash response: '%s'"),
6defce2b02 1376) die(_("Could not create directory for '%s'"),
6defce2b02 1382) die(_("could not reset --hard"));
e65123a71d 1426) ret = !!error(_("could not parse '%s'"),
e65123a71d 1428) goto cleanup;
e65123a71d 1437) ret = !!error(_("could not switch to "
1ed9c14ff2 1447)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1448) puts(_("HEAD is up to date."));
9a48a615b4 1457)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1458) puts(_("HEAD is up to date, rebase forced."));

builtin/repack.c
2f0c9e9a9b 239) die("repack: Expecting full hex object ID lines only 
from pack-objects.");
2f0c9e9a9b 411) die("repack: Expecting full hex object ID lines only 
from pack-objects.");

builtin/rev-list.c
7c0fe330d5 builtin/rev-list.c 227) die("unexpected missing %s object '%s'",
7c0fe330d5 builtin/rev-list.c 228)     type_name(obj->type), 
oid_to_hex(&obj->oid));

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

gpg-interface.c
4de9394dcb 155) break;

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

list-objects-filter-options.c
bc5975d24f  55) if (errbuf) {
bc5975d24f  56) strbuf_addstr(
bc5975d24f  60) return 1;
cc0b05a4cc  86) if (errbuf)

list-objects-filter.c
list-objects.c
f447a499db 200) ctx->show_object(obj, base->buf, ctx->show_data);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

ref-filter.c
f0062d3b74 1035) v->s = xstrdup("");
f0062d3b74 1298) free((char *)to_free);
f0062d3b74 1299) return xstrdup("");
f0062d3b74 1336) free((char *)to_free);
f0062d3b74 1337) return xstrdup("");
f0062d3b74 1387) *s = xstrdup("=");
f0062d3b74 1389) *s = xstrdup("<");
f0062d3b74 1514) ref->symref = xstrdup("");
f0062d3b74 1583) v->s = xstrdup("");

sequencer.c
65850686cf 2278) return;
65850686cf 2375) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3373) return error(_("could not checkout %s"), commit);
4df66c40b0 3387) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3407) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4771) return -1;
b97e187364 4774) return -1;
b97e187364 4780) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4783) todo_list_release(&todo_list);
b97e187364 4784) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4803) todo_list_release(&todo_list);
b97e187364 4804) return -1;
b97e187364 4808) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4812) return error(_("could not transform the todo list"));
b97e187364 4841) return error(_("could not transform the todo list"));
b97e187364 4844) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4850) return -1;

strbuf.c
f95736288a  127) --sb->len;

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

Commits introducing uncovered code:
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
brian m. carlson      2f0c9e9a9: builtin/repack: replace hard-coded 
constants
brian m. carlson      eccb5a5f3: apply: rename new_sha1_prefix and 
old_sha1_prefix
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Matthew DeVore      7c0fe330d: rev-list: handle missing tree objects 
properly
Matthew DeVore      bc5975d24: list-objects-filter: implement filter tree:0
Matthew DeVore      cc0b05a4c: list-objects-filter-options: do not 
over-strbuf_init
Matthew DeVore      f447a499d: list-objects: store common func args in 
struct
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Olga Telezhnaya      f0062d3b7: ref-filter: free item->value and 
item->value->s
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      53f9e5be9: builtin rebase: support `ignore-date` option
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      7998dbe1e: builtin rebase: support `-C` and 
`--whitespace=<type>`
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue


Uncovered in mater not in master@{1}
------------------------------------

builtin/help.c
e6e76baaf4 builtin/help.c 429) if (!exclude_guides || alias[0] == '!') {
e6e76baaf4 builtin/help.c 430) printf_ln(_("'%s' is aliased to '%s'"), 
cmd, alias);
e6e76baaf4 builtin/help.c 431) free(alias);
e6e76baaf4 builtin/help.c 432) exit(0);
e6e76baaf4 builtin/help.c 441) fprintf_ln(stderr, _("'%s' is aliased to 
'%s'"), cmd, alias);
e6e76baaf4 builtin/help.c 442) count = split_cmdline(alias, &argv);
e6e76baaf4 builtin/help.c 443) if (count < 0)
e6e76baaf4 builtin/help.c 444) die(_("bad alias.%s string: %s"), cmd,
e6e76baaf4 builtin/help.c 446) free(argv);
e6e76baaf4 builtin/help.c 448) return alias;

git.c
a9a60b94cc 322) fprintf_ln(stderr, _("'%s' is aliased to '%s'"),

ident.c
501afcb8b0 172) strbuf_addstr(&git_default_email, email);
501afcb8b0 173) free((char *)email);

packfile.c
1127a98cce  117) return error("index file %s is too small", path);
1127a98cce  119) return error("empty data");

split-index.c
e3d837989e 335) ce->ce_flags |= CE_UPDATE_IN_BASE;

Commits introducing uncovered code:
Johannes Schindelin      501afcb8b: mingw: use domain information for 
default email
Josh Steadmon      1127a98cc: fuzz: add fuzz testing for packfile indices.
Rasmus Villemoes      a9a60b94c: git.c: handle_alias: prepend alias info 
when first argument is -h
Rasmus Villemoes      e6e76baaf: help: redirect to aliased commands for 
"git cmd --help"
SZEDER Gábor      e3d837989: split-index: don't compare cached data of 
entries already marked for split index


^ permalink raw reply	[relevance 4%]

* Re: [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip
  2018-10-25 23:32 [PATCH 00/10] Resending sb/submodule-recursive-fetch-gets-the-tip Stefan Beller
                   ` (8 preceding siblings ...)
  2018-10-25 23:32 ` [PATCH 10/10] builtin/fetch: check for submodule updates in any ref update Stefan Beller
@ 2018-10-29  3:44 ` Junio C Hamano
  9 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-10-29  3:44 UTC (permalink / raw)
  To: Stefan Beller; +Cc: jonathantanmy, git

Stefan Beller <sbeller@google.com> writes:

> Thanks Jonathan for your thoughtful comments,
> here is the product of the discussion:

Can you use v$n in the subject (if these rerolls are meant for
application and not primarily for discussion, that is)?  It quickly
gets confusing to see many messages with the same subject from
different attempts.

> This is still based on ao/submodule-wo-gitmodules-checked-out.

... which just got updated but I think only one test script changed,
so I expect there won't be anything unexpected when I queue this on
top of a merge of that topic and master.

It seems that the first three preparatory steps haven't changed,
patch #4-#7 have moderate amount of changes, and the previous #8 got
updated quite a lot.  Let's see how well this and updated base topic
will play with other topics in flight.

Thanks.

> previous version
> https://public-inbox.org/git/20181016181327.107186-1-sbeller@google.com/
>
> Stefan Beller (10):
>   sha1-array: provide oid_array_filter
>   submodule.c: fix indentation
>   submodule.c: sort changed_submodule_names before searching it
>   submodule.c: tighten scope of changed_submodule_names struct
>   submodule: store OIDs in changed_submodule_names
>   repository: repo_submodule_init to take a submodule struct
>   submodule: migrate get_next_submodule to use repository structs
>   submodule.c: fetch in submodules git directory instead of in worktree
>   fetch: try fetching submodules if needed objects were not fetched
>   builtin/fetch: check for submodule updates in any ref update
>
>  Documentation/technical/api-oid-array.txt    |   5 +
>  builtin/fetch.c                              |  11 +-
>  builtin/grep.c                               |  17 +-
>  builtin/ls-files.c                           |  12 +-
>  builtin/submodule--helper.c                  |   2 +-
>  repository.c                                 |  27 +-
>  repository.h                                 |  12 +-
>  sha1-array.c                                 |  17 ++
>  sha1-array.h                                 |   3 +
>  submodule.c                                  | 265 ++++++++++++++++---
>  t/helper/test-submodule-nested-repo-config.c |   8 +-
>  t/t5526-fetch-submodules.sh                  |  55 ++++
>  12 files changed, 346 insertions(+), 88 deletions(-)
>
>   git range-diff origin/sb/submodule-recursive-fetch-gets-the-tip... 
>
> 1:  3fbb06aedd ! 1:  0fdb0e2ad9 submodule.c: move global changed_submodule_names into fetch submodule struct
>     @@ -1,12 +1,11 @@
>      Author: Stefan Beller <sbeller@google.com>
>      
>     -    submodule.c: move global changed_submodule_names into fetch submodule struct
>     +    submodule.c: tighten scope of changed_submodule_names struct
>      
>          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>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>      diff --git a/submodule.c b/submodule.c
>      --- a/submodule.c
>     @@ -16,7 +15,6 @@
>       
>       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;
>     @@ -25,22 +23,8 @@
>       }
>       
>      -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 string_list *changed_submodule_names)
>       {
>       	struct argv_array argv = ARGV_ARRAY_INIT;
>       	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
>     @@ -49,30 +33,23 @@
>       
>       		if (!submodule_has_commits(path, commits))
>      -			string_list_append(&changed_submodule_names, name->string);
>     -+			string_list_append(&spf->changed_submodule_names,
>     ++			string_list_append(changed_submodule_names,
>      +					   name->string);
>       	}
>       
>       	free_submodules_oids(&changed_submodules);
>      @@
>     - 	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;
>     --};
>     + 	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}
>     --
>     ++#define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0, STRING_LIST_INIT_DUP }
>     + 
>       static int get_fetch_recurse_config(const struct submodule *submodule,
>       				    struct submodule_parallel_fetch *spf)
>     - {
>      @@
>       		case RECURSE_SUBMODULES_ON_DEMAND:
>       			if (!submodule ||
>     @@ -88,7 +65,7 @@
>       
>      -	calculate_changed_submodule_paths();
>      -	string_list_sort(&changed_submodule_names);
>     -+	calculate_changed_submodule_paths(&spf);
>     ++	calculate_changed_submodule_paths(&spf.changed_submodule_names);
>      +	string_list_sort(&spf.changed_submodule_names);
>       	run_processes_parallel(max_parallel_jobs,
>       			       get_next_submodule,
> 2:  a64a8322a1 ! 2:  a11e6e39a2 submodule.c: do not copy around submodule list
>     @@ -1,6 +1,6 @@
>      Author: Stefan Beller <sbeller@google.com>
>      
>     -    submodule.c: do not copy around submodule list
>     +    submodule: store OIDs in changed_submodule_names
>      
>          'calculate_changed_submodule_paths' uses a local list to compute the
>          changed submodules, and then produces the result by copying appropriate
>     @@ -14,13 +14,13 @@
>          useful in a later patch.
>      
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>     +    Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
>      
>      diff --git a/submodule.c b/submodule.c
>      --- a/submodule.c
>      +++ b/submodule.c
>      @@
>     - 	struct submodule_parallel_fetch *spf)
>     + 	struct string_list *changed_submodule_names)
>       {
>       	struct argv_array argv = ARGV_ARRAY_INIT;
>      -	struct string_list changed_submodules = STRING_LIST_INIT_DUP;
>     @@ -34,10 +34,10 @@
>       	 * commits have been recorded upstream in "changed_submodule_names".
>       	 */
>      -	collect_changed_submodules(&changed_submodules, &argv);
>     -+	collect_changed_submodules(&spf->changed_submodule_names, &argv);
>     ++	collect_changed_submodules(changed_submodule_names, &argv);
>       
>      -	for_each_string_list_item(name, &changed_submodules) {
>     -+	for_each_string_list_item(name, &spf->changed_submodule_names) {
>     ++	for_each_string_list_item(name, changed_submodule_names) {
>       		struct oid_array *commits = name->util;
>       		const struct submodule *submodule;
>       		const char *path = NULL;
>     @@ -46,7 +46,7 @@
>       			continue;
>       
>      -		if (!submodule_has_commits(path, commits))
>     --			string_list_append(&spf->changed_submodule_names,
>     +-			string_list_append(changed_submodule_names,
>      -					   name->string);
>      +		if (submodule_has_commits(path, commits)) {
>      +			oid_array_clear(commits);
>     @@ -55,7 +55,7 @@
>       	}
>       
>      -	free_submodules_oids(&changed_submodules);
>     -+	string_list_remove_empty_items(&spf->changed_submodule_names, 1);
>     ++	string_list_remove_empty_items(changed_submodule_names, 1);
>      +
>       	argv_array_clear(&argv);
>       	oid_array_clear(&ref_tips_before_fetch);
> 3:  9341b92c83 ! 3:  3f4e0d4b8d repository: repo_submodule_init to take a submodule struct
>     @@ -5,17 +5,19 @@
>          When constructing a struct repository for a submodule for some revision
>          of the superproject where the submodule is not contained in the index,
>          it may not be present in the working tree currently either. In that
>     -    siutation giving a 'path' argument is not useful. Upgrade the
>     +    situation giving a 'path' argument is not useful. Upgrade the
>          repo_submodule_init function to take a struct submodule instead.
>     +    The submodule struct can be obtained via submodule_from_{path, name} or
>     +    an artificial submodule struct can be passed in.
>      
>     -    While we are at it, overhaul the repo_submodule_init function by renaming
>     -    the submodule repository struct, which is to be initialized, to a name
>     -    that is not confused with the struct submodule as easily.
>     +    While we are at it, rename the repository struct in the repo_submodule_init
>     +    function, which is to be initialized, to a name that is not confused with
>     +    the struct submodule as easily. Perform such renames in similar functions
>     +    as well.
>      
>          Also move its documentation into the header file.
>      
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>      diff --git a/builtin/grep.c b/builtin/grep.c
>      --- a/builtin/grep.c
>     @@ -104,6 +106,19 @@
>       
>       static void show_ce(struct repository *repo, struct dir_struct *dir,
>      
>     +diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
>     +--- a/builtin/submodule--helper.c
>     ++++ b/builtin/submodule--helper.c
>     +@@
>     + 	if (!sub)
>     + 		BUG("We could get the submodule handle before?");
>     + 
>     +-	if (repo_submodule_init(&subrepo, the_repository, path))
>     ++	if (repo_submodule_init(&subrepo, the_repository, sub))
>     + 		die(_("could not get a repository handle for submodule '%s'"), path);
>     + 
>     + 	if (!repo_config_get_string(&subrepo, "core.worktree", &cw)) {
>     +
>      diff --git a/repository.c b/repository.c
>      --- a/repository.c
>      +++ b/repository.c
>     @@ -178,7 +193,8 @@
>      +/*
>      + * Initialize the repository 'subrepo' as the submodule given by the
>      + * struct submodule 'sub' in parent repository 'superproject'.
>     -+ * Return 0 upon success and a non-zero value upon failure.
>     ++ * Return 0 upon success and a non-zero value upon failure, which may happen
>     ++ * if the submodule is not found, or 'sub' is NULL.
>      + */
>      +struct submodule;
>      +int repo_submodule_init(struct repository *subrepo,
> 4:  cea909cbd4 ! 4:  b1566069e7 submodule: fetch in submodules git directory instead of in worktree
>     @@ -1,44 +1,19 @@
>      Author: Stefan Beller <sbeller@google.com>
>      
>     -    submodule: fetch in submodules git directory instead of in worktree
>     +    submodule: migrate get_next_submodule to use repository structs
>      
>     -    This patch started as a refactoring to make 'get_next_submodule' more
>     -    readable, but upon doing so, I realized that "git fetch" of the submodule
>     -    actually doesn't need to be run in the submodules worktree. So let's run
>     -    it in its git dir instead.
>     +    We used to recurse into submodules, even if they were broken having
>     +    only an objects directory. The child process executed in the submodule
>     +    would fail though if the submodule was broken.
>      
>     -    That should pave the way towards fetching submodules that are currently
>     -    not checked out.
>     -
>     -    This patch leaks the cp->dir in get_next_submodule, as any further
>     -    callback in run_processes_parallel doesn't have access to the child
>     -    process any more. In an early iteration of this patch, the function
>     -    get_submodule_repo_for directly returned the string containing the
>     -    git directory, which would be a better design choice for this patch.
>     -
>     -    However the next patch both fixes the memory leak of cp->dir and also has
>     -    a use case for using the full repository handle of the submodule, so
>     -    it makes sense to introduce the get_submodule_repo_for here already.
>     +    This patch tightens the check upfront, such that we do not need
>     +    to spawn a child process to find out if the submodule is broken.
>      
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>      diff --git a/submodule.c b/submodule.c
>      --- a/submodule.c
>      +++ b/submodule.c
>     -@@
>     - 			 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
>      @@
>       	return spf->default_option;
>       }
>     @@ -99,9 +74,8 @@
>      +		if (repo) {
>       			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 = xstrdup(repo->gitdir);
>     + 			prepare_submodule_repo_env(&cp->env_array);
>     ++			cp->dir = xstrdup(repo->worktree);
>       			cp->git_cmd = 1;
>       			if (!spf->quiet)
>       				strbuf_addf(err, "Fetching submodule %s%s\n",
>     @@ -113,27 +87,17 @@
>      +			repo_clear(repo);
>      +			free(repo);
>       			ret = 1;
>     ++		} else {
>     ++			/*
>     ++			 * An empty directory is normal,
>     ++			 * the submodule is not initialized
>     ++			 */
>     ++			if (S_ISGITLINK(ce->ce_mode) &&
>     ++			    !is_empty_dir(ce->name))
>     ++				die(_("Could not access submodule '%s'"), ce->name);
>       		}
>      -		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
>     ---- a/t/t5526-fetch-submodules.sh
>     -+++ b/t/t5526-fetch-submodules.sh
>     -@@
>     - 
>     - 	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" '
> -:  ---------- > 5:  2d98ff1201 submodule.c: fetch in submodules git directory instead of in worktree
> 5:  9ad0125310 ! 6:  092b9cbcba fetch: retry fetching submodules if needed objects were not fetched
>     @@ -1,25 +1,23 @@
>      Author: Stefan Beller <sbeller@google.com>
>      
>     -    fetch: retry fetching submodules if needed objects were not fetched
>     +    fetch: try fetching submodules if needed objects were not fetched
>      
>          Currently when git-fetch is asked to recurse into submodules, it dispatches
>          a plain "git-fetch -C <submodule-dir>" (with 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>).
>     +    But this default fetch is not sufficient, as a newly fetched commit in
>     +    the superproject could point to a commit in the submodule that is not
>     +    in the default refspec. This is common in workflows like Gerrit's.
>     +    When fetching a Gerrit change under review (from refs/changes/??), the
>     +    commits in that change likely point to submodule commits that have not
>     +    been merged to a branch yet.
>      
>     -    Retry fetching a submodule by object name if the object id that the
>     +    Try fetching a submodule by object id if the object id that the
>          superproject points to, cannot be found.
>      
>     -    This retrying does not happen when the "git fetch" done at the
>     +    The try 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. A later patch will fix this.
>     @@ -32,7 +30,6 @@
>          in case the submodule recursion is set to "on".
>      
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>     -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>      diff --git a/builtin/fetch.c b/builtin/fetch.c
>      --- a/builtin/fetch.c
>     @@ -75,16 +72,16 @@
>       	int result;
>       
>       	struct string_list changed_submodule_names;
>     -+	struct get_next_submodule_task **retry;
>     -+	int retry_nr, retry_alloc;
>     ++	struct get_next_submodule_task **fetch_specific_oids;
>     ++	int fetch_specific_oids_nr, fetch_specific_oids_alloc;
>       };
>      -#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, \
>      +		  NULL, 0, 0}
>       
>     - static void calculate_changed_submodule_paths(
>     - 	struct submodule_parallel_fetch *spf)
>     + static int get_fetch_recurse_config(const struct submodule *submodule,
>     + 				    struct submodule_parallel_fetch *spf)
>      @@
>       	return spf->default_option;
>       }
>     @@ -93,6 +90,8 @@
>      +	struct repository *repo;
>      +	const struct submodule *sub;
>      +	unsigned free_sub : 1; /* Do we need to free the submodule? */
>     ++
>     ++	/* fetch specific oids if set, otherwise fetch default refspec */
>      +	struct oid_array *commits;
>      +};
>      +
>     @@ -224,24 +223,29 @@
>      -			repo_clear(repo);
>      -			free(repo);
>      -			ret = 1;
>     --		}
>     --		strbuf_release(&submodule_prefix);
>     --		if (ret) {
>     - 			spf->count++;
>     ++			spf->count++;
>      +			*task_cb = task;
>      +
>      +			strbuf_release(&submodule_prefix);
>     - 			return 1;
>     -+		} else {
>     ++			return 1;
>     + 		} else {
>     ++
>      +			get_next_submodule_task_release(task);
>      +			free(task);
>     ++
>     + 			/*
>     + 			 * An empty directory is normal,
>     + 			 * the submodule is not initialized
>     +@@
>     + 			    !is_empty_dir(ce->name))
>     + 				die(_("Could not access submodule '%s'"), ce->name);
>       		}
>     - 	}
>     ++	}
>      +
>     -+	if (spf->retry_nr) {
>     -+		struct get_next_submodule_task *task = spf->retry[spf->retry_nr - 1];
>     ++	if (spf->fetch_specific_oids_nr) {
>     ++		struct get_next_submodule_task *task = spf->fetch_specific_oids[spf->fetch_specific_oids_nr - 1];
>      +		struct strbuf submodule_prefix = STRBUF_INIT;
>     -+		spf->retry_nr--;
>     ++		spf->fetch_specific_oids_nr--;
>      +
>      +		strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, task->sub->path);
>      +
>     @@ -262,9 +266,13 @@
>      +					  append_oid_to_argv, &cp->args);
>      +
>      +		*task_cb = task;
>     -+		strbuf_release(&submodule_prefix);
>     + 		strbuf_release(&submodule_prefix);
>     +-		if (ret) {
>     +-			spf->count++;
>     +-			return 1;
>     +-		}
>      +		return 1;
>     -+	}
>     + 	}
>      +
>       	return 0;
>       }
>     @@ -326,9 +334,11 @@
>      +			return 0;
>      +
>      +		task->commits = commits;
>     -+		ALLOC_GROW(spf->retry, spf->retry_nr + 1, spf->retry_alloc);
>     -+		spf->retry[spf->retry_nr] = task;
>     -+		spf->retry_nr++;
>     ++		ALLOC_GROW(spf->fetch_specific_oids,
>     ++			   spf->fetch_specific_oids_nr + 1,
>     ++			   spf->fetch_specific_oids_alloc);
>     ++		spf->fetch_specific_oids[spf->fetch_specific_oids_nr] = task;
>     ++		spf->fetch_specific_oids_nr++;
>      +		return 0;
>      +	}
>      +
>     @@ -346,18 +356,33 @@
>       	test_cmp expect actual
>       '
>       
>     -+test_expect_success "fetch new commits on-demand when they are not reachable" '
>     ++test_expect_success "fetch new submodule commits on-demand outside standard refspec" '
>     ++	# add a second submodule and ensure it is around in downstream first
>     ++	git clone submodule sub1 &&
>     ++	git submodule add ./sub1 &&
>     ++	git commit -m "adding a second submodule" &&
>     ++	git -C downstream pull &&
>     ++	git -C downstream submodule update --init --recursive &&
>     ++
>      +	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 &&
>     ++	test_tick &&
>     ++
>     ++	D=$(git -C sub1 commit-tree -m "new change outside refs/heads" HEAD^{tree}) &&
>     ++	git -C sub1 update-ref refs/changes/2 $D &&
>     ++	git update-index --cacheinfo 160000 $D sub1 &&
>     ++
>     ++	git commit -m "updated submodules outside of refs/heads" &&
>     ++	E=$(git rev-parse HEAD) &&
>     ++	git update-ref refs/changes/2 $E &&
>      +	(
>      +		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:refs/heads/my_branch &&
>      +		git -C submodule cat-file -t $C &&
>     ++		git -C sub1 cat-file -t $D &&
>      +		git checkout --recurse-submodules FETCH_HEAD
>      +	)
>      +'
> 6:  b8db3b45bf < -:  ---------- builtin/fetch: check for submodule updates for non branch fetches
> 7:  905a4f0d4f < -:  ---------- fixup! repository: repo_submodule_init to take a submodule struct
> -:  ---------- > 7:  11bf819782 builtin/fetch: check for submodule updates in any ref update

^ permalink raw reply	[relevance 4%]

* Git Test Coverage Report (Tuesday, Oct 30)
@ 2018-10-30 13:37 Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-10-30 13:37 UTC (permalink / raw)
  To: Git List

This coverage report uses a new build definition that runs the four 
suites in parallel, then combines the results into the report below. You 
can see the build that generated this report at [1].

Thanks,
-Stolee

[1] https://git.visualstudio.com/git/_build/results?buildId=235&view=logs

---

pu: 7f50cad4af91f508e14338e87c5911f990d0a938
jch: 13c38c20c0c9afee77ede86d423027eb79c51ced
next: 53cd27f688b0bae2a5f2d8f5cea6ba63c6e4a781
master: 4ede3d42dfb57f9a41ac96a1f216c62eb7566cc2
master@{1}: c670b1f876521c9f7cd40184bf7ed05aad843433

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
7f50cad4af builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    924) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    925) break;

builtin/describe.c
7f50cad4af builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/fsck.c
372738935a builtin/fsck.c 622) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
372738935a builtin/fsck.c 627) return error(_("invalid %s"), head_ref_name);

builtin/grep.c
c22b820141 builtin/grep.c  429) grep_read_unlock();

builtin/pack-objects.c
7f50cad4af builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 585) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 621) continue;

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fsck.c
7f50cad4af  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
7f50cad4af  878) repo_read_object_file(the_repository,
7f50cad4af  879)       &tag->object.oid, &type, &size);

http-push.c
7f50cad4af 1635) if (!repo_has_object_file(the_repository, &head_oid))
7f50cad4af 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

merge-recursive.c
4cdc48e412 1585) return -1;
4cdc48e412 1588) return -1;
4cdc48e412 1594) return -1;
4cdc48e412 1596) if (update_file(o, 1, b_oid, b_mode, collide_path))
4cdc48e412 1597) return -1;
4cdc48e412 1664) return -1;
4cdc48e412 1667) return -1;
4cdc48e412 1670) return -1;
b58ae691c0 1703) return -1;
387361a6a7 1738) return -1;
387361a6a7 1786) return -1;
387361a6a7 1795) new_path = unique_path(o, a->path, ci->branch1);
387361a6a7 1796) output(o, 1, _("Refusing to lose untracked file"
387361a6a7 1802) return -1;
387361a6a7 1805) return -1;
387361a6a7 1815) return -1;
387361a6a7 1831) return -1;
387361a6a7 1834) return -1;

midx.c
1dcd9f2043  184) return;

negotiator/default.c
7f50cad4af  71) if (repo_parse_commit(the_repository, commit))

packfile.c
dc7d664335  350) close_midx(o->multi_pack_index);
dc7d664335  351) o->multi_pack_index = NULL;

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
7f50cad4af  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
7f50cad4af 1624) repo_unuse_commit_buffer(the_repository, head_commit,
7f50cad4af 3865) repo_unuse_commit_buffer(the_repository,

sha1-array.c
7fdf90d541 91) oidcpy(&oids[dst], &oids[src]);

submodule-config.c
bcbc780d14 740) return CONFIG_INVALID_KEY;
45f5ef3d77 755) warning(_("Could not update .gitmodules entry %s"), key);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
060675d4fc 1378) strbuf_release(&gitdir);
183be9660a 1501) struct get_next_submodule_task *task = task_cb;
183be9660a 1505) get_next_submodule_task_release(task);
183be9660a 1532) return 0;
183be9660a 1536) goto out;
183be9660a 1551) return 0;

tree.c
7f50cad4af 108) if (repo_parse_commit(the_repository, commit))

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Antonio Ospite      c22b82014: submodule: support reading .gitmodules 
when it's not in the working tree
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      dc7d66433: packfile: close multi-pack-index in 
close_all_packs
Elijah Newren      387361a6a: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      4cdc48e41: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      b58ae691c: merge-recursive: fix rename/add conflict 
handling
Junio C Hamano      372738935: Merge branch 
'nd/per-worktree-ref-iteration' into pu
Junio C Hamano      7f50cad4a: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Stefan Beller      060675d4f: submodule: migrate get_next_submodule to 
use repository structs
Stefan Beller      183be9660: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      7fdf90d54: sha1-array: provide oid_array_filter
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup



Uncovered code in 'jch' not in 'next'
----------------------------------------

archive.c
48a40549d5 399) die(_("'%s' is not a valid object name"), name);
48a40549d5 412) die(_("%s is not a tree object"), oid_to_hex(&oid));
48a40549d5 422) die(_("current working directory is untracked"));

attr.c
847aa0ff7a  369) fprintf(stderr, _("%s not allowed: %s:%d\n"),

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/fetch.c
builtin/fsck.c
09120ea781 builtin/fsck.c 154) objerror(parent, _("wrong object type in 
link"));
09120ea781 builtin/fsck.c 265) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
09120ea781 builtin/fsck.c 293) error(_("could not create lost-found"));
09120ea781 builtin/fsck.c 300) die_errno(_("could not write '%s'"), 
filename);
09120ea781 builtin/fsck.c 304) die_errno(_("could not finish '%s'"),
09120ea781 builtin/fsck.c 321) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
09120ea781 builtin/fsck.c 339) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
09120ea781 builtin/fsck.c 358) fprintf_ln(stderr, _("Checking %s %s"),
09120ea781 builtin/fsck.c 371) printf_ln(_("root %s"),
09120ea781 builtin/fsck.c 407) return error(_("%s: object corrupt or 
missing"),
09120ea781 builtin/fsck.c 446) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
09120ea781 builtin/fsck.c 545) error(_("%s: object could not be parsed: 
%s"),
09120ea781 builtin/fsck.c 580) fprintf_ln(stderr, _("Checking object 
directory"));
09120ea781 builtin/fsck.c 596) fprintf_ln(stderr, _("Checking HEAD link"));
09120ea781 builtin/fsck.c 601) return error(_("invalid HEAD"));
09120ea781 builtin/fsck.c 628) fprintf_ln(stderr, _("Checking cache tree"));
09120ea781 builtin/fsck.c 644) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/grep.c
389f2f2d79 builtin/grep.c 1034) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/merge.c
35408df41e builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/reflog.c
b9c4009cca builtin/reflog.c 563) usage(_(reflog_expire_usage));
b9c4009cca builtin/reflog.c 605) status |= error(_("%s points 
nowhere!"), argv[i]);
b9c4009cca builtin/reflog.c 651) usage(_(reflog_delete_usage));
b9c4009cca builtin/reflog.c 657) return error(_("nothing to delete?"));
b9c4009cca builtin/reflog.c 666) status |= error(_("not a reflog: %s"), 
argv[i]);
b9c4009cca builtin/reflog.c 671) status |= error(_("no reflog for 
'%s'"), argv[i]);
b9c4009cca builtin/reflog.c 706) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 714) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 717) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
eb6c5a15dc 200) die(_("could not start pack-objects to repack promisor 
objects"));
3e582cd8a1 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
eb6c5a15dc 250) die_errno(("unable to create '%s'"), promisor_name);
3e582cd8a1 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

git.c
b63c352c11 341) die_errno(_("while expanding alias '%s': '%s'"),
b63c352c11 350) die(_("alias '%s' changes environment variables.\n"
b63c352c11 358) die(_("empty alias for %s"), alias_command);
b63c352c11 361) die(_("recursive alias: %s"), alias_command);
b63c352c11 436) die_errno(_("write failure on standard output"));
b63c352c11 438) die(_("unknown write failure on standard output"));
b63c352c11 440) die_errno(_("close failed on standard output"));
b63c352c11 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

name-hash.c
31bfd155d8 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
31bfd155d8 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
31bfd155d8 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

parse-options-cb.c
35408df41e  21) return error(_("option `%s' expects a numerical value"),
35408df41e  58) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
35408df41e  88) return error(_("%s takes no value"), optname(opt, flags));
35408df41e  90) return error(_("%s isn't available"), optname(opt, flags));
35408df41e  92) return error(_("%s takes no value"), optname(opt, flags));
35408df41e 178) return error(_("%s expects a numerical value"),
35408df41e 194) return error(_("%s expects a non-negative integer value"
e0948db833 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
e0948db833 651) error(_("unknown non-ascii option in string: `%s'"),
35408df41e 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

preload-index.c
31bfd155d8 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
5257b0625a  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
5257b0625a  676)     ce->name, alias->name);
5257b0625a  691) die(_("cannot create an empty blob in the object 
database"));
5257b0625a  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
5257b0625a  786) return error(_("unable to add '%s' to index"), path);
5257b0625a  822) error(_("invalid path '%s'"), path);
5257b0625a  848) error(_("invalid path '%s'"), path);
5257b0625a 1680) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
5257b0625a 1683) return error(_("bad index version %d"), hdr_version);
5257b0625a 1722) return error(_("index uses %.4s extension, which we do 
not understand"),
5257b0625a 1724) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
5257b0625a 1771) die(_("unknown index entry format 0x%08x"), 
extended_flags);
5257b0625a 1842) die(_("unordered stage entries in index"));
5257b0625a 1845) die(_("multiple stage entries for merged file '%s'"),
5257b0625a 1848) die(_("unordered stage entries for '%s'"),
5257b0625a 2142) die_errno(_("%s: index file open failed"), path);
5257b0625a 2146) die_errno(_("%s: cannot stat the open index"), path);
5257b0625a 2150) die(_("%s: index file smaller than expected"), path);
5257b0625a 2154) die_errno(_("%s: unable to map index file"), path);
5257b0625a 2246) warning(_("could not freshen shared index '%s'"), 
shared_index);
5257b0625a 2281) die(_("broken index, expect %s in %s, got %s"),
5257b0625a 3067) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
5257b0625a 3213) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
35408df41e 2324) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
a454d6a26b  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
a454d6a26b  417) error(_("more than one uploadpack given, using the 
first"));
a454d6a26b  683) die(_("key '%s' of pattern had no '*'"), key);
a454d6a26b  693) die(_("value '%s' of pattern has no '*'"), value);
a454d6a26b 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
a454d6a26b 1066) return error(_("dst ref %s receives from more than one 
src"),
a454d6a26b 1753) die(_("couldn't find remote ref %s"), name);
a454d6a26b 1766) error(_("* Ignoring funny ref '%s' locally"),
a454d6a26b 1861) die(_("revision walk setup failed"));
a454d6a26b 2134) return error(_("cannot parse expected object name '%s'"),

revision.c
a63d88e595 2932) return;
a63d88e595 2935) return;
a63d88e595 2941) c->object.flags |= UNINTERESTING;
a63d88e595 2944) return;
a63d88e595 2947) mark_parents_uninteresting(c);
a63d88e595 2970) return;
a63d88e595 2973) return;
a63d88e595 2978) return;
a63d88e595 3042) continue;
f33f8de6af 3090) if (!revs->ignore_missing_links)
f33f8de6af 3091) die("Failed to traverse parents of commit %s",
a63d88e595 3092) oid_to_hex(&commit->object.oid));
a63d88e595 3100) continue;

run-command.c
31bfd155d8 1229) error(_("cannot create async thread: %s"), strerror(err));

sequencer.c
08b6ba5cc0  683) np = strchrnul(buf, '\n');
08b6ba5cc0  684) return error(_("unable to parse '%.*s'"),
08b6ba5cc0  695) return error(_("unable to dequote value of '%s'"),
08b6ba5cc0  737) goto finish;
08b6ba5cc0  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
08b6ba5cc0  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
08b6ba5cc0  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
08b6ba5cc0  756) err = error(_("unknown variable '%s'"),
08b6ba5cc0  761) error(_("missing 'GIT_AUTHOR_NAME'"));
08b6ba5cc0  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
08b6ba5cc0  765) error(_("missing 'GIT_AUTHOR_DATE'"));

setup.c
58b284a2e9  413) return config_error_nonbool(var);

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      a63d88e59: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f33f8de6a: revision.c: begin refactoring 
--topo-order logic
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Junio C Hamano      3e582cd8a: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      09120ea78: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      31bfd155d: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      35408df41: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      389f2f2d7: grep: remove #ifdef NO_PTHREADS
Nguyễn Thái Ngọc Duy      48a40549d: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      5257b0625: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      847aa0ff7: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      a454d6a26: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      b63c352c1: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      b9c4009cc: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      e0948db83: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      eb6c5a15d: repack: mark more strings for 
translation
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Phillip Wood      08b6ba5cc: add read_author_script() to libgit



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
55071ea248   61) strbuf_trim(&out);
55071ea248   62) ret = !strcmp("true", out.buf);
55071ea248   63) strbuf_release(&out);
002ee2fe68  115) die(_("%s requires an interactive rebase"), option);
f95736288a  148) return error_errno(_("could not read '%s'"), path);
f95736288a  162) return -1;
f95736288a  167) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  178) return -1;
f95736288a  179) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  180) return -1;
f95736288a  182) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  186) return -1;
f95736288a  188) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  196) opts->signoff = 1;
73d51ed0a5  197) opts->flags |= REBASE_FORCE;
ead98c111b  204) return -1;
12026a412c  219) return -1;
ba1905a5fe  227) return -1;
ba1905a5fe  235) return -1;
6defce2b02  255) return error(_("Could not read '%s'"), path);
6defce2b02  273) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  277) return res;
bc24382c2b  375) argv_array_pushf(&child.args,
bc24382c2b  377) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  509) struct strbuf dir = STRBUF_INIT;
6defce2b02  511) apply_autostash(opts);
ac7f467fef  512) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  513) remove_dir_recursively(&dir, 0);
ac7f467fef  514) strbuf_release(&dir);
ac7f467fef  515) die("Nothing to do");
ac7f467fef  545) return -1;
ac7f467fef  549) rollback_lock_file(&lock);
ac7f467fef  550) return error(_("could not determine HEAD revision"));
ac7f467fef  567) rollback_lock_file(&lock);
ac7f467fef  568) return error(_("could not read index"));
ac7f467fef  572) error(_("failed to find tree of %s"), oid_to_hex(oid));
ac7f467fef  573) rollback_lock_file(&lock);
ac7f467fef  574) free((void *)desc.buffer);
ac7f467fef  575) return -1;
ac7f467fef  588) ret = error(_("could not write index"));
ac7f467fef  592) return ret;
ac7f467fef  608) } else if (old_orig)
ac7f467fef  609) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  637) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  671) return 1;
9a48a615b4  687) return 0;
55071ea248  895) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  898) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  899) die_errno(_("could not exec %s"), path);
0eabf4b95c  917) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  954) usage_with_options(builtin_rebase_usage,
f95736288a  974) die(_("Cannot read HEAD"));
f95736288a  978) die(_("could not read index"));
f95736288a  992) exit(1);
122420c295 1004) die(_("could not discard worktree changes"));
122420c295 1006) exit(1);
5e5d96197c 1017) exit(1);
5e5d96197c 1020) die(_("could not move back to %s"),
5a61494539 1030) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1049) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1050) const char *state_dir_base =
c54dacb50e 1051) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1052) const char *cmd_live_rebase =
c54dacb50e 1054) strbuf_reset(&buf);
c54dacb50e 1055) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1056) die(_("It seems that there is already a %s directory, 
and\n"
53f9e5be94 1080) strbuf_addstr(&options.git_am_opt, " --ignore-date");
53f9e5be94 1081) options.flags |= REBASE_FORCE;
7998dbe1ec 1093) strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
3c3588c7d3 1125) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1126) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1148) die(_("--strategy requires --merge or --interactive"));
cda614e489 1166) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1175) options.state_dir = apply_dir();
ac7f467fef 1176) break;
ac7f467fef 1253) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1259) die(_("Could not create new root commit"));
e65123a71d 1309) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1317) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1329) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1342) die(_("could not read index"));
6defce2b02 1369) die(_("Cannot autostash"));
6defce2b02 1372) die(_("Unexpected stash response: '%s'"),
6defce2b02 1378) die(_("Could not create directory for '%s'"),
6defce2b02 1384) die(_("could not reset --hard"));
e65123a71d 1428) ret = !!error(_("could not parse '%s'"),
e65123a71d 1430) goto cleanup;
e65123a71d 1439) ret = !!error(_("could not switch to "
1ed9c14ff2 1449)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1450) puts(_("HEAD is up to date."));
9a48a615b4 1459)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1460) puts(_("HEAD is up to date, rebase forced."));

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

gpg-interface.c
4de9394dcb 155) break;

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

sequencer.c
65850686cf 2278) return;
65850686cf 2375) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3373) return error(_("could not checkout %s"), commit);
4df66c40b0 3387) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3407) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4771) return -1;
b97e187364 4774) return -1;
b97e187364 4780) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4783) todo_list_release(&todo_list);
b97e187364 4784) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4803) todo_list_release(&todo_list);
b97e187364 4804) return -1;
b97e187364 4808) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4812) return error(_("could not transform the todo list"));
b97e187364 4841) return error(_("could not transform the todo list"));
b97e187364 4844) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4850) return -1;

strbuf.c
f95736288a  127) --sb->len;

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      53f9e5be9: builtin rebase: support `ignore-date` option
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      7998dbe1e: builtin rebase: support `-C` and 
`--whitespace=<type>`
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

apply.c
eccb5a5f3d 4071) return get_oid_hex(p->old_oid_prefix, oid);

builtin/repack.c
2f0c9e9a9b 239) die("repack: Expecting full hex object ID lines only 
from pack-objects.");
2f0c9e9a9b 411) die("repack: Expecting full hex object ID lines only 
from pack-objects.");

builtin/rev-list.c
7c0fe330d5 builtin/rev-list.c 227) die("unexpected missing %s object '%s'",
7c0fe330d5 builtin/rev-list.c 228)     type_name(obj->type), 
oid_to_hex(&obj->oid));

list-objects-filter-options.c
bc5975d24f  55) if (errbuf) {
bc5975d24f  56) strbuf_addstr(
bc5975d24f  60) return 1;
cc0b05a4cc  86) if (errbuf)

list-objects-filter.c
list-objects.c
f447a499db 200) ctx->show_object(obj, base->buf, ctx->show_data);

ref-filter.c
f0062d3b74 1035) v->s = xstrdup("");
f0062d3b74 1298) free((char *)to_free);
f0062d3b74 1299) return xstrdup("");
f0062d3b74 1336) free((char *)to_free);
f0062d3b74 1337) return xstrdup("");
f0062d3b74 1387) *s = xstrdup("=");
f0062d3b74 1389) *s = xstrdup("<");
f0062d3b74 1514) ref->symref = xstrdup("");
f0062d3b74 1583) v->s = xstrdup("");

Commits introducing uncovered code:
brian m. carlson      2f0c9e9a9: builtin/repack: replace hard-coded 
constants
brian m. carlson      eccb5a5f3: apply: rename new_sha1_prefix and 
old_sha1_prefix
Matthew DeVore      7c0fe330d: rev-list: handle missing tree objects 
properly
Matthew DeVore      bc5975d24: list-objects-filter: implement filter tree:0
Matthew DeVore      cc0b05a4c: list-objects-filter-options: do not 
over-strbuf_init
Matthew DeVore      f447a499d: list-objects: store common func args in 
struct
Olga Telezhnaya      f0062d3b7: ref-filter: free item->value and 
item->value->s

^ permalink raw reply	[relevance 3%]

* [PATCHv2 00/24] Bring more repository handles into our code base]
@ 2018-10-30 22:07 Stefan Beller
  2018-10-30 22:08 ` [PATCH 19/24] submodule: use submodule repos for object lookup Stefan Beller
                   ` (2 more replies)
  0 siblings, 3 replies; 200+ results
From: Stefan Beller @ 2018-10-30 22:07 UTC (permalink / raw)
  To: git; +Cc: szeder.dev, jonathantanmy, Stefan Beller

This resends sb/more-repo-in-api

On Thu, Oct 25, 2018 at 2:14 AM SZEDER Gábor <szeder.dev@gmail.com> wrote:
> On Tue, Oct 16, 2018 at 04:35:49PM -0700, Stefan Beller wrote:
> > This converts the 'show_submodule_header' function to use
> > the repository API properly, such that the submodule objects
> > are not added to the main object store.
>
> This patch breaks the test suite with 'GIT_TEST_COMMIT_GRAPH=1', in
> particular 't4041-diff-submodule-option.sh' fails with:
> [...]

I debugged into this and the last four patches will fix it.

I also picked up the patch for pending semantic patches, as the
first patch, can I have your sign off, please?

This also addresses Jonathans feedback in
https://public-inbox.org/git/20181019203750.110741-1-jonathantanmy@google.com/

A range-diff is below.

Thanks,
Stefan

SZEDER Gábor (1):
  Makefile: add pending semantic patches

Stefan Beller (23):
  sha1_file: allow read_object to read objects in arbitrary repositories
  packfile: allow has_packed_and_bad to handle arbitrary repositories
  object-store: allow read_object_file_extended to read from arbitrary
    repositories
  object-store: prepare read_object_file to deal with arbitrary
    repositories
  object-store: prepare has_{sha1, object}_file[_with_flags] to handle
    arbitrary repositories
  object: parse_object to honor its repository argument
  commit: allow parse_commit* to handle arbitrary repositories
  commit-reach.c: allow paint_down_to_common to handle arbitrary
    repositories
  commit-reach.c: allow merge_bases_many to handle arbitrary
    repositories
  commit-reach.c: allow remove_redundant to handle arbitrary
    repositories
  commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary
    repositories
  commit-reach: prepare get_merge_bases to handle arbitrary repositories
  commit-reach: prepare in_merge_bases[_many] to handle arbitrary
    repositories
  commit: prepare get_commit_buffer to handle arbitrary repositories
  commit: prepare repo_unuse_commit_buffer to handle arbitrary
    repositories
  commit: prepare logmsg_reencode to handle arbitrary repositories
  pretty: prepare format_commit_message to handle arbitrary repositories
  submodule: use submodule repos for object lookup
  submodule: don't add submodule as odb for push
  commit-graph: convert remaining function to handle arbitrary
    repositories
  commit: make free_commit_buffer and release_commit_memory repository
    agnostic
  path.h: make REPO_GIT_PATH_FUNC repository agnostic
  t/helper/test-repository: celebrate independence from the_repository

 Makefile                                      |   6 +-
 builtin/fsck.c                                |   3 +-
 builtin/log.c                                 |   6 +-
 builtin/rev-list.c                            |   3 +-
 cache.h                                       |   2 +
 commit-graph.c                                |  40 +++--
 commit-reach.c                                |  73 +++++----
 commit-reach.h                                |  38 +++--
 commit.c                                      |  41 ++---
 commit.h                                      |  43 +++++-
 .../coccinelle/the_repository.pending.cocci   | 144 ++++++++++++++++++
 object-store.h                                |  35 ++++-
 object.c                                      |   8 +-
 packfile.c                                    |   5 +-
 packfile.h                                    |   2 +-
 path.h                                        |   2 +-
 pretty.c                                      |  28 ++--
 pretty.h                                      |   7 +-
 sha1-file.c                                   |  34 +++--
 streaming.c                                   |   2 +-
 submodule.c                                   |  79 +++++++---
 t/helper/test-repository.c                    |  10 ++
 22 files changed, 459 insertions(+), 152 deletions(-)
 create mode 100644 contrib/coccinelle/the_repository.pending.cocci

git range-diff origin/sb/more-repo-in-api...
[...] # rebased to origin/master
  -:  ---------- > 116:  4ede3d42df Seventh batch for 2.20
  -:  ---------- > 117:  b1de196491 Makefile: add pending semantic patches
  1:  1b9b5c695e = 118:  f1be5eb487 sha1_file: allow read_object to read objects in arbitrary repositories
  2:  33b94066f2 = 119:  9100a5705d packfile: allow has_packed_and_bad to handle arbitrary repositories
  3:  5217b6b1e1 = 120:  a4ad7791da object-store: allow read_object_file_extended to read from arbitrary repositories
  4:  2b7239b55b ! 121:  5d7b3a6dd9 object-store: prepare read_object_file to deal with arbitrary repositories
    @@ -19,10 +19,10 @@
         Signed-off-by: Stefan Beller <sbeller@google.com>
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
      new file mode 100644
      --- /dev/null
    - +++ b/contrib/coccinelle/the_repository.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
     +// This file is used for the ongoing refactoring of
     +// bringing the index or repository struct in all of
    @@ -36,6 +36,7 @@
     +- read_object_file(
     ++ repo_read_object_file(the_repository,
     +  E, F, G)
    ++
     
      diff --git a/object-store.h b/object-store.h
      --- a/object-store.h
  5:  24291f4d84 ! 122:  77d406fc51 object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories
    @@ -3,16 +3,14 @@
         object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
    - - read_object_file(
      + repo_read_object_file(the_repository,
        E, F, G)
    -+
    + 
     +@@
     +expression E;
     +@@
  6:  6aa209978e = 123:  7224b378d8 object: parse_object to honor its repository argument
  7:  9b2d6aa7c3 ! 124:  e4d4ae08ca commit: allow parse_commit* to handle arbitrary repositories
    @@ -93,9 +93,9 @@
      
      struct buffer_slab;
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - has_object_file_with_flags(
      + repo_has_object_file_with_flags(the_repository,
  8:  0e7e681118 ! 125:  f739ef6078 commit-reach.c: allow paint_down_to_common to handle arbitrary repositories
    @@ -5,7 +5,6 @@
         As the function is file local and not widely used, migrate it all at once.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
  9:  e83b26f5b3 ! 126:  c054a80564 commit-reach.c: allow merge_bases_many to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit-reach.c: allow merge_bases_many to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
 10:  d80b9de832 ! 127:  3434a5a262 commit-reach.c: allow remove_redundant to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit-reach.c: allow remove_redundant to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
 11:  3ec21ad503 ! 128:  82f6e797bf commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
 12:  3f21279f50 ! 129:  b66b636a97 commit-reach: prepare get_merge_bases to handle arbitrary repositories
    @@ -9,7 +9,6 @@
         functions behind a wrapper macro.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
    @@ -91,9 +90,9 @@
      int is_descendant_of(struct commit *commit, struct commit_list *with_commit);
      int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - parse_commit(
      + repo_parse_commit(the_repository,
    @@ -124,3 +123,4 @@
     +- get_merge_bases_many_dirty(
     ++ repo_get_merge_bases_many_dirty(the_repository,
     +  E, F, G);
    ++
 13:  4decc3acc1 ! 130:  e68e48ca91 commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
    @@ -76,14 +75,13 @@
      /*
       * Takes a list of commits and returns a new list where those
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
    - - get_merge_bases_many_dirty(
      + repo_get_merge_bases_many_dirty(the_repository,
        E, F, G);
    -+
    + 
     +@@
     +expression E;
     +expression F;
 14:  141b86ea89 ! 131:  aac401ca98 commit: prepare get_commit_buffer to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit: prepare get_commit_buffer to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -46,9 +45,9 @@
      /*
       * Tell the commit subsytem that we are done with a particular commit buffer.
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - in_merge_bases_many(
      + repo_in_merge_bases_many(the_repository,
 15:  2cc415c1db ! 132:  c45e6d2c0c commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
    @@ -3,7 +3,6 @@
         commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -42,9 +41,9 @@
      /*
       * Free any cached object buffer associated with the commit.
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - get_commit_buffer(
      + repo_get_commit_buffer(the_repository,
 16:  554daa8cfc ! 133:  25e8f5dec4 commit: prepare logmsg_reencode to handle arbitrary repositories
    @@ -24,9 +24,9 @@
      
      /** Removes the first commit from a list sorted by date, and adds all
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - unuse_commit_buffer(
      + repo_unuse_commit_buffer(the_repository,
 17:  bd8737176b ! 134:  2cab6c18b6 pretty: prepare format_commit_message to handle arbitrary repositories
    @@ -5,9 +5,9 @@
         Signed-off-by: Stefan Beller <sbeller@google.com>
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - logmsg_reencode(
      + repo_logmsg_reencode(the_repository,
 18:  b303ef65e7 ! 135:  794592c573 submodule: use submodule repos for object lookup
    @@ -7,7 +7,6 @@
         are not added to the main object store.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/submodule.c b/submodule.c
      --- a/submodule.c
    @@ -46,24 +45,26 @@
     + * in .gitmodules. This function exists only to preserve historical behavior,
     + *
     + * Returns 0 on success, -1 when the submodule is not present.
    -+ */
    -+static int open_submodule(struct repository *out, const char *path)
    +  */
    +-static void show_submodule_header(struct diff_options *o, const char *path,
    ++static struct repository *open_submodule(const char *path)
     +{
     +	struct strbuf sb = STRBUF_INIT;
    ++	struct repository *out = xmalloc(sizeof(*out));
     +
     +	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
     +		strbuf_release(&sb);
    -+		return -1;
    ++		free(out);
    ++		return NULL;
     +	}
     +
    -+	out->submodule_prefix = xstrdup(path);
     +	out->submodule_prefix = xstrfmt("%s%s/",
     +					the_repository->submodule_prefix ?
     +					the_repository->submodule_prefix :
     +					"", path);
     +
     +	strbuf_release(&sb);
    -+	return 0;
    ++	return out;
     +}
     +
     +/*
    @@ -73,8 +74,7 @@
     + * If it can locate the submodule git directory it will create a repository
     + * handle for the submodule and lookup both the left and right commits and
     + * put them into the left and right pointers.
    -  */
    --static void show_submodule_header(struct diff_options *o, const char *path,
    ++ */
     +static void show_submodule_header(struct diff_options *o,
     +		const char *path,
      		struct object_id *one, struct object_id *two,
    @@ -116,11 +116,9 @@
      	struct rev_info rev;
      	struct commit *left = NULL, *right = NULL;
      	struct commit_list *merge_bases = NULL;
    -+	struct repository subrepo, *sub = &subrepo;
    -+
    -+	if (open_submodule(&subrepo, path) < 0)
    -+		sub = NULL;
    ++	struct repository *sub;
      
    ++	sub = open_submodule(path);
      	show_submodule_header(o, path, one, two, dirty_submodule,
     -			      &left, &right, &merge_bases);
     +			      sub, &left, &right, &merge_bases);
    @@ -147,8 +145,10 @@
      		free_commit_list(merge_bases);
      	clear_commit_marks(left, ~0);
      	clear_commit_marks(right, ~0);
    -+	if (sub)
    ++	if (sub) {
     +		repo_clear(sub);
    ++		free(sub);
    ++	}
      }
      
      void show_submodule_inline_diff(struct diff_options *o, const char *path,
    @@ -156,11 +156,9 @@
      	struct commit_list *merge_bases = NULL;
      	struct child_process cp = CHILD_PROCESS_INIT;
      	struct strbuf sb = STRBUF_INIT;
    -+	struct repository subrepo, *sub = &subrepo;
    -+
    -+	if (open_submodule(&subrepo, path) < 0)
    -+		sub = NULL;
    ++	struct repository *sub;
      
    ++	sub = open_submodule(path);
      	show_submodule_header(o, path, one, two, dirty_submodule,
     -			      &left, &right, &merge_bases);
     +			      sub, &left, &right, &merge_bases);
    @@ -171,8 +169,10 @@
      		clear_commit_marks(left, ~0);
      	if (right)
      		clear_commit_marks(right, ~0);
    -+	if (sub)
    ++	if (sub) {
     +		repo_clear(sub);
    ++		free(sub);
    ++	}
      }
      
      int should_update_submodules(void)
 19:  dbb0dd9322 ! 136:  df748a859f submodule: don't add submodule as odb for push
    @@ -8,8 +8,10 @@
         objects, and the actual push is done by spawning another process,
         which handles object access by itself.)
     
    +    This code of push_submodule() is exercised in t5531 and continues
    +    to work, showing that the submodule odbc is not needed.
    +
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/submodule.c b/submodule.c
      --- a/submodule.c
  -:  ---------- > 137:  c9e990afac commit-graph: convert remaining function to handle arbitrary repositories
  -:  ---------- > 138:  a086f3dd11 commit: make free_commit_buffer and release_commit_memory repository agnostic
  -:  ---------- > 139:  878bd34799 path.h: make REPO_GIT_PATH_FUNC repository agnostic
  -:  ---------- > 140:  641824bbeb t/helper/test-repository: celebrate independence from the_repository

^ permalink raw reply	[relevance 7%]

* [PATCH 19/24] submodule: use submodule repos for object lookup
  2018-10-30 22:07 [PATCHv2 00/24] Bring more repository handles into our code base] Stefan Beller
@ 2018-10-30 22:08 ` Stefan Beller
  2018-11-02 13:03   ` Derrick Stolee
  2018-10-30 22:08 ` [PATCH 20/24] submodule: don't add submodule as odb for push Stefan Beller
  2018-10-31  6:41 ` [PATCHv2 00/24] Bring more repository handles into our code base] Junio C Hamano
  2 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-10-30 22:08 UTC (permalink / raw)
  To: git; +Cc: szeder.dev, jonathantanmy, Stefan Beller

This converts the 'show_submodule_header' function to use
the repository API properly, such that the submodule objects
are not added to the main object store.

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

diff --git a/submodule.c b/submodule.c
index d9d3046689..0fdda45252 100644
--- a/submodule.c
+++ b/submodule.c
@@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
 	return prepare_revision_walk(rev);
 }
 
-static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
+static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
 {
 	static const char format[] = "  %m %s";
 	struct strbuf sb = STRBUF_INIT;
@@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
 		ctx.date_mode = rev->date_mode;
 		ctx.output_encoding = get_log_output_encoding();
 		strbuf_setlen(&sb, 0);
-		format_commit_message(commit, format, &sb, &ctx);
+		repo_format_commit_message(r, commit, format, &sb,
+				      &ctx);
 		strbuf_addch(&sb, '\n');
 		if (commit->object.flags & SYMMETRIC_LEFT)
 			diff_emit_submodule_del(o, sb.buf);
@@ -481,14 +482,47 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_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
- * left and right pointers.
+/*
+ * Initialize 'out' based on the provided submodule path.
+ *
+ * Unlike repo_submodule_init, this tolerates submodules not present
+ * in .gitmodules. This function exists only to preserve historical behavior,
+ *
+ * Returns 0 on success, -1 when the submodule is not present.
  */
-static void show_submodule_header(struct diff_options *o, const char *path,
+static struct repository *open_submodule(const char *path)
+{
+	struct strbuf sb = STRBUF_INIT;
+	struct repository *out = xmalloc(sizeof(*out));
+
+	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
+		strbuf_release(&sb);
+		free(out);
+		return NULL;
+	}
+
+	out->submodule_prefix = xstrfmt("%s%s/",
+					the_repository->submodule_prefix ?
+					the_repository->submodule_prefix :
+					"", path);
+
+	strbuf_release(&sb);
+	return out;
+}
+
+/*
+ * Helper function to display the submodule header line prior to the full
+ * summary output.
+ *
+ * If it can locate the submodule git directory it will create a repository
+ * handle for the submodule and lookup both the left and right commits and
+ * put them into the left and right pointers.
+ */
+static void show_submodule_header(struct diff_options *o,
+		const char *path,
 		struct object_id *one, struct object_id *two,
 		unsigned dirty_submodule,
+		struct repository *sub,
 		struct commit **left, struct commit **right,
 		struct commit_list **merge_bases)
 {
@@ -507,7 +541,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	else if (is_null_oid(two))
 		message = "(submodule deleted)";
 
-	if (add_submodule_odb(path)) {
+	if (!sub) {
 		if (!message)
 			message = "(commits not present)";
 		goto output_header;
@@ -517,8 +551,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	 * Attempt to lookup the commit references, and determine if this is
 	 * a fast forward or fast backwards update.
 	 */
-	*left = lookup_commit_reference(the_repository, one);
-	*right = lookup_commit_reference(the_repository, two);
+	*left = lookup_commit_reference(sub, one);
+	*right = lookup_commit_reference(sub, two);
 
 	/*
 	 * Warn about missing commits in the submodule project, but only if
@@ -528,7 +562,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	     (!is_null_oid(two) && !*right))
 		message = "(commits not present)";
 
-	*merge_bases = get_merge_bases(*left, *right);
+	*merge_bases = repo_get_merge_bases(sub, *left, *right);
 	if (*merge_bases) {
 		if ((*merge_bases)->item == *left)
 			fast_forward = 1;
@@ -562,16 +596,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 	struct rev_info rev;
 	struct commit *left = NULL, *right = NULL;
 	struct commit_list *merge_bases = NULL;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/*
 	 * If we don't have both a left and a right pointer, there is no
 	 * reason to try and display a summary. The header line should contain
 	 * all the information the user needs.
 	 */
-	if (!left || !right)
+	if (!left || !right || !sub)
 		goto out;
 
 	/* Treat revision walker failure the same as missing commits */
@@ -580,13 +616,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 		goto out;
 	}
 
-	print_submodule_summary(&rev, o);
+	print_submodule_summary(sub, &rev, o);
 
 out:
 	if (merge_bases)
 		free_commit_list(merge_bases);
 	clear_commit_marks(left, ~0);
 	clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 void show_submodule_inline_diff(struct diff_options *o, const char *path,
@@ -598,9 +638,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 	struct commit_list *merge_bases = NULL;
 	struct child_process cp = CHILD_PROCESS_INIT;
 	struct strbuf sb = STRBUF_INIT;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/* We need a valid left and right commit to display a difference */
 	if (!(left || is_null_oid(one)) ||
@@ -661,6 +703,10 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 		clear_commit_marks(left, ~0);
 	if (right)
 		clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 int should_update_submodules(void)
-- 
2.19.1.930.g4563a0d9d0-goog


^ permalink raw reply	[relevance 20%]

* [PATCH 20/24] submodule: don't add submodule as odb for push
  2018-10-30 22:07 [PATCHv2 00/24] Bring more repository handles into our code base] Stefan Beller
  2018-10-30 22:08 ` [PATCH 19/24] submodule: use submodule repos for object lookup Stefan Beller
@ 2018-10-30 22:08 ` Stefan Beller
  2018-10-31  6:41 ` [PATCHv2 00/24] Bring more repository handles into our code base] Junio C Hamano
  2 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-10-30 22:08 UTC (permalink / raw)
  To: git; +Cc: szeder.dev, jonathantanmy, Stefan Beller

In push_submodule(), because we do not actually need access to objects
in the submodule, do not invoke add_submodule_odb().
(for_each_remote_ref_submodule() does not require access to those
objects, and the actual push is done by spawning another process,
which handles object access by itself.)

This code of push_submodule() is exercised in t5531 and continues
to work, showing that the submodule odbc is not needed.

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

diff --git a/submodule.c b/submodule.c
index 0fdda45252..da1ac1e6f8 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1024,9 +1024,6 @@ static int push_submodule(const char *path,
 			  const struct string_list *push_options,
 			  int dry_run)
 {
-	if (add_submodule_odb(path))
-		return 1;
-
 	if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
 		struct child_process cp = CHILD_PROCESS_INIT;
 		argv_array_push(&cp.args, "push");
-- 
2.19.1.930.g4563a0d9d0-goog


^ permalink raw reply	[relevance 14%]

* Re: [PATCHv2 00/24] Bring more repository handles into our code base]
  2018-10-30 22:07 [PATCHv2 00/24] Bring more repository handles into our code base] Stefan Beller
  2018-10-30 22:08 ` [PATCH 19/24] submodule: use submodule repos for object lookup Stefan Beller
  2018-10-30 22:08 ` [PATCH 20/24] submodule: don't add submodule as odb for push Stefan Beller
@ 2018-10-31  6:41 ` Junio C Hamano
  2 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-10-31  6:41 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, szeder.dev, jonathantanmy

Stefan Beller <sbeller@google.com> writes:

> I also picked up the patch for pending semantic patches, as the
> first patch, can I have your sign off, please?

I find this step quite lacking.  

What was posted would have been perfectly fine as a "how about doing
it this way" weatherbaloon patch, but as a part of real series, it
needs to explain to the developers what the distinctions between two
classes are, and who is to use the cocci patch at what point in the
development cycle, etc., in an accompanying documentation update.

So can we have both sign-off and write-up (perhaps cut&paste from
the original e-mail discussion)?

> Stefan Beller (23):
>   sha1_file: allow read_object to read objects in arbitrary repositories
>   packfile: allow has_packed_and_bad to handle arbitrary repositories
>   object-store: allow read_object_file_extended to read from arbitrary
>     repositories
>   object-store: prepare read_object_file to deal with arbitrary
>     repositories
>   object-store: prepare has_{sha1, object}_file[_with_flags] to handle
>     arbitrary repositories
>   object: parse_object to honor its repository argument
>   commit: allow parse_commit* to handle arbitrary repositories
>   commit-reach.c: allow paint_down_to_common to handle arbitrary
>     repositories
>   commit-reach.c: allow merge_bases_many to handle arbitrary
>     repositories
>   commit-reach.c: allow remove_redundant to handle arbitrary
>     repositories
>   commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary
>     repositories
>   commit-reach: prepare get_merge_bases to handle arbitrary repositories
>   commit-reach: prepare in_merge_bases[_many] to handle arbitrary
>     repositories
>   commit: prepare get_commit_buffer to handle arbitrary repositories
>   commit: prepare repo_unuse_commit_buffer to handle arbitrary
>     repositories
>   commit: prepare logmsg_reencode to handle arbitrary repositories
>   pretty: prepare format_commit_message to handle arbitrary repositories
>   submodule: use submodule repos for object lookup
>   submodule: don't add submodule as odb for push
>   commit-graph: convert remaining function to handle arbitrary
>     repositories
>   commit: make free_commit_buffer and release_commit_memory repository
>     agnostic
>   path.h: make REPO_GIT_PATH_FUNC repository agnostic
>   t/helper/test-repository: celebrate independence from the_repository

It seems that this topic is full of commits with overly long title.

>
>  Makefile                                      |   6 +-
>  builtin/fsck.c                                |   3 +-
>  builtin/log.c                                 |   6 +-
>  builtin/rev-list.c                            |   3 +-
>  cache.h                                       |   2 +
>  commit-graph.c                                |  40 +++--
>  commit-reach.c                                |  73 +++++----
>  commit-reach.h                                |  38 +++--
>  commit.c                                      |  41 ++---
>  commit.h                                      |  43 +++++-
>  .../coccinelle/the_repository.pending.cocci   | 144 ++++++++++++++++++
>  object-store.h                                |  35 ++++-
>  object.c                                      |   8 +-
>  packfile.c                                    |   5 +-
>  packfile.h                                    |   2 +-
>  path.h                                        |   2 +-
>  pretty.c                                      |  28 ++--
>  pretty.h                                      |   7 +-
>  sha1-file.c                                   |  34 +++--
>  streaming.c                                   |   2 +-
>  submodule.c                                   |  79 +++++++---
>  t/helper/test-repository.c                    |  10 ++
>  22 files changed, 459 insertions(+), 152 deletions(-)
>  create mode 100644 contrib/coccinelle/the_repository.pending.cocci
>
> git range-diff origin/sb/more-repo-in-api...
> [...] # rebased to origin/master

I offhand do not recall what happened during these 100+ pacthes.
DId we acquire something significantly new that would have
conflicted with this new round of the topic?  I do not mind at all
seeing that a series gets adjusted to the updated codebase, but I do
dislike seeing it done without explanation---an unexplained rebase
to a new base is a wasted opportunity to learn what areas of the
codebase are so hot that multiple and separate topics would want to
touch them.

>   -:  ---------- > 116:  4ede3d42df Seventh batch for 2.20
>   -:  ---------- > 117:  b1de196491 Makefile: add pending semantic patches
>   1:  1b9b5c695e = 118:  f1be5eb487 sha1_file: allow read_object to read objects in arbitrary repositories
>   2:  33b94066f2 = 119:  9100a5705d packfile: allow has_packed_and_bad to handle arbitrary repositories
>   3:  5217b6b1e1 = 120:  a4ad7791da object-store: allow read_object_file_extended to read from arbitrary repositories
>   4:  2b7239b55b ! 121:  5d7b3a6dd9 object-store: prepare read_object_file to deal with arbitrary repositories
>     @@ -19,10 +19,10 @@
>          Signed-off-by: Stefan Beller <sbeller@google.com>
>          Signed-off-by: Junio C Hamano <gitster@pobox.com>
>      
>     - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
>     + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
>       new file mode 100644
>       --- /dev/null
>     - +++ b/contrib/coccinelle/the_repository.cocci
>     + +++ b/contrib/coccinelle/the_repository.pending.cocci
>      @@
>      +// This file is used for the ongoing refactoring of
>      +// bringing the index or repository struct in all of
>     @@ -36,6 +36,7 @@
>      +- read_object_file(
>      ++ repo_read_object_file(the_repository,
>      +  E, F, G)
>     ++

Is it necessary for this file to end with a trailing blank line?



Thanks.

^ permalink raw reply	[relevance 2%]

* Re: [PATCH 18/19] submodule: use submodule repos for object lookup
  2018-10-16 23:35 ` [PATCH 18/19] submodule: use submodule repos for object lookup Stefan Beller
  2018-10-25  9:14   ` SZEDER Gábor
@ 2018-10-31 13:38   ` Derrick Stolee
  2018-11-01 19:13     ` Stefan Beller
  1 sibling, 1 reply; 200+ results
From: Derrick Stolee @ 2018-10-31 13:38 UTC (permalink / raw)
  To: Stefan Beller, git; +Cc: jonathantanmy

On 10/16/2018 7:35 PM, Stefan Beller wrote:
> @@ -482,14 +483,46 @@ void prepare_submodule_repo_env(struct argv_array *out)
>   			 DEFAULT_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
> - * left and right pointers.
> +/*
> + * Initialize 'out' based on the provided submodule path.
> + *
> + * Unlike repo_submodule_init, this tolerates submodules not present
> + * in .gitmodules. This function exists only to preserve historical behavior,
> + *
> + * Returns 0 on success, -1 when the submodule is not present.
> + */
> +static int open_submodule(struct repository *out, const char *path)
> +{
> +	struct strbuf sb = STRBUF_INIT;
> +
> +	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
> +		strbuf_release(&sb);
> +		return -1;
> +	}
> +
> +	out->submodule_prefix = xstrdup(path);
> +	out->submodule_prefix = xstrfmt("%s%s/",
> +					the_repository->submodule_prefix ?
> +					the_repository->submodule_prefix :
> +					"", path);
> +
> +	strbuf_release(&sb);
> +	return 0;
> +}

Based on the recent test coverage report [1], this xstrfmt() call is never
run witha non-null the_repository->submodule_prefix. Is there a way we can
exercise that branch?

Thanks,
-Stolee

[1] 
https://public-inbox.org/git/62f0bcf6-aa73-c192-d804-e6d69cac146f@gmail.com/

^ permalink raw reply	[relevance 5%]

* Git Test Coverage Report (Thursday, Nov 1) Part A
@ 2018-11-01 16:15 Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-01 16:15 UTC (permalink / raw)
  To: Git List

Today's test report doesn't contain any information for the 'master'
branch because the ref was not updated before this run (see 'master' and
'master@{1}' are the same below). If 'master' updates today, then I will
rerun the build and send the report for new lines in 'next' and 'master'.

Thanks,
-Stolee

[1] https://git.visualstudio.com/git/_build/results?buildId=237&view=logs

---

pu: f86906bb5aab712b2a63746c4a643efd6ce19d5b
jch: ce1cd767b7bb0e53083d26b4d60257e3ec0eaeb4
next: 0c4a18a71f0e8e4f10970951c5f8875f429eaef7
master: 4ede3d42dfb57f9a41ac96a1f216c62eb7566cc2
master@{1}: 4ede3d42dfb57f9a41ac96a1f216c62eb7566cc2

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
f86906bb5a builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    924) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    925) break;

builtin/describe.c
f86906bb5a builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/fsck.c
209830491c builtin/fsck.c 622) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
209830491c builtin/fsck.c 627) return error(_("invalid %s"), head_ref_name);

builtin/grep.c
76e9bdc437 builtin/grep.c  429) grep_read_unlock();

builtin/pack-objects.c
f86906bb5a builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 585) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 621) continue;

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fsck.c
f86906bb5a  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
f86906bb5a  878) repo_read_object_file(the_repository,
f86906bb5a  879)       &tag->object.oid, &type, &size);

http-push.c
f86906bb5a 1635) if (!repo_has_object_file(the_repository, &head_oid))
f86906bb5a 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

merge-recursive.c
4cdc48e412 1585) return -1;
4cdc48e412 1588) return -1;
4cdc48e412 1594) return -1;
4cdc48e412 1596) if (update_file(o, 1, b_oid, b_mode, collide_path))
4cdc48e412 1597) return -1;
4cdc48e412 1664) return -1;
4cdc48e412 1667) return -1;
4cdc48e412 1670) return -1;
b58ae691c0 1703) return -1;
387361a6a7 1738) return -1;
387361a6a7 1786) return -1;
387361a6a7 1795) new_path = unique_path(o, a->path, ci->branch1);
387361a6a7 1796) output(o, 1, _("Refusing to lose untracked file"
387361a6a7 1802) return -1;
387361a6a7 1805) return -1;
387361a6a7 1815) return -1;
387361a6a7 1831) return -1;
387361a6a7 1834) return -1;

negotiator/default.c
f86906bb5a  71) if (repo_parse_commit(the_repository, commit))

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
f86906bb5a  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
f86906bb5a 1624) repo_unuse_commit_buffer(the_repository, head_commit,
f86906bb5a 3868) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule-config.c
bcbc780d14 740) return CONFIG_INVALID_KEY;
45f5ef3d77 755) warning(_("Could not update .gitmodules entry %s"), key);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
e2419f7e30 1378) strbuf_release(&gitdir);
7454fe5cb6 1501) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1505) get_next_submodule_task_release(task);
7454fe5cb6 1532) return 0;
7454fe5cb6 1536) goto out;
7454fe5cb6 1551) return 0;

tree.c
f86906bb5a 108) if (repo_parse_commit(the_repository, commit))

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Elijah Newren      387361a6a: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      4cdc48e41: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      b58ae691c: merge-recursive: fix rename/add conflict 
handling
Junio C Hamano      209830491: Merge branch 
'nd/per-worktree-ref-iteration' into pu
Junio C Hamano      f86906bb5: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

archive.c
48a40549d5 399) die(_("'%s' is not a valid object name"), name);
48a40549d5 412) die(_("%s is not a tree object"), oid_to_hex(&oid));
48a40549d5 422) die(_("current working directory is untracked"));

attr.c
847aa0ff7a  369) fprintf(stderr, _("%s not allowed: %s:%d\n"),

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));

builtin/fetch.c
builtin/fsck.c
09120ea781 builtin/fsck.c 154) objerror(parent, _("wrong object type in 
link"));
09120ea781 builtin/fsck.c 265) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
09120ea781 builtin/fsck.c 293) error(_("could not create lost-found"));
09120ea781 builtin/fsck.c 300) die_errno(_("could not write '%s'"), 
filename);
09120ea781 builtin/fsck.c 304) die_errno(_("could not finish '%s'"),
09120ea781 builtin/fsck.c 321) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
09120ea781 builtin/fsck.c 339) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
09120ea781 builtin/fsck.c 358) fprintf_ln(stderr, _("Checking %s %s"),
09120ea781 builtin/fsck.c 371) printf_ln(_("root %s"),
09120ea781 builtin/fsck.c 407) return error(_("%s: object corrupt or 
missing"),
09120ea781 builtin/fsck.c 446) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
09120ea781 builtin/fsck.c 545) error(_("%s: object could not be parsed: 
%s"),
09120ea781 builtin/fsck.c 580) fprintf_ln(stderr, _("Checking object 
directory"));
09120ea781 builtin/fsck.c 596) fprintf_ln(stderr, _("Checking HEAD link"));
09120ea781 builtin/fsck.c 601) return error(_("invalid HEAD"));
09120ea781 builtin/fsck.c 628) fprintf_ln(stderr, _("Checking cache tree"));
09120ea781 builtin/fsck.c 644) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/grep.c
389f2f2d79 builtin/grep.c 1034) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/merge.c
35408df41e builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/reflog.c
b9c4009cca builtin/reflog.c 563) usage(_(reflog_expire_usage));
b9c4009cca builtin/reflog.c 605) status |= error(_("%s points 
nowhere!"), argv[i]);
b9c4009cca builtin/reflog.c 651) usage(_(reflog_delete_usage));
b9c4009cca builtin/reflog.c 657) return error(_("nothing to delete?"));
b9c4009cca builtin/reflog.c 666) status |= error(_("not a reflog: %s"), 
argv[i]);
b9c4009cca builtin/reflog.c 671) status |= error(_("no reflog for 
'%s'"), argv[i]);
b9c4009cca builtin/reflog.c 706) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 714) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 717) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
eb6c5a15dc 200) die(_("could not start pack-objects to repack promisor 
objects"));
479fbb285c 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
eb6c5a15dc 250) die_errno(("unable to create '%s'"), promisor_name);
479fbb285c 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

git.c
b63c352c11 341) die_errno(_("while expanding alias '%s': '%s'"),
b63c352c11 350) die(_("alias '%s' changes environment variables.\n"
b63c352c11 358) die(_("empty alias for %s"), alias_command);
b63c352c11 361) die(_("recursive alias: %s"), alias_command);
b63c352c11 436) die_errno(_("write failure on standard output"));
b63c352c11 438) die(_("unknown write failure on standard output"));
b63c352c11 440) die_errno(_("close failed on standard output"));
b63c352c11 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

midx.c
1dcd9f2043  184) return;

name-hash.c
31bfd155d8 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
31bfd155d8 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
31bfd155d8 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

parse-options-cb.c
35408df41e  21) return error(_("option `%s' expects a numerical value"),
35408df41e  58) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
35408df41e  88) return error(_("%s takes no value"), optname(opt, flags));
35408df41e  90) return error(_("%s isn't available"), optname(opt, flags));
35408df41e  92) return error(_("%s takes no value"), optname(opt, flags));
35408df41e 178) return error(_("%s expects a numerical value"),
35408df41e 194) return error(_("%s expects a non-negative integer value"
e0948db833 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
e0948db833 651) error(_("unknown non-ascii option in string: `%s'"),
35408df41e 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

preload-index.c
31bfd155d8 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
5257b0625a  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
5257b0625a  676)     ce->name, alias->name);
5257b0625a  691) die(_("cannot create an empty blob in the object 
database"));
5257b0625a  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
5257b0625a  786) return error(_("unable to add '%s' to index"), path);
5257b0625a  822) error(_("invalid path '%s'"), path);
5257b0625a  848) error(_("invalid path '%s'"), path);
5257b0625a 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
5257b0625a 1689) return error(_("bad index version %d"), hdr_version);
5257b0625a 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
5257b0625a 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
5257b0625a 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
5257b0625a 1848) die(_("unordered stage entries in index"));
5257b0625a 1851) die(_("multiple stage entries for merged file '%s'"),
5257b0625a 1854) die(_("unordered stage entries for '%s'"),
5257b0625a 2148) die_errno(_("%s: index file open failed"), path);
5257b0625a 2152) die_errno(_("%s: cannot stat the open index"), path);
5257b0625a 2156) die(_("%s: index file smaller than expected"), path);
5257b0625a 2160) die_errno(_("%s: unable to map index file"), path);
5257b0625a 2252) warning(_("could not freshen shared index '%s'"), 
shared_index);
5257b0625a 2287) die(_("broken index, expect %s in %s, got %s"),
5257b0625a 3073) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
5257b0625a 3219) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
35408df41e 2324) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
a454d6a26b  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
a454d6a26b  417) error(_("more than one uploadpack given, using the 
first"));
a454d6a26b  683) die(_("key '%s' of pattern had no '*'"), key);
a454d6a26b  693) die(_("value '%s' of pattern has no '*'"), value);
a454d6a26b 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
a454d6a26b 1066) return error(_("dst ref %s receives from more than one 
src"),
a454d6a26b 1753) die(_("couldn't find remote ref %s"), name);
a454d6a26b 1766) error(_("* Ignoring funny ref '%s' locally"),
a454d6a26b 1861) die(_("revision walk setup failed"));
a454d6a26b 2134) return error(_("cannot parse expected object name '%s'"),

revision.c
a63d88e595 2932) return;
a63d88e595 2935) return;
a63d88e595 2941) c->object.flags |= UNINTERESTING;
a63d88e595 2944) return;
a63d88e595 2947) mark_parents_uninteresting(c);
a63d88e595 2970) return;
a63d88e595 2973) return;
a63d88e595 2978) return;
a63d88e595 3042) continue;
f33f8de6af 3090) if (!revs->ignore_missing_links)
f33f8de6af 3091) die("Failed to traverse parents of commit %s",
a63d88e595 3092) oid_to_hex(&commit->object.oid));
a63d88e595 3100) continue;

run-command.c
31bfd155d8 1229) error(_("cannot create async thread: %s"), strerror(err));

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      a63d88e59: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f33f8de6a: revision.c: begin refactoring 
--topo-order logic
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Junio C Hamano      479fbb285: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      09120ea78: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      31bfd155d: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      35408df41: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      389f2f2d7: grep: remove #ifdef NO_PTHREADS
Nguyễn Thái Ngọc Duy      48a40549d: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      5257b0625: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      847aa0ff7: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      a454d6a26: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      b63c352c1: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      b9c4009cc: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      e0948db83: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      eb6c5a15d: repack: mark more strings for 
translation
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Phillip Wood      bcd33ec25: add read_author_script() to libgit



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
55071ea248   61) strbuf_trim(&out);
55071ea248   62) ret = !strcmp("true", out.buf);
55071ea248   63) strbuf_release(&out);
002ee2fe68  115) die(_("%s requires an interactive rebase"), option);
f95736288a  148) return error_errno(_("could not read '%s'"), path);
f95736288a  162) return -1;
f95736288a  167) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  178) return -1;
f95736288a  179) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  180) return -1;
f95736288a  182) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  186) return -1;
f95736288a  188) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  196) opts->signoff = 1;
73d51ed0a5  197) opts->flags |= REBASE_FORCE;
ead98c111b  204) return -1;
12026a412c  219) return -1;
ba1905a5fe  227) return -1;
ba1905a5fe  235) return -1;
6defce2b02  255) return error(_("Could not read '%s'"), path);
6defce2b02  273) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  277) return res;
bc24382c2b  375) argv_array_pushf(&child.args,
bc24382c2b  377) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  509) struct strbuf dir = STRBUF_INIT;
6defce2b02  511) apply_autostash(opts);
ac7f467fef  512) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  513) remove_dir_recursively(&dir, 0);
ac7f467fef  514) strbuf_release(&dir);
ac7f467fef  515) die("Nothing to do");
ac7f467fef  545) return -1;
ac7f467fef  549) rollback_lock_file(&lock);
ac7f467fef  550) return error(_("could not determine HEAD revision"));
ac7f467fef  567) rollback_lock_file(&lock);
ac7f467fef  568) return error(_("could not read index"));
ac7f467fef  572) error(_("failed to find tree of %s"), oid_to_hex(oid));
ac7f467fef  573) rollback_lock_file(&lock);
ac7f467fef  574) free((void *)desc.buffer);
ac7f467fef  575) return -1;
ac7f467fef  588) ret = error(_("could not write index"));
ac7f467fef  592) return ret;
ac7f467fef  608) } else if (old_orig)
ac7f467fef  609) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  637) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  671) return 1;
9a48a615b4  687) return 0;
55071ea248  895) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  898) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  899) die_errno(_("could not exec %s"), path);
0eabf4b95c  917) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  954) usage_with_options(builtin_rebase_usage,
f95736288a  974) die(_("Cannot read HEAD"));
f95736288a  978) die(_("could not read index"));
f95736288a  992) exit(1);
122420c295 1004) die(_("could not discard worktree changes"));
122420c295 1006) exit(1);
5e5d96197c 1017) exit(1);
5e5d96197c 1020) die(_("could not move back to %s"),
5a61494539 1030) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1049) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1050) const char *state_dir_base =
c54dacb50e 1051) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1052) const char *cmd_live_rebase =
c54dacb50e 1054) strbuf_reset(&buf);
c54dacb50e 1055) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1056) die(_("It seems that there is already a %s directory, 
and\n"
53f9e5be94 1080) strbuf_addstr(&options.git_am_opt, " --ignore-date");
53f9e5be94 1081) options.flags |= REBASE_FORCE;
7998dbe1ec 1093) strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
3c3588c7d3 1125) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1126) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1148) die(_("--strategy requires --merge or --interactive"));
cda614e489 1166) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1175) options.state_dir = apply_dir();
ac7f467fef 1176) break;
ac7f467fef 1253) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1259) die(_("Could not create new root commit"));
e65123a71d 1309) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1317) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1329) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1342) die(_("could not read index"));
6defce2b02 1369) die(_("Cannot autostash"));
6defce2b02 1372) die(_("Unexpected stash response: '%s'"),
6defce2b02 1378) die(_("Could not create directory for '%s'"),
6defce2b02 1384) die(_("could not reset --hard"));
e65123a71d 1428) ret = !!error(_("could not parse '%s'"),
e65123a71d 1430) goto cleanup;
e65123a71d 1439) ret = !!error(_("could not switch to "
1ed9c14ff2 1449)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1450) puts(_("HEAD is up to date."));
9a48a615b4 1459)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1460) puts(_("HEAD is up to date, rebase forced."));

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

gpg-interface.c
4de9394dcb 155) break;

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

sequencer.c
65850686cf 2279) return;
65850686cf 2376) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3374) return error(_("could not checkout %s"), commit);
4df66c40b0 3388) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3408) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4772) return -1;
b97e187364 4775) return -1;
b97e187364 4781) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4784) todo_list_release(&todo_list);
b97e187364 4785) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4804) todo_list_release(&todo_list);
b97e187364 4805) return -1;
b97e187364 4809) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4813) return error(_("could not transform the todo list"));
b97e187364 4842) return error(_("could not transform the todo list"));
b97e187364 4845) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4851) return -1;

setup.c
58b284a2e9  413) return config_error_nonbool(var);

strbuf.c
f95736288a  127) --sb->len;

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      53f9e5be9: builtin rebase: support `ignore-date` option
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      7998dbe1e: builtin rebase: support `-C` and 
`--whitespace=<type>`
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed


^ permalink raw reply	[relevance 3%]

* Re: [PATCH 18/19] submodule: use submodule repos for object lookup
  2018-10-31 13:38   ` Derrick Stolee
@ 2018-11-01 19:13     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-01 19:13 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: git, Jonathan Tan

On Wed, Oct 31, 2018 at 6:38 AM Derrick Stolee <stolee@gmail.com> wrote:
>
> On 10/16/2018 7:35 PM, Stefan Beller wrote:
> > @@ -482,14 +483,46 @@ void prepare_submodule_repo_env(struct argv_array *out)
> >                        DEFAULT_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
> > - * left and right pointers.
> > +/*
> > + * Initialize 'out' based on the provided submodule path.
> > + *
> > + * Unlike repo_submodule_init, this tolerates submodules not present
> > + * in .gitmodules. This function exists only to preserve historical behavior,
> > + *
> > + * Returns 0 on success, -1 when the submodule is not present.
> > + */
> > +static int open_submodule(struct repository *out, const char *path)
> > +{
> > +     struct strbuf sb = STRBUF_INIT;
> > +
> > +     if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
> > +             strbuf_release(&sb);
> > +             return -1;
> > +     }
> > +
> > +     out->submodule_prefix = xstrdup(path);
> > +     out->submodule_prefix = xstrfmt("%s%s/",
> > +                                     the_repository->submodule_prefix ?
> > +                                     the_repository->submodule_prefix :
> > +                                     "", path);
> > +
> > +     strbuf_release(&sb);
> > +     return 0;
> > +}
>
> Based on the recent test coverage report [1], this xstrfmt() call is never
> run witha non-null the_repository->submodule_prefix. Is there a way we can
> exercise that branch?

No it's dead code, actually. the_repository never has submodule_prefix set
as it is the main repository. So this is overly cautious to enable the
'any repo'
case.
In a resend we'll go with xstrdup(path);

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 19/24] submodule: use submodule repos for object lookup
  2018-10-30 22:08 ` [PATCH 19/24] submodule: use submodule repos for object lookup Stefan Beller
@ 2018-11-02 13:03   ` Derrick Stolee
  2018-11-02 17:23     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Derrick Stolee @ 2018-11-02 13:03 UTC (permalink / raw)
  To: Stefan Beller, git; +Cc: szeder.dev, jonathantanmy

On 10/30/2018 6:08 PM, Stefan Beller wrote:
> This converts the 'show_submodule_header' function to use
> the repository API properly, such that the submodule objects
> are not added to the main object store.
>
> Signed-off-by: Stefan Beller <sbeller@google.com>

A couple tests are broken in 'pu' when run with GIT_TEST_COMMIT_GRAPH=1, 
including t4041-diff-submodule-option.sh. The failure bisects to this patch.

Here is a verbose output of the first failure in that script:;


expecting success:
         git diff-index -p --submodule=log HEAD >actual &&
         cat >expected <<-EOF &&
         Submodule sm1 $head2..$head3 (rewind):
           < Add foo3 ($added foo3)
           < Add foo2 ($added foo2)
         EOF
         test_cmp expected actual

+ git diff-index -p --submodule=log HEAD
+ cat
+ test_cmp expected actual
+ diff -u expected actual
--- expected    2018-11-02 12:58:43.429262380 +0000
+++ actual      2018-11-02 12:58:43.429262380 +0000
@@ -1,3 +1,5 @@
-Submodule sm1 30b9670..dafb207 (rewind):
+Submodule sm1 30b9670...dafb207:
    < Add foo3 (hinzugefügt foo3)
    < Add foo2 (hinzugefügt foo2)
+  > Add foo1 (hinzugefügt foo1)
+  < Add foo1 (hinzugefügt foo1)
error: last command exited with $?=1
not ok 9 - modified submodule(backward)

I've been looking into the patch below to see if there is an obvious 
problem, but the best I can think is that open_submodule() creates an 
alternate 'struct repository' and somehow the commit-graph feature is 
interacting poorly with that struct.

Stefan, do you know what's going on?

Thanks,

-Stolee

> ---
>   submodule.c | 76 ++++++++++++++++++++++++++++++++++++++++++-----------
>   1 file changed, 61 insertions(+), 15 deletions(-)
>
> diff --git a/submodule.c b/submodule.c
> index d9d3046689..0fdda45252 100644
> --- a/submodule.c
> +++ b/submodule.c
> @@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
>   	return prepare_revision_walk(rev);
>   }
>   
> -static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
> +static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
>   {
>   	static const char format[] = "  %m %s";
>   	struct strbuf sb = STRBUF_INIT;
> @@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
>   		ctx.date_mode = rev->date_mode;
>   		ctx.output_encoding = get_log_output_encoding();
>   		strbuf_setlen(&sb, 0);
> -		format_commit_message(commit, format, &sb, &ctx);
> +		repo_format_commit_message(r, commit, format, &sb,
> +				      &ctx);
>   		strbuf_addch(&sb, '\n');
>   		if (commit->object.flags & SYMMETRIC_LEFT)
>   			diff_emit_submodule_del(o, sb.buf);
> @@ -481,14 +482,47 @@ void prepare_submodule_repo_env(struct argv_array *out)
>   			 DEFAULT_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
> - * left and right pointers.
> +/*
> + * Initialize 'out' based on the provided submodule path.
> + *
> + * Unlike repo_submodule_init, this tolerates submodules not present
> + * in .gitmodules. This function exists only to preserve historical behavior,
> + *
> + * Returns 0 on success, -1 when the submodule is not present.
>    */
> -static void show_submodule_header(struct diff_options *o, const char *path,
> +static struct repository *open_submodule(const char *path)
> +{
> +	struct strbuf sb = STRBUF_INIT;
> +	struct repository *out = xmalloc(sizeof(*out));
> +
> +	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
> +		strbuf_release(&sb);
> +		free(out);
> +		return NULL;
> +	}
> +
> +	out->submodule_prefix = xstrfmt("%s%s/",
> +					the_repository->submodule_prefix ?
> +					the_repository->submodule_prefix :
> +					"", path);
> +
> +	strbuf_release(&sb);
> +	return out;
> +}
> +
> +/*
> + * Helper function to display the submodule header line prior to the full
> + * summary output.
> + *
> + * If it can locate the submodule git directory it will create a repository
> + * handle for the submodule and lookup both the left and right commits and
> + * put them into the left and right pointers.
> + */
> +static void show_submodule_header(struct diff_options *o,
> +		const char *path,
>   		struct object_id *one, struct object_id *two,
>   		unsigned dirty_submodule,
> +		struct repository *sub,
>   		struct commit **left, struct commit **right,
>   		struct commit_list **merge_bases)
>   {
> @@ -507,7 +541,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
>   	else if (is_null_oid(two))
>   		message = "(submodule deleted)";
>   
> -	if (add_submodule_odb(path)) {
> +	if (!sub) {
>   		if (!message)
>   			message = "(commits not present)";
>   		goto output_header;
> @@ -517,8 +551,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
>   	 * Attempt to lookup the commit references, and determine if this is
>   	 * a fast forward or fast backwards update.
>   	 */
> -	*left = lookup_commit_reference(the_repository, one);
> -	*right = lookup_commit_reference(the_repository, two);
> +	*left = lookup_commit_reference(sub, one);
> +	*right = lookup_commit_reference(sub, two);
>   
>   	/*
>   	 * Warn about missing commits in the submodule project, but only if
> @@ -528,7 +562,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
>   	     (!is_null_oid(two) && !*right))
>   		message = "(commits not present)";
>   
> -	*merge_bases = get_merge_bases(*left, *right);
> +	*merge_bases = repo_get_merge_bases(sub, *left, *right);
>   	if (*merge_bases) {
>   		if ((*merge_bases)->item == *left)
>   			fast_forward = 1;
> @@ -562,16 +596,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
>   	struct rev_info rev;
>   	struct commit *left = NULL, *right = NULL;
>   	struct commit_list *merge_bases = NULL;
> +	struct repository *sub;
>   
> +	sub = open_submodule(path);
>   	show_submodule_header(o, path, one, two, dirty_submodule,
> -			      &left, &right, &merge_bases);
> +			      sub, &left, &right, &merge_bases);
>   
>   	/*
>   	 * If we don't have both a left and a right pointer, there is no
>   	 * reason to try and display a summary. The header line should contain
>   	 * all the information the user needs.
>   	 */
> -	if (!left || !right)
> +	if (!left || !right || !sub)
>   		goto out;
>   
>   	/* Treat revision walker failure the same as missing commits */
> @@ -580,13 +616,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
>   		goto out;
>   	}
>   
> -	print_submodule_summary(&rev, o);
> +	print_submodule_summary(sub, &rev, o);
>   
>   out:
>   	if (merge_bases)
>   		free_commit_list(merge_bases);
>   	clear_commit_marks(left, ~0);
>   	clear_commit_marks(right, ~0);
> +	if (sub) {
> +		repo_clear(sub);
> +		free(sub);
> +	}
>   }
>   
>   void show_submodule_inline_diff(struct diff_options *o, const char *path,
> @@ -598,9 +638,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
>   	struct commit_list *merge_bases = NULL;
>   	struct child_process cp = CHILD_PROCESS_INIT;
>   	struct strbuf sb = STRBUF_INIT;
> +	struct repository *sub;
>   
> +	sub = open_submodule(path);
>   	show_submodule_header(o, path, one, two, dirty_submodule,
> -			      &left, &right, &merge_bases);
> +			      sub, &left, &right, &merge_bases);
>   
>   	/* We need a valid left and right commit to display a difference */
>   	if (!(left || is_null_oid(one)) ||
> @@ -661,6 +703,10 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
>   		clear_commit_marks(left, ~0);
>   	if (right)
>   		clear_commit_marks(right, ~0);
> +	if (sub) {
> +		repo_clear(sub);
> +		free(sub);
> +	}
>   }
>   
>   int should_update_submodules(void)

^ permalink raw reply	[relevance 8%]

* Re: submodule support in git-bundle
      [irrelevant] <CACsJy8AVfkWsAP_-CNd5RSbQ=tyCzdw-ix1k5zwmAKaj+z1qXw@mail.gmail.com>
@ 2018-11-02 17:08 ` Stefan Beller
  2018-11-02 18:34   ` Duy Nguyen
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-02 17:08 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

On Fri, Nov 2, 2018 at 9:10 AM Duy Nguyen <pclouds@gmail.com> wrote:
>
> I use git-bundle today and it occurs to me that if I want to use it to
> transfer part of a history that involves submodule changes, things
> aren't pretty. Has anybody given thought on how to do binary history
> transfer that contains changes from submodules?
>
> Since .bundle files are basically .pack files, i'm not sure if it's
> easy to bundle multiple pack files (one per repo)...

That is a really good discussion starter!

As bundles are modeled after the fetch protocol, I would
redirect the discussion there.

The new fetch protocol could support sending more than
one pack, which could be for both the superproject as
well as the relevant submodule updates (i.e. what is recorded
in the superproject) based on a new capability.

We at Google have given this idea some thought, but from a
different angle: As you may know currently Android uses the
repo tool, which we want to replace with Gits native submodules
eventually. The repo tool tests for each repository to clone if
there is a bundle file for that repository, such that instead of
cloning the repo, the bundle can be downloaded and then
a catch-up fetch can be performed. (This helps the Git servers
as well as the client, the bundle can be hosted on a CDN,
which is faster and cheaper than a git server for us).

So we've given some thought on extending the packfiles in the
fetch protocol to have some redirection to a CDN possible,
i.e. instead of sending bytes as is, you get more or less a "todo"
list, which might be
    (a) take the following bytes as is (current pack format)
    (b) download these other bytes from $THERE
        (possibly with a checksum)
once the stream of bytes is assembled, it will look like a regular
packfile with deltas etc.

This offloading-to-CDN (or "mostly resumable clone" in the
sense that the communication with the server is minimal, and
you get most of your data via resumable http range-requests)
sounds like complete offtopic, but is one of the requirements
for the repo to submodule migration, hence I came to speak of it.

Did you have other things in mind, on a higher level?
e.g. querying the bundle and creating submodule bundles
based off the superproject bundle? 'git bundle create' could
learn the --recurse-submodules option, which then produces
multiple bundle files without changing the file formats.

Stefan

^ permalink raw reply	[relevance 7%]

* Re: [PATCH 19/24] submodule: use submodule repos for object lookup
  2018-11-02 13:03   ` Derrick Stolee
@ 2018-11-02 17:23     ` Stefan Beller
  2018-11-02 17:27       ` Derrick Stolee
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-02 17:23 UTC (permalink / raw)
  To: Derrick Stolee; +Cc: git, SZEDER Gábor, Jonathan Tan

On Fri, Nov 2, 2018 at 6:03 AM Derrick Stolee <stolee@gmail.com> wrote:
>
> On 10/30/2018 6:08 PM, Stefan Beller wrote:
> > This converts the 'show_submodule_header' function to use
> > the repository API properly, such that the submodule objects
> > are not added to the main object store.
> >
> > Signed-off-by: Stefan Beller <sbeller@google.com>
>
> A couple tests are broken in 'pu' when run with GIT_TEST_COMMIT_GRAPH=1,
> including t4041-diff-submodule-option.sh. The failure bisects to this patch.
>
> Here is a verbose output of the first failure in that script:;
>
>
> expecting success:
>          git diff-index -p --submodule=log HEAD >actual &&
>          cat >expected <<-EOF &&
>          Submodule sm1 $head2..$head3 (rewind):
>            < Add foo3 ($added foo3)
>            < Add foo2 ($added foo2)
>          EOF
>          test_cmp expected actual
>
> + git diff-index -p --submodule=log HEAD
> + cat
> + test_cmp expected actual
> + diff -u expected actual
> --- expected    2018-11-02 12:58:43.429262380 +0000
> +++ actual      2018-11-02 12:58:43.429262380 +0000
> @@ -1,3 +1,5 @@
> -Submodule sm1 30b9670..dafb207 (rewind):
> +Submodule sm1 30b9670...dafb207:
>     < Add foo3 (hinzugefügt foo3)
>     < Add foo2 (hinzugefügt foo2)
> +  > Add foo1 (hinzugefügt foo1)
> +  < Add foo1 (hinzugefügt foo1)
> error: last command exited with $?=1
> not ok 9 - modified submodule(backward)
>
> I've been looking into the patch below to see if there is an obvious
> problem, but the best I can think is that open_submodule() creates an
> alternate 'struct repository' and somehow the commit-graph feature is
> interacting poorly with that struct.
>
> Stefan, do you know what's going on?

Sure, see the last four patches of this series
https://public-inbox.org/git/20181030220817.61691-1-sbeller@google.com/
(to which you also reply to? Junio did not queue this one, yet).

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 19/24] submodule: use submodule repos for object lookup
  2018-11-02 17:23     ` Stefan Beller
@ 2018-11-02 17:27       ` Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-02 17:27 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, SZEDER Gábor, Jonathan Tan

On 11/2/2018 1:23 PM, Stefan Beller wrote:
> On Fri, Nov 2, 2018 at 6:03 AM Derrick Stolee <stolee@gmail.com> wrote:
>> On 10/30/2018 6:08 PM, Stefan Beller wrote:
>>> This converts the 'show_submodule_header' function to use
>>> the repository API properly, such that the submodule objects
>>> are not added to the main object store.
>>>
>>> Signed-off-by: Stefan Beller <sbeller@google.com>
>> A couple tests are broken in 'pu' when run with GIT_TEST_COMMIT_GRAPH=1,
>> including t4041-diff-submodule-option.sh. The failure bisects to this patch.
>>
>> Here is a verbose output of the first failure in that script:;
>>
>>
>> expecting success:
>>           git diff-index -p --submodule=log HEAD >actual &&
>>           cat >expected <<-EOF &&
>>           Submodule sm1 $head2..$head3 (rewind):
>>             < Add foo3 ($added foo3)
>>             < Add foo2 ($added foo2)
>>           EOF
>>           test_cmp expected actual
>>
>> + git diff-index -p --submodule=log HEAD
>> + cat
>> + test_cmp expected actual
>> + diff -u expected actual
>> --- expected    2018-11-02 12:58:43.429262380 +0000
>> +++ actual      2018-11-02 12:58:43.429262380 +0000
>> @@ -1,3 +1,5 @@
>> -Submodule sm1 30b9670..dafb207 (rewind):
>> +Submodule sm1 30b9670...dafb207:
>>      < Add foo3 (hinzugefügt foo3)
>>      < Add foo2 (hinzugefügt foo2)
>> +  > Add foo1 (hinzugefügt foo1)
>> +  < Add foo1 (hinzugefügt foo1)
>> error: last command exited with $?=1
>> not ok 9 - modified submodule(backward)
>>
>> I've been looking into the patch below to see if there is an obvious
>> problem, but the best I can think is that open_submodule() creates an
>> alternate 'struct repository' and somehow the commit-graph feature is
>> interacting poorly with that struct.
>>
>> Stefan, do you know what's going on?
> Sure, see the last four patches of this series
> https://public-inbox.org/git/20181030220817.61691-1-sbeller@google.com/
> (to which you also reply to? Junio did not queue this one, yet).

Sorry! Got a bit mixed up looking at everything. I didn't realize that 
the current 'pu' didn't have your latest. Thanks!


^ permalink raw reply	[relevance 5%]

* Re: submodule support in git-bundle
  2018-11-02 17:08 ` submodule support in git-bundle Stefan Beller
@ 2018-11-02 18:34   ` Duy Nguyen
  2018-11-02 19:00     ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Duy Nguyen @ 2018-11-02 18:34 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Git Mailing List

On Fri, Nov 2, 2018 at 6:09 PM Stefan Beller <sbeller@google.com> wrote:
>
> On Fri, Nov 2, 2018 at 9:10 AM Duy Nguyen <pclouds@gmail.com> wrote:
> >
> > I use git-bundle today and it occurs to me that if I want to use it to
> > transfer part of a history that involves submodule changes, things
> > aren't pretty. Has anybody given thought on how to do binary history
> > transfer that contains changes from submodules?
> >
> > Since .bundle files are basically .pack files, i'm not sure if it's
> > easy to bundle multiple pack files (one per repo)...
>
> That is a really good discussion starter!
>
> As bundles are modeled after the fetch protocol, I would
> redirect the discussion there.
>
> The new fetch protocol could support sending more than
> one pack, which could be for both the superproject as
> well as the relevant submodule updates (i.e. what is recorded
> in the superproject) based on a new capability.
>
> We at Google have given this idea some thought, but from a
> different angle: As you may know currently Android uses the
> repo tool, which we want to replace with Gits native submodules
> eventually. The repo tool tests for each repository to clone if
> there is a bundle file for that repository, such that instead of
> cloning the repo, the bundle can be downloaded and then
> a catch-up fetch can be performed. (This helps the Git servers
> as well as the client, the bundle can be hosted on a CDN,
> which is faster and cheaper than a git server for us).
>
> So we've given some thought on extending the packfiles in the
> fetch protocol to have some redirection to a CDN possible,
> i.e. instead of sending bytes as is, you get more or less a "todo"
> list, which might be
>     (a) take the following bytes as is (current pack format)
>     (b) download these other bytes from $THERE
>         (possibly with a checksum)
> once the stream of bytes is assembled, it will look like a regular
> packfile with deltas etc.
>
> This offloading-to-CDN (or "mostly resumable clone" in the
> sense that the communication with the server is minimal, and
> you get most of your data via resumable http range-requests)
> sounds like complete offtopic, but is one of the requirements
> for the repo to submodule migration, hence I came to speak of it.

Hm.. so what you're saying is, we could have a pack file that lists
other (real) pack files and for the bundle case they are all in the
same file. And "download from $THERE" in this case is "download at
this file offset"? That might actually work.

> Did you have other things in mind, on a higher level?
> e.g. querying the bundle and creating submodule bundles
> based off the superproject bundle? 'git bundle create' could
> learn the --recurse-submodules option, which then produces
> multiple bundle files without changing the file formats.

This is probably the simplest way to support submodules. I just
haven't really thought much about it (the problem just came up to me
like 2 hours ago). Two problems with this are convenience (I don't
want to handle multiple files) and submodule info (which pack should
be unbundled on which submodule?). But I suppose if "git bundle"
produces a tarball of these bundle files then you solve both.

But of course there may be other and better options like what you
described above. If in long term we have "pack with hyperlinks" anyway
for resumable clone and other fancy stuff then reusing the same
mechanism for bundles makes sense, less maintenance burden.
-- 
Duy

^ permalink raw reply	[relevance 7%]

* Re: submodule support in git-bundle
  2018-11-02 18:34   ` Duy Nguyen
@ 2018-11-02 19:00     ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-02 19:00 UTC (permalink / raw)
  To: Duy Nguyen; +Cc: git

> > This offloading-to-CDN (or "mostly resumable clone" in the
> > sense that the communication with the server is minimal, and
> > you get most of your data via resumable http range-requests)
> > sounds like complete offtopic, but is one of the requirements
> > for the repo to submodule migration, hence I came to speak of it.
>
> Hm.. so what you're saying is, we could have a pack file that lists
> other (real) pack files and for the bundle case they are all in the
> same file. And "download from $THERE" in this case is "download at
> this file offset"? That might actually work.

We're conflating 2 things here.
This idea of CDN offloading has nothing to do with submodules, it's
just a general thing to improve the fetch protocol.
And the pointed at file doesn't need to be a "real" packfile, as long
as the bytestream at the end looks like a real packfile. For example
the bytes to get from $THERE would not need to have a pack header
(or if it had, I would ask you to omit the first bytes containing the header)
as I can give the header myself.

The idea for submodules is more along the lines of having "just"
multiple pack files in the stream. For the bundle case we would
probably not have redirection to $THERE in there, as it should
be self contained completely (we don't know if the bundle recipient
can access $THERE in a timely manner).


> > Did you have other things in mind, on a higher level?
> > e.g. querying the bundle and creating submodule bundles
> > based off the superproject bundle? 'git bundle create' could
> > learn the --recurse-submodules option, which then produces
> > multiple bundle files without changing the file formats.
>
> This is probably the simplest way to support submodules.

Yep, that sounds simplest, but I think it makes for bad UX.
(Multiple files, need to be kept in some order and applied correctly)


> I just
> haven't really thought much about it (the problem just came up to me
> like 2 hours ago). Two problems with this are convenience (I don't
> want to handle multiple files) and submodule info (which pack should
> be unbundled on which submodule?). But I suppose if "git bundle"
> produces a tarball of these bundle files then you solve both.

The tarball makes it one file and would naturally provide some
order. It feels iffy, I'd rather have multiple packs in the bundle.

> But of course there may be other and better options like what you
> described above. If in long term we have "pack with hyperlinks" anyway
> for resumable clone and other fancy stuff then reusing the same
> mechanism for bundles makes sense, less maintenance burden.

I think of the hyperlinks in packs as an orthogonal feature, but closely
nearby in code and implementation, which is why I brought it up.

^ permalink raw reply	[relevance 7%]

* Git Test Coverage Report (Friday, Nov 2)
@ 2018-11-03  2:16 Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-03  2:16 UTC (permalink / raw)
  To: git

Here is the coverage report for today. Some builds were timing out, so I 
removed the tests with number 9000 or more from the build [1]. Hopefully 
this is a temporary measure.

Thanks,

-Stolee

[1] 
https://dev.azure.com/git/git/_build/results?buildId=250&_a=summary&view=logs

---

pu: 44234e885f450a57812806cefe0d4aa3f43f2800
jch: 35594a3ecc09908facb9790ba3817ad08d2af8e1
next: 96ac06677ac950c97d331f0ef4892125027eff39
master: d582ea202b626dcc6c3b01e1e11a296d9badd730
master@{1}: 4ede3d42dfb57f9a41ac96a1f216c62eb7566cc2

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
44234e885f builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    924) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    925) break;

builtin/describe.c
44234e885f builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/fsck.c
255a564e58 builtin/fsck.c 622) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
255a564e58 builtin/fsck.c 627) return error(_("invalid %s"), head_ref_name);

builtin/grep.c
76e9bdc437 builtin/grep.c  429) grep_read_unlock();

builtin/pack-objects.c
44234e885f builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 585) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 621) continue;

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fast-import.c
44234e885f 2935) buf = repo_read_object_file(the_repository, oid, &type, 
&size);
44234e885f 3041) buf = repo_read_object_file(the_repository, oid, &unused,

fsck.c
44234e885f  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
44234e885f  878) repo_read_object_file(the_repository,
44234e885f  879)       &tag->object.oid, &type, &size);

http-push.c
44234e885f 1635) if (!repo_has_object_file(the_repository, &head_oid))
44234e885f 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

merge-recursive.c
4cdc48e412 1585) return -1;
4cdc48e412 1588) return -1;
4cdc48e412 1594) return -1;
4cdc48e412 1596) if (update_file(o, 1, b_oid, b_mode, collide_path))
4cdc48e412 1597) return -1;
4cdc48e412 1664) return -1;
4cdc48e412 1667) return -1;
4cdc48e412 1670) return -1;
b58ae691c0 1703) return -1;
387361a6a7 1738) return -1;
387361a6a7 1786) return -1;
387361a6a7 1795) new_path = unique_path(o, a->path, ci->branch1);
387361a6a7 1796) output(o, 1, _("Refusing to lose untracked file"
387361a6a7 1802) return -1;
387361a6a7 1805) return -1;
387361a6a7 1815) return -1;
387361a6a7 1831) return -1;
387361a6a7 1834) return -1;

negotiator/default.c
44234e885f  71) if (repo_parse_commit(the_repository, commit))

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
44234e885f  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
44234e885f 1624) repo_unuse_commit_buffer(the_repository, head_commit,
44234e885f 3868) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule-config.c
bcbc780d14 740) return CONFIG_INVALID_KEY;
45f5ef3d77 755) warning(_("Could not update .gitmodules entry %s"), key);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
e2419f7e30 1378) strbuf_release(&gitdir);
7454fe5cb6 1501) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1505) get_next_submodule_task_release(task);
7454fe5cb6 1532) return 0;
7454fe5cb6 1536) goto out;
7454fe5cb6 1551) return 0;

tree.c
44234e885f 108) if (repo_parse_commit(the_repository, commit))

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Elijah Newren      387361a6a: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      4cdc48e41: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      b58ae691c: merge-recursive: fix rename/add conflict 
handling
Junio C Hamano      255a564e5: Merge branch 
'nd/per-worktree-ref-iteration' into pu
Junio C Hamano      44234e885: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

archive.c
48a40549d5 399) die(_("'%s' is not a valid object name"), name);
48a40549d5 412) die(_("%s is not a tree object"), oid_to_hex(&oid));
48a40549d5 422) die(_("current working directory is untracked"));

attr.c
847aa0ff7a  369) fprintf(stderr, _("%s not allowed: %s:%d\n"),

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));

builtin/fetch.c
builtin/fsck.c
09120ea781 builtin/fsck.c 154) objerror(parent, _("wrong object type in 
link"));
09120ea781 builtin/fsck.c 265) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
09120ea781 builtin/fsck.c 293) error(_("could not create lost-found"));
09120ea781 builtin/fsck.c 300) die_errno(_("could not write '%s'"), 
filename);
09120ea781 builtin/fsck.c 304) die_errno(_("could not finish '%s'"),
09120ea781 builtin/fsck.c 321) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
09120ea781 builtin/fsck.c 339) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
09120ea781 builtin/fsck.c 358) fprintf_ln(stderr, _("Checking %s %s"),
09120ea781 builtin/fsck.c 371) printf_ln(_("root %s"),
09120ea781 builtin/fsck.c 407) return error(_("%s: object corrupt or 
missing"),
09120ea781 builtin/fsck.c 446) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
09120ea781 builtin/fsck.c 545) error(_("%s: object could not be parsed: 
%s"),
09120ea781 builtin/fsck.c 580) fprintf_ln(stderr, _("Checking object 
directory"));
09120ea781 builtin/fsck.c 596) fprintf_ln(stderr, _("Checking HEAD link"));
09120ea781 builtin/fsck.c 601) return error(_("invalid HEAD"));
09120ea781 builtin/fsck.c 628) fprintf_ln(stderr, _("Checking cache tree"));
09120ea781 builtin/fsck.c 644) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/grep.c
389f2f2d79 builtin/grep.c 1034) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/merge.c
35408df41e builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/reflog.c
b9c4009cca builtin/reflog.c 563) usage(_(reflog_expire_usage));
b9c4009cca builtin/reflog.c 605) status |= error(_("%s points 
nowhere!"), argv[i]);
b9c4009cca builtin/reflog.c 651) usage(_(reflog_delete_usage));
b9c4009cca builtin/reflog.c 657) return error(_("nothing to delete?"));
b9c4009cca builtin/reflog.c 666) status |= error(_("not a reflog: %s"), 
argv[i]);
b9c4009cca builtin/reflog.c 671) status |= error(_("no reflog for 
'%s'"), argv[i]);
b9c4009cca builtin/reflog.c 706) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 714) usage(_(reflog_exists_usage));
b9c4009cca builtin/reflog.c 717) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
eb6c5a15dc 200) die(_("could not start pack-objects to repack promisor 
objects"));
55b48d6630 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
eb6c5a15dc 250) die_errno(("unable to create '%s'"), promisor_name);
55b48d6630 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

combine-diff.c
3bf45e7f67  377) state->sline[state->nb-1].p_lno =
3bf45e7f67  378) xcalloc(state->num_parent, sizeof(unsigned long));

date.c
c27cc94fad  904) tm->tm_mon = number-1;
c27cc94fad  908) else if (number > 69 && number < 100)
c27cc94fad  909) tm->tm_year = number;
c27cc94fad  910) else if (number < 38)
c27cc94fad  911) tm->tm_year = 100 + number;
c27cc94fad  952) pending_number(tm, num);

dir.c
8a2c174677  287) name = to_free = xmemdupz(name, namelen);

git.c
b63c352c11 341) die_errno(_("while expanding alias '%s': '%s'"),
b63c352c11 350) die(_("alias '%s' changes environment variables.\n"
b63c352c11 358) die(_("empty alias for %s"), alias_command);
b63c352c11 361) die(_("recursive alias: %s"), alias_command);
b63c352c11 436) die_errno(_("write failure on standard output"));
b63c352c11 438) die(_("unknown write failure on standard output"));
b63c352c11 440) die_errno(_("close failed on standard output"));
b63c352c11 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

midx.c
1dcd9f2043  184) return;

name-hash.c
31bfd155d8 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
31bfd155d8 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
31bfd155d8 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

parse-options-cb.c
35408df41e  21) return error(_("option `%s' expects a numerical value"),
35408df41e  58) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
35408df41e  88) return error(_("%s takes no value"), optname(opt, flags));
35408df41e  90) return error(_("%s isn't available"), optname(opt, flags));
35408df41e  92) return error(_("%s takes no value"), optname(opt, flags));
35408df41e 178) return error(_("%s expects a numerical value"),
35408df41e 194) return error(_("%s expects a non-negative integer value"
e0948db833 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
e0948db833 651) error(_("unknown non-ascii option in string: `%s'"),
35408df41e 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

preload-index.c
31bfd155d8 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
5257b0625a  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
5257b0625a  676)     ce->name, alias->name);
5257b0625a  691) die(_("cannot create an empty blob in the object 
database"));
5257b0625a  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
5257b0625a  786) return error(_("unable to add '%s' to index"), path);
5257b0625a  822) error(_("invalid path '%s'"), path);
5257b0625a  848) error(_("invalid path '%s'"), path);
5257b0625a 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
5257b0625a 1689) return error(_("bad index version %d"), hdr_version);
5257b0625a 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
5257b0625a 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
5257b0625a 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
5257b0625a 1848) die(_("unordered stage entries in index"));
5257b0625a 1851) die(_("multiple stage entries for merged file '%s'"),
5257b0625a 1854) die(_("unordered stage entries for '%s'"),
5257b0625a 2148) die_errno(_("%s: index file open failed"), path);
5257b0625a 2152) die_errno(_("%s: cannot stat the open index"), path);
5257b0625a 2156) die(_("%s: index file smaller than expected"), path);
5257b0625a 2160) die_errno(_("%s: unable to map index file"), path);
5257b0625a 2252) warning(_("could not freshen shared index '%s'"), 
shared_index);
5257b0625a 2287) die(_("broken index, expect %s in %s, got %s"),
5257b0625a 3073) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
5257b0625a 3219) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
35408df41e 2324) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
a454d6a26b  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
a454d6a26b  417) error(_("more than one uploadpack given, using the 
first"));
a454d6a26b  683) die(_("key '%s' of pattern had no '*'"), key);
a454d6a26b  693) die(_("value '%s' of pattern has no '*'"), value);
a454d6a26b 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
a454d6a26b 1066) return error(_("dst ref %s receives from more than one 
src"),
a454d6a26b 1753) die(_("couldn't find remote ref %s"), name);
a454d6a26b 1766) error(_("* Ignoring funny ref '%s' locally"),
a454d6a26b 1861) die(_("revision walk setup failed"));
a454d6a26b 2134) return error(_("cannot parse expected object name '%s'"),

revision.c
b45424181e 2936) return;
b45424181e 2939) return;
b45424181e 2945) c->object.flags |= UNINTERESTING;
b45424181e 2948) return;
b45424181e 2951) mark_parents_uninteresting(c);
b45424181e 2974) return;
b45424181e 2977) return;
b45424181e 3042) continue;
f0d9cc4196 3091) if (!revs->ignore_missing_links)
f0d9cc4196 3092) die("Failed to traverse parents of commit %s",
f0d9cc4196 3093)     oid_to_hex(&commit->object.oid));
b45424181e 3101) continue;

run-command.c
31bfd155d8 1229) error(_("cannot create async thread: %s"), strerror(err));

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

xdiff-interface.c
xdiff/xutils.c
611e42a598 405) return -1;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Jeff King      3bf45e7f6: combine-diff: use an xdiff hunk callback
Jeff King      611e42a59: xdiff: provide a separate emit callback for hunks
Jeff King      8a2c17467: pathspec: handle non-terminated strings with 
:(attr)
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Jeff King      c27cc94fa: approxidate: handle pending number for "specials"
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Junio C Hamano      55b48d663: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      09120ea78: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      31bfd155d: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      35408df41: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      389f2f2d7: grep: remove #ifdef NO_PTHREADS
Nguyễn Thái Ngọc Duy      48a40549d: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      5257b0625: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      847aa0ff7: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      a454d6a26: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      b63c352c1: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      b9c4009cc: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      e0948db83: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      eb6c5a15d: repack: mark more strings for 
translation
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Phillip Wood      bcd33ec25: add read_author_script() to libgit



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

gpg-interface.c
4de9394dcb 155) break;

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

setup.c
58b284a2e9  413) return config_error_nonbool(var);

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
55071ea248   61) strbuf_trim(&out);
55071ea248   62) ret = !strcmp("true", out.buf);
55071ea248   63) strbuf_release(&out);
002ee2fe68  115) die(_("%s requires an interactive rebase"), option);
f95736288a  148) return error_errno(_("could not read '%s'"), path);
f95736288a  162) return -1;
f95736288a  167) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  178) return -1;
f95736288a  179) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  180) return -1;
f95736288a  182) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  186) return -1;
f95736288a  188) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  196) opts->signoff = 1;
73d51ed0a5  197) opts->flags |= REBASE_FORCE;
ead98c111b  204) return -1;
12026a412c  219) return -1;
ba1905a5fe  227) return -1;
ba1905a5fe  235) return -1;
6defce2b02  255) return error(_("Could not read '%s'"), path);
6defce2b02  273) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  277) return res;
bc24382c2b  375) argv_array_pushf(&child.args,
bc24382c2b  377) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  509) struct strbuf dir = STRBUF_INIT;
6defce2b02  511) apply_autostash(opts);
ac7f467fef  512) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  513) remove_dir_recursively(&dir, 0);
ac7f467fef  514) strbuf_release(&dir);
ac7f467fef  515) die("Nothing to do");
ac7f467fef  545) return -1;
ac7f467fef  549) rollback_lock_file(&lock);
ac7f467fef  550) return error(_("could not determine HEAD revision"));
ac7f467fef  567) rollback_lock_file(&lock);
ac7f467fef  568) return error(_("could not read index"));
ac7f467fef  572) error(_("failed to find tree of %s"), oid_to_hex(oid));
ac7f467fef  573) rollback_lock_file(&lock);
ac7f467fef  574) free((void *)desc.buffer);
ac7f467fef  575) return -1;
ac7f467fef  588) ret = error(_("could not write index"));
ac7f467fef  592) return ret;
ac7f467fef  608) } else if (old_orig)
ac7f467fef  609) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  637) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  671) return 1;
9a48a615b4  687) return 0;
55071ea248  895) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  898) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  899) die_errno(_("could not exec %s"), path);
0eabf4b95c  917) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  954) usage_with_options(builtin_rebase_usage,
f95736288a  974) die(_("Cannot read HEAD"));
f95736288a  978) die(_("could not read index"));
f95736288a  992) exit(1);
122420c295 1004) die(_("could not discard worktree changes"));
122420c295 1006) exit(1);
5e5d96197c 1017) exit(1);
5e5d96197c 1020) die(_("could not move back to %s"),
5a61494539 1030) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1049) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1050) const char *state_dir_base =
c54dacb50e 1051) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1052) const char *cmd_live_rebase =
c54dacb50e 1054) strbuf_reset(&buf);
c54dacb50e 1055) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1056) die(_("It seems that there is already a %s directory, 
and\n"
53f9e5be94 1080) strbuf_addstr(&options.git_am_opt, " --ignore-date");
53f9e5be94 1081) options.flags |= REBASE_FORCE;
7998dbe1ec 1093) strbuf_addf(&options.git_am_opt, " -C%d", opt_c);
3c3588c7d3 1125) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1126) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1148) die(_("--strategy requires --merge or --interactive"));
cda614e489 1166) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1175) options.state_dir = apply_dir();
ac7f467fef 1176) break;
ac7f467fef 1253) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1259) die(_("Could not create new root commit"));
e65123a71d 1309) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1317) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1329) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1342) die(_("could not read index"));
6defce2b02 1369) die(_("Cannot autostash"));
6defce2b02 1372) die(_("Unexpected stash response: '%s'"),
6defce2b02 1378) die(_("Could not create directory for '%s'"),
6defce2b02 1384) die(_("could not reset --hard"));
e65123a71d 1428) ret = !!error(_("could not parse '%s'"),
e65123a71d 1430) goto cleanup;
e65123a71d 1439) ret = !!error(_("could not switch to "
1ed9c14ff2 1449)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1450) puts(_("HEAD is up to date."));
9a48a615b4 1459)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1460) puts(_("HEAD is up to date, rebase forced."));

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

sequencer.c
65850686cf 2279) return;
65850686cf 2376) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3374) return error(_("could not checkout %s"), commit);
4df66c40b0 3388) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3408) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4772) return -1;
b97e187364 4775) return -1;
b97e187364 4781) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4784) todo_list_release(&todo_list);
b97e187364 4785) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4804) todo_list_release(&todo_list);
b97e187364 4805) return -1;
b97e187364 4809) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4813) return error(_("could not transform the todo list"));
b97e187364 4842) return error(_("could not transform the todo list"));
b97e187364 4845) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4851) return -1;

strbuf.c
f95736288a  127) --sb->len;

Commits introducing uncovered code:
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      53f9e5be9: builtin rebase: support `ignore-date` option
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      7998dbe1e: builtin rebase: support `-C` and 
`--whitespace=<type>`
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue




^ permalink raw reply	[relevance 3%]

* Re: [PATCH] gitk: don't highlight submodule diff lines outside submodule diffs
      [irrelevant] <20181106195417.5456-1-dpb@corrigendum.ru>
@ 2018-11-06 20:06 ` Stefan Beller
  2018-11-06 21:56   ` Роман Донченко
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-06 20:06 UTC (permalink / raw)
  To: dpb; +Cc: git, Paul Mackerras

On Tue, Nov 6, 2018 at 12:03 PM Роман Донченко <dpb@corrigendum.ru> wrote:
>
> A line that starts with "  <" or "  >" is not necessarily a submodule
> diff line. It might just be a context line in a normal diff, representing
> a line starting with " <" or " >" respectively.
>
> Use the currdiffsubmod variable to track whether we are currently
> inside a submodule diff and only highlight these lines if we are.

This explanation makes sense, some prior art is at
https://public-inbox.org/git/20181021163401.4458-1-dummy@example.com/
which was not taken AFAICT.

Thanks,
Stefan

>
> Signed-off-by: Роман Донченко <dpb@corrigendum.ru>
> ---
>  gitk | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/gitk b/gitk
> index a14d7a1..6bb6dc6 100755
> --- a/gitk
> +++ b/gitk
> @@ -8109,6 +8109,8 @@ proc parseblobdiffline {ids line} {
>         }
>         # start of a new file
>         set diffinhdr 1
> +       set currdiffsubmod ""
> +
>         $ctext insert end "\n"
>         set curdiffstart [$ctext index "end - 1c"]
>         lappend ctext_file_names ""
> @@ -8191,12 +8193,10 @@ proc parseblobdiffline {ids line} {
>         } else {
>             $ctext insert end "$line\n" filesep
>         }
> -    } elseif {![string compare -length 3 "  >" $line]} {
> -       set $currdiffsubmod ""
> +    } elseif {$currdiffsubmod ne "" && ![string compare -length 3 "  >" $line]} {
>         set line [encoding convertfrom $diffencoding $line]
>         $ctext insert end "$line\n" dresult
> -    } elseif {![string compare -length 3 "  <" $line]} {
> -       set $currdiffsubmod ""
> +    } elseif {$currdiffsubmod ne "" && ![string compare -length 3 "  <" $line]} {
>         set line [encoding convertfrom $diffencoding $line]
>         $ctext insert end "$line\n" d0
>      } elseif {$diffinhdr} {
> --
> 2.19.1.windows.1
>

^ permalink raw reply	[relevance 5%]

* Re: [PATCH] gitk: don't highlight submodule diff lines outside submodule diffs
  2018-11-06 20:06 ` [PATCH] gitk: don't highlight submodule diff lines outside submodule diffs Stefan Beller
@ 2018-11-06 21:56   ` Роман Донченко
  0 siblings, 0 replies; 200+ results
From: Роман Донченко @ 2018-11-06 21:56 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, Paul Mackerras

06.11.2018 23:06, Stefan Beller пишет:
> On Tue, Nov 6, 2018 at 12:03 PM Роман Донченко <dpb@corrigendum.ru> wrote:
>>
>> A line that starts with "  <" or "  >" is not necessarily a submodule
>> diff line. It might just be a context line in a normal diff, representing
>> a line starting with " <" or " >" respectively.
>>
>> Use the currdiffsubmod variable to track whether we are currently
>> inside a submodule diff and only highlight these lines if we are.
> 
> This explanation makes sense, some prior art is at
> https://public-inbox.org/git/20181021163401.4458-1-dummy@example.com/
> which was not taken AFAICT.

Didn't see that patch. That said, I think it's incorrect, since it never 
resets currdiffsubmod back to the empty string, so if a normal diff 
follows a submodule diff, the same issue will occur.

(The `set $currdiffsubmod ""` lines that are already there are 
effectively useless because they set the variable whose name is the 
contents of currdiffsubmod, rather than currdiffsubmod itself. I assume
it was a typo.)

-Roman

> 
> Thanks,
> Stefan
> 
>>
>> Signed-off-by: Роман Донченко <dpb@corrigendum.ru>
>> ---
>>   gitk | 8 ++++----
>>   1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/gitk b/gitk
>> index a14d7a1..6bb6dc6 100755
>> --- a/gitk
>> +++ b/gitk
>> @@ -8109,6 +8109,8 @@ proc parseblobdiffline {ids line} {
>>          }
>>          # start of a new file
>>          set diffinhdr 1
>> +       set currdiffsubmod ""
>> +
>>          $ctext insert end "\n"
>>          set curdiffstart [$ctext index "end - 1c"]
>>          lappend ctext_file_names ""
>> @@ -8191,12 +8193,10 @@ proc parseblobdiffline {ids line} {
>>          } else {
>>              $ctext insert end "$line\n" filesep
>>          }
>> -    } elseif {![string compare -length 3 "  >" $line]} {
>> -       set $currdiffsubmod ""
>> +    } elseif {$currdiffsubmod ne "" && ![string compare -length 3 "  >" $line]} {
>>          set line [encoding convertfrom $diffencoding $line]
>>          $ctext insert end "$line\n" dresult
>> -    } elseif {![string compare -length 3 "  <" $line]} {
>> -       set $currdiffsubmod ""
>> +    } elseif {$currdiffsubmod ne "" && ![string compare -length 3 "  <" $line]} {
>>          set line [encoding convertfrom $diffencoding $line]
>>          $ctext insert end "$line\n" d0
>>       } elseif {$diffinhdr} {
>> --
>> 2.19.1.windows.1
>>

^ permalink raw reply	[relevance 8%]

* Git Test Coverage Report (Wednesday, Nov 7)
@ 2018-11-07 14:37 Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-07 14:37 UTC (permalink / raw)
  To: Git List

Here is the coverage report for today.

Thanks,

-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=251&view=logs

---

pu: 381b31f0006e46fe041e7fc6e5f7b19da5ccd889
jch: ab76604d6537afa18c9d8588c08f699c1f539659
next: 8438c0b2453a7207c9c45756f5e37dfe283db602
master: 8858448bb49332d353febc078ce4a3abcc962efe
master@{1}: d582ea202b626dcc6c3b01e1e11a296d9badd730

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
381b31f000 builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/describe.c
381b31f000 builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/pack-objects.c
381b31f000 builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

diff.c
b613de67c4  316) ret |= COLOR_MOVED_WS_ERROR;
b613de67c4  348) unsigned cm = parse_color_moved_ws(value);
b613de67c4  349) if (cm & COLOR_MOVED_WS_ERROR)

fast-import.c
381b31f000 2935) buf = repo_read_object_file(the_repository, oid, &type, 
&size);
381b31f000 3041) buf = repo_read_object_file(the_repository, oid, &unused,

fsck.c
381b31f000  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
381b31f000  878) repo_read_object_file(the_repository,
381b31f000  879)       &tag->object.oid, &type, &size);

http-push.c
381b31f000 1635) if (!repo_has_object_file(the_repository, &head_oid))
381b31f000 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

negotiator/default.c
381b31f000  71) if (repo_parse_commit(the_repository, commit))

remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
381b31f000  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
381b31f000 1624) repo_unuse_commit_buffer(the_repository, head_commit,
381b31f000 3868) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
e2419f7e30 1378) strbuf_release(&gitdir);
7454fe5cb6 1501) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1505) get_next_submodule_task_release(task);
7454fe5cb6 1532) return 0;
7454fe5cb6 1536) goto out;
7454fe5cb6 1551) return 0;

tree.c
381b31f000 108) if (repo_parse_commit(the_repository, commit))

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Junio C Hamano      381b31f00: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup
Stefan Beller      b613de67c: diff: differentiate error handling in 
parse_color_moved_ws
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

archive.c
8a705c4638 399) die(_("not a valid object name: %s"), name);
8a705c4638 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
8a705c4638 422) die(_("current working directory is untracked"));

attr.c
aa4fa3fa79  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

builtin/am.c
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/branch.c
0ecb1fc726 builtin/branch.c 452) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 458) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/cat-file.c
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/fsck.c
0a995c2567 builtin/fsck.c  87) ret = _("unknown");
0a995c2567 builtin/fsck.c 164) objerror(parent, _("wrong object type in 
link"));
0a995c2567 builtin/fsck.c 275) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
0a995c2567 builtin/fsck.c 303) error(_("could not create lost-found"));
0a995c2567 builtin/fsck.c 310) die_errno(_("could not write '%s'"), 
filename);
0a995c2567 builtin/fsck.c 314) die_errno(_("could not finish '%s'"),
0a995c2567 builtin/fsck.c 331) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
0a995c2567 builtin/fsck.c 349) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
0a995c2567 builtin/fsck.c 368) fprintf_ln(stderr, _("Checking %s %s"),
0a995c2567 builtin/fsck.c 381) printf_ln(_("root %s"),
0a995c2567 builtin/fsck.c 417) return error(_("%s: object corrupt or 
missing"),
0a995c2567 builtin/fsck.c 456) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
0a995c2567 builtin/fsck.c 580) error(_("%s: object could not be parsed: 
%s"),
0a995c2567 builtin/fsck.c 615) fprintf_ln(stderr, _("Checking object 
directory"));
e4d034baf2 builtin/fsck.c 633) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
e4d034baf2 builtin/fsck.c 638) return error(_("invalid %s"), head_ref_name);
0a995c2567 builtin/fsck.c 667) fprintf_ln(stderr, _("Checking cache tree"));
0a995c2567 builtin/fsck.c 683) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/grep.c
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/log.c
517fe807d6 builtin/log.c 1196) BUG_ON_OPT_NEG(unset);

builtin/merge.c
23c0ab7312 builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/read-tree.c
517fe807d6 builtin/read-tree.c  47) BUG_ON_OPT_NEG(unset);

builtin/reflog.c
977e72ca96 builtin/reflog.c 592) usage(_(reflog_expire_usage));
977e72ca96 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
977e72ca96 builtin/reflog.c 689) usage(_(reflog_delete_usage));
977e72ca96 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
977e72ca96 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
977e72ca96 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
977e72ca96 builtin/reflog.c 744) usage(_(reflog_exists_usage));
977e72ca96 builtin/reflog.c 752) usage(_(reflog_exists_usage));
977e72ca96 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
0e1a23ceca 200) die(_("could not start pack-objects to repack promisor 
objects"));
e4d034baf2 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
0e1a23ceca 250) die_errno(_("unable to create '%s'"), promisor_name);
e4d034baf2 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/show-branch.c
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

git.c
4a4f8ae763 341) die_errno(_("while expanding alias '%s': '%s'"),
4a4f8ae763 350) die(_("alias '%s' changes environment variables.\n"
4a4f8ae763 358) die(_("empty alias for %s"), alias_command);
4a4f8ae763 361) die(_("recursive alias: %s"), alias_command);
4a4f8ae763 412) die(_("%s doesn't support --super-prefix"), p->cmd);
4a4f8ae763 436) die_errno(_("write failure on standard output"));
4a4f8ae763 438) die(_("unknown write failure on standard output"));
4a4f8ae763 440) die_errno(_("close failed on standard output"));
4a4f8ae763 658) die(_("%s doesn't support --super-prefix"), argv[0]);
4a4f8ae763 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

merge-recursive.c
55ea0bf4c1 1584) return -1;
55ea0bf4c1 1587) return -1;
55ea0bf4c1 1593) return -1;
55ea0bf4c1 1596) return -1;
55ea0bf4c1 1663) return -1;
55ea0bf4c1 1666) return -1;
55ea0bf4c1 1669) return -1;
143dc79002 1702) return -1;
f10ffbb2ff 1737) return -1;
f10ffbb2ff 1785) return -1;
f10ffbb2ff 1801) return -1;
f10ffbb2ff 1804) return -1;
f10ffbb2ff 1814) return -1;
f10ffbb2ff 1830) return -1;
f10ffbb2ff 1833) return -1;

midx.c
name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

parse-options-cb.c
23c0ab7312  21) return error(_("option `%s' expects a numerical value"),
23c0ab7312  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
23c0ab7312  88) return error(_("%s takes no value"), optname(opt, flags));
23c0ab7312  90) return error(_("%s isn't available"), optname(opt, flags));
23c0ab7312  92) return error(_("%s takes no value"), optname(opt, flags));
23c0ab7312 178) return error(_("%s expects a numerical value"),
23c0ab7312 194) return error(_("%s expects a non-negative integer value"
e7dd7bc3fd 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
e7dd7bc3fd 651) error(_("unknown non-ascii option in string: `%s'"),
23c0ab7312 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

preload-index.c
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
567e20ae23  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
567e20ae23  676)     ce->name, alias->name);
567e20ae23  691) die(_("cannot create an empty blob in the object 
database"));
567e20ae23  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
567e20ae23  786) return error(_("unable to add '%s' to index"), path);
567e20ae23  822) error(_("invalid path '%s'"), path);
567e20ae23  848) error(_("invalid path '%s'"), path);
567e20ae23 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
567e20ae23 1689) return error(_("bad index version %d"), hdr_version);
567e20ae23 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
567e20ae23 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
567e20ae23 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
567e20ae23 1848) die(_("unordered stage entries in index"));
567e20ae23 1851) die(_("multiple stage entries for merged file '%s'"),
567e20ae23 1854) die(_("unordered stage entries for '%s'"),
567e20ae23 2148) die_errno(_("%s: index file open failed"), path);
567e20ae23 2152) die_errno(_("%s: cannot stat the open index"), path);
567e20ae23 2156) die(_("%s: index file smaller than expected"), path);
567e20ae23 2160) die_errno(_("%s: unable to map index file"), path);
567e20ae23 2250) warning(_("could not freshen shared index '%s'"), 
shared_index);
567e20ae23 2285) die(_("broken index, expect %s in %s, got %s"),
567e20ae23 3071) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
567e20ae23 3217) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
23c0ab7312 2326) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
eafdc91bbc  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
eafdc91bbc  417) error(_("more than one uploadpack given, using the 
first"));
eafdc91bbc  683) die(_("key '%s' of pattern had no '*'"), key);
eafdc91bbc  693) die(_("value '%s' of pattern has no '*'"), value);
eafdc91bbc 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
eafdc91bbc 1066) return error(_("dst ref %s receives from more than one 
src"),
eafdc91bbc 1785) die(_("couldn't find remote ref %s"), name);
eafdc91bbc 1798) error(_("* Ignoring funny ref '%s' locally"),
eafdc91bbc 1893) die(_("revision walk setup failed"));
eafdc91bbc 2166) return error(_("cannot parse expected object name '%s'"),

revision.c
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3048) continue;
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Elijah Newren      143dc7900: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      55ea0bf4c: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      f10ffbb2f: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      fce566480: am: handle --no-patch-format option
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Junio C Hamano      e4d034baf: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      0a995c256: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      0e1a23cec: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      23c0ab731: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      4a4f8ae76: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      567e20ae2: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      8a705c463: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      977e72ca9: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      aa4fa3fa7: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      e7dd7bc3f: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      eafdc91bb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet



Uncovered code in 'next' not in 'master'
--------------------------------------------

builtin/add.c
d1664e73ad builtin/add.c 458) die(_("index file corrupt"));

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));

builtin/fetch.c
builtin/fsck.c
b29759d89a builtin/fsck.c 613) fprintf(stderr, "Checking %s link\n", 
head_ref_name);
b29759d89a builtin/fsck.c 618) return error("Invalid %s", head_ref_name);

builtin/grep.c
76e9bdc437 builtin/grep.c  439) grep_read_unlock();

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 580) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 616) continue;

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

combine-diff.c
0074c9110d  377) state->sline[state->nb-1].p_lno =
0074c9110d  378) xcalloc(state->num_parent, sizeof(unsigned long));

date.c
c27cc94fad  904) tm->tm_mon = number-1;
c27cc94fad  908) else if (number > 69 && number < 100)
c27cc94fad  909) tm->tm_year = number;
c27cc94fad  910) else if (number < 38)
c27cc94fad  911) tm->tm_year = 100 + number;
c27cc94fad  952) pending_number(tm, num);

dir.c
8a2c174677  287) name = to_free = xmemdupz(name, namelen);

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

midx.c
1dcd9f2043  184) return;

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
85daa01f6b 1219) continue;
85daa01f6b 1225) continue;

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));

setup.c
58b284a2e9  413) return config_error_nonbool(var);

submodule-config.c
bcbc780d14 739) return CONFIG_INVALID_KEY;
45f5ef3d77 754) warning(_("Could not update .gitmodules entry %s"), key);

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

xdiff-interface.c
xdiff/xutils.c
611e42a598 405) return -1;

Commits introducing uncovered code:
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Ben Peart      d1664e73a: add: speed up cmd_add() by utilizing 
read_cache_preload()
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      85daa01f6: remote: make add_missing_tags() linear
Jeff King      0074c9110: combine-diff: use an xdiff hunk callback
Jeff King      611e42a59: xdiff: provide a separate emit callback for hunks
Jeff King      8a2c17467: pathspec: handle non-terminated strings with 
:(attr)
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Jeff King      c27cc94fa: approxidate: handle pending number for "specials"
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      b29759d89: fsck: check HEAD and reflog from 
other worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Phillip Wood      bcd33ec25: add read_author_script() to libgit



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

builtin/submodule--helper.c
e0a862fdaf 1648) url = sub->url;

gpg-interface.c
4de9394dcb 155) break;

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

pretty.c
4de9394dcb 1264) if (c->signature_check.primary_key_fingerprint)
4de9394dcb 1265) strbuf_addstr(sb, 
c->signature_check.primary_key_fingerprint);
4de9394dcb 1266) break;

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

Commits introducing uncovered code:
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed




^ permalink raw reply	[relevance 4%]

* Re: [PATCH 2/9] submodule--helper: prefer strip_suffix() to ends_with()
      [irrelevant] ` <20181112144703.GB7400@sigill.intra.peff.net>
@ 2018-11-12 18:23   ` Stefan Beller
  0 siblings, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-12 18:23 UTC (permalink / raw)
  To: Jeff King
  Cc: gerardu, Ævar Arnfjörð Bjarmason, Junio C Hamano,
	git, René Scharfe, tikuta

On Mon, Nov 12, 2018 at 6:47 AM Jeff King <peff@peff.net> wrote:
>
> Using strip_suffix() lets us avoid repeating ourselves. It also makes
> the handling of "/" a bit less subtle (we strip one less character than
> we matched in order to leave it in place, but we can just as easily
> include the "/" when we add more path components).
>
> Signed-off-by: Jeff King <peff@peff.net>

This makes sense. Thanks!

(This patch caught my attention as it's a submodule thing,
but now looking at the rest of the series)

^ permalink raw reply	[relevance 7%]

* Git Test Coverage Report (Tuesday, Nov 13)
@ 2018-11-13 18:05 Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-13 18:05 UTC (permalink / raw)
  To: Git List

Here is the test coverage report for today.

Thanks,
-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=256&view=logs

---

pu: a849d4c48bb308cdf3f9d7dc84251d92b4d7ff03
jch: e3cb78b4131db2f98330ff110525db31c6abff16
next: 17fedb746fde9e40924a6ce11c0976a097eb126b
master: d166e6afe5f257217836ef24a73764eba390c58d
master@{1}: 8858448bb49332d353febc078ce4a3abcc962efe

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
a849d4c48b builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/describe.c
a849d4c48b builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/pack-objects.c
a849d4c48b builtin/pack-objects.c 2832) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/remote.c
b7f4e371e7 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
b7f4e371e7 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

diff.c
b613de67c4  316) ret |= COLOR_MOVED_WS_ERROR;
b613de67c4  348) unsigned cm = parse_color_moved_ws(value);
b613de67c4  349) if (cm & COLOR_MOVED_WS_ERROR)

fast-import.c
a849d4c48b 2935) buf = repo_read_object_file(the_repository, oid, &type, 
&size);
a849d4c48b 3041) buf = repo_read_object_file(the_repository, oid, &unused,

fsck.c
a849d4c48b  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
a849d4c48b  878) repo_read_object_file(the_repository,
a849d4c48b  879)       &tag->object.oid, &type, &size);

http-push.c
a849d4c48b 1635) if (!repo_has_object_file(the_repository, &head_oid))
a849d4c48b 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

negotiator/default.c
a849d4c48b  71) if (repo_parse_commit(the_repository, commit))

remote.c
879b6a9e6f 1140) return error(_("dst ref %s receives from more than one 
src."),

revision.c
a849d4c48b  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
a849d4c48b 1643) repo_unuse_commit_buffer(the_repository, head_commit,
a849d4c48b 3914) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule.c
b303ef65e7  524) the_repository->submodule_prefix :
e2419f7e30 1378) strbuf_release(&gitdir);
7454fe5cb6 1501) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1505) get_next_submodule_task_release(task);
7454fe5cb6 1532) return 0;
7454fe5cb6 1536) goto out;
7454fe5cb6 1551) return 0;

tree.c
a849d4c48b 108) if (repo_parse_commit(the_repository, commit))

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      879b6a9e6: i18n: remote.c: mark error(...) 
messages for translation
Denton Liu      b7f4e371e: remote: add --save-to-push option to git 
remote set-url
Junio C Hamano      a849d4c48: merge-fix/dl/remote-save-to-push
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      b303ef65e: submodule: use submodule repos for object 
lookup
Stefan Beller      b613de67c: diff: differentiate error handling in 
parse_color_moved_ws
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 420) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 459) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 583) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 618) fprintf_ln(stderr, _("Checking object 
directory"));
287d68a44b builtin/fsck.c 636) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
287d68a44b builtin/fsck.c 641) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 670) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 686) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/pack-objects.c
ca473cef91 builtin/pack-objects.c 2086) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2087) oid_to_hex(&trg_entry->idx.oid), 
(uintmax_t)sz,
ca473cef91 builtin/pack-objects.c 2113) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2114) oid_to_hex(&src_entry->idx.oid), 
(uintmax_t)sz,

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/rebase.c
3249c1251e  544) ret = -1;
3249c1251e  545) goto leave_reset_head;
bac2a1e36f  549) ret = error(_("could not determine HEAD revision"));
bac2a1e36f  550) goto leave_reset_head;
3249c1251e  568) ret = error(_("could not read index"));
3249c1251e  569) goto leave_reset_head;
bac2a1e36f  573) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
bac2a1e36f  574) goto leave_reset_head;
3249c1251e  578) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
3249c1251e  579) goto leave_reset_head;
3249c1251e  592) goto leave_reset_head;

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
287d68a44b 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
287d68a44b 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

builtin/stash.c
3d5ec65ce8 builtin/stash--helper.c  126) error(_("'%s' is not a 
stash-like commit"), revision);
3d5ec65ce8 builtin/stash--helper.c  127) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  128) exit(128);
3d5ec65ce8 builtin/stash--helper.c  161) free_stash_info(info);
3d5ec65ce8 builtin/stash--helper.c  162) fprintf_ln(stderr, _("No stash 
entries found."));
3d5ec65ce8 builtin/stash--helper.c  163) return -1;
3d5ec65ce8 builtin/stash--helper.c  198) free_stash_info(info);
7005771171 builtin/stash--helper.c  225) return error(_("git stash clear 
with parameters is "
3d5ec65ce8 builtin/stash--helper.c  241) return -1;
3d5ec65ce8 builtin/stash--helper.c  249) return -1;
3d5ec65ce8 builtin/stash--helper.c  262) return -1;
3d5ec65ce8 builtin/stash--helper.c  265) return error(_("unable to write 
new index file"));
3d5ec65ce8 builtin/stash--helper.c  377) remove_path(stash_index_path.buf);
3d5ec65ce8 builtin/stash--helper.c  378) return -1;
3d5ec65ce8 builtin/stash--helper.c  405) return -1;
3d5ec65ce8 builtin/stash--helper.c  408) return error(_("cannot apply a 
stash in the middle of a merge"));
3d5ec65ce8 builtin/stash--helper.c  418) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  419) return error(_("Could not 
generate diff %s^!."),
3d5ec65ce8 builtin/stash--helper.c  426) return error(_("Conflicts in 
index."
3d5ec65ce8 builtin/stash--helper.c  432) return error(_("Could not save 
index tree"));
3d5ec65ce8 builtin/stash--helper.c  439) return error(_("could not 
restore untracked files from stash"));
3d5ec65ce8 builtin/stash--helper.c  470) return -1;
3d5ec65ce8 builtin/stash--helper.c  475) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  480) strbuf_release(&out);
3d5ec65ce8 builtin/stash--helper.c  481) return -1;
7005771171 builtin/stash--helper.c  557) return error(_("%s: Could not 
drop stash entry"),
5bf62a19c0 builtin/stash--helper.c  632) printf_ln(_("The stash entry is 
kept in case "
104eb50d14 builtin/stash--helper.c  766) free_stash_info(&info);
193c3e3516 builtin/stash.c          767) 
usage_with_options(git_stash_show_usage, options);
813904a0ce builtin/stash--helper.c  783) stash_msg = "Created via \"git 
stash store\".";
813904a0ce builtin/stash--helper.c  789) if (!quiet) {
813904a0ce builtin/stash--helper.c  790) fprintf_ln(stderr, _("Cannot 
update %s with %s"),
813904a0ce builtin/stash--helper.c  793) return -1;
813904a0ce builtin/stash--helper.c  817) if (!quiet)
813904a0ce builtin/stash--helper.c  818) fprintf_ln(stderr, _("\"git 
stash store\" requires one "
813904a0ce builtin/stash--helper.c  820) return -1;
9f630e7480 builtin/stash--helper.c  902) return -1;
9f630e7480 builtin/stash--helper.c  962) ret = -1;
9f630e7480 builtin/stash--helper.c  963) goto done;
9f630e7480 builtin/stash--helper.c  968) ret = -1;
9f630e7480 builtin/stash--helper.c  969) goto done;
9f630e7480 builtin/stash--helper.c  974) ret = -1;
9f630e7480 builtin/stash--helper.c  975) goto done;
9f630e7480 builtin/stash--helper.c 1001) ret = -1;
9f630e7480 builtin/stash--helper.c 1002) goto done;
9f630e7480 builtin/stash--helper.c 1013) ret = -1;
9f630e7480 builtin/stash--helper.c 1014) goto done;
9f630e7480 builtin/stash--helper.c 1020) ret = -1;
9f630e7480 builtin/stash--helper.c 1021) goto done;
9f630e7480 builtin/stash--helper.c 1028) ret = -1;
9f630e7480 builtin/stash--helper.c 1029) goto done;
9f630e7480 builtin/stash--helper.c 1054) ret = -1;
9f630e7480 builtin/stash--helper.c 1055) goto done;
9f630e7480 builtin/stash--helper.c 1067) ret = -1;
9f630e7480 builtin/stash--helper.c 1068) goto done;
9f630e7480 builtin/stash--helper.c 1074) ret = -1;
9f630e7480 builtin/stash--helper.c 1075) goto done;
9f630e7480 builtin/stash--helper.c 1086) ret = -1;
9f630e7480 builtin/stash--helper.c 1087) goto done;
9f630e7480 builtin/stash--helper.c 1092) ret = -1;
9f630e7480 builtin/stash--helper.c 1093) goto done;
c2cc69f192 builtin/stash--helper.c 1128) fprintf_ln(stderr, _("You do 
not have "
9f630e7480 builtin/stash--helper.c 1137) ret = 1;
9f630e7480 builtin/stash--helper.c 1138) goto done;
c2cc69f192 builtin/stash--helper.c 1154) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1155) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1157) ret = -1;
9f630e7480 builtin/stash--helper.c 1158) goto done;
c2cc69f192 builtin/stash--helper.c 1163) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1164) fprintf_ln(stderr, _("Cannot save "
9f630e7480 builtin/stash--helper.c 1166) ret = -1;
9f630e7480 builtin/stash--helper.c 1167) goto done;
c2cc69f192 builtin/stash--helper.c 1174) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1175) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1177) goto done;
c2cc69f192 builtin/stash--helper.c 1183) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1184) fprintf_ln(stderr, _("Cannot 
save the current "
9f630e7480 builtin/stash--helper.c 1186) ret = -1;
9f630e7480 builtin/stash--helper.c 1187) goto done;
c2cc69f192 builtin/stash--helper.c 1213) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1214) fprintf_ln(stderr, _("Cannot 
record "
9f630e7480 builtin/stash--helper.c 1216) ret = -1;
9f630e7480 builtin/stash--helper.c 1217) goto done;
1a0f0409a7 builtin/stash--helper.c 1289) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1290) goto done;
1a0f0409a7 builtin/stash--helper.c 1300) ret = -1;
c2cc69f192 builtin/stash--helper.c 1301) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1302) fprintf_ln(stderr, _("Cannot 
initialize stash"));
1a0f0409a7 builtin/stash--helper.c 1303) goto done;
1a0f0409a7 builtin/stash--helper.c 1313) ret = -1;
c2cc69f192 builtin/stash--helper.c 1314) if (!quiet)
c2cc69f192 builtin/stash--helper.c 1315) fprintf_ln(stderr, _("Cannot 
save the current status"));
1a0f0409a7 builtin/stash--helper.c 1316) goto done;
1a0f0409a7 builtin/stash--helper.c 1333) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1352) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1353) goto done;
1a0f0409a7 builtin/stash--helper.c 1362) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1363) goto done;
1a0f0409a7 builtin/stash--helper.c 1371) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1380) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1391) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1392) goto done;
1a0f0409a7 builtin/stash--helper.c 1401) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1402) goto done;
1a0f0409a7 builtin/stash--helper.c 1410) ret = -1;
1a0f0409a7 builtin/stash--helper.c 1436) ret = -1;
193c3e3516 builtin/stash.c         1568) 
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
193c3e3516 builtin/stash.c         1596) continue;

bundle.c
74ae4b638d 380) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

fast-import.c
ca473cef91 2958) strbuf_addf(&line, "%s %s %"PRIuMAX"\n", oid_to_hex(oid),

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 658) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 770) die(_("cannot handle %s as a builtin"), cmd);

hex.c
b3a41547ce  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
b3a41547ce  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
b3a41547ce 116) char *hash_to_hex(const unsigned char *hash)
b3a41547ce 118) return hash_to_hex_algop(hash, the_hash_algo);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 651) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

protocol.c
c95f252809  37) die(_("Unrecognized protocol version"));
c95f252809  39) die(_("Unrecognized protocol_version"));

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2250) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2285) die(_("broken index, expect %s in %s, got %s"),
9d0a9e9089 3071) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3217) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
bbfc042ef9  238) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  247) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  255) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
9440b831ad 2380) return error(_("option `%s' is incompatible with 
--no-merged"),

remote.c
0b9c3afdbf  362) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  417) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  683) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  693) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1044) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1066) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1785) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1798) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1893) die(_("revision walk setup failed"));
0b9c3afdbf 2166) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
18e711a162 2387) opts->quiet = 1;
f11c958054 3977) res = error_dirty_index(r->index, opts);

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;
f0eaf63819 sha1-file.c 2207) return r;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      b3a41547c: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Joel Teichroeb      3d5ec65ce: stash: convert apply to builtin
Joel Teichroeb      5bf62a19c: stash: convert pop to builtin
Joel Teichroeb      700577117: stash: convert drop and clear to builtin
Johannes Schindelin      3249c1251: rebase: consolidate clean-up code 
before leaving reset_head()
Johannes Schindelin      bac2a1e36: built-in rebase: reinstate `checkout 
-q` behavior where appropriate
Josh Steadmon      c95f25280: protocol: advertise multiple supported 
versions
Junio C Hamano      287d68a44: Merge branch 'nd/i18n' into jch
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option
Paul-Sebastian Ungureanu      104eb50d1: stash: convert show to builtin
Paul-Sebastian Ungureanu      193c3e351: stash: convert 
`stash--helper.c` into `stash.c`
Paul-Sebastian Ungureanu      1a0f0409a: stash: convert push to builtin
Paul-Sebastian Ungureanu      813904a0c: stash: convert store to builtin
Paul-Sebastian Ungureanu      9f630e748: stash: convert create to builtin
Paul-Sebastian Ungureanu      c2cc69f19: stash: make push -q quiet
Torsten Bögershausen      ca473cef9: Upcast size_t variables to 
uintmax_t when printing



Uncovered code in 'next' not in 'master'
--------------------------------------------

apply.c
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

builtin/am.c
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/archive.c
e001fd3a50 builtin/archive.c  78) die(_("git archive: expected ACK/NAK, 
got a flush packet"));
e001fd3a50 builtin/archive.c  80) if (starts_with(reader.line, "NACK "))
e001fd3a50 builtin/archive.c  81) die(_("git archive: NACK %s"), 
reader.line + 5);
e001fd3a50 builtin/archive.c  82) if (starts_with(reader.line, "ERR "))
e001fd3a50 builtin/archive.c  83) die(_("remote error: %s"), reader.line 
+ 4);
e001fd3a50 builtin/archive.c  84) die(_("git archive: protocol error"));
e001fd3a50 builtin/archive.c  89) die(_("git archive: expected a flush"));
fb19d32f05 builtin/archive.c  99) if (version != discover_version(&reader))
fb19d32f05 builtin/archive.c 100) die(_("git archive: received different 
protocol versions in subsequent requests"));

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/cat-file.c
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/grep.c
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/log.c
517fe807d6 builtin/log.c 1196) BUG_ON_OPT_NEG(unset);

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/show-branch.c
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

builtin/upload-archive.c
e001fd3a50 builtin/upload-archive.c 113) if (version == protocol_v0 || 
version == protocol_v1)
e001fd3a50 builtin/upload-archive.c 114) packet_write_fmt(1, "NACK 
unable to spawn subprocess\n");
e001fd3a50 builtin/upload-archive.c 115) else if (version == protocol_v2)
e001fd3a50 builtin/upload-archive.c 116) error_clnt("unable to spawn 
subprocess\n");

http-backend.c
fb19d32f05 646) argv[1] = ".";
fb19d32f05 647) argv[2] = NULL;

midx.c
name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

preload-index.c
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

revision.c
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3048) continue;
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

transport-helper.c
fb19d32f05  643) if (!data->connect && !data->stateless_connect)

Commits introducing uncovered code:
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      fce566480: am: handle --no-patch-format option
Josh Steadmon      e001fd3a5: archive: implement protocol v2 archive command
Josh Steadmon      fb19d32f0: archive: allow archive over HTTP(S) with 
proto v2
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

builtin/add.c
d1664e73ad builtin/add.c 458) die(_("index file corrupt"));

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));

builtin/fetch.c
builtin/fsck.c
b29759d89a builtin/fsck.c 613) fprintf(stderr, "Checking %s link\n", 
head_ref_name);
b29759d89a builtin/fsck.c 618) return error("Invalid %s", head_ref_name);

builtin/grep.c
76e9bdc437 builtin/grep.c  439) grep_read_unlock();

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 580) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 616) continue;

combine-diff.c
0074c9110d  377) state->sline[state->nb-1].p_lno =
0074c9110d  378) xcalloc(state->num_parent, sizeof(unsigned long));

date.c
c27cc94fad  904) tm->tm_mon = number-1;
c27cc94fad  908) else if (number > 69 && number < 100)
c27cc94fad  909) tm->tm_year = number;
c27cc94fad  910) else if (number < 38)
c27cc94fad  911) tm->tm_year = 100 + number;
c27cc94fad  952) pending_number(tm, num);

dir.c
8a2c174677  287) name = to_free = xmemdupz(name, namelen);

midx.c
1dcd9f2043  184) return;

refs.c
3a3b9d8cde  657) return 0;

refs/files-backend.c
remote.c
85daa01f6b 1219) continue;
85daa01f6b 1225) continue;

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));

setup.c
58b284a2e9  413) return config_error_nonbool(var);

submodule-config.c
bcbc780d14 739) return CONFIG_INVALID_KEY;
45f5ef3d77 754) warning(_("Could not update .gitmodules entry %s"), key);

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

xdiff-interface.c
xdiff/xutils.c
611e42a598 405) return -1;

Commits introducing uncovered code:
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Ben Peart      d1664e73a: add: speed up cmd_add() by utilizing 
read_cache_preload()
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      85daa01f6: remote: make add_missing_tags() linear
Jeff King      0074c9110: combine-diff: use an xdiff hunk callback
Jeff King      611e42a59: xdiff: provide a separate emit callback for hunks
Jeff King      8a2c17467: pathspec: handle non-terminated strings with 
:(attr)
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Jeff King      c27cc94fa: approxidate: handle pending number for "specials"
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      b29759d89: fsck: check HEAD and reflog from 
other worktrees
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Phillip Wood      bcd33ec25: add read_author_script() to libgit


^ permalink raw reply	[relevance 3%]

* [PATCHv3 00/23] Bring more repository handles into our code base
@ 2018-11-14  0:12 Stefan Beller
  2018-11-14  0:13 ` [PATCH 18/23] submodule: use submodule repos for object lookup Stefan Beller
  2018-11-14  0:13 ` [PATCH 19/23] submodule: don't add submodule as odb for push Stefan Beller
  0 siblings, 2 replies; 200+ results
From: Stefan Beller @ 2018-11-14  0:12 UTC (permalink / raw)
  To: gitster, jonathantanmy; +Cc: git, Stefan Beller

This resends origin/sb/more-repo-in-api.

Unlike the previous resend (v2), this is not rebased to a newer base.
This doesn't contain the patch for pending semantic changes, as that
seems to go in its own topic branch.

Please have a look at the last 4 patches specifically as they were new in
the last iteration (but did not receive any comment), as they demonstrate
and fix a problem that is only exposed when using GIT_TEST_COMMIT_GRAPH=1
for the test suite.

Previous discussion at
https://public-inbox.org/git/20181030220817.61691-1-sbeller@google.com/

Thanks,
Stefan

Stefan Beller (23):
  sha1_file: allow read_object to read objects in arbitrary repositories
  packfile: allow has_packed_and_bad to handle arbitrary repositories
  object-store: allow read_object_file_extended to read from any repo
  object-store: prepare read_object_file to deal with any repo
  object-store: prepare has_{sha1, object}_file to handle any repo
  object: parse_object to honor its repository argument
  commit: allow parse_commit* to handle any repo
  commit-reach.c: allow paint_down_to_common to handle any repo
  commit-reach.c: allow merge_bases_many to handle any repo
  commit-reach.c: allow remove_redundant to handle any repo
  commit-reach.c: allow get_merge_bases_many_0 to handle any repo
  commit-reach: prepare get_merge_bases to handle any repo
  commit-reach: prepare in_merge_bases[_many] to handle any repo
  commit: prepare get_commit_buffer to handle any repo
  commit: prepare repo_unuse_commit_buffer to handle any repo
  commit: prepare logmsg_reencode to handle arbitrary repositories
  pretty: prepare format_commit_message to handle arbitrary repositories
  submodule: use submodule repos for object lookup
  submodule: don't add submodule as odb for push
  commit-graph: convert remaining functions to handle any repo
  commit: prepare free_commit_buffer and release_commit_memory for any
    repo
  path.h: make REPO_GIT_PATH_FUNC repository agnostic
  t/helper/test-repository: celebrate independence from the_repository

 builtin/fsck.c                                |   3 +-
 builtin/log.c                                 |   6 +-
 builtin/rev-list.c                            |   3 +-
 cache.h                                       |   2 +
 commit-graph.c                                |  40 +++--
 commit-reach.c                                |  73 +++++----
 commit-reach.h                                |  38 +++--
 commit.c                                      |  41 ++---
 commit.h                                      |  43 +++++-
 .../coccinelle/the_repository.pending.cocci   | 144 ++++++++++++++++++
 object-store.h                                |  35 ++++-
 object.c                                      |   8 +-
 packfile.c                                    |   5 +-
 packfile.h                                    |   2 +-
 path.h                                        |   2 +-
 pretty.c                                      |  28 ++--
 pretty.h                                      |   7 +-
 sha1-file.c                                   |  34 +++--
 streaming.c                                   |   2 +-
 submodule.c                                   |  76 ++++++---
 t/helper/test-repository.c                    |  10 ++
 21 files changed, 452 insertions(+), 150 deletions(-)
 create mode 100644 contrib/coccinelle/the_repository.pending.cocci

Range-diff:
 1:  1b9b5c695e =  1:  ca9fece80e sha1_file: allow read_object to read objects in arbitrary repositories
 2:  33b94066f2 =  2:  8eac25fe32 packfile: allow has_packed_and_bad to handle arbitrary repositories
 3:  5217b6b1e1 !  3:  06e5f83b66 object-store: allow read_object_file_extended to read from arbitrary repositories
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    object-store: allow read_object_file_extended to read from arbitrary repositories
    +    object-store: allow read_object_file_extended to read from any repo
     
         read_object_file_extended is not widely used, so migrate it all at once.
     
 4:  2b7239b55b !  4:  6167722608 object-store: prepare read_object_file to deal with arbitrary repositories
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    object-store: prepare read_object_file to deal with arbitrary repositories
    +    object-store: prepare read_object_file to deal with any repo
     
         As read_object_file is a widely used function (which is also regularly used
         in new code in flight between master..pu), changing its signature is painful
    @@ -13,16 +13,14 @@
         e675765235 (diff.c: remove implicit dependency on the_index, 2018-09-21)
     
         Add a coccinelle patch to convert existing callers, but do not apply
    -    the resulting patch from 'make coccicheck' to keep the diff of this
    -    patch small.
    +    the resulting patch to keep the diff of this patch small.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
      new file mode 100644
      --- /dev/null
    - +++ b/contrib/coccinelle/the_repository.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
     +// This file is used for the ongoing refactoring of
     +// bringing the index or repository struct in all of
 5:  24291f4d84 !  5:  2a88a868bb object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories
    @@ -1,13 +1,12 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    object-store: prepare has_{sha1, object}_file[_with_flags] to handle arbitrary repositories
    +    object-store: prepare has_{sha1, object}_file to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - read_object_file(
      + repo_read_object_file(the_repository,
 6:  6aa209978e =  6:  fd4a151e07 object: parse_object to honor its repository argument
 7:  9b2d6aa7c3 !  7:  5484abc785 commit: allow parse_commit* to handle arbitrary repositories
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit: allow parse_commit* to handle arbitrary repositories
    +    commit: allow parse_commit* to handle any repo
     
         Just like the previous commit, parse_commit and friends are used a lot
         and are found in new patches, so we cannot change their signature easily.
    @@ -9,7 +9,6 @@
         argument and keep the original as a shallow macro.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -93,9 +92,9 @@
      
      struct buffer_slab;
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - has_object_file_with_flags(
      + repo_has_object_file_with_flags(the_repository,
 8:  0e7e681118 !  8:  8cc3054b31 commit-reach.c: allow paint_down_to_common to handle arbitrary repositories
    @@ -1,11 +1,10 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach.c: allow paint_down_to_common to handle arbitrary repositories
    +    commit-reach.c: allow paint_down_to_common to handle any repo
     
         As the function is file local and not widely used, migrate it all at once.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
 9:  e83b26f5b3 !  9:  45e67ba283 commit-reach.c: allow merge_bases_many to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach.c: allow merge_bases_many to handle arbitrary repositories
    +    commit-reach.c: allow merge_bases_many to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
10:  d80b9de832 ! 10:  917d8cbaee commit-reach.c: allow remove_redundant to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach.c: allow remove_redundant to handle arbitrary repositories
    +    commit-reach.c: allow remove_redundant to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
11:  3ec21ad503 ! 11:  a008e62fea commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach.c: allow get_merge_bases_many_0 to handle arbitrary repositories
    +    commit-reach.c: allow get_merge_bases_many_0 to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
12:  3f21279f50 ! 12:  a50a7f52b0 commit-reach: prepare get_merge_bases to handle arbitrary repositories
    @@ -1,6 +1,6 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach: prepare get_merge_bases to handle arbitrary repositories
    +    commit-reach: prepare get_merge_bases to handle any repo
     
         Similarly to previous patches, the get_merge_base functions are used
         often in the code base, which makes migrating them hard.
    @@ -9,7 +9,6 @@
         functions behind a wrapper macro.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
    @@ -91,9 +90,9 @@
      int is_descendant_of(struct commit *commit, struct commit_list *with_commit);
      int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference);
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - parse_commit(
      + repo_parse_commit(the_repository,
13:  4decc3acc1 ! 13:  d82074d34b commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit-reach: prepare in_merge_bases[_many] to handle arbitrary repositories
    +    commit-reach: prepare in_merge_bases[_many] to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit-reach.c b/commit-reach.c
      --- a/commit-reach.c
    @@ -76,9 +75,9 @@
      /*
       * Takes a list of commits and returns a new list where those
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - get_merge_bases_many_dirty(
      + repo_get_merge_bases_many_dirty(the_repository,
14:  141b86ea89 ! 14:  6035c18ca1 commit: prepare get_commit_buffer to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit: prepare get_commit_buffer to handle arbitrary repositories
    +    commit: prepare get_commit_buffer to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -46,9 +45,9 @@
      /*
       * Tell the commit subsytem that we are done with a particular commit buffer.
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - in_merge_bases_many(
      + repo_in_merge_bases_many(the_repository,
15:  2cc415c1db ! 15:  85dcc6f806 commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
    @@ -1,9 +1,8 @@
     Author: Stefan Beller <sbeller@google.com>
     
    -    commit: prepare repo_unuse_commit_buffer to handle arbitrary repositories
    +    commit: prepare repo_unuse_commit_buffer to handle any repo
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/commit.c b/commit.c
      --- a/commit.c
    @@ -42,9 +41,9 @@
      /*
       * Free any cached object buffer associated with the commit.
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - get_commit_buffer(
      + repo_get_commit_buffer(the_repository,
16:  554daa8cfc ! 16:  0e1b98701f commit: prepare logmsg_reencode to handle arbitrary repositories
    @@ -24,9 +24,9 @@
      
      /** Removes the first commit from a list sorted by date, and adds all
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - unuse_commit_buffer(
      + repo_unuse_commit_buffer(the_repository,
17:  bd8737176b ! 17:  da611e902b pretty: prepare format_commit_message to handle arbitrary repositories
    @@ -5,9 +5,9 @@
         Signed-off-by: Stefan Beller <sbeller@google.com>
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
    - diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci
    - --- a/contrib/coccinelle/the_repository.cocci
    - +++ b/contrib/coccinelle/the_repository.cocci
    + diff --git a/contrib/coccinelle/the_repository.pending.cocci b/contrib/coccinelle/the_repository.pending.cocci
    + --- a/contrib/coccinelle/the_repository.pending.cocci
    + +++ b/contrib/coccinelle/the_repository.pending.cocci
     @@
      - logmsg_reencode(
      + repo_logmsg_reencode(the_repository,
18:  b303ef65e7 ! 18:  a98112634e submodule: use submodule repos for object lookup
    @@ -7,7 +7,6 @@
         are not added to the main object store.
     
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/submodule.c b/submodule.c
      --- a/submodule.c
    @@ -46,24 +45,23 @@
     + * in .gitmodules. This function exists only to preserve historical behavior,
     + *
     + * Returns 0 on success, -1 when the submodule is not present.
    -+ */
    -+static int open_submodule(struct repository *out, const char *path)
    +  */
    +-static void show_submodule_header(struct diff_options *o, const char *path,
    ++static struct repository *open_submodule(const char *path)
     +{
     +	struct strbuf sb = STRBUF_INIT;
    ++	struct repository *out = xmalloc(sizeof(*out));
     +
     +	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
     +		strbuf_release(&sb);
    -+		return -1;
    ++		free(out);
    ++		return NULL;
     +	}
     +
     +	out->submodule_prefix = xstrdup(path);
    -+	out->submodule_prefix = xstrfmt("%s%s/",
    -+					the_repository->submodule_prefix ?
    -+					the_repository->submodule_prefix :
    -+					"", path);
     +
     +	strbuf_release(&sb);
    -+	return 0;
    ++	return out;
     +}
     +
     +/*
    @@ -73,8 +71,7 @@
     + * If it can locate the submodule git directory it will create a repository
     + * handle for the submodule and lookup both the left and right commits and
     + * put them into the left and right pointers.
    -  */
    --static void show_submodule_header(struct diff_options *o, const char *path,
    ++ */
     +static void show_submodule_header(struct diff_options *o,
     +		const char *path,
      		struct object_id *one, struct object_id *two,
    @@ -116,11 +113,9 @@
      	struct rev_info rev;
      	struct commit *left = NULL, *right = NULL;
      	struct commit_list *merge_bases = NULL;
    -+	struct repository subrepo, *sub = &subrepo;
    -+
    -+	if (open_submodule(&subrepo, path) < 0)
    -+		sub = NULL;
    ++	struct repository *sub;
      
    ++	sub = open_submodule(path);
      	show_submodule_header(o, path, one, two, dirty_submodule,
     -			      &left, &right, &merge_bases);
     +			      sub, &left, &right, &merge_bases);
    @@ -147,8 +142,10 @@
      		free_commit_list(merge_bases);
      	clear_commit_marks(left, ~0);
      	clear_commit_marks(right, ~0);
    -+	if (sub)
    ++	if (sub) {
     +		repo_clear(sub);
    ++		free(sub);
    ++	}
      }
      
      void show_submodule_inline_diff(struct diff_options *o, const char *path,
    @@ -156,11 +153,9 @@
      	struct commit_list *merge_bases = NULL;
      	struct child_process cp = CHILD_PROCESS_INIT;
      	struct strbuf sb = STRBUF_INIT;
    -+	struct repository subrepo, *sub = &subrepo;
    -+
    -+	if (open_submodule(&subrepo, path) < 0)
    -+		sub = NULL;
    ++	struct repository *sub;
      
    ++	sub = open_submodule(path);
      	show_submodule_header(o, path, one, two, dirty_submodule,
     -			      &left, &right, &merge_bases);
     +			      sub, &left, &right, &merge_bases);
    @@ -171,8 +166,10 @@
      		clear_commit_marks(left, ~0);
      	if (right)
      		clear_commit_marks(right, ~0);
    -+	if (sub)
    ++	if (sub) {
     +		repo_clear(sub);
    ++		free(sub);
    ++	}
      }
      
      int should_update_submodules(void)
19:  dbb0dd9322 ! 19:  6aad29a006 submodule: don't add submodule as odb for push
    @@ -8,8 +8,10 @@
         objects, and the actual push is done by spawning another process,
         which handles object access by itself.)
     
    +    This code of push_submodule() is exercised in t5531 and continues
    +    to work, showing that the submodule odbc is not needed.
    +
         Signed-off-by: Stefan Beller <sbeller@google.com>
    -    Signed-off-by: Junio C Hamano <gitster@pobox.com>
     
      diff --git a/submodule.c b/submodule.c
      --- a/submodule.c
 -:  ---------- > 20:  1687e96586 commit-graph: convert remaining functions to handle any repo
 -:  ---------- > 21:  d348185ca9 commit: prepare free_commit_buffer and release_commit_memory for any repo
 -:  ---------- > 22:  19f62807cc path.h: make REPO_GIT_PATH_FUNC repository agnostic
 -:  ---------- > 23:  61da0c2812 t/helper/test-repository: celebrate independence from the_repository
-- 
2.19.1.1215.g8438c0b245-goog


^ permalink raw reply	[relevance 7%]

* [PATCH 18/23] submodule: use submodule repos for object lookup
  2018-11-14  0:12 [PATCHv3 00/23] Bring more repository handles into our code base Stefan Beller
@ 2018-11-14  0:13 ` Stefan Beller
      [irrelevant]   ` <20181115195416.21890-1-jonathantanmy@google.com>
  2018-11-14  0:13 ` [PATCH 19/23] submodule: don't add submodule as odb for push Stefan Beller
  1 sibling, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-14  0:13 UTC (permalink / raw)
  To: gitster, jonathantanmy; +Cc: git, Stefan Beller

This converts the 'show_submodule_header' function to use
the repository API properly, such that the submodule objects
are not added to the main object store.

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

diff --git a/submodule.c b/submodule.c
index d9d3046689..262f03f118 100644
--- a/submodule.c
+++ b/submodule.c
@@ -443,7 +443,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
 	return prepare_revision_walk(rev);
 }
 
-static void print_submodule_summary(struct rev_info *rev, struct diff_options *o)
+static void print_submodule_summary(struct repository *r, struct rev_info *rev, struct diff_options *o)
 {
 	static const char format[] = "  %m %s";
 	struct strbuf sb = STRBUF_INIT;
@@ -454,7 +454,8 @@ static void print_submodule_summary(struct rev_info *rev, struct diff_options *o
 		ctx.date_mode = rev->date_mode;
 		ctx.output_encoding = get_log_output_encoding();
 		strbuf_setlen(&sb, 0);
-		format_commit_message(commit, format, &sb, &ctx);
+		repo_format_commit_message(r, commit, format, &sb,
+				      &ctx);
 		strbuf_addch(&sb, '\n');
 		if (commit->object.flags & SYMMETRIC_LEFT)
 			diff_emit_submodule_del(o, sb.buf);
@@ -481,14 +482,44 @@ void prepare_submodule_repo_env(struct argv_array *out)
 			 DEFAULT_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
- * left and right pointers.
+/*
+ * Initialize 'out' based on the provided submodule path.
+ *
+ * Unlike repo_submodule_init, this tolerates submodules not present
+ * in .gitmodules. This function exists only to preserve historical behavior,
+ *
+ * Returns 0 on success, -1 when the submodule is not present.
  */
-static void show_submodule_header(struct diff_options *o, const char *path,
+static struct repository *open_submodule(const char *path)
+{
+	struct strbuf sb = STRBUF_INIT;
+	struct repository *out = xmalloc(sizeof(*out));
+
+	if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
+		strbuf_release(&sb);
+		free(out);
+		return NULL;
+	}
+
+	out->submodule_prefix = xstrdup(path);
+
+	strbuf_release(&sb);
+	return out;
+}
+
+/*
+ * Helper function to display the submodule header line prior to the full
+ * summary output.
+ *
+ * If it can locate the submodule git directory it will create a repository
+ * handle for the submodule and lookup both the left and right commits and
+ * put them into the left and right pointers.
+ */
+static void show_submodule_header(struct diff_options *o,
+		const char *path,
 		struct object_id *one, struct object_id *two,
 		unsigned dirty_submodule,
+		struct repository *sub,
 		struct commit **left, struct commit **right,
 		struct commit_list **merge_bases)
 {
@@ -507,7 +538,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	else if (is_null_oid(two))
 		message = "(submodule deleted)";
 
-	if (add_submodule_odb(path)) {
+	if (!sub) {
 		if (!message)
 			message = "(commits not present)";
 		goto output_header;
@@ -517,8 +548,8 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	 * Attempt to lookup the commit references, and determine if this is
 	 * a fast forward or fast backwards update.
 	 */
-	*left = lookup_commit_reference(the_repository, one);
-	*right = lookup_commit_reference(the_repository, two);
+	*left = lookup_commit_reference(sub, one);
+	*right = lookup_commit_reference(sub, two);
 
 	/*
 	 * Warn about missing commits in the submodule project, but only if
@@ -528,7 +559,7 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 	     (!is_null_oid(two) && !*right))
 		message = "(commits not present)";
 
-	*merge_bases = get_merge_bases(*left, *right);
+	*merge_bases = repo_get_merge_bases(sub, *left, *right);
 	if (*merge_bases) {
 		if ((*merge_bases)->item == *left)
 			fast_forward = 1;
@@ -562,16 +593,18 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 	struct rev_info rev;
 	struct commit *left = NULL, *right = NULL;
 	struct commit_list *merge_bases = NULL;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/*
 	 * If we don't have both a left and a right pointer, there is no
 	 * reason to try and display a summary. The header line should contain
 	 * all the information the user needs.
 	 */
-	if (!left || !right)
+	if (!left || !right || !sub)
 		goto out;
 
 	/* Treat revision walker failure the same as missing commits */
@@ -580,13 +613,17 @@ void show_submodule_summary(struct diff_options *o, const char *path,
 		goto out;
 	}
 
-	print_submodule_summary(&rev, o);
+	print_submodule_summary(sub, &rev, o);
 
 out:
 	if (merge_bases)
 		free_commit_list(merge_bases);
 	clear_commit_marks(left, ~0);
 	clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 void show_submodule_inline_diff(struct diff_options *o, const char *path,
@@ -598,9 +635,11 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 	struct commit_list *merge_bases = NULL;
 	struct child_process cp = CHILD_PROCESS_INIT;
 	struct strbuf sb = STRBUF_INIT;
+	struct repository *sub;
 
+	sub = open_submodule(path);
 	show_submodule_header(o, path, one, two, dirty_submodule,
-			      &left, &right, &merge_bases);
+			      sub, &left, &right, &merge_bases);
 
 	/* We need a valid left and right commit to display a difference */
 	if (!(left || is_null_oid(one)) ||
@@ -661,6 +700,10 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
 		clear_commit_marks(left, ~0);
 	if (right)
 		clear_commit_marks(right, ~0);
+	if (sub) {
+		repo_clear(sub);
+		free(sub);
+	}
 }
 
 int should_update_submodules(void)
-- 
2.19.1.1215.g8438c0b245-goog


^ permalink raw reply	[relevance 20%]

* [PATCH 19/23] submodule: don't add submodule as odb for push
  2018-11-14  0:12 [PATCHv3 00/23] Bring more repository handles into our code base Stefan Beller
  2018-11-14  0:13 ` [PATCH 18/23] submodule: use submodule repos for object lookup Stefan Beller
@ 2018-11-14  0:13 ` Stefan Beller
  1 sibling, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-14  0:13 UTC (permalink / raw)
  To: gitster, jonathantanmy; +Cc: git, Stefan Beller

In push_submodule(), because we do not actually need access to objects
in the submodule, do not invoke add_submodule_odb().
(for_each_remote_ref_submodule() does not require access to those
objects, and the actual push is done by spawning another process,
which handles object access by itself.)

This code of push_submodule() is exercised in t5531 and continues
to work, showing that the submodule odbc is not needed.

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

diff --git a/submodule.c b/submodule.c
index 262f03f118..5818088df2 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1021,9 +1021,6 @@ static int push_submodule(const char *path,
 			  const struct string_list *push_options,
 			  int dry_run)
 {
-	if (add_submodule_odb(path))
-		return 1;
-
 	if (for_each_remote_ref_submodule(path, has_remote, NULL) > 0) {
 		struct child_process cp = CHILD_PROCESS_INIT;
 		argv_array_push(&cp.args, "push");
-- 
2.19.1.1215.g8438c0b245-goog


^ permalink raw reply	[relevance 14%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-10-25 18:26   ` Confusing behavior with ignored submodules and `git commit -a` Stefan Beller
@ 2018-11-15  5:12     ` Michael Forney
  2018-11-15  6:05       ` Michael Forney
  2018-11-15 19:39       ` Stefan Beller
  0 siblings, 2 replies; 200+ results
From: Michael Forney @ 2018-11-15  5:12 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

On 2018-10-25, Stefan Beller <sbeller@google.com> wrote:
> On Thu, Oct 25, 2018 at 11:03 AM Michael Forney <mforney@mforney.org>
> wrote:
>>
>> On 2018-03-16, Michael Forney <mforney@mforney.org> wrote:
>> > Hi,
>> >
>> > In the past few months have noticed some confusing behavior with
>> > ignored submodules. I finally got around to bisecting this to commit
>> > 5556808690ea245708fb80383be5c1afee2fb3eb (add, reset: ensure
>> > submodules can be added or reset).
>
> Uh. :(
>
> See the discussion starting at
> https://public-inbox.org/git/20170725213928.125998-4-bmwill@google.com/
> specifically
> https://public-inbox.org/git/xmqqinieq49v.fsf@gitster.mtv.corp.google.com/

Thanks for the links. Let me explain how I'm using
submodule.<name>.ignore. Maybe there's a better mechanism in git to
deal with this (if .ignore is a misfeature).

I have a git repository which contains a number of submodules that
refer to external repositories. Some of these repositories need to
patched in some way, so patches are stored alongside the submodules,
and are applied when building. This mostly works fine, but causes
submodules to show up as modified in `git status` and get updated with
`git commit -a`. To resolve this, I've added `ignore = all` to
.gitmodules for all the submodules that need patches applied. This
way, I can explicitly `git add` the submodule when I want to update
the base commit, but otherwise pretend that they are clean. This has
worked pretty well for me, but less so since git 2.15 when this issue
was introduced.

Of course, I could maintain and publish forks of those repositories
and use those as the remote for the submodules. However in many cases
these patches are just temporary until they get applied upstream and a
new release is made, and I don't really want to keep mirrors
unnecessarily, or keep switching the submodule URL between upstream
and my fork.

>> > However, if I go to update `foo.txt` and
>> > commit with `git commit -a`, changes to inner get recorded
>> > unexpectedly. What's worse is the shortstat output of `git commit -a`,
>> > and the diff output of `git show` give no indication that the
>> > submodule was changed.
>
> This is really bad. git-status and git-commit share some code,
> and we'll populate the commit message with a status output.
> So it seems reasonable to expect the status and the commit to match,
> i.e. if status tells me there is no change, then commit should not record
> the submodule update.

I just checked and if I don't specify a message on the command-line,
the status output in the message template *does* mention that `inner`
is getting updated.

>> > There have been a couple occasions where I accidentally pushed local
>> > changes to ignored submodules because of this. Since they don't show
>> > up in the log output, it is difficult to figure out what actually has
>> > gone wrong.
>
> How was it prevented before? Just by git commit -a not picking up the
> submodule change?

Yes. Previously, `git commit -a` would not pick up the change (unless
I added it explicitly with `git add`), and `git log` would still show
changes to ignored submodules (which is the behavior I want).

> I guess reverting that commit is not a good idea now, as
> I would expect something to break.
>
> Maybe looking through the series 614ea03a71
> (Merge branch 'bw/submodule-config-cleanup', 2017-08-26)
> to understand why it happened in the context would be a good start.

Thanks, that's a good idea. I'll take a look through that series.

>> I accidentally pushed local changes to ignored submodules again due to
>> this.
>>
>> Can anyone confirm whether this is the intended behavior of ignore? If
>> it is, then at least the documentation needs an update saying that
>> `commit -a` will commit all submodule changes, even if they are
>> ignored.
>
> The docs say "(but it will nonetheless show up in the output of
> status and commit when it has been staged)" as well, so that commit
> sounds like a regression?

I just came across someone else affected by this issue:
https://github.com/git/git/commit/55568086#commitcomment-27137460

^ permalink raw reply	[relevance 7%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15  5:12     ` Michael Forney
@ 2018-11-15  6:05       ` Michael Forney
  2018-11-15 20:03         ` Stefan Beller
  2018-11-15 19:39       ` Stefan Beller
  1 sibling, 1 reply; 200+ results
From: Michael Forney @ 2018-11-15  6:05 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git, bmwill

+bmwill

On 2018-11-14, Michael Forney <mforney@mforney.org> wrote:
> On 2018-10-25, Stefan Beller <sbeller@google.com> wrote:
>> I guess reverting that commit is not a good idea now, as
>> I would expect something to break.
>>
>> Maybe looking through the series 614ea03a71
>> (Merge branch 'bw/submodule-config-cleanup', 2017-08-26)
>> to understand why it happened in the context would be a good start.
>
> Thanks, that's a good idea. I'll take a look through that series.

Interesting. If I build git from master after reverting 55568086, I do
indeed observe the issue it claims to fix (unable to add ignored
submodules). However, if I build from 9ef23f91fc (the immediate parent
of 55568086), I do not see the issue.

Investigating this further, it seems that 55568086 addresses an issue
that does not appear until later on in the series in ff6f1f564c
(submodule-config: lazy-load a repository's .gitmodules file). Perhaps
this was a result of reordering commits during a rebase. In other
words, I get correct behavior until 55568086, and in
55568086..ff6f1f564c^ if I revert 55568086.

Looking at ff6f1f564c, I don't really see anything that might be
related to git-add, git-reset, or git-diff, so I'm guessing that this
only worked before because the submodule config wasn't getting loaded
during `git add` or `git reset`. Now that the config is loaded
automatically, submodule.<name>.ignore started taking effect where it
shouldn't.

Unfortunately, this doesn't really get me much closer to finding a fix.

^ permalink raw reply	[relevance 5%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15  5:12     ` Michael Forney
  2018-11-15  6:05       ` Michael Forney
@ 2018-11-15 19:39       ` Stefan Beller
  1 sibling, 0 replies; 200+ results
From: Stefan Beller @ 2018-11-15 19:39 UTC (permalink / raw)
  To: Michael Forney; +Cc: git

> I have a git repository which contains a number of submodules that
> refer to external repositories. Some of these repositories need to
> patched in some way, so patches are stored alongside the submodules,
> and are applied when building. This mostly works fine, but causes
> submodules to show up as modified in `git status` and get updated with
> `git commit -a`. To resolve this, I've added `ignore = all` to
> .gitmodules for all the submodules that need patches applied. This
> way, I can explicitly `git add` the submodule when I want to update
> the base commit, but otherwise pretend that they are clean. This has
> worked pretty well for me, but less so since git 2.15 when this issue
> was introduced.

> > This is really bad. git-status and git-commit share some code,
> > and we'll populate the commit message with a status output.
> > So it seems reasonable to expect the status and the commit to match,
> > i.e. if status tells me there is no change, then commit should not record
> > the submodule update.
>
> I just checked and if I don't specify a message on the command-line,
> the status output in the message template *does* mention that `inner`
> is getting updated.

That's good.

> >> > There have been a couple occasions where I accidentally pushed local
> >> > changes to ignored submodules because of this. Since they don't show
> >> > up in the log output, it is difficult to figure out what actually has
> >> > gone wrong.
> >
> > How was it prevented before? Just by git commit -a not picking up the
> > submodule change?
>
> Yes. Previously, `git commit -a` would not pick up the change (unless
> I added it explicitly with `git add`), and `git log` would still show
> changes to ignored submodules (which is the behavior I want).

and both are broken currently (commit -a will commit a submodule if
it is changed, and it will also not show that in log, but it did show that
it is committing it in the commit message template)

> I just came across someone else affected by this issue:
> https://github.com/git/git/commit/55568086#commitcomment-27137460

Point taken.

^ permalink raw reply	[relevance 7%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15  6:05       ` Michael Forney
@ 2018-11-15 20:03         ` Stefan Beller
  2018-11-15 21:33           ` Michael Forney
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-15 20:03 UTC (permalink / raw)
  To: Michael Forney; +Cc: git, Brandon Williams

On Wed, Nov 14, 2018 at 10:05 PM Michael Forney <mforney@mforney.org> wrote:
>
> +bmwill
>
> On 2018-11-14, Michael Forney <mforney@mforney.org> wrote:
> > On 2018-10-25, Stefan Beller <sbeller@google.com> wrote:
> >> I guess reverting that commit is not a good idea now, as
> >> I would expect something to break.
> >>
> >> Maybe looking through the series 614ea03a71
> >> (Merge branch 'bw/submodule-config-cleanup', 2017-08-26)
> >> to understand why it happened in the context would be a good start.
> >
> > Thanks, that's a good idea. I'll take a look through that series.
>
> Interesting. If I build git from master after reverting 55568086, I do
> indeed observe the issue it claims to fix (unable to add ignored
> submodules). However, if I build from 9ef23f91fc (the immediate parent
> of 55568086), I do not see the issue.
>
> Investigating this further, it seems that 55568086 addresses an issue
> that does not appear until later on in the series in ff6f1f564c
> (submodule-config: lazy-load a repository's .gitmodules file). Perhaps
> this was a result of reordering commits during a rebase. In other
> words, I get correct behavior until 55568086, and in
> 55568086..ff6f1f564c^ if I revert 55568086.
>
> Looking at ff6f1f564c, I don't really see anything that might be
> related to git-add, git-reset, or git-diff, so I'm guessing that this
> only worked before because the submodule config wasn't getting loaded
> during `git add` or `git reset`. Now that the config is loaded
> automatically, submodule.<name>.ignore started taking effect where it
> shouldn't.
>
> Unfortunately, this doesn't really get me much closer to finding a fix.

Maybe selectively unloading or overwriting the config?

Or we can change is_submodule_ignored() in diff.c
to be only applied selectively whether we are running the
right command? For this approach we'd have to figure out the
set of commands to which the ignore config should apply or
not (and come up with a more concise documentation then)

This approach sounds appealing to me as it would cover
new commands as well and we'd only have a central point
where the decision for ignoring is made.

Stefan

^ permalink raw reply	[relevance 5%]

* Re: [PATCH 18/23] submodule: use submodule repos for object lookup
      [irrelevant]   ` <20181115195416.21890-1-jonathantanmy@google.com>
@ 2018-11-15 20:36     ` Stefan Beller
  2018-12-12 20:22       ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-15 20:36 UTC (permalink / raw)
  To: Jonathan Tan; +Cc: Junio C Hamano, git

On Thu, Nov 15, 2018 at 11:54 AM Jonathan Tan <jonathantanmy@google.com> wrote:
>
> > +/*
> > + * Initialize 'out' based on the provided submodule path.
> > + *
> > + * Unlike repo_submodule_init, this tolerates submodules not present
> > + * in .gitmodules. This function exists only to preserve historical behavior,
> > + *
> > + * Returns 0 on success, -1 when the submodule is not present.
> >   */
> > -static void show_submodule_header(struct diff_options *o, const char *path,
> > +static struct repository *open_submodule(const char *path)
>
> The function documentation needs to be reworded - there's no "out", and
> the return value is now a possibly NULL pointer to struct repository.

Noted.

>
> > +{
> > +     struct strbuf sb = STRBUF_INIT;
> > +     struct repository *out = xmalloc(sizeof(*out));
> > +
> > +     if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) {
> > +             strbuf_release(&sb);
> > +             free(out);
> > +             return NULL;
> > +     }
> > +
> > +     out->submodule_prefix = xstrdup(path);
>
> I've discussed this submodule_prefix line before [1] - do we really need
> this? Tests pass even if I remove this line.

We might not need it yet as the tests indicate, but it's the right thing to do:
/*
 * Path from the root of the top-level superproject down to this
 * repository.  This is only non-NULL if the repository is initialized
 * as a submodule of another repository.
 */

We're not (yet) using this string in our error reporting, but
I anticipate that we'll do eventually.

> Other than that, this patch looks good.

Thanks,
Stefan

^ permalink raw reply	[relevance 8%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15 20:03         ` Stefan Beller
@ 2018-11-15 21:33           ` Michael Forney
  2018-11-15 22:23             ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Michael Forney @ 2018-11-15 21:33 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

On 2018-11-15, Stefan Beller <sbeller@google.com> wrote:
> On Wed, Nov 14, 2018 at 10:05 PM Michael Forney <mforney@mforney.org>
> wrote:
>> Looking at ff6f1f564c, I don't really see anything that might be
>> related to git-add, git-reset, or git-diff, so I'm guessing that this
>> only worked before because the submodule config wasn't getting loaded
>> during `git add` or `git reset`. Now that the config is loaded
>> automatically, submodule.<name>.ignore started taking effect where it
>> shouldn't.
>>
>> Unfortunately, this doesn't really get me much closer to finding a fix.
>
> Maybe selectively unloading or overwriting the config?
>
> Or we can change is_submodule_ignored() in diff.c
> to be only applied selectively whether we are running the
> right command? For this approach we'd have to figure out the
> set of commands to which the ignore config should apply or
> not (and come up with a more concise documentation then)
>
> This approach sounds appealing to me as it would cover
> new commands as well and we'd only have a central point
> where the decision for ignoring is made.

Well, currently the submodule config can be disabled in diff_flags by
setting override_submodule_config=1. However, I'm thinking it may be
simpler to selectively *enable* the submodule config in diff_flags
where it is needed instead of disabling it everywhere else (i.e.
use_submodule_config instead of override_submodule_config).

I'm also starting to see why this is tricky. The only difference that
diff.c:run_diff_files sees between `git add inner` and `git add --all`
is whether the index entry matched the pathspec exactly or not.

Here is a work-in-progress diff that seems to have the correct
behavior in all cases I tried. Can you think of any cases that it
breaks? I'm not quite sure of the consequences of having diff_change
and diff_addremove always ignore the submodule config; git-diff and
git-status still seem to work correctly.

diff --git a/builtin/add.c b/builtin/add.c
index f65c17229..9902f7742 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -117,7 +117,6 @@ int add_files_to_cache(const char *prefix,
 	rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
 	rev.diffopt.format_callback = update_callback;
 	rev.diffopt.format_callback_data = &data;
-	rev.diffopt.flags.override_submodule_config = 1;
 	rev.max_count = 0; /* do not compare unmerged paths with stage #2 */
 	run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
 	clear_pathspec(&rev.prune_data);
diff --git a/diff-lib.c b/diff-lib.c
index 83fce5151..fbb048cca 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -68,12 +68,13 @@ static int check_removed(const struct cache_entry
*ce, struct stat *st)
 static int match_stat_with_submodule(struct diff_options *diffopt,
 				     const struct cache_entry *ce,
 				     struct stat *st, unsigned ce_option,
-				     unsigned *dirty_submodule)
+				     unsigned *dirty_submodule,
+				     int exact)
 {
 	int changed = ie_match_stat(diffopt->repo->index, ce, st, ce_option);
 	if (S_ISGITLINK(ce->ce_mode)) {
 		struct diff_flags orig_flags = diffopt->flags;
-		if (!diffopt->flags.override_submodule_config)
+		if (!diffopt->flags.override_submodule_config && !exact)
 			set_diffopt_flags_from_submodule_config(diffopt, ce->name);
 		if (diffopt->flags.ignore_submodules)
 			changed = 0;
@@ -88,7 +89,7 @@ static int match_stat_with_submodule(struct
diff_options *diffopt,

 int run_diff_files(struct rev_info *revs, unsigned int option)
 {
-	int entries, i;
+	int entries, i, matched;
 	int diff_unmerged_stage = revs->max_count;
 	unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
 			      ? CE_MATCH_RACY_IS_DIRTY : 0);
@@ -110,7 +111,8 @@ int run_diff_files(struct rev_info *revs, unsigned
int option)
 		if (diff_can_quit_early(&revs->diffopt))
 			break;

-		if (!ce_path_match(istate, ce, &revs->prune_data, NULL))
+		matched = ce_path_match(istate, ce, &revs->prune_data, NULL);
+		if (!matched)
 			continue;

 		if (ce_stage(ce)) {
@@ -226,7 +228,8 @@ int run_diff_files(struct rev_info *revs, unsigned
int option)
 			}

 			changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
-							    ce_option, &dirty_submodule);
+							    ce_option, &dirty_submodule,
+							    matched == MATCHED_EXACTLY);
 			newmode = ce_mode_from_stat(ce, st.st_mode);
 		}

@@ -292,7 +295,7 @@ static int get_stat_data(const struct cache_entry *ce,
 			return -1;
 		}
 		changed = match_stat_with_submodule(diffopt, ce, &st,
-						    0, dirty_submodule);
+						    0, dirty_submodule, 0);
 		if (changed) {
 			mode = ce_mode_from_stat(ce, st.st_mode);
 			oid = &null_oid;
diff --git a/diff.c b/diff.c
index e38d1ecaf..73dc75286 100644
--- a/diff.c
+++ b/diff.c
@@ -6209,24 +6209,6 @@ int diff_can_quit_early(struct diff_options *opt)
 		opt->flags.has_changes);
 }

-/*
- * Shall changes to this submodule be ignored?
- *
- * Submodule changes can be configured to be ignored separately for each path,
- * but that configuration can be overridden from the command line.
- */
-static int is_submodule_ignored(const char *path, struct diff_options *options)
-{
-	int ignored = 0;
-	struct diff_flags orig_flags = options->flags;
-	if (!options->flags.override_submodule_config)
-		set_diffopt_flags_from_submodule_config(options, path);
-	if (options->flags.ignore_submodules)
-		ignored = 1;
-	options->flags = orig_flags;
-	return ignored;
-}
-
 void diff_addremove(struct diff_options *options,
 		    int addremove, unsigned mode,
 		    const struct object_id *oid,
@@ -6235,7 +6217,7 @@ void diff_addremove(struct diff_options *options,
 {
 	struct diff_filespec *one, *two;

-	if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath, options))
+	if (S_ISGITLINK(mode) && options->flags.ignore_submodules)
 		return;

 	/* This may look odd, but it is a preparation for
@@ -6285,7 +6267,7 @@ void diff_change(struct diff_options *options,
 	struct diff_filepair *p;

 	if (S_ISGITLINK(old_mode) && S_ISGITLINK(new_mode) &&
-	    is_submodule_ignored(concatpath, options))
+	    options->flags.ignore_submodules)
 		return;

 	if (options->flags.reverse_diff) {

^ permalink raw reply	[relevance 6%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15 21:33           ` Michael Forney
@ 2018-11-15 22:23             ` Stefan Beller
  2018-11-16  0:31               ` Michael Forney
  0 siblings, 1 reply; 200+ results
From: Stefan Beller @ 2018-11-15 22:23 UTC (permalink / raw)
  To: Michael Forney; +Cc: git

On Thu, Nov 15, 2018 at 1:33 PM Michael Forney <mforney@mforney.org> wrote:
>
> On 2018-11-15, Stefan Beller <sbeller@google.com> wrote:
> > On Wed, Nov 14, 2018 at 10:05 PM Michael Forney <mforney@mforney.org>
> > wrote:
> >> Looking at ff6f1f564c, I don't really see anything that might be
> >> related to git-add, git-reset, or git-diff, so I'm guessing that this
> >> only worked before because the submodule config wasn't getting loaded
> >> during `git add` or `git reset`. Now that the config is loaded
> >> automatically, submodule.<name>.ignore started taking effect where it
> >> shouldn't.
> >>
> >> Unfortunately, this doesn't really get me much closer to finding a fix.
> >
> > Maybe selectively unloading or overwriting the config?
> >
> > Or we can change is_submodule_ignored() in diff.c
> > to be only applied selectively whether we are running the
> > right command? For this approach we'd have to figure out the
> > set of commands to which the ignore config should apply or
> > not (and come up with a more concise documentation then)
> >
> > This approach sounds appealing to me as it would cover
> > new commands as well and we'd only have a central point
> > where the decision for ignoring is made.
>
> Well, currently the submodule config can be disabled in diff_flags by
> setting override_submodule_config=1. However, I'm thinking it may be
> simpler to selectively *enable* the submodule config in diff_flags
> where it is needed instead of disabling it everywhere else (i.e.
> use_submodule_config instead of override_submodule_config).

This sounds like undoing the good(?) part of the series that introduced
this regression, as before that we selectively loaded the submodule
config, which lead to confusion when you forgot it. Selectively *enabling*
the submodule config sounds like that state before?

Or do we *only* talk about enabling the ignore flag, while loading the
rest of the submodule config automatic?

> I'm also starting to see why this is tricky. The only difference that
> diff.c:run_diff_files sees between `git add inner` and `git add --all`
> is whether the index entry matched the pathspec exactly or not.

Unrelated to the trickiness, I think we'd need to document the behavior
of the -a flag in git-add and git-commit better as adding the diff below
will depart from the "all" rule again, which I thought was a strong
motivator for Brandons series (IIRC).

> Here is a work-in-progress diff that seems to have the correct
> behavior in all cases I tried. Can you think of any cases that it
> breaks? I'm not quite sure of the consequences of having diff_change
> and diff_addremove always ignore the submodule config; git-diff and
> git-status still seem to work correctly.
>
> diff --git a/builtin/add.c b/builtin/add.c
> index f65c17229..9902f7742 100644
> --- a/builtin/add.c
> +++ b/builtin/add.c
> @@ -117,7 +117,6 @@ int add_files_to_cache(const char *prefix,
>         rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
>         rev.diffopt.format_callback = update_callback;
>         rev.diffopt.format_callback_data = &data;
> -       rev.diffopt.flags.override_submodule_config = 1;

This line partially reverts 5556808, taking 02f2f56bc377c28
into account.

> diff --git a/diff-lib.c b/diff-lib.c
> index 83fce5151..fbb048cca 100644
> --- a/diff-lib.c
> +++ b/diff-lib.c
> @@ -68,12 +68,13 @@ static int check_removed(const struct cache_entry
> *ce, struct stat *st)
>  static int match_stat_with_submodule(struct diff_options *diffopt,
>                                      const struct cache_entry *ce,
>                                      struct stat *st, unsigned ce_option,
> -                                    unsigned *dirty_submodule)
> +                                    unsigned *dirty_submodule,
> +                                    int exact)
> [...];

This is an interesting take so far as it is all about *detecting* change
here via stat information and not like the previous (before the regression)
where it was about correcting output.

match_stat_with_submodule would grow its documentation to be
slightly more complicated as a result.

> diff --git a/diff.c b/diff.c
> index e38d1ecaf..73dc75286 100644
> --- a/diff.c
> +++ b/diff.c
> [...]
> -static int is_submodule_ignored(const char *path, struct diff_options *options)
> -{
> [...]
> -       if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath, options))
> +       if (S_ISGITLINK(mode) && options->flags.ignore_submodules)
>                 return;

This basically inlines the function is_submodule_ignored,
except for the part:

    if (!options->flags.override_submodule_config)
        set_diffopt_flags_from_submodule_config(options, path);

but that was taken care off in match_stat_with_submodule in diff-lib?

This WIP looks really promising, thanks for looking into this!
Stefan

^ permalink raw reply	[relevance 7%]

* Re: Confusing behavior with ignored submodules and `git commit -a`
  2018-11-15 22:23             ` Stefan Beller
@ 2018-11-16  0:31               ` Michael Forney
  2018-11-27  0:03                 ` Stefan Beller
  0 siblings, 1 reply; 200+ results
From: Michael Forney @ 2018-11-16  0:31 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

On 2018-11-15, Stefan Beller <sbeller@google.com> wrote:
> On Thu, Nov 15, 2018 at 1:33 PM Michael Forney <mforney@mforney.org> wrote:
>> Well, currently the submodule config can be disabled in diff_flags by
>> setting override_submodule_config=1. However, I'm thinking it may be
>> simpler to selectively *enable* the submodule config in diff_flags
>> where it is needed instead of disabling it everywhere else (i.e.
>> use_submodule_config instead of override_submodule_config).
>
> This sounds like undoing the good(?) part of the series that introduced
> this regression, as before that we selectively loaded the submodule
> config, which lead to confusion when you forgot it. Selectively *enabling*
> the submodule config sounds like that state before?
>
> Or do we *only* talk about enabling the ignore flag, while loading the
> rest of the submodule config automatic?

Yes, that is what I meant. I believe the automatic loading of
submodule config is the right thing to do, it just uncovered cases
where the current handling of override_submodule_config is not quite
sufficient.

My suggestion of replacing override_submodule_config with
use_submodule_config is because it seems like there are fewer places
where we want to apply the ignore config than not. I think it should
only apply in diffs against the working tree and when staging changes
to the index (unless specified explicitly). The documentation just
mentions the "diff family", but all but one of the possible values for
submodule.<name>.ignore ("all") don't make sense unless comparing with
the working tree. This is also how show/log -p behaved in git <2.15.
So I think that clarifying that it is about modifications *to the
working tree* would be a good idea.

>> I'm also starting to see why this is tricky. The only difference that
>> diff.c:run_diff_files sees between `git add inner` and `git add --all`
>> is whether the index entry matched the pathspec exactly or not.
>
> Unrelated to the trickiness, I think we'd need to document the behavior
> of the -a flag in git-add and git-commit better as adding the diff below
> will depart from the "all" rule again, which I thought was a strong
> motivator for Brandons series (IIRC).

Can you explain what you mean by the "all" rule?

>> Here is a work-in-progress diff that seems to have the correct
>> behavior in all cases I tried. Can you think of any cases that it
>> breaks? I'm not quite sure of the consequences of having diff_change
>> and diff_addremove always ignore the submodule config; git-diff and
>> git-status still seem to work correctly.
>>
>> diff --git a/builtin/add.c b/builtin/add.c
>> index f65c17229..9902f7742 100644
>> --- a/builtin/add.c
>> +++ b/builtin/add.c
>> @@ -117,7 +117,6 @@ int add_files_to_cache(const char *prefix,
>>         rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
>>         rev.diffopt.format_callback = update_callback;
>>         rev.diffopt.format_callback_data = &data;
>> -       rev.diffopt.flags.override_submodule_config = 1;
>
> This line partially reverts 5556808, taking 02f2f56bc377c28
> into account.

Correct. The problem with 55568086 is that add_files_to_cache is used
by both git-add and git-commit, regardless of whether --all was
specified. So, while it made it possible to stage ignored submodules,
it also made it so the submodule ignore config was overridden in all
uses of git-add and git-commit.

So, this diff attempts to make it so the ignore config is only applied
when the pathspec matches exactly rather than just always overriding
the ignore config.

>> diff --git a/diff-lib.c b/diff-lib.c
>> index 83fce5151..fbb048cca 100644
>> --- a/diff-lib.c
>> +++ b/diff-lib.c
>> @@ -68,12 +68,13 @@ static int check_removed(const struct cache_entry
>> *ce, struct stat *st)
>>  static int match_stat_with_submodule(struct diff_options *diffopt,
>>                                      const struct cache_entry *ce,
>>                                      struct stat *st, unsigned ce_option,
>> -                                    unsigned *dirty_submodule)
>> +                                    unsigned *dirty_submodule,
>> +                                    int exact)
>> [...];
>
> This is an interesting take so far as it is all about *detecting* change
> here via stat information and not like the previous (before the regression)
> where it was about correcting output.
>
> match_stat_with_submodule would grow its documentation to be
> slightly more complicated as a result.

Yes, this is one part I'm not quite happy with. I wonder if instead
match_stat_with_submodule could be made simpler by moving the
ie_match_stat call up to the two call sites, and then it could be
selectively called by run_diff_files depending on the value of
matched.

>> diff --git a/diff.c b/diff.c
>> index e38d1ecaf..73dc75286 100644
>> --- a/diff.c
>> +++ b/diff.c
>> [...]
>> -static int is_submodule_ignored(const char *path, struct diff_options
>> *options)
>> -{
>> [...]
>> -       if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath,
>> options))
>> +       if (S_ISGITLINK(mode) && options->flags.ignore_submodules)
>>                 return;
>
> This basically inlines the function is_submodule_ignored,
> except for the part:
>
>     if (!options->flags.override_submodule_config)
>         set_diffopt_flags_from_submodule_config(options, path);
>
> but that was taken care off in match_stat_with_submodule in diff-lib?

Yeah, since run_diff_files already skips ignored submodules (except if
given by name), and we still want the changes to be applied to the
index. Like I said, I'm not really sure if there are any other uses of
diff_change and diff_addremove where we actually do want the .ignore
config applied.

But, maybe if I instead left
`rev.diffopt.flags.override_submodule_config = 1` in builtin/add.c and
changed the condition in match_stat_with_submodule from `&& !exact` to
`|| !exact`, these functions would not need to be changed. In other
words, we relax the behavior when override_submodule_config is
specified, rather than making it stricter when it is not specified.

Testing this out, it looks like it fixes the behavior with add/commit
--all, but still omits ignored submodules in diffs between commits
(which is not the behavior I expect, see above). So, without the
changes to diff_change/diff_addremove we probably would need to add
override_submodule_config=1 to even more places.

Too many negatives are making this difficult to reason about.

> This WIP looks really promising, thanks for looking into this!

Thanks for taking the time to help me!

^ permalink raw reply	[relevance 6%]

* [ANNOUNCE] Git v2.20.0-rc0
@ 2018-11-18 14:20 Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-11-18 14:20 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

An early preview release Git v2.20.0-rc0 is now available for
testing at the usual places.  It is comprised of 887 non-merge
commits since v2.19.0, contributed by 71 people, 23 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.20.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.19.0 are as follows.
Welcome to the Git development community!

  Aaron Lindsay, Alexander Pyhalov, Anton Serbulov, Brendan
  Forster, Carlo Marcelo Arenas Belón, Daniels Umanovskis, David
  Zych, Frederick Eaton, James Knight, Jann Horn, Joshua Watt,
  Loo Rong Jie, Lucas De Marchi, Matthew DeVore, Mihir Mehta,
  Nickolai Belakovski, Roger Strain, Sam McKelvie, Saulius Gurklys,
  Shulhan, Steven Fernandez, Strain, Roger L, and Tim Schumacher.

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

  Ævar Arnfjörð Bjarmason, Alban Gruin, Andreas Gruenbacher,
  Andreas Heiduk, Antonio Ospite, Ben Peart, Brandon Williams,
  brian m. carlson, Christian Couder, Christian Hesse, Denton Liu,
  Derrick Stolee, Elijah Newren, Eric Sunshine, Jeff Hostetler,
  Jeff King, Johannes Schindelin, Johannes Sixt, Jonathan Nieder,
  Jonathan Tan, Josh Steadmon, Junio C Hamano, Karsten Blees,
  Luke Diamand, Martin Ågren, Max Kirillov, Michael Witten,
  Michał Górny, Nguyễn Thái Ngọc Duy, Noam Postavsky,
  Olga Telezhnaya, Phillip Wood, Pratik Karki, Rafael Ascensão,
  Ralf Thielow, Ramsay Jones, Rasmus Villemoes, René Scharfe,
  Sebastian Staudt, Stefan Beller, Stephen P. Smith, Steve Hoelzer,
  SZEDER Gábor, Tao Qingyun, Taylor Blau, Thomas Gummerer,
  Torsten Bögershausen, and Uwe Kleine-König.

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

Git Release Notes
=========================

Backward Compatibility Notes
----------------------------

 * "git branch -l <foo>" used to be a way to ask a reflog to be
   created while creating a new branch, but that is no longer the
   case.  It is a short-hand for "git branch --list <foo>" now.

 * "git push" into refs/tags/* hierarchy is rejected without getting
   forced, but "git fetch" (misguidedly) used the "fast forwarding"
   rule used for the refs/heads/* hierarchy; this has been corrected,
   which means some fetches of tags that did not fail with older
   version of Git will fail without "--force" with this version.

 * "git help -a" now gives verbose output (same as "git help -av").
   Those who want the old output may say "git help --no-verbose -a"..

 * "git cpn --help", when "cpn" is an alias to, say, "cherry-pick -n",
   reported only the alias expansion of "cpn" in earlier versions of
   Git.  It now runs "git cherry-pick --help" to show the manual page
   of the command, while sending the alias expansion to the standard
   error stream.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by". This is a backward-incompatible
   change.  Adding "--suppress-cc=misc-by" on the command line, or
   setting sendemail.suppresscc configuration variable to "misc-by",
   can be used to disable this behaviour.


Updates since v2.19
-------------------

UI, Workflows & Features

 * Running "git clone" against a project that contain two files with
   pathnames that differ only in cases on a case insensitive
   filesystem would result in one of the files lost because the
   underlying filesystem is incapable of holding both at the same
   time.  An attempt is made to detect such a case and warn.

 * "git checkout -b newbranch [HEAD]" should not have to do as much as
   checking out a commit different from HEAD.  An attempt is made to
   optimize this special case.

 * "git rev-list --stdin </dev/null" used to be an error; it now shows
   no output without an error.  "git rev-list --stdin --default HEAD"
   still falls back to the given default when nothing is given on the
   standard input.

 * Lift code from GitHub to restrict delta computation so that an
   object that exists in one fork is not made into a delta against
   another object that does not appear in the same forked repository.

 * "git format-patch" learned new "--interdiff" and "--range-diff"
   options to explain the difference between this version and the
   previous attempt in the cover letter (or after the three-dashes as
   a comment).

 * "git mailinfo" used in "git am" learned to make a best-effort
   recovery of a patch corrupted by MUA that sends text/plain with
   format=flawed option.
   (merge 3aa4d81f88 rs/mailinfo-format-flowed later to maint).

 * The rules used by "git push" and "git fetch" to determine if a ref
   can or cannot be updated were inconsistent; specifically, fetching
   to update existing tags were allowed even though tags are supposed
   to be unmoving anchoring points.  "git fetch" was taught to forbid
   updates to existing tags without the "--force" option.

 * "git multi-pack-index" learned to detect corruption in the .midx
   file it uses, and this feature has been integrated into "git fsck".

 * Generation of (experimental) commit-graph files have so far been
   fairly silent, even though it takes noticeable amount of time in a
   meaningfully large repository.  The users will now see progress
   output.

 * The minimum version of Windows supported by Windows port of Git is
   now set to Vista.

 * The completion script (in contrib/) learned to complete a handful of
   options "git stash list" command takes.

 * The completion script (in contrib/) learned that "git fetch
   --multiple" only takes remote names as arguments and no refspecs.

 * "git status" learns to show progress bar when refreshing the index
   takes a long time.
   (merge ae9af12287 nd/status-refresh-progress later to maint).

 * "git help -a" and "git help -av" give different pieces of
   information, and generally the "verbose" version is more friendly
   to the new users.  "git help -a" by default now uses the more
   verbose output (with "--no-verbose", you can go back to the
   original).  Also "git help -av" now lists aliases and external
   commands, which it did not used to.

 * Unlike "grep", "git grep" by default recurses to the whole tree.
   The command learned "git grep --recursive" option, so that "git
   grep --no-recursive" can serve as a synonym to setting the
   max-depth to 0.

 * When pushing into a repository that borrows its objects from an
   alternate object store, "git receive-pack" that responds to the
   push request on the other side lists the tips of refs in the
   alternate to reduce the amount of objects transferred.  This
   sometimes is detrimental when the number of refs in the alternate
   is absurdly large, in which case the bandwidth saved in potentially
   fewer objects transferred is wasted in excessively large ref
   advertisement.  The alternate refs that are advertised are now
   configurable with a pair of configuration variables.

 * "git cmd --help" when "cmd" is aliased used to only say "cmd is
   aliased to ...".  Now it shows that to the standard error stream
   and runs "git $cmd --help" where $cmd is the first word of the
   alias expansion.

 * The documentation of "git gc" has been updated to mention that it
   is no longer limited to "pruning away crufts" but also updates
   ancillary files like commit-graph as a part of repository
   optimization.

 * "git p4 unshelve" improvements.

 * The logic to select the default user name and e-mail on Windows has
   been improved.
   (merge 501afcb8b0 js/mingw-default-ident later to maint).

 * The "rev-list --filter" feature learned to exclude all trees via
   "tree:0" filter.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by"; --suppress-cc=misc-by on the
   command line, or setting sendemail.suppresscc configuration
   variable to "misc-by", can be used to disable this behaviour.

 * Developer builds now uses -Wunused-function compilation option.

 * One of our CI tests to run with "unusual/experimental/random"
   settings now also uses commit-graph and midx.

 * "git mergetool" learned to take the "--[no-]gui" option, just like
   "git difftool" does.

 * "git rebase -i" learned a new insn, 'break', that the user can
   insert in the to-do list.  Upon hitting it, the command returns
   control back to the user.

 * New "--pretty=format:" placeholders %GF and %GP that show the GPG
   key fingerprints have been invented.

 * On platforms with recent cURL library, http.sslBackend configuration
   variable can be used to choose a different SSL backend at runtime.
   The Windows port uses this mechanism to switch between OpenSSL and
   Secure Channel while talking over the HTTPS protocol.

 * "git send-email" learned to disable SMTP authentication via the
   "--smtp-auth=none" option, even when the smtp username is given
   (which turns the authentication on by default).

 * A fourth class of configuration files (in addition to the
   traditional "system wide", "per user in the $HOME directory" and
   "per repository in the $GIT_DIR/config") has been introduced so
   that different worktrees that share the same repository (hence the
   same $GIT_DIR/config file) can use different customization.

 * A pattern with '**' that does not have a slash on either side used
   to be an invalid one, but the code now treats such double-asterisks
   the same way as two normal asterisks that happen to be adjacent to
   each other.
   (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).

 * The "--no-patch" option, which can be used to get a high-level
   overview without the actual line-by-line patch difference shown, of
   the "range-diff" command was earlier broken, which has been
   corrected.

 * The recently merged "rebase in C" has an escape hatch to use the
   scripted version when necessary, but it hasn't been documented,
   which has been corrected.


Performance, Internal Implementation, Development Support etc.

 * When there are too many packfiles in a repository (which is not
   recommended), looking up an object in these would require
   consulting many pack .idx files; a new mechanism to have a single
   file that consolidates all of these .idx files is introduced.

 * "git submodule update" is getting rewritten piece-by-piece into C.

 * The code for computing history reachability has been shuffled,
   obtained a bunch of new tests to cover them, and then being
   improved.

 * The unpack_trees() API used in checking out a branch and merging
   walks one or more trees along with the index.  When the cache-tree
   in the index tells us that we are walking a tree whose flattened
   contents is known (i.e. matches a span in the index), as linearly
   scanning a span in the index is much more efficient than having to
   open tree objects recursively and listing their entries, the walk
   can be optimized, which has been done.

 * When creating a thin pack, which allows objects to be made into a
   delta against another object that is not in the resulting pack but
   is known to be present on the receiving end, the code learned to
   take advantage of the reachability bitmap; this allows the server
   to send a delta against a base beyond the "boundary" commit.

 * spatch transformation to replace boolean uses of !hashcmp() to
   newly introduced oideq() is added, and applied, to regain
   performance lost due to support of multiple hash algorithms.

 * Fix a bug in which the same path could be registered under multiple
   worktree entries if the path was missing (for instance, was removed
   manually).  Also, as a convenience, expand the number of cases in
   which --force is applicable.

 * Split Documentation/config.txt for easier maintenance.
   (merge 6014363f0b nd/config-split later to maint).

 * Test helper binaries clean-up.
   (merge c9a1f4161f nd/test-tool later to maint).

 * Various tests have been updated to make it easier to swap the
   hash function used for object identification.
   (merge ae0c89d41b bc/hash-independent-tests later to maint).

 * Update fsck.skipList implementation and documentation.
   (merge 371a655074 ab/fsck-skiplist later to maint).

 * An alias that expands to another alias has so far been forbidden,
   but now it is allowed to create such an alias.

 * Various test scripts have been updated for style and also correct
   handling of exit status of various commands.

 * "gc --auto" ended up calling exit(-1) upon error, which has been
   corrected to use exit(1).  Also the error reporting behaviour when
   daemonized has been updated to exit with zero status when stopping
   due to a previously discovered error (which implies there is no
   point running gc to improve the situation); we used to exit with
   failure in such a case.

 * Various codepaths in the core-ish part learned to work on an
   arbitrary in-core index structure, not necessarily the default
   instance "the_index".
   (merge b3c7eef9b0 nd/the-index later to maint).

 * Code clean-up in the internal machinery used by "git status" and
   "git commit --dry-run".
   (merge 73ba5d78b4 ss/wt-status-committable later to maint).

 * Some environment variables that control the runtime options of Git
   used during tests are getting renamed for consistency.
   (merge 4231d1ba99 bp/rename-test-env-var later to maint).

 * A new extension to the index file has been introduced, which allows
   the index file to be read in parallel for performance.

 * The oidset API was built on top of the oidmap API which in turn is
   on the hashmap API.  Replace the implementation to build on top of
   the khash API and gain performance.

 * Over some transports, fetching objects with an exact commit object
   name can be done without first seeing the ref advertisements.  The
   code has been optimized to exploit this.

 * In a partial clone that will lazily be hydrated from the
   originating repository, we generally want to avoid "does this
   object exist (locally)?" on objects that we deliberately omitted
   when we created the clone.  The cache-tree codepath (which is used
   to write a tree object out of the index) however insisted that the
   object exists, even for paths that are outside of the partial
   checkout area.  The code has been updated to avoid such a check.

 * To help developers, an EditorConfig file that attempts to follow
   the project convention has been added.
   (merge b548d698a0 bc/editorconfig later to maint).

 * The result of coverage test can be combined with "git blame" to
   check the test coverage of code introduced recently with a new
   'coverage-diff' tool (in contrib/).
   (merge 783faedd65 ds/coverage-diff later to maint).

 * An experiment to fuzz test a few areas, hopefully we can gain more
   coverage to various areas.

 * More codepaths are moving away from hardcoded hash sizes.

 * The way the Windows port figures out the current directory has been
   improved.

 * The way DLLs are loaded on the Windows port has been improved.

 * Some tests have been reorganized and renamed; "ls t/" now gives a
   better overview of what is tested for these scripts than before.

 * "git rebase" and "git rebase -i" have been reimplemented in C.

 * Windows port learned to use nano-second resolution file timestamps.

 * The overly large Documentation/config.txt file have been split into
   million little pieces.  This potentially allows each individual piece
   included into the manual page of the command it affects more easily.

 * Replace three string-list instances used as look-up tables in "git
   fetch" with hashmaps.

 * Unify code to read the author-script used in "git am" and the
   commands that use the sequencer machinery, e.g. "git rebase -i".

 * In preparation to the day when we can deprecate and remove the
   "rebase -p", make sure we can skip and later remove tests for
   it.

 * The history traversal used to implement the tag-following has been
   optimized by introducing a new helper.

 * The helper function to refresh the cached stat information in the
   in-core index has learned to perform the lstat() part of the
   operation in parallel on multi-core platforms.

 * The code to traverse objects for reachability, used to decide what
   objects are unreferenced and expendable, have been taught to also
   consider per-worktree refs of other worktrees as starting points to
   prevent data loss.

 * "git add" needs to internally run "diff-files" equivalent, and the
   codepath learned the same optimization as "diff-files" has to run
   lstat(2) in parallel to find which paths have been updated in the
   working tree.

 * The procedure to install dependencies before testing at Travis CI
   is getting revamped for both simplicity and flexibility, taking
   advantage of the recent move to the vm-based environment.

 * The support for format-patch (and send-email) by the command-line
   completion script (in contrib/) has been simplified a bit.

 * The revision walker machinery learned to take advantage of the
   commit generation numbers stored in the commit-graph file.

 * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".

 * The way -lcurl library gets linked has been simplified by taking
   advantage of the fact that we can just ask curl-config command how.

 * Various functions have been audited for "-Wunused-parameter" warnings
   and bugs in them got fixed.

 * A sanity check for start-up sequence has been added in the config
   API codepath.

 * The build procedure to link for fuzzing test has been made
   customizable with a new Makefile variable.

 * The way "git rebase" parses and forwards the command line options
   meant for underlying "git am" has been revamped, which fixed for
   options with parameters that were not passed correctly.


Fixes since v2.19
-----------------

 * "git interpret-trailers" and its underlying machinery had a buggy
   code that attempted to ignore patch text after commit log message,
   which triggered in various codepaths that will always get the log
   message alone and never get such an input.
   (merge 66e83d9b41 jk/trailer-fixes later to maint).

 * Malformed or crafted data in packstream can make our code attempt
   to read or write past the allocated buffer and abort, instead of
   reporting an error, which has been fixed.

 * "git rebase -i" did not clear the state files correctly when a run
   of "squash/fixup" is aborted and then the user manually amended the
   commit instead, which has been corrected.
   (merge 10d2f35436 js/rebase-i-autosquash-fix later to maint).

 * When fsmonitor is in use, after operation on submodules updates
   .gitmodules, we lost track of the fact that we did so and relied on
   stale fsmonitor data.
   (merge 43f1180814 bp/mv-submodules-with-fsmonitor later to maint).

 * Fix for a long-standing bug that leaves the index file corrupt when
   it shrinks during a partial commit.
   (merge 6c003d6ffb jk/reopen-tempfile-truncate later to maint).

 * Further fix for O_APPEND emulation on Windows
   (merge eeaf7ddac7 js/mingw-o-append later to maint).

 * A corner case bugfix in "git rerere" code.
   (merge ad2bf0d9b4 en/rerere-multi-stage-1-fix later to maint).

 * "git add ':(attr:foo)'" is not supported and is supposed to be
   rejected while the command line arguments are parsed, but we fail
   to reject such a command line upfront.
   (merge 84d938b732 nd/attr-pathspec-fix later to maint).

 * Recent update broke the reachability algorithm when refs (e.g.
   tags) that point at objects that are not commit were involved,
   which has been fixed.

 * "git rebase" etc. in Git 2.19 fails to abort when given an empty
   commit log message as result of editing, which has been corrected.
   (merge a3ec9eaf38 en/sequencer-empty-edit-result-aborts later to maint).

 * The code to backfill objects in lazily cloned repository did not
   work correctly, which has been corrected.
   (merge e68302011c jt/lazy-object-fetch-fix later to maint).

 * Update error messages given by "git remote" and make them consistent.
   (merge 5025425dff ms/remote-error-message-update later to maint).

 * "git update-ref" learned to make both "--no-deref" and "--stdin"
   work at the same time.
   (merge d345e9fbe7 en/update-ref-no-deref-stdin later to maint).

 * Recently added "range-diff" had a corner-case bug to cause it
   segfault, which has been corrected.
   (merge e467a90c7a tg/range-diff-corner-case-fix later to maint).

 * The recently introduced commit-graph auxiliary data is incompatible
   with mechanisms such as replace & grafts that "breaks" immutable
   nature of the object reference relationship.  Disable optimizations
   based on its use (and updating existing commit-graph) when these
   incompatible features are in use in the repository.
   (merge 829a321569 ds/commit-graph-with-grafts later to maint).

 * The mailmap file update.
   (merge 255eb03edf jn/mailmap-update later to maint).

 * The code in "git status" sometimes hit an assertion failure.  This
   was caused by a structure that was reused without cleaning the data
   used for the first run, which has been corrected.
   (merge 3e73cc62c0 en/status-multiple-renames-to-the-same-target-fix later to maint).

 * "git fetch $repo $object" in a partial clone did not correctly
   fetch the asked-for object that is referenced by an object in
   promisor packfile, which has been fixed.

 * A corner-case bugfix.
   (merge c5cbb27cb5 sm/show-superproject-while-conflicted later to maint).

 * Various fixes to "diff --color-moved-ws".

 * A partial clone that is configured to lazily fetch missing objects
   will on-demand issue a "git fetch" request to the originating
   repository to fill not-yet-obtained objects.  The request has been
   optimized for requesting a tree object (and not the leaf blob
   objects contained in it) by telling the originating repository that
   no blobs are needed.
   (merge 4c7f9567ea jt/non-blob-lazy-fetch later to maint).

 * The codepath to support the experimental split-index mode had
   remaining "racily clean" issues fixed.
   (merge 4c490f3d32 sg/split-index-racefix later to maint).

 * "git log --graph" showing an octopus merge sometimes miscounted the
   number of display columns it is consuming to show the merge and its
   parent commits, which has been corrected.
   (merge 04005834ed np/log-graph-octopus-fix later to maint).

 * "git range-diff" did not work well when the compared ranges had
   changes in submodules and the "--submodule=log" was used.

 * The implementation of run_command() API on the UNIX platforms had a
   bug that caused a command not on $PATH to be found in the current
   directory.
   (merge f67b980771 jk/run-command-notdot later to maint).

 * A mutex used in "git pack-objects" were not correctly initialized
   and this caused "git repack" to dump core on Windows.
   (merge 34204c8166 js/pack-objects-mutex-init-fix later to maint).

 * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
   Windows would strip initial parts from the paths because they
   were not recognized as absolute, which has been corrected.
   (merge ffd04e92e2 js/diff-notice-has-drive-prefix later to maint).

 * The receive.denyCurrentBranch=updateInstead codepath kicked in even
   when the push should have been rejected due to other reasons, such
   as it does not fast-forward or the update-hook rejects it, which
   has been corrected.
   (merge b072a25fad jc/receive-deny-current-branch-fix later to maint).

 * The logic to determine the archive type "git archive" uses did not
   correctly kick in for "git archive --remote", which has been
   corrected.

 * "git repack" in a shallow clone did not correctly update the
   shallow points in the repository, leading to a repository that
   does not pass fsck.
   (merge 5dcfbf564c js/shallow-and-fetch-prune later to maint).

 * Some codepaths failed to form a proper URL when .gitmodules record
   the URL to a submodule repository as relative to the repository of
   superproject, which has been corrected.
   (merge e0a862fdaf sb/submodule-url-to-absolute later to maint).

 * "git fetch" over protocol v2 into a shallow repository failed to
   fetch full history behind a new tip of history that was diverged
   before the cut-off point of the history that was previously fetched
   shallowly.

 * The command line completion machinery (in contrib/) has been
   updated to allow the completion script to tweak the list of options
   that are reported by the parse-options machinery correctly.
   (merge 276b49ff34 nd/completion-negation later to maint).

 * Operations on promisor objects make sense in the context of only a
   small subset of the commands that internally use the revisions
   machinery, but the "--exclude-promisor-objects" option were taken
   and led to nonsense results by commands like "log", to which it
   didn't make much sense.  This has been corrected.
   (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).

 * The "container" mode of TravisCI is going away.  Our .travis.yml
   file is getting prepared for the transition.
   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).

 * Our test scripts can now take the '-V' option as a synonym for the
   '--verbose-log' option.
   (merge a5f52c6dab sg/test-verbose-log later to maint).

 * A regression in Git 2.12 era made "git fsck" fall into an infinite
   loop while processing truncated loose objects.
   (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).

 * "git ls-remote $there foo" was broken by recent update for the
   protocol v2 and stopped showing refs that match 'foo' that are not
   refs/{heads,tags}/foo, which has been fixed.
   (merge 6a139cdd74 jk/proto-v2-ref-prefix-fix later to maint).

 * Additional comment on a tricky piece of code to help developers.
   (merge 0afbe3e806 jk/stream-pack-non-delta-clarification later to maint).

 * A couple of tests used to leave the repository in a state that is
   deliberately corrupt, which have been corrected.
   (merge aa984dbe5e ab/pack-tests-cleanup later to maint).

 * The submodule support has been updated to read from the blob at
   HEAD:.gitmodules when the .gitmodules file is missing from the
   working tree.
   (merge 2b1257e463 ao/submodule-wo-gitmodules-checked-out later to maint).

 * "git fetch" was a bit loose in parsing responses from the other side
   when talking over the protocol v2.

 * "git rev-parse --exclude=* --branches --branches"  (i.e. first
   saying "add only things that do not match '*' out of all branches"
   and then adding all branches, without any exclusion this time")
   worked as expected, but "--exclude=* --all --all" did not work the
   same way, which has been fixed.
   (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).

 * "git send-email --transfer-encoding=..." in recent versions of Git
   sometimes produced an empty "Content-Transfer-Encoding:" header,
   which has been corrected.
   (merge 3c88e46f1a al/send-email-auto-cte-fixup later to maint).

 * The interface into "xdiff" library used to discover the offset and
   size of a generated patch hunk by first formatting it into the
   textual hunk header "@@ -n,m +k,l @@" and then parsing the numbers
   out.  A new interface has been introduced to allow callers a more
   direct access to them.
   (merge 5eade0746e jk/xdiff-interface later to maint).

 * Pathspec matching against a tree object were buggy when negative
   pathspec elements were involved, which has been fixed.
   (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).

 * "git merge" and "git pull" that merges into an unborn branch used
   to completely ignore "--verify-signatures", which has been
   corrected.
   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).

 * "git rebase --autostash" did not correctly re-attach the HEAD at times.

 * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
   quite work, which has been corrected.
   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).

 * When editing a patch in a "git add -i" session, a hunk could be
   made to no-op.  The "git apply" program used to reject a patch with
   such a no-op hunk to catch user mistakes, but it is now updated to
   explicitly allow a no-op hunk in an edited patch.
   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).

 * The URL to an MSDN page in a comment has been updated.
   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).

 * "git ls-remote --sort=<thing>" can feed an object that is not yet
   available into the comparison machinery and segfault, which has
   been corrected to check such a request upfront and reject it.

 * When "git bundle" aborts due to an empty commit ranges
   (i.e. resulting in an empty pack), it left a file descriptor to an
   lockfile open, which resulted in leftover lockfile on Windows where
   you cannot remove a file with an open file descriptor.  This has
   been corrected.
   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).

 * Code cleanup, docfix, build fix, etc.
   (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
   (merge b9b07efdb2 tg/conflict-marker-size later to maint).
   (merge fa0aeea770 sg/doc-trace-appends later to maint).
   (merge d64324cb60 tb/void-check-attr later to maint).
   (merge c3b9bc94b9 en/double-semicolon-fix later to maint).
   (merge 79336116f5 sg/t3701-tighten-trace later to maint).
   (merge 801fa63a90 jk/dev-build-format-security later to maint).
   (merge 0597dd62ba sb/string-list-remove-unused later to maint).
   (merge db2d36fad8 bw/protocol-v2 later to maint).
   (merge 456d7cd3a9 sg/split-index-test later to maint).
   (merge 7b6057c852 tq/refs-internal-comment-fix later to maint).
   (merge 29e8dc50ad tg/t5551-with-curl-7.61.1 later to maint).
   (merge 55f6bce2c9 fe/doc-updates later to maint).
   (merge 7987d2232d jk/check-everything-connected-is-long-gone later to maint).
   (merge 4ba3c9be47 dz/credential-doc-url-matching-rules later to maint).
   (merge 4c399442f7 ma/commit-graph-docs later to maint).
   (merge fc0503b04e ma/t1400-undebug-test later to maint).
   (merge e56b53553a nd/packobjectshook-doc-fix later to maint).
   (merge c56170a0c4 ma/mailing-list-address-in-git-help later to maint).
   (merge 6e8fc70fce rs/sequencer-oidset-insert-avoids-dups later to maint).
   (merge ad0b8f9575 mw/doc-typofixes later to maint).
   (merge d9f079ad1a jc/how-to-document-api later to maint).
   (merge b1492bf315 ma/t7005-bash-workaround later to maint).
   (merge ac1f98a0df du/rev-parse-is-plumbing later to maint).
   (merge ca8ed443a5 mm/doc-no-dashed-git later to maint).
   (merge ce366a8144 du/get-tar-commit-id-is-plumbing later to maint).
   (merge 61018fe9e0 du/cherry-is-plumbing later to maint).
   (merge c7e5fe79b9 sb/strbuf-h-update later to maint).
   (merge 8d2008196b tq/branch-create-wo-branch-get later to maint).
   (merge 2e3c894f4b tq/branch-style-fix later to maint).
   (merge c5d844af9c sg/doc-show-branch-typofix later to maint).
   (merge 081d91618b ah/doc-updates later to maint).
   (merge b84c783882 jc/cocci-preincr later to maint).
   (merge 5e495f8122 uk/merge-subtree-doc-update later to maint).
   (merge aaaa881822 jk/uploadpack-packobjectshook-fix later to maint).
   (merge 3063477445 tb/char-may-be-unsigned later to maint).
   (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
   (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).

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

Changes since v2.19.0 are as follows:

Aaron Lindsay (1):
      send-email: avoid empty transfer encoding header

Alban Gruin (21):
      sequencer: make three functions and an enum from sequencer.c public
      rebase -i: rewrite append_todo_help() in C
      editor: add a function to launch the sequence editor
      rebase -i: rewrite the edit-todo functionality in C
      sequencer: add a new function to silence a command, except if it fails
      rebase -i: rewrite setup_reflog_action() in C
      rebase -i: rewrite checkout_onto() in C
      sequencer: refactor append_todo_help() to write its message to a buffer
      sequencer: change the way skip_unnecessary_picks() returns its result
      t3404: todo list with commented-out commands only aborts
      rebase -i: rewrite complete_action() in C
      rebase -i: remove unused modes and functions
      rebase -i: implement the logic to initialize $revisions in C
      rebase -i: rewrite the rest of init_revisions_and_shortrevisions() in C
      rebase -i: rewrite write_basic_state() in C
      rebase -i: rewrite init_basic_state() in C
      rebase -i: implement the main part of interactive rebase as a builtin
      rebase--interactive2: rewrite the submodes of interactive rebase in C
      rebase -i: remove git-rebase--interactive.sh
      rebase -i: move rebase--helper modes to rebase--interactive
      p3400: replace calls to `git checkout -b' by `git checkout -B'

Alexander Pyhalov (1):
      t7005-editor: quote filename to fix whitespace-issue

Andreas Gruenbacher (1):
      rev-parse: clear --exclude list after 'git rev-parse --all'

Andreas Heiduk (6):
      doc: clarify boundaries of 'git worktree list --porcelain'
      doc: fix ASCII art tab spacing
      doc: fix inappropriate monospace formatting
      doc: fix descripion for 'git tag --format'
      doc: fix indentation of listing blocks in gitweb.conf.txt
      doc: fix formatting in git-update-ref

Anton Serbulov (1):
      mingw: fix getcwd when the parent directory cannot be queried

Antonio Ospite (10):
      submodule: add a print_config_from_gitmodules() helper
      submodule: factor out a config_set_in_gitmodules_file_gently function
      t7411: merge tests 5 and 6
      t7411: be nicer to future tests and really clean things up
      submodule--helper: add a new 'config' subcommand
      submodule: use the 'submodule--helper config' command
      t7506: clean up .gitmodules properly before setting up new scenario
      submodule: add a helper to check if it is safe to write to .gitmodules
      submodule: support reading .gitmodules when it's not in the working tree
      t/helper: add test-submodule-nested-repo-config

Ben Peart (19):
      checkout: optimize "git checkout -b <new_branch>"
      git-mv: allow submodules and fsmonitor to work together
      t/README: correct spelling of "uncommon"
      preload-index: use git_env_bool() not getenv() for customization
      fsmonitor: update GIT_TEST_FSMONITOR support
      read-cache: update TEST_GIT_INDEX_VERSION support
      preload-index: update GIT_FORCE_PRELOAD_TEST support
      read-cache: clean up casting and byte decoding
      eoie: add End of Index Entry (EOIE) extension
      config: add new index.threads config setting
      read-cache: load cache extensions on a worker thread
      ieot: add Index Entry Offset Table (IEOT) extension
      read-cache: load cache entries on worker threads
      reset: don't compute unstaged changes after reset when --quiet
      reset: add new reset.quiet config setting
      reset: warn when refresh_index() takes more than 2 seconds
      speed up refresh_index() by utilizing preload_index()
      add: speed up cmd_add() by utilizing read_cache_preload()
      refresh_index: remove unnecessary calls to preload_index()

Brandon Williams (1):
      config: document value 2 for protocol.version

Brendan Forster (1):
      http: add support for disabling SSL revocation checks in cURL

Carlo Marcelo Arenas Belón (8):
      unpack-trees: avoid dead store for struct progress
      multi-pack-index: avoid dead store for struct progress
      read-cache: use of memory after it is freed
      commit-slabs: move MAYBE_UNUSED out
      khash: silence -Wunused-function for delta-islands
      compat: make sure git_mmap is not expected to write
      sequencer: cleanup for gcc warning in non developer mode
      builtin/notes: remove unnecessary free

Christian Couder (3):
      pack-objects: refactor code into compute_layer_order()
      pack-objects: move tree_depth into 'struct packing_data'
      pack-objects: move 'layer' into 'struct packing_data'

Christian Hesse (2):
      subtree: add build targets 'man' and 'html'
      subtree: make install targets depend on build targets

Daniels Umanovskis (3):
      doc: move git-rev-parse from porcelain to plumbing
      doc: move git-get-tar-commit-id to plumbing
      doc: move git-cherry to plumbing

David Zych (1):
      doc: clarify gitcredentials path component matching

Denton Liu (3):
      mergetool: accept -g/--[no-]gui as arguments
      completion: support `git mergetool --[no-]gui`
      doc: document diff/merge.guitool config keys

Derrick Stolee (92):
      multi-pack-index: add design document
      multi-pack-index: add format details
      multi-pack-index: add builtin
      multi-pack-index: add 'write' verb
      midx: write header information to lockfile
      multi-pack-index: load into memory
      t5319: expand test data
      packfile: generalize pack directory list
      multi-pack-index: read packfile list
      multi-pack-index: write pack names in chunk
      midx: read pack names into array
      midx: sort and deduplicate objects from packfiles
      midx: write object ids in a chunk
      midx: write object id fanout chunk
      midx: write object offsets
      config: create core.multiPackIndex setting
      midx: read objects from multi-pack-index
      midx: use midx in abbreviation calculations
      midx: use existing midx when writing new one
      midx: use midx in approximate_object_count
      midx: prevent duplicate packfile loads
      packfile: skip loading index if in multi-pack-index
      midx: clear midx on repack
      commit-reach: move walk methods from commit.c
      commit.h: remove method declarations
      commit-reach: move ref_newer from remote.c
      commit-reach: move commit_contains from ref-filter
      upload-pack: make reachable() more generic
      upload-pack: refactor ok_to_give_up()
      upload-pack: generalize commit date cutoff
      commit-reach: move can_all_from_reach_with_flags
      test-reach: create new test tool for ref_newer
      test-reach: test in_merge_bases
      test-reach: test is_descendant_of
      test-reach: test get_merge_bases_many
      test-reach: test reduce_heads
      test-reach: test can_all_from_reach_with_flags
      test-reach: test commit_contains
      commit-reach: replace ref_newer logic
      commit-reach: make can_all_from_reach... linear
      commit-reach: use can_all_from_reach
      multi-pack-index: provide more helpful usage info
      multi-pack-index: store local property
      midx: mark bad packed objects
      midx: stop reporting garbage
      midx: fix bug that skips midx with alternates
      packfile: add all_packs list
      treewide: use get_all_packs
      midx: test a few commands that use get_all_packs
      pack-objects: consider packs in multi-pack-index
      commit-graph: update design document
      test-repository: properly init repo
      commit-graph: not compatible with replace objects
      commit-graph: not compatible with grafts
      commit-graph: not compatible with uninitialized repo
      commit-graph: close_commit_graph before shallow walk
      commit-graph: define GIT_TEST_COMMIT_GRAPH
      t3206-range-diff.sh: cover single-patch case
      t5318: use test_oid for HASH_LEN
      multi-pack-index: add 'verify' verb
      multi-pack-index: verify bad header
      multi-pack-index: verify corrupt chunk lookup table
      multi-pack-index: verify packname order
      multi-pack-index: verify missing pack
      multi-pack-index: verify oid fanout order
      multi-pack-index: verify oid lookup order
      multi-pack-index: fix 32-bit vs 64-bit size check
      multi-pack-index: verify object offsets
      multi-pack-index: report progress during 'verify'
      fsck: verify multi-pack-index
      commit-reach: properly peel tags
      commit-reach: fix memory and flag leaks
      commit-reach: cleanups in can_all_from_reach...
      commit-graph: clean up leaked memory during write
      commit-graph: reduce initial oid allocation
      midx: fix broken free() in close_midx()
      contrib: add coverage-diff script
      ci: add optional test variables
      commit-reach: fix first-parent heuristic
      midx: close multi-pack-index on repack
      multi-pack-index: define GIT_TEST_MULTI_PACK_INDEX
      packfile: close multi-pack-index in close_all_packs
      prio-queue: add 'peek' operation
      test-reach: add run_three_modes method
      test-reach: add rev-list tests
      revision.c: begin refactoring --topo-order logic
      commit/revisions: bookkeeping before refactoring
      revision.c: generation-based topo-order algorithm
      t6012: make rev-list tests more interesting
      commit-reach: implement get_reachable_subset
      test-reach: test get_reachable_subset
      remote: make add_missing_tags() linear

Elijah Newren (14):
      Remove superfluous trailing semicolons
      t4200: demonstrate rerere segfault on specially crafted merge
      rerere: avoid buffer overrun
      update-ref: fix type of update_flags variable to match its usage
      update-ref: allow --no-deref with --stdin
      sequencer: fix --allow-empty-message behavior, make it smarter
      merge-recursive: set paths correctly when three-way merging content
      merge-recursive: avoid wrapper function when unnecessary and wasteful
      merge-recursive: remove final remaining caller of merge_file_one()
      merge-recursive: rename merge_file_1() and merge_content()
      commit: fix erroneous BUG, 'multiple renames on the same target? how?'
      merge-recursive: improve auto-merging messages with path collisions
      merge-recursive: avoid showing conflicts with merge branch before HEAD
      fsck: move fsck_head_link() to get_default_heads() to avoid some globals

Eric Sunshine (26):
      format-patch: allow additional generated content in make_cover_letter()
      format-patch: add --interdiff option to embed diff in cover letter
      format-patch: teach --interdiff to respect -v/--reroll-count
      interdiff: teach show_interdiff() to indent interdiff
      log-tree: show_log: make commentary block delimiting reusable
      format-patch: allow --interdiff to apply to a lone-patch
      range-diff: respect diff_option.file rather than assuming 'stdout'
      range-diff: publish default creation factor
      range-diff: relieve callers of low-level configuration burden
      format-patch: add --range-diff option to embed diff in cover letter
      format-patch: extend --range-diff to accept revision range
      format-patch: teach --range-diff to respect -v/--reroll-count
      format-patch: add --creation-factor tweak for --range-diff
      format-patch: allow --range-diff to apply to a lone-patch
      worktree: don't die() in library function find_worktree()
      worktree: move delete_git_dir() earlier in file for upcoming new callers
      worktree: generalize delete_git_dir() to reduce code duplication
      worktree: prepare for more checks of whether path can become worktree
      worktree: disallow adding same path multiple times
      worktree: teach 'add' to respect --force for registered but missing path
      worktree: teach 'move' to override lock when --force given twice
      worktree: teach 'remove' to override lock when --force given twice
      worktree: delete .git/worktrees if empty after 'remove'
      doc-diff: fix non-portable 'man' invocation
      doc-diff: add --clean mode to remove temporary working gunk
      doc/Makefile: drop doc-diff worktree and temporary files on "make clean"

Frederick Eaton (3):
      git-archimport.1: specify what kind of Arch we're talking about
      git-column.1: clarify initial description, provide examples
      git-describe.1: clarify that "human readable" is also git-readable

James Knight (1):
      build: link with curl-defined linker flags

Jann Horn (2):
      patch-delta: fix oob read
      patch-delta: consistently report corruption

Jeff Hostetler (2):
      t0051: test GIT_TRACE to a windows named pipe
      mingw: fix mingw_open_append to work with named pipes

Jeff King (94):
      branch: make "-l" a synonym for "--list"
      Add delta-islands.{c,h}
      pack-objects: add delta-islands support
      repack: add delta-islands support
      t5320: tests for delta islands
      t/perf: factor boilerplate out of test_perf
      t/perf: factor out percent calculations
      t/perf: add infrastructure for measuring sizes
      t/perf: add perf tests for fetches from a bitmapped server
      pack-bitmap: save "have" bitmap from walk
      pack-objects: reuse on-disk deltas for thin "have" objects
      SubmittingPatches: mention doc-diff
      rev-list: make empty --stdin not an error
      trailer: use size_t for string offsets
      trailer: use size_t for iterating trailer list
      trailer: pass process_trailer_opts to trailer_info_get()
      interpret-trailers: tighten check for "---" patch boundary
      interpret-trailers: allow suppressing "---" divider
      pretty, ref-filter: format %(trailers) with no_divider option
      sequencer: ignore "---" divider when parsing trailers
      append_signoff: use size_t for string offsets
      coccinelle: use <...> for function exclusion
      introduce hasheq() and oideq()
      convert "oidcmp() == 0" to oideq()
      convert "hashcmp() == 0" to hasheq()
      convert "oidcmp() != 0" to "!oideq()"
      convert "hashcmp() != 0" to "!hasheq()"
      convert hashmap comparison functions to oideq()
      read-cache: use oideq() in ce_compare functions
      show_dirstat: simplify same-content check
      doc-diff: always use oids inside worktree
      test-delta: read input into a heap buffer
      t5303: test some corrupt deltas
      patch-delta: handle truncated copy parameters
      t5303: use printf to generate delta bases
      doc/git-branch: remove obsolete "-l" references
      bitmap_has_sha1_in_uninteresting(): drop BUG check
      t5310: test delta reuse with bitmaps
      traverse_bitmap_commit_list(): don't free result
      pack-bitmap: drop "loaded" flag
      reopen_tempfile(): truncate opened file
      doc-diff: force worktree add
      config.mak.dev: add -Wformat-security
      pack-objects: handle island check for "external" delta base
      receive-pack: update comment with check_everything_connected
      submodule--helper: use "--" to signal end of clone options
      submodule-config: ban submodule urls that start with dash
      submodule-config: ban submodule paths that start with a dash
      fsck: detect submodule urls starting with dash
      fsck: detect submodule paths starting with dash
      more oideq/hasheq conversions
      transport: drop refnames from for_each_alternate_ref
      test-tool: show tool list on error
      config.mak.dev: enable -Wunused-function
      run-command: mark path lookup errors with ENOENT
      t5410: use longer path for sample script
      upload-pack: fix broken if/else chain in config callback
      t1450: check large blob in trailing-garbage test
      check_stream_sha1(): handle input underflow
      cat-file: handle streaming failures consistently
      ls-remote: do not send ref prefixes for patterns
      ls-remote: pass heads/tags prefixes to transport
      read_istream_pack_non_delta(): document input handling
      xdiff: provide a separate emit callback for hunks
      xdiff-interface: provide a separate consume callback for hunks
      rev-list: handle flags for --indexed-objects
      approxidate: handle pending number for "specials"
      pathspec: handle non-terminated strings with :(attr)
      diff: avoid generating unused hunk header lines
      diff: discard hunk headers for patch-ids earlier
      diff: use hunk callback for word-diff
      combine-diff: use an xdiff hunk callback
      diff: convert --check to use a hunk callback
      range-diff: use a hunk callback
      xdiff-interface: drop parse_hunk_header()
      apply: mark include/exclude options as NONEG
      am: handle --no-patch-format option
      ls-files: mark exclude options as NONEG
      pack-objects: mark index-version option as NONEG
      cat-file: mark batch options with NONEG
      status: mark --find-renames option with NONEG
      format-patch: mark "--no-numbered" option with NONEG
      show-branch: mark --reflog option as NONEG
      tag: mark "--message" option with NONEG
      cat-file: report an error on multiple --batch options
      apply: return -1 from option callback instead of calling exit(1)
      parse-options: drop OPT_DATE()
      assert NOARG/NONEG behavior of parse-options callbacks
      midx: double-check large object write loop
      merge: extract verify_merge_signature() helper
      merge: handle --verify-signatures for unborn branch
      pull: handle --verify-signatures for unborn branch
      approxidate: fix NULL dereference in date_time()
      bundle: dup() output descriptor closer to point-of-use

Johannes Schindelin (55):
      rebase -i --autosquash: demonstrate a problem skipping the last squash
      rebase -i: be careful to wrap up fixup/squash chains
      compat/poll: prepare for targeting Windows Vista
      mingw: set _WIN32_WINNT explicitly for Git for Windows
      mingw: bump the minimum Windows version to Vista
      builtin rebase: prepare for builtin rebase -i
      rebase -i: clarify what happens on a failed `exec`
      rebase -i: introduce the 'break' command
      getpwuid(mingw): initialize the structure only once
      getpwuid(mingw): provide a better default for the user name
      mingw: use domain information for default email
      http: add support for selecting SSL backends at runtime
      pack-objects: fix typo 'detla' -> 'delta'
      pack-objects (mingw): demonstrate a segmentation fault with large deltas
      pack-objects (mingw): initialize `packing_data` mutex in the correct spot
      rebase (autostash): avoid duplicate call to state_dir_path()
      rebase (autostash): store the full OID in <state-dir>/autostash
      rebase (autostash): use an explicit OID to apply the stash
      mingw: factor out code to set stat() data
      rebase --autostash: demonstrate a problem with dirty submodules
      rebase --autostash: fix issue with dirty submodules
      mingw: load system libraries the recommended way
      mingw: ensure `getcwd()` reports the correct case
      repack: point out a bug handling stale shallow info
      shallow: offer to prune only non-existing entries
      repack -ad: prune the list of shallow commits
      http: when using Secure Channel, ignore sslCAInfo by default
      t7800: fix quoting
      mingw: reencode environment variables on the fly (UTF-16 <-> UTF-8)
      config: rename `dummy` parameter to `cb` in git_default_config()
      config: allow for platform-specific core.* config settings
      config: move Windows-specific config settings into compat/mingw.c
      mingw: unset PERL5LIB by default
      mingw: fix isatty() after dup2()
      t3404: decouple some test cases from outcomes of previous test cases
      t3418: decouple test cases from a previous `rebase -p` test case
      tests: optionally skip `git rebase -p` tests
      Windows: force-recompile git.res for differing architectures
      built-in rebase: demonstrate regression with --autostash
      built-in rebase --autostash: leave the current branch alone if possible
      Update .mailmap
      rebase -r: demonstrate bug with conflicting merges
      rebase -r: do not write MERGE_HEAD unless needed
      rebase -i: include MERGE_HEAD into files to clean up
      built-in rebase --skip/--abort: clean up stale .git/<name> files
      status: rebase and merge can be in progress at the same time
      apply --recount: allow "no-op hunks"
      rebase: consolidate clean-up code before leaving reset_head()
      rebase: prepare reset_head() for more flags
      built-in rebase: reinstate `checkout -q` behavior where appropriate
      mingw: use `CreateHardLink()` directly
      rebase: really just passthru the `git am` options
      rebase: validate -C<n> and --whitespace=<mode> parameters early
      config: report a bug if git_dir exists without commondir
      mingw: replace an obsolete link with the superseding one

Johannes Sixt (3):
      diff: don't attempt to strip prefix from absolute Windows paths
      rebase -i: recognize short commands without arguments
      t3404-rebase-interactive: test abbreviated commands

Jonathan Nieder (6):
      gc: improve handling of errors reading gc.log
      gc: exit with status 128 on failure
      gc: do not return error for prior errors in daemonized mode
      commit-reach: correct accidental #include of C file
      mailmap: consistently normalize brian m. carlson's name
      git doc: direct bug reporters to mailing list archive

Jonathan Tan (15):
      fetch-object: unify fetch_object[s] functions
      fetch-object: set exact_oid when fetching
      connected: document connectivity in partial clones
      fetch: in partial clone, check presence of targets
      fetch-pack: avoid object flags if no_dependents
      fetch-pack: exclude blobs when lazy-fetching trees
      transport: allow skipping of ref listing
      transport: do not list refs if possible
      transport: list refs before fetch if necessary
      fetch: do not list refs if fetching only hashes
      cache-tree: skip some blob checks in partial clone
      upload-pack: make have_obj not global
      upload-pack: make want_obj not global
      upload-pack: clear flags before each v2 request
      fetch-pack: be more precise in parsing v2 response

Josh Steadmon (4):
      fuzz: add basic fuzz testing target.
      fuzz: add fuzz testing for packfile indices.
      archive: initialize archivers earlier
      Makefile: use FUZZ_CXXFLAGS for linking fuzzers

Joshua Watt (1):
      send-email: explicitly disable authentication

Junio C Hamano (29):
      Revert "doc/Makefile: drop doc-diff worktree and temporary files on "make clean""
      Initial batch post 2.19
      Second batch post 2.19
      Git 2.14.5
      Git 2.15.3
      Git 2.16.5
      Git 2.17.2
      Git 2.18.1
      Git 2.19.1
      t0000: do not get self-test disrupted by environment warnings
      CodingGuidelines: document the API in *.h files
      Declare that the next one will be named 2.20
      Third batch for 2.20
      rebase: fix typoes in error messages
      Fourth batch for 2.20
      Revert "subtree: make install targets depend on build targets"
      Fifth batch for 2.20
      receive: denyCurrentBranch=updateinstead should not blindly update
      cocci: simplify "if (++u > 1)" to "if (u++)"
      fsck: s/++i > 1/i++/
      http: give curl version warnings consistently
      Sixth batch for 2.20
      Seventh batch for 2.20
      fetch: replace string-list used as a look-up table with a hashmap
      rebase: apply cocci patch
      Eighth batch for 2.20
      Ninth batch for 2.20
      Tenth batch for 2.20
      Git 2.20-rc0

Karsten Blees (2):
      mingw: replace MSVCRT's fstat() with a Win32-based implementation
      mingw: implement nanosecond-precision file times

Loo Rong Jie (1):
      win32: replace pthread_cond_*() with much simpler code

Lucas De Marchi (1):
      range-diff: allow to diff files regardless of submodule config

Luke Diamand (3):
      git-p4: do not fail in verbose mode for missing 'fileSize' key
      git-p4: unshelve into refs/remotes/p4-unshelved, not refs/remotes/p4/unshelved
      git-p4: fully support unshelving changelists

Martin Ågren (9):
      Doc: use `--type=bool` instead of `--bool`
      git-config.txt: fix 'see: above' note
      git-commit-graph.txt: fix bullet lists
      git-commit-graph.txt: typeset more in monospace
      git-commit-graph.txt: refer to "*commit*-graph file"
      Doc: refer to the "commit-graph file" with dash
      t1400: drop debug `echo` to actually execute `test`
      builtin/commit-graph.c: UNLEAK variables
      sequencer: break out of loop explicitly

Matthew DeVore (19):
      list-objects: store common func args in struct
      list-objects: refactor to process_tree_contents
      list-objects: always parse trees gently
      t/README: reformat Do, Don't, Keep in mind lists
      Documentation: add shell guidelines
      tests: standardize pipe placement
      t/*: fix ordering of expected/observed arguments
      tests: don't swallow Git errors upstream of pipes
      t9109: don't swallow Git errors upstream of pipes
      tests: order arguments to git-rev-list properly
      rev-list: handle missing tree objects properly
      revision: mark non-user-given objects instead
      list-objects-filter: use BUG rather than die
      list-objects-filter-options: do not over-strbuf_init
      list-objects-filter: implement filter tree:0
      filter-trees: code clean-up of tests
      list-objects: support for skipping tree traversal
      Documentation/git-log.txt: do not show --exclude-promisor-objects
      exclude-promisor-objects: declare when option is allowed

Max Kirillov (1):
      http-backend test: make empty CONTENT_LENGTH test more realistic

Michael Witten (3):
      docs: typo: s/go/to/
      docs: graph: remove unnecessary `graph_update()' call
      docs: typo: s/isimilar/similar/

Michał Górny (6):
      gpg-interface.c: detect and reject multiple signatures on commits
      gpg-interface.c: use flags to determine key/signer info presence
      gpg-interface.c: support getting key fingerprint via %GF format
      gpg-interface.c: obtain primary key fingerprint as well
      t/t7510-signed-commit.sh: Add %GP to custom format checks
      t/t7510-signed-commit.sh: add signing subkey to Eris Discordia key

Mihir Mehta (1):
      doc: fix a typo and clarify a sentence

Nguyễn Thái Ngọc Duy (166):
      clone: report duplicate entries on case-insensitive filesystems
      trace.h: support nested performance tracing
      unpack-trees: add performance tracing
      unpack-trees: optimize walking same trees with cache-tree
      unpack-trees: reduce malloc in cache-tree walk
      unpack-trees: reuse (still valid) cache-tree from src_index
      unpack-trees: add missing cache invalidation
      cache-tree: verify valid cache-tree in the test suite
      Document update for nd/unpack-trees-with-cache-tree
      bisect.c: make show_list() build again
      t/helper: keep test-tool command list sorted
      t/helper: merge test-dump-untracked-cache into test-tool
      t/helper: merge test-pkt-line into test-tool
      t/helper: merge test-parse-options into test-tool
      t/helper: merge test-dump-fsmonitor into test-tool
      Makefile: add a hint about TEST_BUILTINS_OBJS
      config.txt: follow camelCase naming
      config.txt: move fetch part out to a separate file
      config.txt: move format part out to a separate file
      config.txt: move gitcvs part out to a separate file
      config.txt: move gui part out to a separate file
      config.txt: move pull part out to a separate file
      config.txt: move push part out to a separate file
      config.txt: move receive part out to a separate file
      config.txt: move sendemail part out to a separate file
      config.txt: move sequence.editor out of "core" part
      config.txt: move submodule part out to a separate file
      archive.c: remove implicit dependency the_repository
      status: show progress bar if refreshing the index takes too long
      add: do not accept pathspec magic 'attr'
      completion: support "git fetch --multiple"
      read-cache.c: remove 'const' from index_has_changes()
      diff.c: reduce implicit dependency on the_index
      combine-diff.c: remove implicit dependency on the_index
      blame.c: rename "repo" argument to "r"
      diff.c: remove the_index dependency in textconv() functions
      grep.c: remove implicit dependency on the_index
      diff.c: remove implicit dependency on the_index
      read-cache.c: remove implicit dependency on the_index
      diff-lib.c: remove implicit dependency on the_index
      ll-merge.c: remove implicit dependency on the_index
      merge-blobs.c: remove implicit dependency on the_index
      merge.c: remove implicit dependency on the_index
      patch-ids.c: remove implicit dependency on the_index
      sha1-file.c: remove implicit dependency on the_index
      rerere.c: remove implicit dependency on the_index
      userdiff.c: remove implicit dependency on the_index
      line-range.c: remove implicit dependency on the_index
      submodule.c: remove implicit dependency on the_index
      tree-diff.c: remove implicit dependency on the_index
      ws.c: remove implicit dependency on the_index
      revision.c: remove implicit dependency on the_index
      revision.c: reduce implicit dependency the_repository
      read-cache.c: optimize reading index format v4
      config.txt: correct the note about uploadpack.packObjectsHook
      help -a: improve and make --verbose default
      refs.c: indent with tabs, not spaces
      Add a place for (not) sharing stuff between worktrees
      submodule.c: remove some of the_repository references
      completion: fix __gitcomp_builtin no longer consider extra options
      t1300: extract and use test_cmp_config()
      worktree: add per-worktree config files
      refs: new ref types to make per-worktree refs visible to all worktrees
      revision.c: correct a parameter name
      revision.c: better error reporting on ref from different worktrees
      fsck: check HEAD and reflog from other worktrees
      reflog expire: cover reflog from all worktrees
      Update makefile in preparation for Documentation/config/*.txt
      config.txt: move advice.* to a separate file
      config.txt: move core.* to a separate file
      config.txt: move add.* to a separate file
      config.txt: move alias.* to a separate file
      config.txt: move am.* to a separate file
      config.txt: move apply.* to a separate file
      config.txt: move blame.* to a separate file
      config.txt: move branch.* to a separate file
      config.txt: move browser.* to a separate file
      config.txt: move checkout.* to a separate file
      config.txt: move clean.* to a separate file
      config.txt: move color.* to a separate file
      config.txt: move column.* to a separate file
      config.txt: move commit.* to a separate file
      config.txt: move credential.* to a separate file
      config.txt: move completion.* to a separate file
      config.txt: move diff-config.txt to config/
      config.txt: move difftool.* to a separate file
      config.txt: move fastimport.* to a separate file
      config.txt: move fetch-config.txt to config/
      config.txt: move filter.* to a separate file
      config.txt: move format-config.txt to config/
      config.txt: move fmt-merge-msg-config.txt to config/
      config.txt: move fsck.* to a separate file
      config.txt: move gc.* to a separate file
      config.txt: move gitcvs-config.txt to config/
      config.txt: move gitweb.* to a separate file
      config.txt: move grep.* to a separate file
      config.txt: move gpg.* to a separate file
      config.txt: move gui-config.txt to config/
      config.txt: move guitool.* to a separate file
      config.txt: move help.* to a separate file
      config.txt: move ssh.* to a separate file
      config.txt: move http.* to a separate file
      config.txt: move i18n.* to a separate file
      git-imap-send.txt: move imap.* to a separate file
      config.txt: move index.* to a separate file
      config.txt: move init.* to a separate file
      config.txt: move instaweb.* to a separate file
      config.txt: move interactive.* to a separate file
      config.txt: move log.* to a separate file
      config.txt: move mailinfo.* to a separate file
      config.txt: move mailmap.* to a separate file
      config.txt: move man.* to a separate file
      config.txt: move merge-config.txt to config/
      config.txt: move mergetool.* to a separate file
      config.txt: move notes.* to a separate file
      config.txt: move pack.* to a separate file
      config.txt: move pager.* to a separate file
      config.txt: move pretty.* to a separate file
      config.txt: move protocol.* to a separate file
      config.txt: move pull-config.txt to config/
      config.txt: move push-config.txt to config/
      config.txt: move rebase-config.txt to config/
      config.txt: move receive-config.txt to config/
      config.txt: move remote.* to a separate file
      config.txt: move remotes.* to a separate file
      config.txt: move repack.* to a separate file
      config.txt: move rerere.* to a separate file
      config.txt: move reset.* to a separate file
      config.txt: move sendemail-config.txt to config/
      config.txt: move sequencer.* to a separate file
      config.txt: move showBranch.* to a separate file
      config.txt: move splitIndex.* to a separate file
      config.txt: move status.* to a separate file
      config.txt: move stash.* to a separate file
      config.txt: move submodule.* to a separate file
      config.txt: move tag.* to a separate file
      config.txt: move transfer.* to a separate file
      config.txt: move uploadarchive.* to a separate file
      config.txt: move uploadpack.* to a separate file
      config.txt: move url.* to a separate file
      config.txt: move user.* to a separate file
      config.txt: move versionsort.* to a separate file
      config.txt: move web.* to a separate file
      config.txt: move worktree.* to a separate file
      config.txt: remove config/dummy.txt
      thread-utils: macros to unconditionally compile pthreads API
      wildmatch: change behavior of "foo**bar" in WM_PATHNAME mode
      git-worktree.txt: correct linkgit command name
      sequencer.c: remove a stray semicolon
      tree-walk.c: fix overoptimistic inclusion in :(exclude) matching
      run-command.h: include thread-utils.h instead of pthread.h
      send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c
      index-pack: remove #ifdef NO_PTHREADS
      name-hash.c: remove #ifdef NO_PTHREADS
      attr.c: remove #ifdef NO_PTHREADS
      grep: remove #ifdef NO_PTHREADS
      grep: clean up num_threads handling
      preload-index.c: remove #ifdef NO_PTHREADS
      pack-objects: remove #ifdef NO_PTHREADS
      read-cache.c: remove #ifdef NO_PTHREADS
      read-cache.c: reduce branching based on HAVE_THREADS
      read-cache.c: initialize copy_len to shut up gcc 8
      Clean up pthread_create() error handling
      completion: use __gitcomp_builtin for format-patch
      build: fix broken command-list.h generation with core.autocrlf
      doc: move extensions.worktreeConfig to the right place

Nickolai Belakovski (2):
      worktree: update documentation for lock_reason and lock_reason_valid
      worktree: rename is_worktree_locked to worktree_lock_reason

Noam Postavsky (1):
      log: fix coloring of certain octopus merge shapes

Olga Telezhnaya (3):
      ref-filter: free memory from used_atom
      ls-remote: release memory instead of UNLEAK
      ref-filter: free item->value and item->value->s

Phillip Wood (11):
      diff: fix --color-moved-ws=allow-indentation-change
      diff --color-moved-ws: fix double free crash
      diff --color-moved-ws: fix out of bounds string access
      diff --color-moved-ws: fix a memory leak
      diff --color-moved-ws: fix another memory leak
      diff --color-moved: fix a memory leak
      am: don't die in read_author_script()
      am: improve author-script error reporting
      am: rename read_author_script()
      add read_author_script() to libgit
      sequencer: use read_author_script()

Pratik Karki (46):
      rebase: start implementing it as a builtin
      rebase: refactor common shell functions into their own file
      builtin/rebase: support running "git rebase <upstream>"
      builtin rebase: support --onto
      builtin rebase: support `git rebase --onto A...B`
      builtin rebase: handle the pre-rebase hook and --no-verify
      builtin rebase: support --quiet
      builtin rebase: support the `verbose` and `diffstat` options
      builtin rebase: require a clean worktree
      builtin rebase: try to fast forward when possible
      builtin rebase: support --force-rebase
      builtin rebase: start a new rebase only if none is in progress
      builtin rebase: only store fully-qualified refs in `options.head_name`
      builtin rebase: support `git rebase <upstream> <switch-to>`
      builtin rebase: support --continue
      builtin rebase: support --skip
      builtin rebase: support --abort
      builtin rebase: support --quit
      builtin rebase: support --edit-todo and --show-current-patch
      builtin rebase: actions require a rebase in progress
      builtin rebase: stop if `git am` is in progress
      builtin rebase: allow selecting the rebase "backend"
      builtin rebase: support --signoff
      builtin rebase: support --rerere-autoupdate
      builtin rebase: support --committer-date-is-author-date
      builtin rebase: support `ignore-whitespace` option
      builtin rebase: support `ignore-date` option
      builtin rebase: support `keep-empty` option
      builtin rebase: support `--autosquash`
      builtin rebase: support `--gpg-sign` option
      builtin rebase: support `-C` and `--whitespace=<type>`
      builtin rebase: support `--autostash` option
      builtin rebase: support `--exec`
      builtin rebase: support `--allow-empty-message` option
      builtin rebase: support --rebase-merges[=[no-]rebase-cousins]
      merge-base --fork-point: extract libified function
      builtin rebase: support `fork-point` option
      builtin rebase: add support for custom merge strategies
      builtin rebase: support --root
      builtin rebase: optionally auto-detect the upstream
      builtin rebase: optionally pass custom reflogs to reset_head()
      builtin rebase: fast-forward to onto if it is a proper descendant
      builtin rebase: show progress when connected to a terminal
      builtin rebase: use no-op editor when interactive is "implied"
      builtin rebase: error out on incompatible option/mode combinations
      rebase: default to using the builtin rebase

Rafael Ascensão (2):
      refs: show --exclude failure with --branches/tags/remotes=glob
      refs: fix some exclude patterns being ignored

Ralf Thielow (1):
      git-rebase.sh: fix typos in error messages

Ramsay Jones (12):
      Makefile: add a hdr-check target
      json-writer.h: add missing include (hdr-check)
      ewah/ewok_rlw.h: add missing include (hdr-check)
      refs/ref-cache.h: add missing declarations (hdr-check)
      refs/packed-backend.h: add missing declaration (hdr-check)
      refs/refs-internal.h: add missing declarations (hdr-check)
      midx.h: add missing forward declarations (hdr-check)
      delta-islands.h: add missing forward declarations (hdr-check)
      headers: normalize the spelling of some header guards
      fetch-object.h: add missing declaration (hdr-check)
      ewok_rlw.h: add missing 'inline' to function definition
      commit-reach.h: add missing declarations (hdr-check)

Rasmus Villemoes (6):
      help: redirect to aliased commands for "git cmd --help"
      git.c: handle_alias: prepend alias info when first argument is -h
      git-help.txt: document "git help cmd" vs "git cmd --help" for aliases
      Documentation/git-send-email.txt: style fixes
      send-email: only consider lines containing @ or <> for automatic Cc'ing
      send-email: also pick up cc addresses from -by trailers

René Scharfe (12):
      mailinfo: support format=flowed
      fsck: add a performance test for skipList
      fsck: use strbuf_getline() to read skiplist file
      fsck: use oidset instead of oid_array for skipList
      sequencer: use return value of oidset_insert()
      grep: add -r/--[no-]recursive
      fetch-pack: factor out is_unmatched_ref()
      fetch-pack: load tip_oids eagerly iff needed
      khash: factor out kh_release_*
      oidset: use khash
      oidset: uninline oidset_init()
      commit-reach: fix cast in compare_commits_by_gen()

Roger Strain (1):
      subtree: performance improvement for finding unexpected parent commits

SZEDER Gábor (16):
      t1404: increase core.packedRefsTimeout to avoid occasional test failure
      Documentation/git.txt: clarify that GIT_TRACE=/path appends
      t3701-add-interactive: tighten the check of trace output
      t1700-split-index: drop unnecessary 'grep'
      t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index
      t1700-split-index: document why FSMONITOR is disabled in this test script
      split-index: add tests to demonstrate the racy split index problem
      t1700-split-index: date back files to avoid racy situations
      split-index: count the number of deleted entries
      split-index: don't compare cached data of entries already marked for split index
      split-index: smudge and add racily clean cache entries to split index
      split-index: BUG() when cache entry refers to non-existing shared entry
      object_id.cocci: match only expressions of type 'struct object_id'
      test-lib: introduce the '-V' short option for '--verbose-log'
      travis-ci: install packages in 'ci/install-dependencies.sh'
      ref-filter: don't look for objects when outside of a repository

Sam McKelvie (1):
      rev-parse: --show-superproject-working-tree should work during a merge

Saulius Gurklys (1):
      doc: fix small typo in git show-branch

Sebastian Staudt (1):
      travis-ci: no longer use containers

Shulhan (1):
      builtin/remote: quote remote name on error to display empty name

Stefan Beller (25):
      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
      test_decode_color: understand FAINT and ITALIC
      t3206: add color test for range-diff --dual-color
      diff.c: simplify caller of emit_line_0
      diff.c: reorder arguments for emit_line_ws_markup
      diff.c: add set_sign to emit_line_0
      diff: use emit_line_0 once per line
      diff.c: omit check for line prefix in emit_line_0
      diff.c: rewrite emit_line_0 more understandably
      diff.c: add --output-indicator-{new, old, context}
      range-diff: make use of different output indicators
      range-diff: indent special lines as context
      refs.c: migrate internal ref iteration to pass thru repository argument
      refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback
      string-list: remove unused function print_string_list
      strbuf.h: format according to coding guidelines
      diff.c: pass sign_index to emit_line_ws_markup
      submodule helper: convert relative URL to absolute URL if needed
      builtin/submodule--helper: remove debugging leftover tracing

Stephen P. Smith (10):
      wt-status.c: move has_unmerged earlier in the file
      wt-status: rename commitable to committable
      t7501: add test of "commit --dry-run --short"
      wt-status.c: set the committable flag in the collect phase
      roll wt_status_state into wt_status and populate in the collect phase
      t2000: rename and combine checkout clash tests
      t7509: cleanup description and filename
      t7502: rename commit test script to comply with naming convention
      t7500: rename commit tests script to comply with naming convention
      t7501: rename commit test to comply with naming convention

Steve Hoelzer (1):
      poll: use GetTickCount64() to avoid wrap-around issues

Steven Fernandez (1):
      git-completion.bash: add completion for stash list

Strain, Roger L (4):
      subtree: refactor split of a commit into standalone method
      subtree: make --ignore-joins pay attention to adds
      subtree: use commits before rejoins for splits
      subtree: improve decision on merges kept in split

Tao Qingyun (3):
      refs: docstring typo
      builtin/branch.c: remove useless branch_get
      branch: trivial style fix

Taylor Blau (4):
      transport.c: extract 'fill_alternate_refs_command'
      transport.c: introduce core.alternateRefsCommand
      transport.c: introduce core.alternateRefsPrefixes
      Documentation/config.txt: fix typo in core.alternateRefsCommand

Thomas Gummerer (17):
      rerere: unify error messages when read_cache fails
      rerere: lowercase error messages
      rerere: wrap paths in output in sq
      rerere: mark strings for translation
      rerere: add documentation for conflict normalization
      rerere: fix crash with files rerere can't handle
      rerere: only return whether a path has conflicts or not
      rerere: factor out handle_conflict function
      rerere: return strbuf from handle path
      rerere: teach rerere to handle nested conflicts
      rerere: recalculate conflict ID when unresolved conflict is committed
      rerere: mention caveat about unmatched conflict markers
      rerere: add note about files with existing conflict markers
      .gitattributes: add conflict-marker-size for relevant files
      linear-assignment: fix potential out of bounds memory access
      t5551: move setup code inside test_expect blocks
      t5551: compare sorted cookies files

Tim Schumacher (4):
      Documentation/Makefile: make manpage-base-url.xsl generation quieter
      alias: add support for aliases of an alias
      alias: show the call history when an alias is looping
      t0014: introduce an alias testing suite

Torsten Bögershausen (2):
      Make git_check_attr() a void function
      path.c: char is not (always) signed

Uwe Kleine-König (1):
      howto/using-merge-subtree: mention --allow-unrelated-histories

brian m. carlson (26):
      t: add test functions to translate hash-related values
      t0000: use hash translation table
      t0000: update tests for SHA-256
      t0002: abstract away SHA-1 specific constants
      t0064: make hash size independent
      t1006: make hash size independent
      t1400: switch hard-coded object ID to variable
      t1405: make hash size independent
      t1406: make hash-size independent
      t1407: make hash size independent
      editorconfig: provide editor settings for Git developers
      editorconfig: indicate settings should be kept in sync
      pack-bitmap-write: use GIT_MAX_RAWSZ for allocation
      builtin/repack: replace hard-coded constants
      builtin/mktree: remove hard-coded constant
      builtin/fetch-pack: remove constants with parse_oid_hex
      pack-revindex: express constants in terms of the_hash_algo
      packfile: express constants in terms of the_hash_algo
      refs/packed-backend: express constants using the_hash_algo
      upload-pack: express constants in terms of the_hash_algo
      transport: use parse_oid_hex instead of a constant
      tag: express constant in terms of the_hash_algo
      apply: replace hard-coded constants
      apply: rename new_sha1_prefix and old_sha1_prefix
      submodule: make zero-oid comparison hash function agnostic
      rerere: convert to use the_hash_algo

Ævar Arnfjörð Bjarmason (31):
      fetch: change "branch" to "reference" in --force -h output
      push tests: make use of unused $1 in test description
      push tests: use spaces in interpolated string
      fetch tests: add a test for clobbering tag behavior
      push doc: remove confusing mention of remote merger
      push doc: move mention of "tag <tag>" later in the prose
      push doc: correct lies about how push refspecs work
      fetch: document local ref updates with/without --force
      fetch: stop clobbering existing tags without --force
      fsck tests: setup of bogus commit object
      fsck tests: add a test for no skipList input
      fsck: document and test sorted skipList input
      fsck: document and test commented & empty line skipList input
      fsck: document that skipList input must be unabbreviated
      fsck: add a performance test
      fsck: support comments & empty lines in skipList
      commit-graph write: add progress output
      commit-graph verify: add progress output
      config doc: add missing list separator for checkout.optimizeNewBranch
      push doc: add spacing between two words
      fetch doc: correct grammar in --force docs
      gc: fix regression in 7b0f229222 impacting --quiet
      gc doc: mention the commit-graph in the intro
      pack-objects test: modernize style
      pack-objects tests: don't leave test .git corrupt at end
      index-pack tests: don't leave test repo dirty at end
      range-diff doc: add a section about output stability
      range-diff: fix regression in passing along diff options
      range-diff: make diff option behavior (e.g. --stat) consistent
      rebase doc: document rebase.useBuiltin
      tests: add a special setup where rebase.useBuiltin is off


^ permalink raw reply	[relevance 3%]

* Git Test Coverage Report (Sunday, Nov 18th)
@ 2018-11-18 20:01 Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-18 20:01 UTC (permalink / raw)
  To: git

Here is the test coverage report for today.

Thanks,

-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=257&view=logs

---


pu: d02f4432dcda003413023869ebe412f03155f230
jch: af77f5458d76b45843ab70c577a54db24b4ea92f
next: 6e8e63e21ad73680486866b4870b45db87c3d939
master: 26aa9fc81d4c7f6c3b456a29da0b7ec72e5c6595
master@{1}: d166e6afe5f257217836ef24a73764eba390c58d

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/remote.c
b7f4e371e7 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
b7f4e371e7 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

protocol.c
24c10f7473  37) die(_("Unrecognized protocol version"));
24c10f7473  39) die(_("Unrecognized protocol_version"));

remote-curl.c
24c10f7473  403) return 0;

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

submodule.c
e2419f7e30 1376) strbuf_release(&gitdir);
7454fe5cb6 1499) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1503) get_next_submodule_task_release(task);
7454fe5cb6 1530) return 0;
7454fe5cb6 1534) goto out;
7454fe5cb6 1549) return 0;

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Denton Liu      b7f4e371e: remote: add --save-to-push option to git 
remote set-url
Josh Steadmon      24c10f747: protocol: advertise multiple supported 
versions
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/pull.c
88eeb24cb1 647) argv_array_push(&args, opt_cleanup);

hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

sequencer.c
18e711a162 2387) opts->quiet = 1;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Denton Liu      88eeb24cb: merge: add scissors line on merge conflict
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths



Uncovered code in 'next' not in 'master'
--------------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fast-export.c
b93b81e799 builtin/fast-export.c   52) signed_tag_mode = SIGNED_TAG_ABORT;
b93b81e799 builtin/fast-export.c   70) tag_of_filtered_mode = 
TAG_FILTERING_ABORT;
f129c4275c builtin/fast-export.c  202) if (!p->parents)
f129c4275c builtin/fast-export.c  203) return NULL;
f129c4275c builtin/fast-export.c  204) p = p->parents->item;
f129c4275c builtin/fast-export.c  205) }
843b9e6d48 builtin/fast-export.c  265) die("oid mismatch in blob %s", 
oid_to_hex(oid));
a965bb3116 builtin/fast-export.c  277) printf("original-oid %s\n", 
oid_to_hex(oid));
843b9e6d48 builtin/fast-export.c  356) const unsigned hashsz = 
the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  357) unsigned char *out = 
xcalloc(hashsz, 1);
843b9e6d48 builtin/fast-export.c  358) put_be32(out + hashsz - 4, 
counter++);
843b9e6d48 builtin/fast-export.c  362) static const struct object_id 
*anonymize_oid(const struct object_id *oid)
843b9e6d48 builtin/fast-export.c  365) size_t len = the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  366) return anonymize_mem(&objs, 
generate_fake_oid, oid, &len);
843b9e6d48 builtin/fast-export.c  426) anonymize_oid(&spec->oid) :
a965bb3116 builtin/fast-export.c  644) printf("original-oid %s\n", 
oid_to_hex(&commit->object.oid));
530ca19c02 builtin/fast-export.c  668) printf("%s\n", oid_to_hex(anonymize ?
530ca19c02 builtin/fast-export.c  669) anonymize_oid(&obj->oid) :
f129c4275c builtin/fast-export.c  810) p = rewrite_commit((struct commit 
*)tagged);
f129c4275c builtin/fast-export.c  811) if (!p) {
f129c4275c builtin/fast-export.c  812) printf("reset %s\nfrom %s\n\n",
f129c4275c builtin/fast-export.c  814) free(buf);
f129c4275c builtin/fast-export.c  815) return;
a965bb3116 builtin/fast-export.c  825) printf("original-oid %s\n", 
oid_to_hex(&tag->object.oid));
cd13762d8f builtin/fast-export.c  943) printf("reset %s\nfrom %s\n\n",
cd13762d8f builtin/fast-export.c  945) continue;
530ca19c02 builtin/fast-export.c  960) if (!reference_excluded_commits) {
530ca19c02 builtin/fast-export.c  962) printf("reset %s\nfrom %s\n\n",
530ca19c02 builtin/fast-export.c  964) continue;
530ca19c02 builtin/fast-export.c  967) printf("reset %s\nfrom %s\n\n", name,
530ca19c02 builtin/fast-export.c  968) oid_to_hex(&commit->object.oid));
fdf31b6369 builtin/fast-export.c  969) continue;

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 420) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 459) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 583) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 618) fprintf_ln(stderr, _("Checking object 
directory"));
5215bd2f7d builtin/fsck.c 636) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
5215bd2f7d builtin/fsck.c 641) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 670) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 686) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/pack-objects.c
ca473cef91 builtin/pack-objects.c 2086) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2087) oid_to_hex(&trg_entry->idx.oid), 
(uintmax_t)sz,
ca473cef91 builtin/pack-objects.c 2113) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2114) oid_to_hex(&src_entry->idx.oid), 
(uintmax_t)sz,

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
5215bd2f7d 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
5215bd2f7d 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

bundle.c
74ae4b638d 394) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

fast-import.c
a965bb3116 1821) read_next_command();
ca473cef91 2816) strbuf_addf(&line, "%s %s %"PRIuMAX"\n", oid_to_hex(oid),

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 657) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 769) die(_("cannot handle %s as a builtin"), cmd);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 651) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2250) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2285) die(_("broken index, expect %s in %s, got %s"),
9d0a9e9089 3071) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3217) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
bbfc042ef9  236) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  245) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
9440b831ad 2353) return error(_("option `%s' is incompatible with 
--no-merged"),

remote-curl.c
afa5d74929  359) die("invalid server response; expected service, got 
flush packet");

remote.c
0b9c3afdbf  363) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  418) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  684) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  694) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1102) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1121) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1840) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1853) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1948) die(_("revision walk setup failed"));
0b9c3afdbf 2221) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
f11c958054 3974) res = error_dirty_index(r->index, opts);

sha1-file.c
f0eaf63819 sha1-file.c 2139) return r;

Commits introducing uncovered code:
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      530ca19c0: fast-export: add 
--reference-excluded-parents option
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      843b9e6d4: fast-export: convert sha1 to oid
Elijah Newren      a965bb311: fast-export: add a --show-original-ids 
option to show original names
Elijah Newren      b93b81e79: fast-export: use value from correct enum
Elijah Newren      cd13762d8: fast-export: when using paths, avoid 
corrupt stream with non-existent mark
Elijah Newren      f129c4275: fast-export: move commit rewriting logic 
into a function for reuse
Elijah Newren      fdf31b636: fast-export: ensure we export requested refs
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      afa5d7492: remote-curl: refactor smart-http discovery
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Junio C Hamano      5215bd2f7: Merge branch 'nd/i18n' into next
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option
Torsten Bögershausen      ca473cef9: Upcast size_t variables to 
uintmax_t when printing



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

apply.c
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

builtin/am.c
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/cat-file.c
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/grep.c
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/log.c
517fe807d6 builtin/log.c 1196) BUG_ON_OPT_NEG(unset);

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/rebase.c
62c23938fa   55) return env;
3249c1251e  556) ret = -1;
3249c1251e  557) goto leave_reset_head;
bac2a1e36f  561) ret = error(_("could not determine HEAD revision"));
bac2a1e36f  562) goto leave_reset_head;
3249c1251e  580) ret = error(_("could not read index"));
3249c1251e  581) goto leave_reset_head;
bac2a1e36f  585) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
bac2a1e36f  586) goto leave_reset_head;
3249c1251e  590) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
3249c1251e  591) goto leave_reset_head;
3249c1251e  604) goto leave_reset_head;

builtin/show-branch.c
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

bundle.c
2c8ee1f53c 267) error_errno(_("unable to dup bundle descriptor"));
2c8ee1f53c 268) child_process_clear(&pack_objects);
2c8ee1f53c 269) return -1;
2c8ee1f53c 478) rollback_lock_file(&lock);

config.c
midx.c
name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

preload-index.c
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

revision.c
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3048) continue;
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      62c23938f: tests: add a special setup where 
rebase.useBuiltin is off
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      2c8ee1f53: bundle: dup() output descriptor closer to 
point-of-use
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      fce566480: am: handle --no-patch-format option
Johannes Schindelin      3249c1251: rebase: consolidate clean-up code 
before leaving reset_head()
Johannes Schindelin      bac2a1e36: built-in rebase: reinstate `checkout 
-q` behavior where appropriate
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling



^ permalink raw reply	[relevance 2%]

* Git Test Coverage Report (v2.20.0-rc0)
@ 2018-11-19  2:54 Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-19  2:54 UTC (permalink / raw)
  To: git

Here is a test coverage report for the uncovered lines introduced in 
v2.20.0-rc0 compared to v2.19.1.

Thanks,

-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=263&view=logs

---


apply.c
eccb5a5f3d 4071) return get_oid_hex(p->old_oid_prefix, oid);
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

blame.c
a470beea39  113)  !strcmp(r->index->cache[-1 - pos]->name, path))
a470beea39  272) int pos = index_name_pos(r->index, path, len);
a470beea39  274) mode = r->index->cache[pos]->ce_mode;

builtin/add.c
d1664e73ad builtin/add.c 458) die(_("index file corrupt"));

builtin/am.c
2abf350385 1362) repo_init_revisions(the_repository, &rev_info, NULL);
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/cat-file.c
98f425b453 builtin/cat-file.c  56) die("unable to stream %s to stdout", 
oid_to_hex(oid));
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/checkout.c
fa655d8411 builtin/checkout.c  539) return 0;
fa655d8411 builtin/checkout.c  953) return error(_("index file corrupt"));

builtin/difftool.c
4a7e27e957 441) if (oideq(&loid, &roid))

builtin/fast-export.c
4a7e27e957 builtin/fast-export.c  387) if (oideq(&ospec->oid, &spec->oid) &&

builtin/fetch.c
builtin/fsck.c
b29759d89a builtin/fsck.c 613) fprintf(stderr, "Checking %s link\n", 
head_ref_name);
b29759d89a builtin/fsck.c 618) return error("Invalid %s", head_ref_name);
454ea2e4d7 builtin/fsck.c 769) for (p = get_all_packs(the_repository); p;
66ec0390e7 builtin/fsck.c 888) midx_argv[2] = "--object-dir";
66ec0390e7 builtin/fsck.c 889) midx_argv[3] = alt->path;
66ec0390e7 builtin/fsck.c 890) if (run_command(&midx_verify))
66ec0390e7 builtin/fsck.c 891) errors_found |= ERROR_COMMIT_GRAPH;

builtin/gc.c
3029970275 builtin/gc.c 461) ret = error_errno(_("cannot stat '%s'"), 
gc_log_path);
3029970275 builtin/gc.c 470) ret = error_errno(_("cannot read '%s'"), 
gc_log_path);
fec2ed2187 builtin/gc.c 495) die(FAILED_RUN, pack_refs_cmd.argv[0]);
fec2ed2187 builtin/gc.c 498) die(FAILED_RUN, reflog.argv[0]);
3029970275 builtin/gc.c 585) exit(128);
fec2ed2187 builtin/gc.c 637) die(FAILED_RUN, repack.argv[0]);
fec2ed2187 builtin/gc.c 647) die(FAILED_RUN, prune.argv[0]);
fec2ed2187 builtin/gc.c 654) die(FAILED_RUN, prune_worktrees.argv[0]);
fec2ed2187 builtin/gc.c 658) die(FAILED_RUN, rerere.argv[0]);

builtin/grep.c
76e9bdc437 builtin/grep.c  424) grep_read_unlock();
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/help.c
e6e76baaf4 builtin/help.c 429) if (!exclude_guides || alias[0] == '!') {
e6e76baaf4 builtin/help.c 430) printf_ln(_("'%s' is aliased to '%s'"), 
cmd, alias);
e6e76baaf4 builtin/help.c 431) free(alias);
e6e76baaf4 builtin/help.c 432) exit(0);
e6e76baaf4 builtin/help.c 441) fprintf_ln(stderr, _("'%s' is aliased to 
'%s'"), cmd, alias);
e6e76baaf4 builtin/help.c 442) count = split_cmdline(alias, &argv);
e6e76baaf4 builtin/help.c 443) if (count < 0)
e6e76baaf4 builtin/help.c 444) die(_("bad alias.%s string: %s"), cmd,
e6e76baaf4 builtin/help.c 446) free(argv);
e6e76baaf4 builtin/help.c 448) return alias;

builtin/log.c
517fe807d6 builtin/log.c 1196) BUG_ON_OPT_NEG(unset);
2e6fd71a52 builtin/log.c 1472) die(_("failed to infer range-diff ranges"));
ee6cbf712e builtin/log.c 1818) die(_("--interdiff requires 
--cover-letter or single patch"));
8631bf1cdd builtin/log.c 1828) else if (!rdiff_prev)
8631bf1cdd builtin/log.c 1829) die(_("--creation-factor requires 
--range-diff"));
40ce41604d builtin/log.c 1833) die(_("--range-diff requires 
--cover-letter or single patch"));

builtin/multi-pack-index.c
6d68e6a461 35) usage_with_options(builtin_multi_pack_index_usage,
6d68e6a461 39) die(_("too many arguments"));
6d68e6a461 48) die(_("unrecognized verb: %s"), argv[0]);

builtin/pack-objects.c
6a22d52126 builtin/pack-objects.c 1091) continue;
2fa233a554 builtin/pack-objects.c 1512) hashcpy(base_oid.hash, base_sha1);
2fa233a554 builtin/pack-objects.c 1513) if 
(!in_same_island(&delta->idx.oid, &base_oid))
2fa233a554 builtin/pack-objects.c 1514) return 0;
28b8a73080 builtin/pack-objects.c 2793) depth++;
108f530385 builtin/pack-objects.c 2797) oe_set_tree_depth(&to_pack, ent, 
depth);
454ea2e4d7 builtin/pack-objects.c 2981) p = get_all_packs(the_repository);

builtin/pack-redundant.c
454ea2e4d7 builtin/pack-redundant.c 580) struct packed_git *p = 
get_all_packs(the_repository);
454ea2e4d7 builtin/pack-redundant.c 595) struct packed_git *p = 
get_all_packs(the_repository);

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/rebase--interactive.c
53bbcfbde7 builtin/rebase--interactive2.c  24) return error(_("no HEAD?"));
53bbcfbde7 builtin/rebase--interactive2.c  51) return 
error_errno(_("could not create temporary %s"), path_state_dir());
53bbcfbde7 builtin/rebase--interactive2.c  57) return 
error_errno(_("could not mark as interactive"));
53bbcfbde7 builtin/rebase--interactive2.c  77) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  81) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  87) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  88) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c  90) return -1;
53bbcfbde7 builtin/rebase--interactive2.c  98) free(revisions);
53bbcfbde7 builtin/rebase--interactive2.c  99) free(shortrevisions);
53bbcfbde7 builtin/rebase--interactive2.c 101) return 
error_errno(_("could not open %s"), rebase_path_todo());
53bbcfbde7 builtin/rebase--interactive2.c 106) 
argv_array_push(&make_script_args, restrict_revision);
53bbcfbde7 builtin/rebase--interactive2.c 114) error(_("could not 
generate todo list"));
53bbcfbde7 builtin/rebase--interactive2.c 206) 
usage_with_options(builtin_rebase_interactive_usage, options);
53bbcfbde7 builtin/rebase--interactive2.c 220) 
warning(_("--[no-]rebase-cousins has no effect without "
0af129b2ed builtin/rebase--interactive2.c 226) die(_("a base commit must 
be provided with --upstream or --onto"));
34b47315d9 builtin/rebase--interactive.c  261) ret = rearrange_squash();
34b47315d9 builtin/rebase--interactive.c  262) break;
34b47315d9 builtin/rebase--interactive.c  264) ret = 
sequencer_add_exec_commands(cmd);
34b47315d9 builtin/rebase--interactive.c  265) break;

builtin/rebase.c
62c23938fa   55) return env;
55071ea248   65) strbuf_trim(&out);
55071ea248   66) ret = !strcmp("true", out.buf);
55071ea248   67) strbuf_release(&out);
002ee2fe68  119) die(_("%s requires an interactive rebase"), option);
f95736288a  152) return error_errno(_("could not read '%s'"), path);
f95736288a  166) return -1;
f95736288a  171) return error(_("could not get 'onto': '%s'"), buf.buf);
f95736288a  182) return -1;
f95736288a  183) } else if (read_one(state_dir_path("head", opts), &buf))
f95736288a  184) return -1;
f95736288a  186) return error(_("invalid orig-head: '%s'"), buf.buf);
f95736288a  190) return -1;
f95736288a  192) opts->flags &= ~REBASE_NO_QUIET;
73d51ed0a5  200) opts->signoff = 1;
73d51ed0a5  201) opts->flags |= REBASE_FORCE;
ead98c111b  208) return -1;
12026a412c  223) return -1;
ba1905a5fe  231) return -1;
ba1905a5fe  239) return -1;
6defce2b02  259) return error(_("Could not read '%s'"), path);
6defce2b02  277) res = error(_("Cannot store %s"), autostash.buf);
6defce2b02  281) return res;
bc24382c2b  379) argv_array_pushf(&child.args,
bc24382c2b  381) oid_to_hex(&opts->restrict_revision->object.oid));
ac7f467fef  515) struct strbuf dir = STRBUF_INIT;
6defce2b02  517) apply_autostash(opts);
ac7f467fef  518) strbuf_addstr(&dir, opts->state_dir);
ac7f467fef  519) remove_dir_recursively(&dir, 0);
ac7f467fef  520) strbuf_release(&dir);
ac7f467fef  521) die("Nothing to do");
3249c1251e  556) ret = -1;
3249c1251e  557) goto leave_reset_head;
bac2a1e36f  561) ret = error(_("could not determine HEAD revision"));
bac2a1e36f  562) goto leave_reset_head;
3249c1251e  580) ret = error(_("could not read index"));
3249c1251e  581) goto leave_reset_head;
bac2a1e36f  585) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
bac2a1e36f  586) goto leave_reset_head;
3249c1251e  590) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
3249c1251e  591) goto leave_reset_head;
ac7f467fef  603) ret = error(_("could not write index"));
3249c1251e  604) goto leave_reset_head;
ac7f467fef  621) } else if (old_orig)
ac7f467fef  622) delete_ref(NULL, "ORIG_HEAD", old_orig, 0);
bff014dac7  655) opts->flags &= !REBASE_DIFFSTAT;
9a48a615b4  689) return 1;
9a48a615b4  705) return 0;
55071ea248  916) const char *path = mkpath("%s/git-legacy-rebase",
55071ea248  919) if (sane_execvp(path, (char **)argv) < 0)
55071ea248  920) die_errno(_("could not exec %s"), path);
0eabf4b95c  938) die(_("It looks like 'git am' is in progress. Cannot 
rebase."));
f28d40d3a9  975) usage_with_options(builtin_rebase_usage,
f95736288a  995) die(_("Cannot read HEAD"));
f95736288a  999) die(_("could not read index"));
f95736288a 1013) exit(1);
122420c295 1026) die(_("could not discard worktree changes"));
122420c295 1029) exit(1);
5e5d96197c 1040) exit(1);
5e5d96197c 1044) die(_("could not move back to %s"),
5a61494539 1055) die(_("could not remove '%s'"), options.state_dir);
c54dacb50e 1074) const char *last_slash = strrchr(options.state_dir, '/');
c54dacb50e 1075) const char *state_dir_base =
c54dacb50e 1076) last_slash ? last_slash + 1 : options.state_dir;
c54dacb50e 1077) const char *cmd_live_rebase =
c54dacb50e 1079) strbuf_reset(&buf);
c54dacb50e 1080) strbuf_addf(&buf, "rm -fr \"%s\"", options.state_dir);
c54dacb50e 1081) die(_("It seems that there is already a %s directory, 
and\n"
3c3588c7d3 1138) else if (strcmp("no-rebase-cousins", rebase_merges))
3c3588c7d3 1139) die(_("Unknown mode: %s"), rebase_merges);
ba1905a5fe 1161) die(_("--strategy requires --merge or --interactive"));
cda614e489 1179) strbuf_addstr(&options.git_format_patch_opt, " 
--progress");
ac7f467fef 1188) options.state_dir = apply_dir();
ac7f467fef 1189) break;
ac7f467fef 1261) die(_("invalid upstream '%s'"), options.upstream_name);
9dba809a69 1267) die(_("Could not create new root commit"));
e65123a71d 1317) die(_("fatal: no such branch/commit '%s'"),
ac7f467fef 1325) die(_("No such ref: %s"), "HEAD");
ac7f467fef 1337) die(_("Could not resolve HEAD to a revision"));
e0333e5c63 1350) die(_("could not read index"));
6defce2b02 1377) die(_("Cannot autostash"));
6defce2b02 1380) die(_("Unexpected stash response: '%s'"),
6defce2b02 1386) die(_("Could not create directory for '%s'"),
6defce2b02 1392) die(_("could not reset --hard"));
e65123a71d 1436) ret = !!error(_("could not parse '%s'"),
e65123a71d 1438) goto cleanup;
e65123a71d 1447) ret = !!error(_("could not switch to "
1ed9c14ff2 1457)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
1ed9c14ff2 1458) puts(_("HEAD is up to date."));
9a48a615b4 1467)  resolve_ref_unsafe("HEAD", 0, NULL, &flag))
9a48a615b4 1468) puts(_("HEAD is up to date, rebase forced."));

builtin/reflog.c
c9ef0d95eb builtin/reflog.c 580) all_worktrees = 0;
c9ef0d95eb builtin/reflog.c 616) continue;

builtin/remote.c
5025425dff builtin/remote.c  864) return error(_("No such remote: 
'%s'"), name);

builtin/repack.c
16d75fa48d  48) use_delta_islands = git_config_bool(var, value);
16d75fa48d  49) return 0;
2f0c9e9a9b 239) die("repack: Expecting full hex object ID lines only 
from pack-objects.");
2f0c9e9a9b 411) die("repack: Expecting full hex object ID lines only 
from pack-objects.");

builtin/rerere.c
2373b65059 builtin/rerere.c  79) warning(_("'git rerere forget' without 
paths is deprecated"));
2373b65059 builtin/rerere.c 111) die(_("unable to generate diff for 
'%s'"), rerere_path(id, NULL));

builtin/rev-list.c
7c0fe330d5 builtin/rev-list.c 227) die("unexpected missing %s object '%s'",
7c0fe330d5 builtin/rev-list.c 228)     type_name(obj->type), 
oid_to_hex(&obj->oid));

builtin/show-branch.c
9001dc2a74 builtin/show-branch.c 430) if (get_oid(refname + ofs, &tmp) 
|| !oideq(&tmp, oid))
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

builtin/submodule--helper.c
ee69b2a90c 1469) die(_("Invalid update mode '%s' for submodule path '%s'"),
ee69b2a90c 1473) die(_("Invalid update mode '%s' configured for 
submodule path '%s'"),
ee69b2a90c 1476) out->type = sub->update_strategy.type;
ee69b2a90c 1477) out->command = sub->update_strategy.command;
ee69b2a90c 1497) die("submodule--helper update-module-clone expects 
<just-cloned> <path> [<update>]");
e0a862fdaf 1648) url = sub->url;
74d4731da1 2057) die(_("could not get a repository handle for submodule 
'%s'"), path);

builtin/unpack-objects.c
4a7e27e957 builtin/unpack-objects.c 306) if (oideq(&info->base_oid, 
&obj_list[nr].oid) ||

builtin/update-index.c
4a7e27e957 builtin/update-index.c  672) if (oideq(&ce_2->oid, &ce_3->oid) &&

builtin/worktree.c
e5353bef55  60) error_errno(_("failed to delete '%s'"), sb.buf);
e19831c94f 251)     die(_("unable to re-add worktree '%s'"), path);
68a6b3a1bd 793) die(_("cannot move a locked working tree, lock reason: 
%s\nuse 'move -f -f' to override or unlock first"),
f4143101cb 906) die(_("cannot remove a locked working tree, lock reason: 
%s\nuse 'remove -f -f' to override or unlock first"),

bundle.c
2c8ee1f53c 267) error_errno(_("unable to dup bundle descriptor"));
2c8ee1f53c 268) child_process_clear(&pack_objects);
2c8ee1f53c 269) return -1;
2c8ee1f53c 478) rollback_lock_file(&lock);

cache-tree.c
combine-diff.c
0074c9110d  377) state->sline[state->nb-1].p_lno =
0074c9110d  378) xcalloc(state->num_parent, sizeof(unsigned long));

commit-graph.c
20fd6d5799   79) return 0;
6cc017431c  275) return 0;

commit-reach.c
5227c38566 134) return ret;
5227c38566 282) return 1;
5227c38566 314) return ret;
5227c38566 317) return ret;
1d614d41e5 395) return 0;
1d614d41e5 401) return 0;
1d614d41e5 405) return 0;
4fbcca4eff 538) return 1;
b67f6b26e3 559) continue;
b67f6b26e3 570) from->objects[i].item->flags |= assign_flag;
b67f6b26e3 571) continue;
b67f6b26e3 577) result = 0;
b67f6b26e3 578) goto cleanup;

config.c
c780b9cfe8 2303) return val;
c780b9cfe8 2306) if (is_bool)
c780b9cfe8 2307) return val ? 0 : 1;
c780b9cfe8 2309) return val;

date.c
c27cc94fad  904) tm->tm_mon = number-1;
c27cc94fad  908) else if (number > 69 && number < 100)
c27cc94fad  909) tm->tm_year = number;
c27cc94fad  910) else if (number < 38)
c27cc94fad  911) tm->tm_year = 100 + number;
c27cc94fad  952) pending_number(tm, num);

delta-islands.c
c8d521faf7  53) memcpy(b, old, size);
c8d521faf7  73) return 1;
c8d521faf7 118) return 0;
c8d521faf7 130) return 0;
c8d521faf7 187) b->refcount--;
c8d521faf7 188) b = kh_value(island_marks, pos) = island_bitmap_new(b);
c8d521faf7 202) continue;
c8d521faf7 212) obj = ((struct tag *)obj)->tagged;
c8d521faf7 213) if (obj) {
c8d521faf7 214) parse_object(the_repository, &obj->oid);
c8d521faf7 215) marks = create_or_get_island_marks(obj);
c8d521faf7 216) island_bitmap_set(marks, island_counter);
c8d521faf7 248) return;
c8d521faf7 268) progress_state = start_progress(_("Propagating island 
marks"), nr);
c8d521faf7 286) die(_("bad tree object %s"), oid_to_hex(&ent->idx.oid));
c8d521faf7 293) continue;
c8d521faf7 297) continue;
c8d521faf7 321) return config_error_nonbool(k);
c8d521faf7 330) die(_("failed to load island regex for '%s': %s"), k, 
re.buf);
c8d521faf7 386) warning(_("island regex from config has "
c8d521faf7 397) strbuf_addch(&island_name, '-');
c8d521faf7 433) continue;
c8d521faf7 436) list[dst] = list[src];

diff-lib.c
9001dc2a74 diff-lib.c 346)     (!oideq(oid, &old_entry->oid) || 
!oideq(&old_entry->oid, &new_entry->oid))) {

diff.c
b78ea5fc35 4130) add_external_diff_name(o->repo, &argv, other, two);

dir.c
8a2c174677  287) name = to_free = xmemdupz(name, namelen);
c46c406ae1 2282) trace_performance_leave("read directory %.*s", len, path);

entry.c
b878579ae7 402) static void mark_colliding_entries(const struct checkout 
*state,
b878579ae7 405) int i, trust_ino = check_stat;
b878579ae7 411) ce->ce_flags |= CE_MATCHED;
b878579ae7 413) for (i = 0; i < state->istate->cache_nr; i++) {
b878579ae7 414) struct cache_entry *dup = state->istate->cache[i];
b878579ae7 416) if (dup == ce)
b878579ae7 417) break;
b878579ae7 419) if (dup->ce_flags & (CE_MATCHED | CE_VALID | 
CE_SKIP_WORKTREE))
b878579ae7 420) continue;
b878579ae7 422) if ((trust_ino && dup->ce_stat_data.sd_ino == st->st_ino) ||
b878579ae7 423)     (!trust_ino && !fspathcmp(ce->name, dup->name))) {
b878579ae7 424) dup->ce_flags |= CE_MATCHED;
b878579ae7 425) break;
b878579ae7 428) }
b878579ae7 488) mark_colliding_entries(state, ce, &st);

fsck.c
fb8952077d  214) die_errno("Could not read '%s'", path);

git.c
a9a60b94cc 322) fprintf_ln(stderr, _("'%s' is aliased to '%s'"),
c6d75bc17a 735) string_list_clear(&cmd_list, 0);

gpg-interface.c
4de9394dcb 155) break;

help.c
26c7d06783 help.c         500) static int get_alias(const char *var, 
const char *value, void *data)
26c7d06783 help.c         502) struct string_list *list = data;
26c7d06783 help.c         504) if (skip_prefix(var, "alias.", &var))
26c7d06783 help.c         505) string_list_append(list, var)->util = 
xstrdup(value);
26c7d06783 help.c         507) return 0;
26c7d06783 help.c         530) printf("\n%s\n", _("Command aliases"));
26c7d06783 help.c         531) ALLOC_ARRAY(aliases, alias_list.nr + 1);
26c7d06783 help.c         532) for (i = 0; i < alias_list.nr; i++) {
26c7d06783 help.c         533) aliases[i].name = alias_list.items[i].string;
26c7d06783 help.c         534) aliases[i].help = alias_list.items[i].util;
26c7d06783 help.c         535) aliases[i].category = 1;
26c7d06783 help.c         537) aliases[alias_list.nr].name = NULL;
26c7d06783 help.c         538) print_command_list(aliases, 1, longest);
26c7d06783 help.c         539) free(aliases);

http.c
21084e84a4  316) free(http_ssl_backend);
21084e84a4  317) http_ssl_backend = xstrdup_or_null(value);
21084e84a4  318) return 0;
93aef7c79b  322) http_schannel_check_revoke = git_config_bool(var, value);
93aef7c79b  323) return 0;
b67d40adbb  327) http_schannel_use_ssl_cainfo = git_config_bool(var, value);
b67d40adbb  328) return 0;
93aef7c79b  833)     !http_schannel_check_revoke) {
93aef7c79b  835) curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, 
CURLSSLOPT_NO_REVOKE);
b67d40adbb  883)     !http_schannel_use_ssl_cainfo) {
b67d40adbb  884) curl_easy_setopt(result, CURLOPT_CAINFO, NULL);

ident.c
501afcb8b0 172) strbuf_addstr(&git_default_email, email);
501afcb8b0 173) free((char *)email);

list-objects-filter-options.c
bc5975d24f  55) if (errbuf) {
bc5975d24f  56) strbuf_addstr(
bc5975d24f  60) return 1;
cc0b05a4cc  86) if (errbuf)

list-objects-filter.c
list-objects.c
f447a499db 200) ctx->show_object(obj, base->buf, ctx->show_data);

ll-merge.c
d64324cb60 380) marker_size = DEFAULT_CONFLICT_MARKER_SIZE;

log-tree.c
4a7e27e957 477) if (oideq(&parent->item->object.oid, oid))

mailinfo.c
3aa4d81f88  992) len--;
3aa4d81f88  998) handle_filter(mi, prev);
3aa4d81f88  999) strbuf_reset(prev);
3aa4d81f88 1090) handle_filter(mi, &prev);

midx.c
4d80560c54   58) error_errno(_("failed to read %s"), midx_name);
4d80560c54   59) goto cleanup_fail;
4d80560c54   65) error(_("multi-pack-index file %s is too small"), 
midx_name);
4d80560c54   66) goto cleanup_fail;
0d5b3a5ef7  146) die(_("multi-pack-index missing required OID lookup 
chunk"));
662148c435  148) die(_("multi-pack-index missing required object offsets 
chunk"));
4d80560c54  173) munmap(midx_map, midx_size);
4d80560c54  175) close(fd);
1dcd9f2043  184) return;
3715a6335c  266) return 0;
fe1ed56f5e  413) warning(_("failed to open pack-index '%s'"),
fe1ed56f5e  415) close_pack(packs->list[packs->nr]);
fe1ed56f5e  416) FREE_AND_NULL(packs->list[packs->nr]);
fe1ed56f5e  417) return;
a40498a126  490) return 1;
fe1ed56f5e  507) die(_("failed to locate object %d in packfile"), 
cur_object);
fc59e74844  769) die_errno(_("unable to create leading directories of %s"),
525e18c04b  943) die(_("failed to clear multi-pack-index at %s"), midx);
56ee7ff156  969) return 0;
cc6af73c02 1010) midx_report(_("failed to load pack-index for packfile %s"),
cc6af73c02 1011)     e.p->pack_name);
cc6af73c02 1012) break;

name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

oidmap.c
cc00e5ce6b 11) return !oideq(&entry_->oid,

oidset.c
8b2f8cbcb1 29) kh_del_oid(&set->set, pos);
8b2f8cbcb1 30) return 1;

pack-bitmap.c
30cdc33fba 1130) return 0;

pack-objects.c
108f530385 172) REALLOC_ARRAY(pdata->tree_depth, pdata->nr_alloc);
fe0ac2fb7f 175) REALLOC_ARRAY(pdata->layer, pdata->nr_alloc);
108f530385 192) pdata->tree_depth[pdata->nr_objects - 1] = 0;
fe0ac2fb7f 195) pdata->layer[pdata->nr_objects - 1] = 0;

packfile.c
1127a98cce  117) return error("index file %s is too small", path);
1127a98cce  119) return error("empty data");
fe1ed56f5e  211) if (open_pack_index(p))
fe1ed56f5e  212) return 0;
fe1ed56f5e  213) level1_ofs = p->index_data;
17c35c8969  490) break;
17c35c8969  548) return 0;

preload-index.c
ae9af12287  63) struct progress_data *pd = p->progress;
ae9af12287  65) pthread_mutex_lock(&pd->mutex);
ae9af12287  66) pd->n += last_nr - nr;
ae9af12287  67) display_progress(pd->progress, pd->n);
ae9af12287  68) pthread_mutex_unlock(&pd->mutex);
ae9af12287  69) last_nr = nr;
ae9af12287  83) struct progress_data *pd = p->progress;
ae9af12287  85) pthread_mutex_lock(&pd->mutex);
ae9af12287  86) display_progress(pd->progress, pd->n + last_nr);
ae9af12287  87) pthread_mutex_unlock(&pd->mutex);
ae9af12287 118) pd.progress = start_delayed_progress(_("Refreshing 
index"), index->cache_nr);
ae9af12287 119) pthread_mutex_init(&pd.mutex, NULL);
ae9af12287 132) p->progress = &pd;
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

read-cache.c
ae9af12287 1490) progress = start_delayed_progress(_("Refresh index"),
ae9af12287 1491)   istate->cache_nr);
ae9af12287 1539) display_progress(progress, i);
ae9af12287 1572) display_progress(progress, istate->cache_nr);
ae9af12287 1573) stop_progress(&progress);
252d079cbd 1784) const unsigned char *cp = (const unsigned char *)name;
252d079cbd 1788) strip_len = decode_varint(&cp);
77ff1127a4 1789) if (previous_ce) {
77ff1127a4 1790) previous_len = previous_ce->ce_namelen;
77ff1127a4 1791) if (previous_len < strip_len)
252d079cbd 1792) die(_("malformed name field in the index, near path '%s'"),
77ff1127a4 1793) previous_ce->name);
77ff1127a4 1794) copy_len = previous_len - strip_len;
252d079cbd 1796) name = (const char *)cp;
252d079cbd 1802) len += copy_len;
252d079cbd 1823) if (copy_len)
252d079cbd 1824) memcpy(ce->name, previous_ce->name, copy_len);
252d079cbd 1825) memcpy(ce->name + copy_len, name, len + 1 - copy_len);
252d079cbd 1826) *ent_size = (name - ((char *)ondisk)) + len + 1 - copy_len;
abb4bb8384 1959) munmap((void *)p->mmap, p->mmap_size);
abb4bb8384 1960) die(_("index file corrupt"));
77ff1127a4 2001) mem_pool_init(&istate->ce_mem_pool,
77ff1127a4 2039) static void *load_cache_entries_thread(void *_data)
77ff1127a4 2041) struct load_cache_entries_thread_data *p = _data;
77ff1127a4 2045) for (i = p->ieot_start; i < p->ieot_start + 
p->ieot_blocks; i++) {
77ff1127a4 2046) p->consumed += load_cache_entry_block(p->istate, 
p->ce_mem_pool,
77ff1127a4 2047) p->offset, p->ieot->entries[i].nr, p->mmap, 
p->ieot->entries[i].offset, NULL);
77ff1127a4 2048) p->offset += p->ieot->entries[i].nr;
77ff1127a4 2050) return NULL;
77ff1127a4 2053) static unsigned long load_cache_entries_threaded(struct 
index_state *istate, const char *mmap, size_t mmap_size,
77ff1127a4 2058) unsigned long consumed = 0;
77ff1127a4 2061) if (istate->name_hash_initialized)
77ff1127a4 2064) mem_pool_init(&istate->ce_mem_pool, 0);
77ff1127a4 2067) if (nr_threads > ieot->nr)
77ff1127a4 2068) nr_threads = ieot->nr;
77ff1127a4 2069) data = xcalloc(nr_threads, sizeof(*data));
77ff1127a4 2071) offset = ieot_start = 0;
77ff1127a4 2072) ieot_blocks = DIV_ROUND_UP(ieot->nr, nr_threads);
77ff1127a4 2073) for (i = 0; i < nr_threads; i++) {
77ff1127a4 2074) struct load_cache_entries_thread_data *p = &data[i];
77ff1127a4 2077) if (ieot_start + ieot_blocks > ieot->nr)
77ff1127a4 2078) ieot_blocks = ieot->nr - ieot_start;
77ff1127a4 2080) p->istate = istate;
77ff1127a4 2081) p->offset = offset;
77ff1127a4 2082) p->mmap = mmap;
77ff1127a4 2083) p->ieot = ieot;
77ff1127a4 2084) p->ieot_start = ieot_start;
77ff1127a4 2085) p->ieot_blocks = ieot_blocks;
77ff1127a4 2088) nr = 0;
77ff1127a4 2089) for (j = p->ieot_start; j < p->ieot_start + 
p->ieot_blocks; j++)
77ff1127a4 2090) nr += p->ieot->entries[j].nr;
77ff1127a4 2091) if (istate->version == 4) {
77ff1127a4 2092) mem_pool_init(&p->ce_mem_pool,
77ff1127a4 2095) mem_pool_init(&p->ce_mem_pool,
77ff1127a4 2099) err = pthread_create(&p->pthread, NULL, 
load_cache_entries_thread, p);
77ff1127a4 2100) if (err)
77ff1127a4 2101) die(_("unable to create load_cache_entries thread: 
%s"), strerror(err));
77ff1127a4 2104) for (j = 0; j < ieot_blocks; j++)
77ff1127a4 2105) offset += ieot->entries[ieot_start + j].nr;
77ff1127a4 2106) ieot_start += ieot_blocks;
77ff1127a4 2109) for (i = 0; i < nr_threads; i++) {
77ff1127a4 2110) struct load_cache_entries_thread_data *p = &data[i];
77ff1127a4 2112) err = pthread_join(p->pthread, NULL);
77ff1127a4 2113) if (err)
77ff1127a4 2114) die(_("unable to join load_cache_entries thread: %s"), 
strerror(err));
77ff1127a4 2115) mem_pool_combine(istate->ce_mem_pool, p->ce_mem_pool);
77ff1127a4 2116) consumed += p->consumed;
77ff1127a4 2119) free(data);
77ff1127a4 2121) return consumed;
abb4bb8384 2193) extension_offset = read_eoie_extension(mmap, mmap_size);
abb4bb8384 2194) if (extension_offset) {
abb4bb8384 2197) p.src_offset = extension_offset;
abb4bb8384 2198) err = pthread_create(&p.pthread, NULL, 
load_index_extensions, &p);
abb4bb8384 2199) if (err)
abb4bb8384 2200) die(_("unable to create load_index_extensions thread: 
%s"), strerror(err));
abb4bb8384 2202) nr_threads--;
77ff1127a4 2211) ieot = read_ieot_extension(mmap, mmap_size, 
extension_offset);
77ff1127a4 2214) src_offset += load_cache_entries_threaded(istate, mmap, 
mmap_size, src_offset, nr_threads, ieot);
77ff1127a4 2215) free(ieot);
abb4bb8384 2225) int ret = pthread_join(p.pthread, NULL);
abb4bb8384 2226) if (ret)
abb4bb8384 2227) die(_("unable to join load_index_extensions thread: 
%s"), strerror(ret));
3255089ada 2769) ieot_blocks = nr_threads;
77ff1127a4 2770) if (ieot_blocks > istate->cache_nr)
77ff1127a4 2771) ieot_blocks = istate->cache_nr;
3255089ada 2779) ieot = xcalloc(1, sizeof(struct index_entry_offset_table)
3255089ada 2780) + (ieot_blocks * sizeof(struct index_entry_offset)));
77ff1127a4 2781) ieot_entries = DIV_ROUND_UP(entries, ieot_blocks);
3255089ada 2787) free(ieot);
3b1d9e045e 2788) return -1;
3255089ada 2814) ieot->entries[ieot->nr].nr = nr;
3255089ada 2815) ieot->entries[ieot->nr].offset = offset;
3255089ada 2816) ieot->nr++;
3255089ada 2822) if (previous_name)
3255089ada 2823) previous_name->buf[0] = 0;
3255089ada 2824) nr = 0;
3255089ada 2825) offset = lseek(newfd, 0, SEEK_CUR);
3255089ada 2826) if (offset < 0) {
3255089ada 2827) free(ieot);
3255089ada 2828) return -1;
3255089ada 2830) offset += write_buffer_len;
3255089ada 2840) ieot->entries[ieot->nr].nr = nr;
3255089ada 2841) ieot->entries[ieot->nr].offset = offset;
3255089ada 2842) ieot->nr++;
3255089ada 2854) free(ieot);
3b1d9e045e 2855) return -1;
3255089ada 2868) struct strbuf sb = STRBUF_INIT;
3255089ada 2870) write_ieot_extension(&sb, ieot);
3255089ada 2871) err = write_index_ext_header(&c, &eoie_c, newfd, 
CACHE_EXT_INDEXENTRYOFFSETTABLE, sb.len) < 0
3255089ada 2872) || ce_write(&c, newfd, sb.buf, sb.len) < 0;
3255089ada 2873) strbuf_release(&sb);
3255089ada 2874) free(ieot);
3255089ada 2875) if (err)
3255089ada 2876) return -1;
3b1d9e045e 3363) static size_t read_eoie_extension(const char *mmap, 
size_t mmap_size)
3b1d9e045e 3381) if (mmap_size < sizeof(struct cache_header) + 
EOIE_SIZE_WITH_HEADER + the_hash_algo->rawsz)
3b1d9e045e 3382) return 0;
3b1d9e045e 3385) index = eoie = mmap + mmap_size - EOIE_SIZE_WITH_HEADER 
- the_hash_algo->rawsz;
3b1d9e045e 3386) if (CACHE_EXT(index) != CACHE_EXT_ENDOFINDEXENTRIES)
3b1d9e045e 3387) return 0;
3b1d9e045e 3388) index += sizeof(uint32_t);
3b1d9e045e 3391) extsize = get_be32(index);
3b1d9e045e 3392) if (extsize != EOIE_SIZE)
3b1d9e045e 3393) return 0;
3b1d9e045e 3394) index += sizeof(uint32_t);
3b1d9e045e 3400) offset = get_be32(index);
3b1d9e045e 3401) if (mmap + offset < mmap + sizeof(struct cache_header))
3b1d9e045e 3402) return 0;
3b1d9e045e 3403) if (mmap + offset >= eoie)
3b1d9e045e 3404) return 0;
3b1d9e045e 3405) index += sizeof(uint32_t);
3b1d9e045e 3416) src_offset = offset;
3b1d9e045e 3417) the_hash_algo->init_fn(&c);
3b1d9e045e 3418) while (src_offset < mmap_size - the_hash_algo->rawsz - 
EOIE_SIZE_WITH_HEADER) {
3b1d9e045e 3426) memcpy(&extsize, mmap + src_offset + 4, 4);
3b1d9e045e 3427) extsize = ntohl(extsize);
3b1d9e045e 3430) if (src_offset + 8 + extsize < src_offset)
3b1d9e045e 3431) return 0;
3b1d9e045e 3433) the_hash_algo->update_fn(&c, mmap + src_offset, 8);
3b1d9e045e 3435) src_offset += 8;
3b1d9e045e 3436) src_offset += extsize;
3b1d9e045e 3438) the_hash_algo->final_fn(hash, &c);
3b1d9e045e 3439) if (!hasheq(hash, (const unsigned char *)index))
3b1d9e045e 3440) return 0;
3b1d9e045e 3443) if (src_offset != mmap_size - the_hash_algo->rawsz - 
EOIE_SIZE_WITH_HEADER)
3b1d9e045e 3444) return 0;
3b1d9e045e 3446) return offset;
3255089ada 3465) static struct index_entry_offset_table 
*read_ieot_extension(const char *mmap, size_t mmap_size, size_t offset)
3255089ada 3467)        const char *index = NULL;
3255089ada 3473)        if (!offset)
3255089ada 3474)        return NULL;
3255089ada 3475)        while (offset <= mmap_size - 
the_hash_algo->rawsz - 8) {
3255089ada 3476)        extsize = get_be32(mmap + offset + 4);
3255089ada 3477)        if (CACHE_EXT((mmap + offset)) == 
CACHE_EXT_INDEXENTRYOFFSETTABLE) {
3255089ada 3478)        index = mmap + offset + 4 + 4;
3255089ada 3479)        break;
3255089ada 3481)        offset += 8;
3255089ada 3482)        offset += extsize;
3255089ada 3484)        if (!index)
3255089ada 3485)        return NULL;
3255089ada 3488)        ext_version = get_be32(index);
3255089ada 3489)        if (ext_version != IEOT_VERSION) {
3255089ada 3490)        error("invalid IEOT version %d", ext_version);
3255089ada 3491)        return NULL;
3255089ada 3493)        index += sizeof(uint32_t);
3255089ada 3496)        nr = (extsize - sizeof(uint32_t)) / 
(sizeof(uint32_t) + sizeof(uint32_t));
3255089ada 3497)        if (!nr) {
3255089ada 3498)        error("invalid number of IEOT entries %d", nr);
3255089ada 3499)        return NULL;
3255089ada 3501)        ieot = xmalloc(sizeof(struct 
index_entry_offset_table)
3255089ada 3502)        + (nr * sizeof(struct index_entry_offset)));
3255089ada 3503)        ieot->nr = nr;
3255089ada 3504)        for (i = 0; i < nr; i++) {
3255089ada 3505)        ieot->entries[i].offset = get_be32(index);
3255089ada 3506)        index += sizeof(uint32_t);
3255089ada 3507)        ieot->entries[i].nr = get_be32(index);
3255089ada 3508)        index += sizeof(uint32_t);
3255089ada 3511)        return ieot;
3255089ada 3514) static void write_ieot_extension(struct strbuf *sb, 
struct index_entry_offset_table *ieot)
3255089ada 3520)        put_be32(&buffer, IEOT_VERSION);
3255089ada 3521)        strbuf_add(sb, &buffer, sizeof(uint32_t));
3255089ada 3524)        for (i = 0; i < ieot->nr; i++) {
3255089ada 3527)        put_be32(&buffer, ieot->entries[i].offset);
3255089ada 3528)        strbuf_add(sb, &buffer, sizeof(uint32_t));
3255089ada 3531)        put_be32(&buffer, ieot->entries[i].nr);
3255089ada 3532)        strbuf_add(sb, &buffer, sizeof(uint32_t));
3255089ada 3534) }

rebase-interactive.c
64a43cbd5d 62) return error_errno(_("could not read '%s'."), todo_file);
64a43cbd5d 66) strbuf_release(&buf);
64a43cbd5d 67) return -1;
a9f5476fbc 75) return error_errno(_("could not read '%s'."), todo_file);
a9f5476fbc 79) strbuf_release(&buf);
a9f5476fbc 80) return -1;
64a43cbd5d 86) return -1;

ref-filter.c
f0062d3b74 1039) v->s = xstrdup("");
f0062d3b74 1302) free((char *)to_free);
f0062d3b74 1303) return xstrdup("");
f0062d3b74 1340) free((char *)to_free);
f0062d3b74 1341) return xstrdup("");
f0062d3b74 1391) *s = xstrdup("=");
f0062d3b74 1393) *s = xstrdup("<");
f0062d3b74 1518) ref->symref = xstrdup("");
f0062d3b74 1587) v->s = xstrdup("");

refs.c
3a3b9d8cde  661) return 0;
4a6067cda5 1431) return 0;

refs/files-backend.c
refs/packed-backend.c
9001dc2a74 1163) } else if (!oideq(&update->old_oid, iter->oid)) {

refs/ref-cache.c
9001dc2a74 275) if (!oideq(&ref1->u.value.oid, &ref2->u.value.oid))

remote.c
85daa01f6b 1219) continue;
85daa01f6b 1225) continue;

rerere.c
2373b65059  217) die(_("corrupt MERGE_RR"));
2373b65059  226) die(_("corrupt MERGE_RR"));
2373b65059  229) die(_("corrupt MERGE_RR"));
2373b65059  264) die(_("unable to write rerere record"));
2373b65059  269) die(_("unable to write rerere record"));
4af32207bc  376) break;
4af32207bc  380) strbuf_addbuf(&two, &conflict);
c0f16f8e14  384) break;
c0f16f8e14  388) break;
c0f16f8e14  392) break;
2373b65059  480) return error_errno(_("could not open '%s'"), path);
2373b65059  485) error_errno(_("could not write '%s'"), output);
2373b65059  495) error(_("there were errors while writing '%s' (%s)"),
2373b65059  498) io.io.wrerror = error_errno(_("failed to flush '%s'"), 
path);
2373b65059  565) return error(_("index file corrupt"));
2373b65059  599) return error(_("index file corrupt"));
2373b65059  684) warning_errno(_("failed utime() on '%s'"),
2373b65059  690) return error_errno(_("could not open '%s'"), path);
2373b65059  692) error_errno(_("could not write '%s'"), path);
2373b65059  694) return error_errno(_("writing '%s' failed"), path);
2373b65059  720) die(_("unable to write new index file"));
2373b65059  803) die_errno(_("cannot unlink stray '%s'"), path);
2373b65059 1057) error(_("failed to update conflicted state in '%s'"), 
path);
2373b65059 1075) error(_("no remembered resolution for '%s'"), path);
2373b65059 1077) error_errno(_("cannot unlink '%s'"), filename);
2373b65059 1111) return error(_("index file corrupt"));
2373b65059 1199) die_errno(_("unable to open rr-cache directory"));

revision.c
2abf350385 1538) if (ce_path_match(istate, ce, &revs->prune_data, NULL)) {
2abf350385 1544) while ((i+1 < istate->cache_nr) &&
2abf350385 1545)        ce_same_name(ce, istate->cache[i+1]))
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3048) continue;
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;
4a7e27e957 3473)     oideq(&p->item->object.oid, &commit->object.oid))

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

sequencer.c
bcd33ec25f  683) np = strchrnul(buf, '\n');
bcd33ec25f  684) return error(_("no key present in '%.*s'"),
bcd33ec25f  695) return error(_("unable to dequote value of '%s'"),
bcd33ec25f  737) goto finish;
bcd33ec25f  742) name_i = error(_("'GIT_AUTHOR_NAME' already given"));
bcd33ec25f  747) email_i = error(_("'GIT_AUTHOR_EMAIL' already given"));
bcd33ec25f  752) date_i = error(_("'GIT_AUTHOR_DATE' already given"));
bcd33ec25f  756) err = error(_("unknown variable '%s'"),
bcd33ec25f  761) error(_("missing 'GIT_AUTHOR_NAME'"));
bcd33ec25f  763) error(_("missing 'GIT_AUTHOR_EMAIL'"));
bcd33ec25f  765) error(_("missing 'GIT_AUTHOR_DATE'"));
65850686cf 2329) return;
65850686cf 2426) write_file(rebase_path_quiet(), "%s\n", quiet);
2c58483a59 3427) return error(_("could not checkout %s"), commit);
4df66c40b0 3441) return error(_("%s: not a valid OID"), orig_head);
71f82465b1 3461) fprintf(stderr, _("Stopped at HEAD\n"));
b97e187364 4827) return -1;
b97e187364 4830) return -1;
b97e187364 4836) return error_errno(_("could not read '%s'."), todo_file);
b97e187364 4839) todo_list_release(&todo_list);
b97e187364 4840) return error(_("unusable todo list: '%s'"), todo_file);
b97e187364 4859) todo_list_release(&todo_list);
b97e187364 4860) return -1;
b97e187364 4864) return error(_("could not copy '%s' to '%s'."), todo_file,
b97e187364 4868) return error(_("could not transform the todo list"));
b97e187364 4897) return error(_("could not transform the todo list"));
b97e187364 4900) return error(_("could not skip unnecessary pick 
commands"));
b97e187364 4906) return -1;

setup.c
58b284a2e9  413) return config_error_nonbool(var);

sha1-file.c
67947c34ae sha1-file.c 2225) if (!hasheq(expected_sha1, real_sha1)) {

sha1-name.c
8aac67a174 sha1-name.c  162) return;

split-index.c
e3d837989e 335) ce->ce_flags |= CE_UPDATE_IN_BASE;

strbuf.c
f95736288a  127) --sb->len;

submodule-config.c
bcbc780d14 739) return CONFIG_INVALID_KEY;
45f5ef3d77 754) warning(_("Could not update .gitmodules entry %s"), key);

trace.c
c46c406ae1 189) now = getnanotime();
c46c406ae1 190) perf_start_times[perf_indent] = now;
c46c406ae1 191) if (perf_indent + 1 < ARRAY_SIZE(perf_start_times))
c46c406ae1 192) perf_indent++;
c46c406ae1 195) return now;
c46c406ae1 211) if (perf_indent >= strlen(space))
c46c406ae1 214) strbuf_addf(&buf, ":%.*s ", perf_indent, space);
c46c406ae1 317) void trace_performance_leave_fl(const char *file, int line,
c46c406ae1 323) if (perf_indent)
c46c406ae1 324) perf_indent--;
c46c406ae1 326) if (!format) /* Allow callers to leave without tracing 
anything */
c46c406ae1 327) return;
c46c406ae1 329) since = perf_start_times[perf_indent];
c46c406ae1 330) va_start(ap, format);
c46c406ae1 331) trace_performance_vprintf_fl(file, line, nanos - since, 
format, ap);
c46c406ae1 332) va_end(ap);
c46c406ae1 477) trace_performance_leave("git command:%s", command_line.buf);
c46c406ae1 485) if (!command_line.len)
c46c406ae1 490) trace_performance_enter();

transport.c
unpack-trees.c
b878579ae7  360) string_list_append(&list, ce->name);
b878579ae7  361) ce->ce_flags &= ~CE_MATCHED;
b878579ae7  368) warning(_("the following paths have collided (e.g. 
case-sensitive paths\n"
b878579ae7  372) for (i = 0; i < list.nr; i++)
b878579ae7  373) fprintf(stderr, "  '%s'\n", list.items[i].string);
f1e11c6510  777) free(tree_ce);
b4da37380b  778) return rc;
b4da37380b  785) printf("Unpacked %d entries from %s to %s using 
cache-tree\n",
b4da37380b  787)        o->src_index->cache[pos]->name,
b4da37380b  788)        o->src_index->cache[pos + nr_entries - 1]->name);

upload-pack.c
1d1243fe63 1403) deepen(INFINITE_DEPTH, data->deepen_relative, 
&data->shallows,

worktree.c
3a3b9d8cde 495) return -1;
3a3b9d8cde 508) return -1;
3a3b9d8cde 517) return -1;
ab3e1f78ae 537) break;

wt-status.c
f3bd35fa0d  671) s->committable = 1;
73ba5d78b4 1958) if (s->state.rebase_in_progress ||
73ba5d78b4 1959)     s->state.rebase_interactive_in_progress)
73ba5d78b4 1960) branch_name = s->state.onto;
73ba5d78b4 1961) else if (s->state.detached_from)
73ba5d78b4 1962) branch_name = s->state.detached_from;

xdiff-interface.c
xdiff/xutils.c
611e42a598 405) return -1;

Commits introducing uncovered code:
Ævar Arnfjörð Bjarmason      62c23938f: tests: add a special setup where 
rebase.useBuiltin is off
Alban Gruin      0af129b2e: rebase--interactive2: rewrite the submodes 
of interactive rebase in C
Alban Gruin      2c58483a5: rebase -i: rewrite setup_reflog_action() in C
Alban Gruin      34b47315d: rebase -i: move rebase--helper modes to 
rebase--interactive
Alban Gruin      4df66c40b: rebase -i: rewrite checkout_onto() in C
Alban Gruin      53bbcfbde: rebase -i: implement the main part of 
interactive rebase as a builtin
Alban Gruin      64a43cbd5: rebase -i: rewrite the edit-todo 
functionality in C
Alban Gruin      65850686c: rebase -i: rewrite write_basic_state() in C
Alban Gruin      a9f5476fb: sequencer: refactor append_todo_help() to 
write its message to a buffer
Alban Gruin      b97e18736: rebase -i: rewrite complete_action() in C
Antonio Ospite      45f5ef3d7: submodule: factor out a 
config_set_in_gitmodules_file_gently function
Antonio Ospite      76e9bdc43: submodule: support reading .gitmodules 
when it's not in the working tree
Antonio Ospite      bcbc780d1: submodule: add a 
print_config_from_gitmodules() helper
Ben Peart      3255089ad: ieot: add Index Entry Offset Table (IEOT) 
extension
Ben Peart      3b1d9e045: eoie: add End of Index Entry (EOIE) extension
Ben Peart      77ff1127a: read-cache: load cache entries on worker threads
Ben Peart      abb4bb838: read-cache: load cache extensions on a worker 
thread
Ben Peart      c780b9cfe: config: add new index.threads config setting
Ben Peart      d1664e73a: add: speed up cmd_add() by utilizing 
read_cache_preload()
Ben Peart      fa655d841: checkout: optimize "git checkout -b <new_branch>"
Brendan Forster      93aef7c79: http: add support for disabling SSL 
revocation checks in cURL
brian m. carlson      2f0c9e9a9: builtin/repack: replace hard-coded 
constants
brian m. carlson      eccb5a5f3: apply: rename new_sha1_prefix and 
old_sha1_prefix
Christian Couder      108f53038: pack-objects: move tree_depth into 
'struct packing_data'
Christian Couder      fe0ac2fb7: pack-objects: move 'layer' into 'struct 
packing_data'
Derrick Stolee      0d5b3a5ef: midx: write object ids in a chunk
Derrick Stolee      17c35c896: packfile: skip loading index if in 
multi-pack-index
Derrick Stolee      1d614d41e: commit-reach: move ref_newer from remote.c
Derrick Stolee      1dcd9f204: midx: close multi-pack-index on repack
Derrick Stolee      20fd6d579: commit-graph: not compatible with grafts
Derrick Stolee      3715a6335: midx: read objects from multi-pack-index
Derrick Stolee      454ea2e4d: treewide: use get_all_packs
Derrick Stolee      4d80560c5: multi-pack-index: load into memory
Derrick Stolee      4fbcca4ef: commit-reach: make can_all_from_reach... 
linear
Derrick Stolee      5227c3856: commit-reach: move walk methods from commit.c
Derrick Stolee      525e18c04: midx: clear midx on repack
Derrick Stolee      56ee7ff15: multi-pack-index: add 'verify' verb
Derrick Stolee      662148c43: midx: write object offsets
Derrick Stolee      66ec0390e: fsck: verify multi-pack-index
Derrick Stolee      6a22d5212: pack-objects: consider packs in 
multi-pack-index
Derrick Stolee      6cc017431: commit-reach: use can_all_from_reach
Derrick Stolee      6d68e6a46: multi-pack-index: provide more helpful 
usage info
Derrick Stolee      85daa01f6: remote: make add_missing_tags() linear
Derrick Stolee      8aac67a17: midx: use midx in abbreviation calculations
Derrick Stolee      a40498a12: midx: use existing midx when writing new one
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      b67f6b26e: commit-reach: properly peel tags
Derrick Stolee      cc6af73c0: multi-pack-index: verify object offsets
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Derrick Stolee      fc59e7484: midx: write header information to lockfile
Derrick Stolee      fe1ed56f5: midx: sort and deduplicate objects from 
packfiles
Duy Nguyen      b878579ae: clone: report duplicate entries on 
case-insensitive filesystems
Eric Sunshine      2e6fd71a5: format-patch: extend --range-diff to 
accept revision range
Eric Sunshine      40ce41604: format-patch: allow --range-diff to apply 
to a lone-patch
Eric Sunshine      68a6b3a1b: worktree: teach 'move' to override lock 
when --force given twice
Eric Sunshine      8631bf1cd: format-patch: add --creation-factor tweak 
for --range-diff
Eric Sunshine      e19831c94: worktree: teach 'add' to respect --force 
for registered but missing path
Eric Sunshine      e5353bef5: worktree: move delete_git_dir() earlier in 
file for upcoming new callers
Eric Sunshine      ee6cbf712: format-patch: allow --interdiff to apply 
to a lone-patch
Eric Sunshine      f4143101c: worktree: teach 'remove' to override lock 
when --force given twice
Jeff King      0074c9110: combine-diff: use an xdiff hunk callback
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      16d75fa48: repack: add delta-islands support
Jeff King      28b8a7308: pack-objects: add delta-islands support
Jeff King      2c8ee1f53: bundle: dup() output descriptor closer to 
point-of-use
Jeff King      2fa233a55: pack-objects: handle island check for 
"external" delta base
Jeff King      30cdc33fb: pack-bitmap: save "have" bitmap from walk
Jeff King      4a7e27e95: convert "oidcmp() == 0" to oideq()
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      611e42a59: xdiff: provide a separate emit callback for hunks
Jeff King      67947c34a: convert "hashcmp() != 0" to "!hasheq()"
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      8a2c17467: pathspec: handle non-terminated strings with 
:(attr)
Jeff King      9001dc2a7: convert "oidcmp() != 0" to "!oideq()"
Jeff King      98f425b45: cat-file: handle streaming failures consistently
Jeff King      c27cc94fa: approxidate: handle pending number for "specials"
Jeff King      c8d521faf: Add delta-islands.{c,h}
Jeff King      cc00e5ce6: convert hashmap comparison functions to oideq()
Jeff King      fce566480: am: handle --no-patch-format option
Johannes Schindelin      21084e84a: http: add support for selecting SSL 
backends at runtime
Johannes Schindelin      3249c1251: rebase: consolidate clean-up code 
before leaving reset_head()
Johannes Schindelin      501afcb8b: mingw: use domain information for 
default email
Johannes Schindelin      71f82465b: rebase -i: introduce the 'break' command
Johannes Schindelin      b67d40adb: http: when using Secure Channel, 
ignore sslCAInfo by default
Johannes Schindelin      bac2a1e36: built-in rebase: reinstate `checkout 
-q` behavior where appropriate
Johannes Schindelin      bc24382c2: builtin rebase: prepare for builtin 
rebase -i
Jonathan Nieder      302997027: gc: do not return error for prior errors 
in daemonized mode
Jonathan Nieder      fec2ed218: gc: exit with status 128 on failure
Jonathan Tan      1d1243fe6: upload-pack: make want_obj not global
Josh Steadmon      1127a98cc: fuzz: add fuzz testing for packfile indices.
Matthew DeVore      7c0fe330d: rev-list: handle missing tree objects 
properly
Matthew DeVore      bc5975d24: list-objects-filter: implement filter tree:0
Matthew DeVore      cc0b05a4c: list-objects-filter-options: do not 
over-strbuf_init
Matthew DeVore      f447a499d: list-objects: store common func args in 
struct
Michał Górny      4de9394dc: gpg-interface.c: obtain primary key 
fingerprint as well
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      252d079cb: read-cache.c: optimize reading 
index format v4
Nguyễn Thái Ngọc Duy      26c7d0678: help -a: improve and make --verbose 
default
Nguyễn Thái Ngọc Duy      2abf35038: revision.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      3a3b9d8cd: refs: new ref types to make 
per-worktree refs visible to all worktrees
Nguyễn Thái Ngọc Duy      58b284a2e: worktree: add per-worktree config files
Nguyễn Thái Ngọc Duy      a470beea3: blame.c: rename "repo" argument to "r"
Nguyễn Thái Ngọc Duy      ab3e1f78a: revision.c: better error reporting 
on ref from different worktrees
Nguyễn Thái Ngọc Duy      ae9af1228: status: show progress bar if 
refreshing the index takes too long
Nguyễn Thái Ngọc Duy      b29759d89: fsck: check HEAD and reflog from 
other worktrees
Nguyễn Thái Ngọc Duy      b4da37380: unpack-trees: optimize walking same 
trees with cache-tree
Nguyễn Thái Ngọc Duy      b78ea5fc3: diff.c: reduce implicit dependency 
on the_index
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      c46c406ae: trace.h: support nested performance 
tracing
Nguyễn Thái Ngọc Duy      c9ef0d95e: reflog expire: cover reflog from 
all worktrees
Nguyễn Thái Ngọc Duy      f1e11c651: unpack-trees: reduce malloc in 
cache-tree walk
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling
Olga Telezhnaya      f0062d3b7: ref-filter: free item->value and 
item->value->s
Phillip Wood      bcd33ec25: add read_author_script() to libgit
Pratik Karki      002ee2fe6: builtin rebase: support `keep-empty` option
Pratik Karki      0eabf4b95: builtin rebase: stop if `git am` is in progress
Pratik Karki      12026a412: builtin rebase: support `--gpg-sign` option
Pratik Karki      122420c29: builtin rebase: support --skip
Pratik Karki      1ed9c14ff: builtin rebase: support --force-rebase
Pratik Karki      3c3588c7d: builtin rebase: support 
--rebase-merges[=[no-]rebase-cousins]
Pratik Karki      55071ea24: rebase: start implementing it as a builtin
Pratik Karki      5a6149453: builtin rebase: support --quit
Pratik Karki      5e5d96197: builtin rebase: support --abort
Pratik Karki      6defce2b0: builtin rebase: support `--autostash` option
Pratik Karki      73d51ed0a: builtin rebase: support --signoff
Pratik Karki      9a48a615b: builtin rebase: try to fast forward when 
possible
Pratik Karki      9dba809a6: builtin rebase: support --root
Pratik Karki      ac7f467fe: builtin/rebase: support running "git rebase 
<upstream>"
Pratik Karki      ba1905a5f: builtin rebase: add support for custom 
merge strategies
Pratik Karki      bff014dac: builtin rebase: support the `verbose` and 
`diffstat` options
Pratik Karki      c54dacb50: builtin rebase: start a new rebase only if 
none is in progress
Pratik Karki      cda614e48: builtin rebase: show progress when 
connected to a terminal
Pratik Karki      e0333e5c6: builtin rebase: require a clean worktree
Pratik Karki      e65123a71: builtin rebase: support `git rebase 
<upstream> <switch-to>`
Pratik Karki      ead98c111: builtin rebase: support --rerere-autoupdate
Pratik Karki      f28d40d3a: builtin rebase: support --onto
Pratik Karki      f95736288: builtin rebase: support --continue
Rasmus Villemoes      a9a60b94c: git.c: handle_alias: prepend alias info 
when first argument is -h
Rasmus Villemoes      e6e76baaf: help: redirect to aliased commands for 
"git cmd --help"
René Scharfe      3aa4d81f8: mailinfo: support format=flowed
René Scharfe      8b2f8cbcb: oidset: use khash
René Scharfe      fb8952077: fsck: use strbuf_getline() to read skiplist 
file
Shulhan      5025425df: builtin/remote: quote remote name on error to 
display empty name
Stefan Beller      4a6067cda: refs.c: migrate internal ref iteration to 
pass thru repository argument
Stefan Beller      74d4731da: submodule--helper: replace 
connect-gitdir-workingtree by ensure-core-worktree
Stefan Beller      e0a862fda: submodule helper: convert relative URL to 
absolute URL if needed
Stefan Beller      ee69b2a90: submodule--helper: introduce new 
update-module-mode helper
Stephen P. Smith      73ba5d78b: roll wt_status_state into wt_status and 
populate in the collect phase
Stephen P. Smith      f3bd35fa0: wt-status.c: set the committable flag 
in the collect phase
SZEDER Gábor      e3d837989: split-index: don't compare cached data of 
entries already marked for split index
Thomas Gummerer      2373b6505: rerere: mark strings for translation
Thomas Gummerer      4af32207b: rerere: teach rerere to handle nested 
conflicts
Thomas Gummerer      c0f16f8e1: rerere: factor out handle_conflict function
Tim Schumacher      c6d75bc17: alias: add support for aliases of an alias
Torsten Bögershausen      d64324cb6: Make git_check_attr() a void function


^ permalink raw reply	[relevance 3%]

* Git Test Coverage Report (Wednesday Nov 21)
@ 2018-11-21 14:46 Derrick Stolee
  0 siblings, 0 replies; 200+ results
From: Derrick Stolee @ 2018-11-21 14:46 UTC (permalink / raw)
  To: Git List

Here is today's test report.

Thanks,
-Stolee

[1] https://dev.azure.com/git/git/_build/results?buildId=271&view=logs

---

pu: c4a21f043160e02a25755bbf43e4d2fa0b9766aa
jch: 29ea8ddbcef3ec1c79fffa23cc5751a45344754c
next: 68bc7959f8dc2d629c09be1a52f1b95b977b3a13
master: bb75be6cb916297f271c846f2f9caa3daaaec718
master@{1}: d166e6afe5f257217836ef24a73764eba390c58d

Uncovered code in 'pu' not in 'jch'
--------------------------------------

builtin/blame.c
c4a21f0431 builtin/blame.c    200) 
repo_unuse_commit_buffer(the_repository, commit, message);
74e8221b52 builtin/blame.c    928) blame_date_width = sizeof("Thu Oct 19 
16:00");
74e8221b52 builtin/blame.c    929) break;

builtin/describe.c
c4a21f0431 builtin/describe.c 257) repo_parse_commit(the_repository, p);

builtin/pack-objects.c
c4a21f0431 builtin/pack-objects.c 2834) if 
(!repo_has_object_file(the_repository, &obj->oid) && 
is_promisor_object(&obj->oid))

builtin/remote.c
b7f4e371e7 builtin/remote.c 1551) die(_("--save-to-push cannot be used 
with other options"));
b7f4e371e7 builtin/remote.c 1575) die(_("--save-to-push can only be used 
when only one url is defined"));

date.c
74e8221b52  113) die("Timestamp too large for this system: %"PRItime, time);
74e8221b52  216) if (tm->tm_mon == human_tm->tm_mon) {
74e8221b52  217) if (tm->tm_mday > human_tm->tm_mday) {
74e8221b52  219) } else if (tm->tm_mday == human_tm->tm_mday) {
74e8221b52  220) hide.date = hide.wday = 1;
74e8221b52  221) } else if (tm->tm_mday + 5 > human_tm->tm_mday) {
74e8221b52  223) hide.date = 1;
74e8221b52  231) gettimeofday(&now, NULL);
74e8221b52  232) show_date_relative(time, tz, &now, buf);
74e8221b52  233) return;
74e8221b52  246) hide.seconds = 1;
74e8221b52  247) hide.tz |= !hide.date;
74e8221b52  248) hide.wday = hide.time = !hide.year;
74e8221b52  262) strbuf_rtrim(buf);
74e8221b52  287) gettimeofday(&now, NULL);
74e8221b52  290) human_tz = local_time_tzoffset(now.tv_sec, &human_tm);
74e8221b52  886) static int auto_date_style(void)
74e8221b52  888) return (isatty(1) || pager_in_use()) ? DATE_HUMAN : 
DATE_NORMAL;
74e8221b52  909) return DATE_HUMAN;
74e8221b52  911) return auto_date_style();

fast-import.c
c4a21f0431 2793) buf = repo_read_object_file(the_repository, oid, &type, 
&size);
c4a21f0431 2899) buf = repo_read_object_file(the_repository, oid, &unused,

fsck.c
c4a21f0431  858) repo_unuse_commit_buffer(the_repository, commit, buffer);
c4a21f0431  878) repo_read_object_file(the_repository,
c4a21f0431  879)       &tag->object.oid, &type, &size);

http-push.c
c4a21f0431 1635) if (!repo_has_object_file(the_repository, &head_oid))
c4a21f0431 1642) if (!repo_has_object_file(the_repository, 
&remote_ref->old_oid))

negotiator/default.c
c4a21f0431  71) if (repo_parse_commit(the_repository, commit))

protocol.c
24c10f7473  37) die(_("Unrecognized protocol version"));
24c10f7473  39) die(_("Unrecognized protocol_version"));

remote-curl.c
24c10f7473  403) return 0;

revision.c
c4a21f0431  726) if (repo_parse_commit(the_repository, p) < 0)

sequencer.c
c4a21f0431 1643) repo_unuse_commit_buffer(the_repository, head_commit,
c4a21f0431 3914) repo_unuse_commit_buffer(the_repository,

sha1-array.c
bba406749a 91) oidcpy(&oids[dst], &oids[src]);

strbuf.c
10a40f5700  397) return 0;

submodule.c
e2419f7e30 1376) strbuf_release(&gitdir);
7454fe5cb6 1499) struct get_next_submodule_task *task = task_cb;
7454fe5cb6 1503) get_next_submodule_task_release(task);
7454fe5cb6 1530) return 0;
7454fe5cb6 1534) goto out;
7454fe5cb6 1549) return 0;

tree.c
c4a21f0431 110) if (repo_parse_commit(the_repository, commit))

wrapper.c
5efde212fc  70) die("Out of memory, malloc failed (tried to allocate %" 
PRIuMAX " bytes)",
5efde212fc  73) error("Out of memory, malloc failed (tried to allocate 
%" PRIuMAX " bytes)",

Commits introducing uncovered code:
Anders Waldenborg      10a40f570: strbuf: separate callback for 
strbuf_expand:ing literals
Denton Liu      b7f4e371e: remote: add --save-to-push option to git 
remote set-url
Josh Steadmon      24c10f747: protocol: advertise multiple supported 
versions
Junio C Hamano      c4a21f043: treewide: apply cocci patch
Linus Torvalds      74e8221b5: Add 'human' date format
Martin Koegler      5efde212f: zlib.c: use size_t for size
Stefan Beller      7454fe5cb: fetch: try fetching submodules if needed 
objects were not fetched
Stefan Beller      bba406749: sha1-array: provide oid_array_filter
Stefan Beller      e2419f7e3: submodule: migrate get_next_submodule to 
use repository structs



Uncovered code in 'jch' not in 'next'
----------------------------------------

apply.c
0f086e6dca 3355) if (checkout_entry(ce, &costate, NULL, NULL) ||
0f086e6dca 3356)     lstat(ce->name, st))

builtin/branch.c
0ecb1fc726 builtin/branch.c 456) die(_("could not resolve HEAD"));
0ecb1fc726 builtin/branch.c 462) die(_("HEAD (%s) points outside of 
refs/heads/"), refname);

builtin/pull.c
b19eee9066 647) argv_array_push(&args, opt_cleanup);

hex.c
47edb64997  93) char *sha1_to_hex_r(char *buffer, const unsigned char *sha1)
47edb64997  95) return hash_to_hex_algop_r(buffer, sha1, 
&hash_algos[GIT_HASH_SHA1]);
47edb64997 116) char *hash_to_hex(const unsigned char *hash)
47edb64997 118) return hash_to_hex_algop(hash, the_hash_algo);

pathspec.c
22af33bece 671) name = to_free = xmemdupz(name, namelen);

read-cache.c
ee70c12820 1730) if (advice_unknown_index_extension) {
ee70c12820 1731) warning(_("ignoring optional %.4s index extension"), ext);
ee70c12820 1732) advise(_("This is likely due to the file having been 
written by a newer\n"

sequencer.c
18e711a162 2387) opts->quiet = 1;

sha1-file.c
2f90b9d9b4 sha1-file.c  172) int hash_algo_by_name(const char *name)
2f90b9d9b4 sha1-file.c  175) if (!name)
2f90b9d9b4 sha1-file.c  176) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  177) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  178) if (!strcmp(name, hash_algos[i].name))
2f90b9d9b4 sha1-file.c  179) return i;
2f90b9d9b4 sha1-file.c  180) return GIT_HASH_UNKNOWN;
2f90b9d9b4 sha1-file.c  183) int hash_algo_by_id(uint32_t format_id)
2f90b9d9b4 sha1-file.c  186) for (i = 1; i < GIT_HASH_NALGOS; i++)
2f90b9d9b4 sha1-file.c  187) if (format_id == hash_algos[i].format_id)
2f90b9d9b4 sha1-file.c  188) return i;
2f90b9d9b4 sha1-file.c  189) return GIT_HASH_UNKNOWN;

tree.c
e092073d64 104) commit = lookup_commit(r, entry.oid);

Commits introducing uncovered code:
brian m. carlson      2f90b9d9b: sha1-file: provide functions to look up 
hash algorithms
brian m. carlson      47edb6499: hex: introduce functions to print 
arbitrary hashes
Daniels Umanovskis      0ecb1fc72: branch: introduce --show-current 
display option
Denton Liu      b19eee906: merge: add scissors line on merge conflict
Elijah Newren      18e711a16: git-rebase, sequencer: extend --quiet 
option for the interactive machinery
Jonathan Nieder      ee70c1282: index: offer advice for unknown index 
extensions
Nguyễn Thái Ngọc Duy      0f086e6dc: checkout: print something when 
checking out paths
Nguyễn Thái Ngọc Duy      22af33bec: dir.c: move, rename and export 
match_attrs()
Nguyễn Thái Ngọc Duy      e092073d6: tree.c: make read_tree*() take 
'struct repository *'



Uncovered code in 'next' not in 'master'
--------------------------------------------

archive.c
c6e7965ddf 399) die(_("not a valid object name: %s"), name);
c6e7965ddf 412) die(_("not a tree object: %s"), oid_to_hex(&oid));
c6e7965ddf 422) die(_("current working directory is untracked"));

attr.c
ad8f8f4aed  369) fprintf_ln(stderr, _("%s not allowed: %s:%d"),

blame.c
fb998eae6c 1717) obj = deref_tag(revs->repo, obj, NULL, 0);
fb998eae6c 1724) head_commit = lookup_commit_reference_gently(revs->repo,

builtin/bundle.c
74ae4b638d builtin/bundle.c 64) return !!unbundle(the_repository, 
&header, bundle_fd, 0) ||

builtin/fast-export.c
b93b81e799 builtin/fast-export.c   52) signed_tag_mode = SIGNED_TAG_ABORT;
b93b81e799 builtin/fast-export.c   70) tag_of_filtered_mode = 
TAG_FILTERING_ABORT;
f129c4275c builtin/fast-export.c  202) if (!p->parents)
f129c4275c builtin/fast-export.c  203) return NULL;
f129c4275c builtin/fast-export.c  204) p = p->parents->item;
f129c4275c builtin/fast-export.c  205) }
843b9e6d48 builtin/fast-export.c  265) die("oid mismatch in blob %s", 
oid_to_hex(oid));
a965bb3116 builtin/fast-export.c  277) printf("original-oid %s\n", 
oid_to_hex(oid));
843b9e6d48 builtin/fast-export.c  356) const unsigned hashsz = 
the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  357) unsigned char *out = 
xcalloc(hashsz, 1);
843b9e6d48 builtin/fast-export.c  358) put_be32(out + hashsz - 4, 
counter++);
843b9e6d48 builtin/fast-export.c  362) static const struct object_id 
*anonymize_oid(const struct object_id *oid)
843b9e6d48 builtin/fast-export.c  365) size_t len = the_hash_algo->rawsz;
843b9e6d48 builtin/fast-export.c  366) return anonymize_mem(&objs, 
generate_fake_oid, oid, &len);
843b9e6d48 builtin/fast-export.c  426) anonymize_oid(&spec->oid) :
a965bb3116 builtin/fast-export.c  644) printf("original-oid %s\n", 
oid_to_hex(&commit->object.oid));
530ca19c02 builtin/fast-export.c  668) printf("%s\n", oid_to_hex(anonymize ?
530ca19c02 builtin/fast-export.c  669) anonymize_oid(&obj->oid) :
f129c4275c builtin/fast-export.c  810) p = rewrite_commit((struct commit 
*)tagged);
f129c4275c builtin/fast-export.c  811) if (!p) {
f129c4275c builtin/fast-export.c  812) printf("reset %s\nfrom %s\n\n",
f129c4275c builtin/fast-export.c  814) free(buf);
f129c4275c builtin/fast-export.c  815) return;
a965bb3116 builtin/fast-export.c  825) printf("original-oid %s\n", 
oid_to_hex(&tag->object.oid));
cd13762d8f builtin/fast-export.c  943) printf("reset %s\nfrom %s\n\n",
cd13762d8f builtin/fast-export.c  945) continue;
530ca19c02 builtin/fast-export.c  960) if (!reference_excluded_commits) {
530ca19c02 builtin/fast-export.c  962) printf("reset %s\nfrom %s\n\n",
530ca19c02 builtin/fast-export.c  964) continue;
530ca19c02 builtin/fast-export.c  967) printf("reset %s\nfrom %s\n\n", name,
530ca19c02 builtin/fast-export.c  968) oid_to_hex(&commit->object.oid));
fdf31b6369 builtin/fast-export.c  969) continue;

builtin/fsck.c
674ba34038 builtin/fsck.c  87) ret = _("unknown");
674ba34038 builtin/fsck.c 167) objerror(parent, _("wrong object type in 
link"));
674ba34038 builtin/fsck.c 278) printf_ln(_("unreachable %s %s"), 
printable_type(obj),
674ba34038 builtin/fsck.c 306) error(_("could not create lost-found"));
674ba34038 builtin/fsck.c 313) die_errno(_("could not write '%s'"), 
filename);
674ba34038 builtin/fsck.c 317) die_errno(_("could not finish '%s'"),
674ba34038 builtin/fsck.c 334) fprintf_ln(stderr, _("Checking %s"), 
describe_object(obj));
674ba34038 builtin/fsck.c 352) fprintf_ln(stderr, _("Checking 
connectivity (%d objects)"), max);
674ba34038 builtin/fsck.c 371) fprintf_ln(stderr, _("Checking %s %s"),
674ba34038 builtin/fsck.c 384) printf_ln(_("root %s"),
674ba34038 builtin/fsck.c 421) return error(_("%s: object corrupt or 
missing"),
674ba34038 builtin/fsck.c 460) fprintf_ln(stderr, _("Checking reflog 
%s->%s"),
674ba34038 builtin/fsck.c 584) error(_("%s: object could not be parsed: 
%s"),
674ba34038 builtin/fsck.c 619) fprintf_ln(stderr, _("Checking object 
directory"));
5215bd2f7d builtin/fsck.c 637) fprintf_ln(stderr, _("Checking %s link"), 
head_ref_name);
5215bd2f7d builtin/fsck.c 642) return error(_("invalid %s"), head_ref_name);
674ba34038 builtin/fsck.c 671) fprintf_ln(stderr, _("Checking cache tree"));
674ba34038 builtin/fsck.c 687) err |= objerror(obj, _("non-tree in 
cache-tree"));

builtin/merge.c
9440b831ad builtin/merge.c  131) return error(_("option `%s' requires a 
value"), opt->long_name);

builtin/rebase--interactive.c
005af339c9 builtin/rebase--interactive.c  262) ret = 
rearrange_squash(the_repository);
005af339c9 builtin/rebase--interactive.c  265) ret = 
sequencer_add_exec_commands(the_repository, cmd);

builtin/rebase.c
4d86503eed  585) ret = error(_("failed to find tree of %s"),

builtin/reflog.c
dd509db342 builtin/reflog.c 592) usage(_(reflog_expire_usage));
dd509db342 builtin/reflog.c 643) status |= error(_("%s points 
nowhere!"), argv[i]);
dd509db342 builtin/reflog.c 689) usage(_(reflog_delete_usage));
dd509db342 builtin/reflog.c 695) return error(_("no reflog specified to 
delete"));
dd509db342 builtin/reflog.c 704) status |= error(_("not a reflog: %s"), 
argv[i]);
dd509db342 builtin/reflog.c 709) status |= error(_("no reflog for 
'%s'"), argv[i]);
dd509db342 builtin/reflog.c 744) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 752) usage(_(reflog_exists_usage));
dd509db342 builtin/reflog.c 755) die(_("invalid ref format: %s"), 
argv[start]);

builtin/repack.c
c83d950e59 200) die(_("could not start pack-objects to repack promisor 
objects"));
5215bd2f7d 239) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));
c83d950e59 250) die_errno(_("unable to create '%s'"), promisor_name);
5215bd2f7d 411) die(_("repack: Expecting full hex object ID lines only 
from pack-objects."));

bundle.c
74ae4b638d 394) struct commit *one = lookup_commit_reference(revs->repo, 
&oid);

config.c
2a9dedef2e 2309) *dest = val ? 0 : 1;
2a9dedef2e 2311) *dest = val;
2a9dedef2e 2312) return 0;

delta-islands.c
385cb64ff3 216) parse_object(r, &obj->oid);

entry.c
e66ceca94b 422) if ((trust_ino && !match_stat_data(&dup->ce_stat_data, 
st)) ||

fast-import.c
a965bb3116 1821) read_next_command();

git.c
8aa8c14097 341) die_errno(_("while expanding alias '%s': '%s'"),
8aa8c14097 350) die(_("alias '%s' changes environment variables.\n"
8aa8c14097 358) die(_("empty alias for %s"), alias_command);
8aa8c14097 361) die(_("recursive alias: %s"), alias_command);
8aa8c14097 412) die(_("%s doesn't support --super-prefix"), p->cmd);
8aa8c14097 436) die_errno(_("write failure on standard output"));
8aa8c14097 438) die(_("unknown write failure on standard output"));
8aa8c14097 440) die_errno(_("close failed on standard output"));
8aa8c14097 657) die(_("%s doesn't support --super-prefix"), argv[0]);
8aa8c14097 769) die(_("cannot handle %s as a builtin"), cmd);

http-walker.c
b69fb867b4 http-walker.c 550) loose_object_path(the_repository, &buf, 
req->sha1);

http.c
d73019feb4  289) return git_config_string(&curl_http_version, var, value);
d73019feb4  797) static int get_curl_http_version_opt(const char 
*version_string, long *opt)
d73019feb4  808) for (i = 0; i < ARRAY_SIZE(choice); i++) {
d73019feb4  809) if (!strcmp(version_string, choice[i].name)) {
d73019feb4  810) *opt = choice[i].opt_token;
d73019feb4  811) return 0;
d73019feb4  815) warning("unknown value given to http.version: '%s'", 
version_string);
d73019feb4  816) return -1; /* not found */
d73019feb4  841) if (!get_curl_http_version_opt(curl_http_version, &opt)) {
d73019feb4  843) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt);

merge-recursive.c
37b65ce36b 1584) return -1;
37b65ce36b 1587) return -1;
37b65ce36b 1593) return -1;
37b65ce36b 1596) return -1;
37b65ce36b 1663) return -1;
37b65ce36b 1666) return -1;
37b65ce36b 1669) return -1;
7f8671656f 1702) return -1;
48c9cb9d6d 1758) return -1;
48c9cb9d6d 1806) return -1;
48c9cb9d6d 1812) return -1;
48c9cb9d6d 1815) return -1;
48c9cb9d6d 1825) return -1;
48c9cb9d6d 1831) return -1;
48c9cb9d6d 1834) return -1;

parse-options-cb.c
9440b831ad  21) return error(_("option `%s' expects a numerical value"),
9440b831ad  51) return error(_("option `%s' expects \"always\", 
\"auto\", or \"never\""),

parse-options.c
9440b831ad  88) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad  90) return error(_("%s isn't available"), optname(opt, flags));
9440b831ad  92) return error(_("%s takes no value"), optname(opt, flags));
9440b831ad 178) return error(_("%s expects a numerical value"),
9440b831ad 194) return error(_("%s expects a non-negative integer value"
8900342628 356) error(_("did you mean `--%s` (with two dashes ?)"), arg);
8900342628 651) error(_("unknown non-ascii option in string: `%s'"),
9440b831ad 785) strbuf_addf(&sb, "option `no-%s'", opt->long_name);

read-cache.c
9d0a9e9089  675) die(_("will not add file alias '%s' ('%s' already 
exists in index)"),
9d0a9e9089  676)     ce->name, alias->name);
9d0a9e9089  691) die(_("cannot create an empty blob in the object 
database"));
9d0a9e9089  712) return error(_("%s: can only add regular files, 
symbolic links or git-directories"), path);
9d0a9e9089  786) return error(_("unable to add '%s' to index"), path);
9d0a9e9089  822) error(_("invalid path '%s'"), path);
9d0a9e9089  848) error(_("invalid path '%s'"), path);
9d0a9e9089 1686) return error(_("bad signature 0x%08x"), 
hdr->hdr_signature);
9d0a9e9089 1689) return error(_("bad index version %d"), hdr_version);
9d0a9e9089 1728) return error(_("index uses %.4s extension, which we do 
not understand"),
9d0a9e9089 1730) fprintf_ln(stderr, _("ignoring %.4s extension"), ext);
9d0a9e9089 1777) die(_("unknown index entry format 0x%08x"), 
extended_flags);
9d0a9e9089 1848) die(_("unordered stage entries in index"));
9d0a9e9089 1851) die(_("multiple stage entries for merged file '%s'"),
9d0a9e9089 1854) die(_("unordered stage entries for '%s'"),
9d0a9e9089 2148) die_errno(_("%s: index file open failed"), path);
9d0a9e9089 2152) die_errno(_("%s: cannot stat the open index"), path);
9d0a9e9089 2156) die(_("%s: index file smaller than expected"), path);
9d0a9e9089 2160) die_errno(_("%s: unable to map index file"), path);
9d0a9e9089 2251) warning(_("could not freshen shared index '%s'"), 
shared_index);
9d0a9e9089 2286) die(_("broken index, expect %s in %s, got %s"),
d8465500c3 2699) return val;
429160544d 2714) return val;
9d0a9e9089 3100) error(_("cannot fix permission bits on '%s'"), 
get_tempfile_path(*temp));
9d0a9e9089 3247) return error(_("%s: cannot drop to stage #0"),

ref-filter.c
bbfc042ef9  236) oi_deref.info.sizep = &oi_deref.size;
bbfc042ef9  245) return strbuf_addf_ret(err, -1, _("unrecognized 
%%(objectsize) argument: %s"), arg);
ab0e367154  253) return strbuf_addf_ret(err, -1, _("%%(deltabase) does 
not take arguments"));
9440b831ad 2353) return error(_("option `%s' is incompatible with 
--no-merged"),

remote-curl.c
afa5d74929  359) die("invalid server response; expected service, got 
flush packet");

remote.c
0b9c3afdbf  363) warning(_("config remote shorthand cannot begin with 
'/': %s"),
0b9c3afdbf  418) error(_("more than one uploadpack given, using the 
first"));
0b9c3afdbf  684) die(_("key '%s' of pattern had no '*'"), key);
0b9c3afdbf  694) die(_("value '%s' of pattern has no '*'"), value);
0b9c3afdbf 1102) error(_("unable to delete '%s': remote ref does not 
exist"),
0b9c3afdbf 1121) return error(_("dst ref %s receives from more than one 
src"),
0b9c3afdbf 1840) die(_("couldn't find remote ref %s"), name);
0b9c3afdbf 1853) error(_("* Ignoring funny ref '%s' locally"),
0b9c3afdbf 1948) die(_("revision walk setup failed"));
0b9c3afdbf 2221) return error(_("cannot parse expected object name '%s'"),

sequencer.c
f11c958054  593) istate->cache_tree = cache_tree();
f11c958054 3974) res = error_dirty_index(r->index, opts);

sha1-file.c
f0eaf63819 sha1-file.c 2145) return r;

Commits introducing uncovered code:
Elijah Newren      37b65ce36: merge-recursive: new function for better 
colliding conflict resolutions
Elijah Newren      48c9cb9d6: merge-recursive: improve 
rename/rename(1to2)/add[/add] handling
Elijah Newren      530ca19c0: fast-export: add 
--reference-excluded-parents option
Elijah Newren      7f8671656: merge-recursive: fix rename/add conflict 
handling
Elijah Newren      843b9e6d4: fast-export: convert sha1 to oid
Elijah Newren      a965bb311: fast-export: add a --show-original-ids 
option to show original names
Elijah Newren      b93b81e79: fast-export: use value from correct enum
Elijah Newren      cd13762d8: fast-export: when using paths, avoid 
corrupt stream with non-existent mark
Elijah Newren      f129c4275: fast-export: move commit rewriting logic 
into a function for reuse
Elijah Newren      fdf31b636: fast-export: ensure we export requested refs
Force Charlie      d73019feb: http: add support selecting http version
Jeff King      afa5d7492: remote-curl: refactor smart-http discovery
Jeff King      b69fb867b: sha1_file_name(): overwrite buffer instead of 
appending
Jeff King      f0eaf6381: sha1-file: use an object_directory for the 
main object dir
Johannes Schindelin      4d86503ee: rebase: warn about the correct 
tree's OID
Jonathan Nieder      2a9dedef2: index: make index.threads=true enable 
ieot and eoie
Jonathan Nieder      429160544: ieot: default to not writing IEOT section
Jonathan Nieder      d8465500c: eoie: default to not writing EOIE section
Junio C Hamano      5215bd2f7: Merge branch 'nd/i18n' into next
Nguyễn Thái Ngọc Duy      005af339c: sequencer.c: remove implicit 
dependency on the_repository
Nguyễn Thái Ngọc Duy      0b9c3afdb: remote.c: mark messages for translation
Nguyễn Thái Ngọc Duy      385cb64ff: delta-islands.c: remove 
the_repository references
Nguyễn Thái Ngọc Duy      674ba3403: fsck: mark strings for translation
Nguyễn Thái Ngọc Duy      74ae4b638: bundle.c: remove the_repository 
references
Nguyễn Thái Ngọc Duy      890034262: parse-options.c: mark more strings 
for translation
Nguyễn Thái Ngọc Duy      8aa8c1409: git.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      9440b831a: parse-options: replace opterror() 
with optname()
Nguyễn Thái Ngọc Duy      9d0a9e908: read-cache.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      ad8f8f4ae: attr.c: mark more string for 
translation
Nguyễn Thái Ngọc Duy      c6e7965dd: archive.c: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      c83d950e5: repack: mark more strings for 
translation
Nguyễn Thái Ngọc Duy      dd509db34: reflog: mark strings for translation
Nguyễn Thái Ngọc Duy      e66ceca94: clone: fix colliding file detection 
on APFS
Nguyễn Thái Ngọc Duy      f11c95805: sequencer.c: remove implicit 
dependency on the_index
Nguyễn Thái Ngọc Duy      fb998eae6: blame.c: remove implicit dependency 
the_repository
Olga Telezhnaya      ab0e36715: ref-filter: add deltabase option
Olga Telezhnaya      bbfc042ef: ref-filter: add objectsize:disk option



Uncovered code in 'master' not in 'master@{1}'
----------------------------------------------------

apply.c
517fe807d6 4776) BUG_ON_OPT_NEG(unset);
735ca208c5 4830) return -1;

builtin/am.c
fce5664805 2117) *opt_value = PATCH_FORMAT_UNKNOWN;

builtin/blame.c
517fe807d6 builtin/blame.c    759) BUG_ON_OPT_NEG(unset);

builtin/cat-file.c
0eb8d3767c builtin/cat-file.c 609) return error(_("only one batch option 
may be specified"));

builtin/grep.c
fd6263fb73 builtin/grep.c 1051) warning(_("invalid option combination, 
ignoring --threads"));
fd6263fb73 builtin/grep.c 1057) die(_("invalid number of threads 
specified (%d)"), num_threads);

builtin/log.c
517fe807d6 builtin/log.c 1194) BUG_ON_OPT_NEG(unset);

builtin/pack-objects.c
ca473cef91 builtin/pack-objects.c 2086) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2087) oid_to_hex(&trg_entry->idx.oid), 
(uintmax_t)sz,
ca473cef91 builtin/pack-objects.c 2113) die(_("object %s inconsistent 
object length (%"PRIuMAX" vs %"PRIuMAX")"),
ca473cef91 builtin/pack-objects.c 2114) oid_to_hex(&src_entry->idx.oid), 
(uintmax_t)sz,

builtin/pull.c
01a31f3bca 565) die(_("unable to access commit %s"),

builtin/rebase.c
3249c1251e  556) ret = -1;
3249c1251e  557) goto leave_reset_head;
bac2a1e36f  561) ret = error(_("could not determine HEAD revision"));
bac2a1e36f  562) goto leave_reset_head;
3249c1251e  580) ret = error(_("could not read index"));
3249c1251e  581) goto leave_reset_head;
bac2a1e36f  585) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
bac2a1e36f  586) goto leave_reset_head;
3249c1251e  590) ret = error(_("failed to find tree of %s"), 
oid_to_hex(oid));
3249c1251e  591) goto leave_reset_head;
3249c1251e  604) goto leave_reset_head;

builtin/show-branch.c
517fe807d6 builtin/show-branch.c 607) BUG_ON_OPT_NEG(unset);

builtin/show-ref.c
517fe807d6 builtin/show-ref.c 154) BUG_ON_OPT_NEG(unset);

bundle.c
2c8ee1f53c 267) error_errno(_("unable to dup bundle descriptor"));
2c8ee1f53c 268) child_process_clear(&pack_objects);
2c8ee1f53c 269) return -1;
2c8ee1f53c 478) rollback_lock_file(&lock);

config.c
fast-import.c
ca473cef91 2958) strbuf_addf(&line, "%s %s %"PRIuMAX"\n", oid_to_hex(oid),

midx.c
name-hash.c
2179045fd0 532) die(_("unable to create lazy_dir thread: %s"), 
strerror(err));
2179045fd0 554) die(_("unable to create lazy_name thread: %s"), 
strerror(err));
2179045fd0 560) die(_("unable to join lazy_name thread: %s"), 
strerror(err));

preload-index.c
2179045fd0 137) die(_("unable to create threaded lstat: %s"), 
strerror(err));

revision.c
b45424181e 2915) define_commit_slab(author_date_slab, timestamp_t);
b45424181e 2942) return;
b45424181e 2945) return;
b45424181e 2948) record_author_date(&info->author_date, c);
b45424181e 2951) c->object.flags |= UNINTERESTING;
b45424181e 2954) return;
b45424181e 2957) mark_parents_uninteresting(c);
b45424181e 2980) return;
b45424181e 2983) return;
b45424181e 3031) info->topo_queue.compare = compare_commits_by_commit_date;
b45424181e 3032) break;
b45424181e 3034) init_author_date_slab(&info->author_date);
b45424181e 3035) info->topo_queue.compare = compare_commits_by_author_date;
b45424181e 3036) info->topo_queue.cb_data = &info->author_date;
b45424181e 3037) break;
b45424181e 3048) continue;
b45424181e 3059) record_author_date(&info->author_date, c);
f0d9cc4196 3097) if (!revs->ignore_missing_links)
f0d9cc4196 3098) die("Failed to traverse parents of commit %s",
f0d9cc4196 3099)     oid_to_hex(&commit->object.oid));
b45424181e 3107) continue;

run-command.c
2179045fd0 1229) error(_("cannot create async thread: %s"), strerror(err));

send-pack.c
c0e40a2d66 207) close(fd[1]);

Commits introducing uncovered code:
Derrick Stolee      b45424181: revision.c: generation-based topo-order 
algorithm
Derrick Stolee      f0d9cc419: revision.c: begin refactoring 
--topo-order logic
Jeff King      01a31f3bc: pull: handle --verify-signatures for unborn branch
Jeff King      0eb8d3767: cat-file: report an error on multiple --batch 
options
Jeff King      2c8ee1f53: bundle: dup() output descriptor closer to 
point-of-use
Jeff King      517fe807d: assert NOARG/NONEG behavior of parse-options 
callbacks
Jeff King      735ca208c: apply: return -1 from option callback instead 
of calling exit(1)
Jeff King      fce566480: am: handle --no-patch-format option
Johannes Schindelin      3249c1251: rebase: consolidate clean-up code 
before leaving reset_head()
Johannes Schindelin      bac2a1e36: built-in rebase: reinstate `checkout 
-q` behavior where appropriate
Nguyễn Thái Ngọc Duy      2179045fd: Clean up pthread_create() error 
handling
Nguyễn Thái Ngọc Duy      c0e40a2d6: send-pack.c: move async's #ifdef 
NO_PTHREADS back to run-command.c
Nguyễn Thái Ngọc Duy      fd6263fb7: grep: clean up num_threads handling
Torsten Bögershausen      ca473cef9: Upcast size_t variables to 
uintmax_t when printing


^ permalink raw reply	[relevance 2%]

* [ANNOUNCE] Git v2.19.2
@ 2018-11-21 15:19 Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-11-21 15:19 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

The latest maintenance release Git v2.19.2 is now available at the
usual places.  This is a collection of small fixes that have been
accumulated on the primary development track, merged on top of
v2.19.1 released earlier in the year.  On the 'master' front, we are
nearing the upcoming future release, by the way.

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.2'
tag and the 'maint' 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

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

Git v2.19.2 Release Notes
=========================

Fixes since v2.19.1
-------------------

 * "git interpret-trailers" and its underlying machinery had a buggy
   code that attempted to ignore patch text after commit log message,
   which triggered in various codepaths that will always get the log
   message alone and never get such an input.

 * "git rebase -i" did not clear the state files correctly when a run
   of "squash/fixup" is aborted and then the user manually amended the
   commit instead, which has been corrected.

 * When fsmonitor is in use, after operation on submodules updates
   .gitmodules, we lost track of the fact that we did so and relied on
   stale fsmonitor data.

 * Fix for a long-standing bug that leaves the index file corrupt when
   it shrinks during a partial commit.

 * Further fix for O_APPEND emulation on Windows

 * A corner case bugfix in "git rerere" code.

 * "git add ':(attr:foo)'" is not supported and is supposed to be
   rejected while the command line arguments are parsed, but we fail
   to reject such a command line upfront.

 * "git rebase" etc. in Git 2.19 fails to abort when given an empty
   commit log message as result of editing, which has been corrected.

 * The code to backfill objects in lazily cloned repository did not
   work correctly, which has been corrected.

 * Update error messages given by "git remote" and make them consistent.

 * "git update-ref" learned to make both "--no-deref" and "--stdin"
   work at the same time.

 * Recently added "range-diff" had a corner-case bug to cause it
   segfault, which has been corrected.

 * The recently introduced commit-graph auxiliary data is incompatible
   with mechanisms such as replace & grafts that "breaks" immutable
   nature of the object reference relationship.  Disable optimizations
   based on its use (and updating existing commit-graph) when these
   incompatible features are in use in the repository.

 * The mailmap file update.

 * The code in "git status" sometimes hit an assertion failure.  This
   was caused by a structure that was reused without cleaning the data
   used for the first run, which has been corrected.

 * A corner-case bugfix.

 * A partial clone that is configured to lazily fetch missing objects
   will on-demand issue a "git fetch" request to the originating
   repository to fill not-yet-obtained objects.  The request has been
   optimized for requesting a tree object (and not the leaf blob
   objects contained in it) by telling the originating repository that
   no blobs are needed.

 * The codepath to support the experimental split-index mode had
   remaining "racily clean" issues fixed.

 * "git log --graph" showing an octopus merge sometimes miscounted the
   number of display columns it is consuming to show the merge and its
   parent commits, which has been corrected.

 * The implementation of run_command() API on the UNIX platforms had a
   bug that caused a command not on $PATH to be found in the current
   directory.

 * A mutex used in "git pack-objects" were not correctly initialized
   and this caused "git repack" to dump core on Windows.

 * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
   Windows would strip initial parts from the paths because they
   were not recognized as absolute, which has been corrected.

 * The receive.denyCurrentBranch=updateInstead codepath kicked in even
   when the push should have been rejected due to other reasons, such
   as it does not fast-forward or the update-hook rejects it, which
   has been corrected.

 * "git repack" in a shallow clone did not correctly update the
   shallow points in the repository, leading to a repository that
   does not pass fsck.

 * Operations on promisor objects make sense in the context of only a
   small subset of the commands that internally use the revisions
   machinery, but the "--exclude-promisor-objects" option were taken
   and led to nonsense results by commands like "log", to which it
   didn't make much sense.  This has been corrected.

 * The "container" mode of TravisCI is going away.  Our .travis.yml
   file is getting prepared for the transition.

 * Our test scripts can now take the '-V' option as a synonym for the
   '--verbose-log' option.

 * A regression in Git 2.12 era made "git fsck" fall into an infinite
   loop while processing truncated loose objects.

Also contains various documentation updates and code clean-ups.

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

Changes since v2.19.1 are as follows:

Alexander Pyhalov (1):
      t7005-editor: quote filename to fix whitespace-issue

Andreas Heiduk (6):
      doc: clarify boundaries of 'git worktree list --porcelain'
      doc: fix ASCII art tab spacing
      doc: fix inappropriate monospace formatting
      doc: fix descripion for 'git tag --format'
      doc: fix indentation of listing blocks in gitweb.conf.txt
      doc: fix formatting in git-update-ref

Ben Peart (1):
      git-mv: allow submodules and fsmonitor to work together

Brandon Williams (1):
      config: document value 2 for protocol.version

Daniels Umanovskis (3):
      doc: move git-rev-parse from porcelain to plumbing
      doc: move git-get-tar-commit-id to plumbing
      doc: move git-cherry to plumbing

David Zych (1):
      doc: clarify gitcredentials path component matching

Derrick Stolee (6):
      commit-graph: update design document
      test-repository: properly init repo
      commit-graph: not compatible with replace objects
      commit-graph: not compatible with grafts
      commit-graph: not compatible with uninitialized repo
      commit-graph: close_commit_graph before shallow walk

Elijah Newren (7):
      Remove superfluous trailing semicolons
      t4200: demonstrate rerere segfault on specially crafted merge
      rerere: avoid buffer overrun
      update-ref: fix type of update_flags variable to match its usage
      update-ref: allow --no-deref with --stdin
      sequencer: fix --allow-empty-message behavior, make it smarter
      commit: fix erroneous BUG, 'multiple renames on the same target? how?'

Frederick Eaton (3):
      git-archimport.1: specify what kind of Arch we're talking about
      git-column.1: clarify initial description, provide examples
      git-describe.1: clarify that "human readable" is also git-readable

Jeff Hostetler (2):
      t0051: test GIT_TRACE to a windows named pipe
      mingw: fix mingw_open_append to work with named pipes

Jeff King (16):
      trailer: use size_t for string offsets
      trailer: use size_t for iterating trailer list
      trailer: pass process_trailer_opts to trailer_info_get()
      interpret-trailers: tighten check for "---" patch boundary
      interpret-trailers: allow suppressing "---" divider
      pretty, ref-filter: format %(trailers) with no_divider option
      sequencer: ignore "---" divider when parsing trailers
      append_signoff: use size_t for string offsets
      reopen_tempfile(): truncate opened file
      config.mak.dev: add -Wformat-security
      receive-pack: update comment with check_everything_connected
      run-command: mark path lookup errors with ENOENT
      upload-pack: fix broken if/else chain in config callback
      t1450: check large blob in trailing-garbage test
      check_stream_sha1(): handle input underflow
      cat-file: handle streaming failures consistently

Johannes Schindelin (8):
      rebase -i --autosquash: demonstrate a problem skipping the last squash
      rebase -i: be careful to wrap up fixup/squash chains
      pack-objects: fix typo 'detla' -> 'delta'
      pack-objects (mingw): demonstrate a segmentation fault with large deltas
      pack-objects (mingw): initialize `packing_data` mutex in the correct spot
      repack: point out a bug handling stale shallow info
      shallow: offer to prune only non-existing entries
      repack -ad: prune the list of shallow commits

Johannes Sixt (2):
      diff: don't attempt to strip prefix from absolute Windows paths
      t3404-rebase-interactive: test abbreviated commands

Jonathan Nieder (2):
      mailmap: consistently normalize brian m. carlson's name
      git doc: direct bug reporters to mailing list archive

Jonathan Tan (4):
      fetch-object: unify fetch_object[s] functions
      fetch-object: set exact_oid when fetching
      fetch-pack: avoid object flags if no_dependents
      fetch-pack: exclude blobs when lazy-fetching trees

Junio C Hamano (5):
      CodingGuidelines: document the API in *.h files
      receive: denyCurrentBranch=updateinstead should not blindly update
      cocci: simplify "if (++u > 1)" to "if (u++)"
      fsck: s/++i > 1/i++/
      Git 2.19.2

Martin Ågren (5):
      git-commit-graph.txt: fix bullet lists
      git-commit-graph.txt: typeset more in monospace
      git-commit-graph.txt: refer to "*commit*-graph file"
      Doc: refer to the "commit-graph file" with dash
      t1400: drop debug `echo` to actually execute `test`

Matthew DeVore (2):
      Documentation/git-log.txt: do not show --exclude-promisor-objects
      exclude-promisor-objects: declare when option is allowed

Michael Witten (3):
      docs: typo: s/go/to/
      docs: graph: remove unnecessary `graph_update()' call
      docs: typo: s/isimilar/similar/

Mihir Mehta (1):
      doc: fix a typo and clarify a sentence

Nguyễn Thái Ngọc Duy (2):
      add: do not accept pathspec magic 'attr'
      config.txt: correct the note about uploadpack.packObjectsHook

Noam Postavsky (1):
      log: fix coloring of certain octopus merge shapes

René Scharfe (1):
      sequencer: use return value of oidset_insert()

SZEDER Gábor (12):
      Documentation/git.txt: clarify that GIT_TRACE=/path appends
      t3701-add-interactive: tighten the check of trace output
      t1700-split-index: drop unnecessary 'grep'
      t0090: disable GIT_TEST_SPLIT_INDEX for the test checking split index
      t1700-split-index: document why FSMONITOR is disabled in this test script
      split-index: add tests to demonstrate the racy split index problem
      t1700-split-index: date back files to avoid racy situations
      split-index: count the number of deleted entries
      split-index: don't compare cached data of entries already marked for split index
      split-index: smudge and add racily clean cache entries to split index
      split-index: BUG() when cache entry refers to non-existing shared entry
      test-lib: introduce the '-V' short option for '--verbose-log'

Sam McKelvie (1):
      rev-parse: --show-superproject-working-tree should work during a merge

Saulius Gurklys (1):
      doc: fix small typo in git show-branch

Sebastian Staudt (1):
      travis-ci: no longer use containers

Shulhan (1):
      builtin/remote: quote remote name on error to display empty name

Stefan Beller (4):
      refs.c: migrate internal ref iteration to pass thru repository argument
      refs.c: upgrade for_each_replace_ref to be a each_repo_ref_fn callback
      string-list: remove unused function print_string_list
      strbuf.h: format according to coding guidelines

Tao Qingyun (3):
      refs: docstring typo
      builtin/branch.c: remove useless branch_get
      branch: trivial style fix

Thomas Gummerer (4):
      .gitattributes: add conflict-marker-size for relevant files
      linear-assignment: fix potential out of bounds memory access
      t5551: move setup code inside test_expect blocks
      t5551: compare sorted cookies files

Tim Schumacher (1):
      Documentation/Makefile: make manpage-base-url.xsl generation quieter

Torsten Bögershausen (2):
      Make git_check_attr() a void function
      path.c: char is not (always) signed

Uwe Kleine-König (1):
      howto/using-merge-subtree: mention --allow-unrelated-histories


^ permalink raw reply	[relevance 2%]

* [ANNOUNCE] Git v2.20.0-rc1
@ 2018-11-21 15:20 Junio C Hamano
  0 siblings, 0 replies; 200+ results
From: Junio C Hamano @ 2018-11-21 15:20 UTC (permalink / raw)
  To: git; +Cc: Linux Kernel, git-packagers

A release candidate Git v2.20.0-rc1 is now available for testing
at the usual places.  It is comprised of 915 non-merge commits
since v2.19.0, contributed by 73 people, 24 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.20.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.19.0 are as follows.
Welcome to the Git development community!

  Aaron Lindsay, Alexander Pyhalov, Anton Serbulov, Brendan
  Forster, Carlo Marcelo Arenas Belón, Daniels Umanovskis, David
  Zych, Đoàn Trần Công Danh, Frederick Eaton, James Knight,
  Jann Horn, Joshua Watt, Loo Rong Jie, Lucas De Marchi, Matthew
  DeVore, Mihir Mehta, Nickolai Belakovski, Roger Strain, Sam
  McKelvie, Saulius Gurklys, Shulhan, Steven Fernandez, Strain,
  Roger L, and Tim Schumacher.

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

  Ævar Arnfjörð Bjarmason, Alban Gruin, Andreas Gruenbacher,
  Andreas Heiduk, Antonio Ospite, Ben Peart, Brandon Williams,
  brian m. carlson, Christian Couder, Christian Hesse, Denton Liu,
  Derrick Stolee, Elijah Newren, Eric Sunshine, Jeff Hostetler,
  Jeff King, Johannes Schindelin, Johannes Sixt, Jonathan Nieder,
  Jonathan Tan, Josh Steadmon, Junio C Hamano, Karsten Blees,
  Luke Diamand, Martin Ågren, Max Kirillov, Michael Witten,
  Michał Górny, Nguyễn Thái Ngọc Duy, Noam Postavsky,
  Olga Telezhnaya, Phillip Wood, Pratik Karki, Rafael Ascensão,
  Ralf Thielow, Ramsay Jones, Rasmus Villemoes, René Scharfe,
  Sebastian Staudt, Stefan Beller, Stephen P. Smith, Steve Hoelzer,
  SZEDER Gábor, Tao Qingyun, Taylor Blau, Thomas Gummerer,
  Todd Zullinger, Torsten Bögershausen, and Uwe Kleine-König.

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

Git 2.20 Release Notes (draft)
==============================

Backward Compatibility Notes
----------------------------

 * "git branch -l <foo>" used to be a way to ask a reflog to be
   created while creating a new branch, but that is no longer the
   case.  It is a short-hand for "git branch --list <foo>" now.

 * "git push" into refs/tags/* hierarchy is rejected without getting
   forced, but "git fetch" (misguidedly) used the "fast forwarding"
   rule used for the refs/heads/* hierarchy; this has been corrected,
   which means some fetches of tags that did not fail with older
   version of Git will fail without "--force" with this version.

 * "git help -a" now gives verbose output (same as "git help -av").
   Those who want the old output may say "git help --no-verbose -a"..

 * "git cpn --help", when "cpn" is an alias to, say, "cherry-pick -n",
   reported only the alias expansion of "cpn" in earlier versions of
   Git.  It now runs "git cherry-pick --help" to show the manual page
   of the command, while sending the alias expansion to the standard
   error stream.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by". This is a backward-incompatible
   change.  Adding "--suppress-cc=misc-by" on the command line, or
   setting sendemail.suppresscc configuration variable to "misc-by",
   can be used to disable this behaviour.


Updates since v2.19
-------------------

UI, Workflows & Features

 * Running "git clone" against a project that contain two files with
   pathnames that differ only in cases on a case insensitive
   filesystem would result in one of the files lost because the
   underlying filesystem is incapable of holding both at the same
   time.  An attempt is made to detect such a case and warn.

 * "git checkout -b newbranch [HEAD]" should not have to do as much as
   checking out a commit different from HEAD.  An attempt is made to
   optimize this special case.

 * "git rev-list --stdin </dev/null" used to be an error; it now shows
   no output without an error.  "git rev-list --stdin --default HEAD"
   still falls back to the given default when nothing is given on the
   standard input.

 * Lift code from GitHub to restrict delta computation so that an
   object that exists in one fork is not made into a delta against
   another object that does not appear in the same forked repository.

 * "git format-patch" learned new "--interdiff" and "--range-diff"
   options to explain the difference between this version and the
   previous attempt in the cover letter (or after the three-dashes as
   a comment).

 * "git mailinfo" used in "git am" learned to make a best-effort
   recovery of a patch corrupted by MUA that sends text/plain with
   format=flawed option.
   (merge 3aa4d81f88 rs/mailinfo-format-flowed later to maint).

 * The rules used by "git push" and "git fetch" to determine if a ref
   can or cannot be updated were inconsistent; specifically, fetching
   to update existing tags were allowed even though tags are supposed
   to be unmoving anchoring points.  "git fetch" was taught to forbid
   updates to existing tags without the "--force" option.

 * "git multi-pack-index" learned to detect corruption in the .midx
   file it uses, and this feature has been integrated into "git fsck".

 * Generation of (experimental) commit-graph files have so far been
   fairly silent, even though it takes noticeable amount of time in a
   meaningfully large repository.  The users will now see progress
   output.

 * The minimum version of Windows supported by Windows port of Git is
   now set to Vista.

 * The completion script (in contrib/) learned to complete a handful of
   options "git stash list" command takes.

 * The completion script (in contrib/) learned that "git fetch
   --multiple" only takes remote names as arguments and no refspecs.

 * "git status" learns to show progress bar when refreshing the index
   takes a long time.
   (merge ae9af12287 nd/status-refresh-progress later to maint).

 * "git help -a" and "git help -av" give different pieces of
   information, and generally the "verbose" version is more friendly
   to the new users.  "git help -a" by default now uses the more
   verbose output (with "--no-verbose", you can go back to the
   original).  Also "git help -av" now lists aliases and external
   commands, which it did not used to.

 * Unlike "grep", "git grep" by default recurses to the whole tree.
   The command learned "git grep --recursive" option, so that "git
   grep --no-recursive" can serve as a synonym to setting the
   max-depth to 0.

 * When pushing into a repository that borrows its objects from an
   alternate object store, "git receive-pack" that responds to the
   push request on the other side lists the tips of refs in the
   alternate to reduce the amount of objects transferred.  This
   sometimes is detrimental when the number of refs in the alternate
   is absurdly large, in which case the bandwidth saved in potentially
   fewer objects transferred is wasted in excessively large ref
   advertisement.  The alternate refs that are advertised are now
   configurable with a pair of configuration variables.

 * "git cmd --help" when "cmd" is aliased used to only say "cmd is
   aliased to ...".  Now it shows that to the standard error stream
   and runs "git $cmd --help" where $cmd is the first word of the
   alias expansion.

 * The documentation of "git gc" has been updated to mention that it
   is no longer limited to "pruning away crufts" but also updates
   ancillary files like commit-graph as a part of repository
   optimization.

 * "git p4 unshelve" improvements.

 * The logic to select the default user name and e-mail on Windows has
   been improved.
   (merge 501afcb8b0 js/mingw-default-ident later to maint).

 * The "rev-list --filter" feature learned to exclude all trees via
   "tree:0" filter.

 * "git send-email" learned to grab address-looking string on any
   trailer whose name ends with "-by"; --suppress-cc=misc-by on the
   command line, or setting sendemail.suppresscc configuration
   variable to "misc-by", can be used to disable this behaviour.

 * Developer builds now uses -Wunused-function compilation option.

 * One of our CI tests to run with "unusual/experimental/random"
   settings now also uses commit-graph and midx.

 * "git mergetool" learned to take the "--[no-]gui" option, just like
   "git difftool" does.

 * "git rebase -i" learned a new insn, 'break', that the user can
   insert in the to-do list.  Upon hitting it, the command returns
   control back to the user.

 * New "--pretty=format:" placeholders %GF and %GP that show the GPG
   key fingerprints have been invented.

 * On platforms with recent cURL library, http.sslBackend configuration
   variable can be used to choose a different SSL backend at runtime.
   The Windows port uses this mechanism to switch between OpenSSL and
   Secure Channel while talking over the HTTPS protocol.

 * "git send-email" learned to disable SMTP authentication via the
   "--smtp-auth=none" option, even when the smtp username is given
   (which turns the authentication on by default).

 * A fourth class of configuration files (in addition to the
   traditional "system wide", "per user in the $HOME directory" and
   "per repository in the $GIT_DIR/config") has been introduced so
   that different worktrees that share the same repository (hence the
   same $GIT_DIR/config file) can use different customization.

 * A pattern with '**' that does not have a slash on either side used
   to be an invalid one, but the code now treats such double-asterisks
   the same way as two normal asterisks that happen to be adjacent to
   each other.
   (merge e5bbe09e88 nd/wildmatch-double-asterisk later to maint).

 * The "--no-patch" option, which can be used to get a high-level
   overview without the actual line-by-line patch difference shown, of
   the "range-diff" command was earlier broken, which has been
   corrected.

 * The recently merged "rebase in C" has an escape hatch to use the
   scripted version when necessary, but it hasn't been documented,
   which has been corrected.


Performance, Internal Implementation, Development Support etc.

 * When there are too many packfiles in a repository (which is not
   recommended), looking up an object in these would require
   consulting many pack .idx files; a new mechanism to have a single
   file that consolidates all of these .idx files is introduced.

 * "git submodule update" is getting rewritten piece-by-piece into C.

 * The code for computing history reachability has been shuffled,
   obtained a bunch of new tests to cover them, and then being
   improved.

 * The unpack_trees() API used in checking out a branch and merging
   walks one or more trees along with the index.  When the cache-tree
   in the index tells us that we are walking a tree whose flattened
   contents is known (i.e. matches a span in the index), as linearly
   scanning a span in the index is much more efficient than having to
   open tree objects recursively and listing their entries, the walk
   can be optimized, which has been done.

 * When creating a thin pack, which allows objects to be made into a
   delta against another object that is not in the resulting pack but
   is known to be present on the receiving end, the code learned to
   take advantage of the reachability bitmap; this allows the server
   to send a delta against a base beyond the "boundary" commit.

 * spatch transformation to replace boolean uses of !hashcmp() to
   newly introduced oideq() is added, and applied, to regain
   performance lost due to support of multiple hash algorithms.

 * Fix a bug in which the same path could be registered under multiple
   worktree entries if the path was missing (for instance, was removed
   manually).  Also, as a convenience, expand the number of cases in
   which --force is applicable.

 * Split Documentation/config.txt for easier maintenance.
   (merge 6014363f0b nd/config-split later to maint).

 * Test helper binaries clean-up.
   (merge c9a1f4161f nd/test-tool later to maint).

 * Various tests have been updated to make it easier to swap the
   hash function used for object identification.
   (merge ae0c89d41b bc/hash-independent-tests later to maint).

 * Update fsck.skipList implementation and documentation.
   (merge 371a655074 ab/fsck-skiplist later to maint).

 * An alias that expands to another alias has so far been forbidden,
   but now it is allowed to create such an alias.

 * Various test scripts have been updated for style and also correct
   handling of exit status of various commands.

 * "gc --auto" ended up calling exit(-1) upon error, which has been
   corrected to use exit(1).  Also the error reporting behaviour when
   daemonized has been updated to exit with zero status when stopping
   due to a previously discovered error (which implies there is no
   point running gc to improve the situation); we used to exit with
   failure in such a case.

 * Various codepaths in the core-ish part learned to work on an
   arbitrary in-core index structure, not necessarily the default
   instance "the_index".
   (merge b3c7eef9b0 nd/the-index later to maint).

 * Code clean-up in the internal machinery used by "git status" and
   "git commit --dry-run".
   (merge 73ba5d78b4 ss/wt-status-committable later to maint).

 * Some environment variables that control the runtime options of Git
   used during tests are getting renamed for consistency.
   (merge 4231d1ba99 bp/rename-test-env-var later to maint).

 * A pair of new extensions to the index file have been introduced.
   They allow the index file to be read in parallel for performance.

 * The oidset API was built on top of the oidmap API which in turn is
   on the hashmap API.  Replace the implementation to build on top of
   the khash API and gain performance.

 * Over some transports, fetching objects with an exact commit object
   name can be done without first seeing the ref advertisements.  The
   code has been optimized to exploit this.

 * In a partial clone that will lazily be hydrated from the
   originating repository, we generally want to avoid "does this
   object exist (locally)?" on objects that we deliberately omitted
   when we created the clone.  The cache-tree codepath (which is used
   to write a tree object out of the index) however insisted that the
   object exists, even for paths that are outside of the partial
   checkout area.  The code has been updated to avoid such a check.

 * To help developers, an EditorConfig file that attempts to follow
   the project convention has been added.
   (merge b548d698a0 bc/editorconfig later to maint).

 * The result of coverage test can be combined with "git blame" to
   check the test coverage of code introduced recently with a new
   'coverage-diff' tool (in contrib/).
   (merge 783faedd65 ds/coverage-diff later to maint).

 * An experiment to fuzz test a few areas, hopefully we can gain more
   coverage to various areas.

 * More codepaths are moving away from hardcoded hash sizes.

 * The way the Windows port figures out the current directory has been
   improved.

 * The way DLLs are loaded on the Windows port has been improved.

 * Some tests have been reorganized and renamed; "ls t/" now gives a
   better overview of what is tested for these scripts than before.

 * "git rebase" and "git rebase -i" have been reimplemented in C.

 * Windows port learned to use nano-second resolution file timestamps.

 * The overly large Documentation/config.txt file have been split into
   million little pieces.  This potentially allows each individual piece
   included into the manual page of the command it affects more easily.

 * Replace three string-list instances used as look-up tables in "git
   fetch" with hashmaps.

 * Unify code to read the author-script used in "git am" and the
   commands that use the sequencer machinery, e.g. "git rebase -i".

 * In preparation to the day when we can deprecate and remove the
   "rebase -p", make sure we can skip and later remove tests for
   it.

 * The history traversal used to implement the tag-following has been
   optimized by introducing a new helper.

 * The helper function to refresh the cached stat information in the
   in-core index has learned to perform the lstat() part of the
   operation in parallel on multi-core platforms.

 * The code to traverse objects for reachability, used to decide what
   objects are unreferenced and expendable, have been taught to also
   consider per-worktree refs of other worktrees as starting points to
   prevent data loss.

 * "git add" needs to internally run "diff-files" equivalent, and the
   codepath learned the same optimization as "diff-files" has to run
   lstat(2) in parallel to find which paths have been updated in the
   working tree.

 * The procedure to install dependencies before testing at Travis CI
   is getting revamped for both simplicity and flexibility, taking
   advantage of the recent move to the vm-based environment.

 * The support for format-patch (and send-email) by the command-line
   completion script (in contrib/) has been simplified a bit.

 * The revision walker machinery learned to take advantage of the
   commit generation numbers stored in the commit-graph file.

 * The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".

 * The way -lcurl library gets linked has been simplified by taking
   advantage of the fact that we can just ask curl-config command how.

 * Various functions have been audited for "-Wunused-parameter" warnings
   and bugs in them got fixed.

 * A sanity check for start-up sequence has been added in the config
   API codepath.

 * The build procedure to link for fuzzing test has been made
   customizable with a new Makefile variable.

 * The way "git rebase" parses and forwards the command line options
   meant for underlying "git am" has been revamped, which fixed for
   options with parameters that were not passed correctly.

 * Our testing framework uses a special i18n "poisoned localization"
   feature to find messages that ought to stay constant but are
   incorrectly marked to be translated.  This feature has been made
   into a runtime option (it used to be a compile-time option).

 * "git push" used to check ambiguities between object-names and
   refnames while processing the list of refs' old and new values,
   which was unnecessary (as it knew that it is feeding raw object
   names).  This has been optimized out.

 * The xcurl_off_t() helper function is used to cast size_t to
   curl_off_t, but some compilers gave warnings against the code to
   ensure the casting is done without wraparound, when size_t is
   narrower than curl_off_t.  This warning has been squelched.

 * Code preparation to replace ulong vars with size_t vars where
   appropriate continues.

 * The "test installed Git" mode of our test suite has been updated to
   work better.

 * A coding convention around the Coccinelle semantic patches to have
   two classes to ease code migration process has been proposed and
   its support has been added to the Makefile.


Fixes since v2.19
-----------------

 * "git interpret-trailers" and its underlying machinery had a buggy
   code that attempted to ignore patch text after commit log message,
   which triggered in various codepaths that will always get the log
   message alone and never get such an input.
   (merge 66e83d9b41 jk/trailer-fixes later to maint).

 * Malformed or crafted data in packstream can make our code attempt
   to read or write past the allocated buffer and abort, instead of
   reporting an error, which has been fixed.

 * "git rebase -i" did not clear the state files correctly when a run
   of "squash/fixup" is aborted and then the user manually amended the
   commit instead, which has been corrected.
   (merge 10d2f35436 js/rebase-i-autosquash-fix later to maint).

 * When fsmonitor is in use, after operation on submodules updates
   .gitmodules, we lost track of the fact that we did so and relied on
   stale fsmonitor data.
   (merge 43f1180814 bp/mv-submodules-with-fsmonitor later to maint).

 * Fix for a long-standing bug that leaves the index file corrupt when
   it shrinks during a partial commit.
   (merge 6c003d6ffb jk/reopen-tempfile-truncate later to maint).

 * Further fix for O_APPEND emulation on Windows
   (merge eeaf7ddac7 js/mingw-o-append later to maint).

 * A corner case bugfix in "git rerere" code.
   (merge ad2bf0d9b4 en/rerere-multi-stage-1-fix later to maint).

 * "git add ':(attr:foo)'" is not supported and is supposed to be
   rejected while the command line arguments are parsed, but we fail
   to reject such a command line upfront.
   (merge 84d938b732 nd/attr-pathspec-fix later to maint).

 * Recent update broke the reachability algorithm when refs (e.g.
   tags) that point at objects that are not commit were involved,
   which has been fixed.

 * "git rebase" etc. in Git 2.19 fails to abort when given an empty
   commit log message as result of editing, which has been corrected.
   (merge a3ec9eaf38 en/sequencer-empty-edit-result-aborts later to maint).

 * The code to backfill objects in lazily cloned repository did not
   work correctly, which has been corrected.
   (merge e68302011c jt/lazy-object-fetch-fix later to maint).

 * Update error messages given by "git remote" and make them consistent.
   (merge 5025425dff ms/remote-error-message-update later to maint).

 * "git update-ref" learned to make both "--no-deref" and "--stdin"
   work at the same time.
   (merge d345e9fbe7 en/update-ref-no-deref-stdin later to maint).

 * Recently added "range-diff" had a corner-case bug to cause it
   segfault, which has been corrected.
   (merge e467a90c7a tg/range-diff-corner-case-fix later to maint).

 * The recently introduced commit-graph auxiliary data is incompatible
   with mechanisms such as replace & grafts that "breaks" immutable
   nature of the object reference relationship.  Disable optimizations
   based on its use (and updating existing commit-graph) when these
   incompatible features are in use in the repository.
   (merge 829a321569 ds/commit-graph-with-grafts later to maint).

 * The mailmap file update.
   (merge 255eb03edf jn/mailmap-update later to maint).

 * The code in "git status" sometimes hit an assertion failure.  This
   was caused by a structure that was reused without cleaning the data
   used for the first run, which has been corrected.
   (merge 3e73cc62c0 en/status-multiple-renames-to-the-same-target-fix later to maint).

 * "git fetch $repo $object" in a partial clone did not correctly
   fetch the asked-for object that is referenced by an object in
   promisor packfile, which has been fixed.

 * A corner-case bugfix.
   (merge c5cbb27cb5 sm/show-superproject-while-conflicted later to maint).

 * Various fixes to "diff --color-moved-ws".

 * A partial clone that is configured to lazily fetch missing objects
   will on-demand issue a "git fetch" request to the originating
   repository to fill not-yet-obtained objects.  The request has been
   optimized for requesting a tree object (and not the leaf blob
   objects contained in it) by telling the originating repository that
   no blobs are needed.
   (merge 4c7f9567ea jt/non-blob-lazy-fetch later to maint).

 * The codepath to support the experimental split-index mode had
   remaining "racily clean" issues fixed.
   (merge 4c490f3d32 sg/split-index-racefix later to maint).

 * "git log --graph" showing an octopus merge sometimes miscounted the
   number of display columns it is consuming to show the merge and its
   parent commits, which has been corrected.
   (merge 04005834ed np/log-graph-octopus-fix later to maint).

 * "git range-diff" did not work well when the compared ranges had
   changes in submodules and the "--submodule=log" was used.

 * The implementation of run_command() API on the UNIX platforms had a
   bug that caused a command not on $PATH to be found in the current
   directory.
   (merge f67b980771 jk/run-command-notdot later to maint).

 * A mutex used in "git pack-objects" were not correctly initialized
   and this caused "git repack" to dump core on Windows.
   (merge 34204c8166 js/pack-objects-mutex-init-fix later to maint).

 * Under certain circumstances, "git diff D:/a/b/c D:/a/b/d" on
   Windows would strip initial parts from the paths because they
   were not recognized as absolute, which has been corrected.
   (merge ffd04e92e2 js/diff-notice-has-drive-prefix later to maint).

 * The receive.denyCurrentBranch=updateInstead codepath kicked in even
   when the push should have been rejected due to other reasons, such
   as it does not fast-forward or the update-hook rejects it, which
   has been corrected.
   (merge b072a25fad jc/receive-deny-current-branch-fix later to maint).

 * The logic to determine the archive type "git archive" uses did not
   correctly kick in for "git archive --remote", which has been
   corrected.

 * "git repack" in a shallow clone did not correctly update the
   shallow points in the repository, leading to a repository that
   does not pass fsck.
   (merge 5dcfbf564c js/shallow-and-fetch-prune later to maint).

 * Some codepaths failed to form a proper URL when .gitmodules record
   the URL to a submodule repository as relative to the repository of
   superproject, which has been corrected.
   (merge e0a862fdaf sb/submodule-url-to-absolute later to maint).

 * "git fetch" over protocol v2 into a shallow repository failed to
   fetch full history behind a new tip of history that was diverged
   before the cut-off point of the history that was previously fetched
   shallowly.

 * The command line completion machinery (in contrib/) has been
   updated to allow the completion script to tweak the list of options
   that are reported by the parse-options machinery correctly.
   (merge 276b49ff34 nd/completion-negation later to maint).

 * Operations on promisor objects make sense in the context of only a
   small subset of the commands that internally use the revisions
   machinery, but the "--exclude-promisor-objects" option were taken
   and led to nonsense results by commands like "log", to which it
   didn't make much sense.  This has been corrected.
   (merge 669b1d2aae md/exclude-promisor-objects-fix later to maint).

 * The "container" mode of TravisCI is going away.  Our .travis.yml
   file is getting prepared for the transition.
   (merge 32ee384be8 ss/travis-ci-force-vm-mode later to maint).

 * Our test scripts can now take the '-V' option as a synonym for the
   '--verbose-log' option.
   (merge a5f52c6dab sg/test-verbose-log later to maint).

 * A regression in Git 2.12 era made "git fsck" fall into an infinite
   loop while processing truncated loose objects.
   (merge 18ad13e5b2 jk/detect-truncated-zlib-input later to maint).

 * "git ls-remote $there foo" was broken by recent update for the
   protocol v2 and stopped showing refs that match 'foo' that are not
   refs/{heads,tags}/foo, which has been fixed.
   (merge 6a139cdd74 jk/proto-v2-ref-prefix-fix later to maint).

 * Additional comment on a tricky piece of code to help developers.
   (merge 0afbe3e806 jk/stream-pack-non-delta-clarification later to maint).

 * A couple of tests used to leave the repository in a state that is
   deliberately corrupt, which have been corrected.
   (merge aa984dbe5e ab/pack-tests-cleanup later to maint).

 * The submodule support has been updated to read from the blob at
   HEAD:.gitmodules when the .gitmodules file is missing from the
   working tree.
   (merge 2b1257e463 ao/submodule-wo-gitmodules-checked-out later to maint).

 * "git fetch" was a bit loose in parsing responses from the other side
   when talking over the protocol v2.

 * "git rev-parse --exclude=* --branches --branches"  (i.e. first
   saying "add only things that do not match '*' out of all branches"
   and then adding all branches, without any exclusion this time")
   worked as expected, but "--exclude=* --all --all" did not work the
   same way, which has been fixed.
   (merge 5221048092 ag/rev-parse-all-exclude-fix later to maint).

 * "git send-email --transfer-encoding=..." in recent versions of Git
   sometimes produced an empty "Content-Transfer-Encoding:" header,
   which has been corrected.
   (merge 3c88e46f1a al/send-email-auto-cte-fixup later to maint).

 * The interface into "xdiff" library used to discover the offset and
   size of a generated patch hunk by first formatting it into the
   textual hunk header "@@ -n,m +k,l @@" and then parsing the numbers
   out.  A new interface has been introduced to allow callers a more
   direct access to them.
   (merge 5eade0746e jk/xdiff-interface later to maint).

 * Pathspec matching against a tree object were buggy when negative
   pathspec elements were involved, which has been fixed.
   (merge b7845cebc0 nd/tree-walk-path-exclusion later to maint).

 * "git merge" and "git pull" that merges into an unborn branch used
   to completely ignore "--verify-signatures", which has been
   corrected.
   (merge 01a31f3bca jk/verify-sig-merge-into-void later to maint).

 * "git rebase --autostash" did not correctly re-attach the HEAD at times.

 * "rev-parse --exclude=<pattern> --branches=<pattern>" etc. did not
   quite work, which has been corrected.
   (merge 9ab9b5df0e ra/rev-parse-exclude-glob later to maint).

 * When editing a patch in a "git add -i" session, a hunk could be
   made to no-op.  The "git apply" program used to reject a patch with
   such a no-op hunk to catch user mistakes, but it is now updated to
   explicitly allow a no-op hunk in an edited patch.
   (merge 22cb3835b9 js/apply-recount-allow-noop later to maint).

 * The URL to an MSDN page in a comment has been updated.
   (merge 2ef2ae2917 js/mingw-msdn-url later to maint).

 * "git ls-remote --sort=<thing>" can feed an object that is not yet
   available into the comparison machinery and segfault, which has
   been corrected to check such a request upfront and reject it.

 * When "git bundle" aborts due to an empty commit ranges
   (i.e. resulting in an empty pack), it left a file descriptor to an
   lockfile open, which resulted in leftover lockfile on Windows where
   you cannot remove a file with an open file descriptor.  This has
   been corrected.
   (merge 2c8ee1f53c jk/close-duped-fd-before-unlock-for-bundle later to maint).

 * "git format-patch --stat=<width>" can be used to specify the width
   used by the diffstat (shown in the cover letter).
   (merge 284aeb7e60 nd/format-patch-cover-letter-stat-width later to maint).

 * The way .git/index and .git/sharedindex* files were initially
   created gave these files different perm bits until they were
   adjusted for shared repository settings.  This was made consistent.
   (merge c9d6c78870 cc/shared-index-permbits later to maint).

 * Code cleanup, docfix, build fix, etc.
   (merge 96a7501aad ts/doc-build-manpage-xsl-quietly later to maint).
   (merge b9b07efdb2 tg/conflict-marker-size later to maint).
   (merge fa0aeea770 sg/doc-trace-appends later to maint).
   (merge d64324cb60 tb/void-check-attr later to maint).
   (merge c3b9bc94b9 en/double-semicolon-fix later to maint).
   (merge 79336116f5 sg/t3701-tighten-trace later to maint).
   (merge 801fa63a90 jk/dev-build-format-security later to maint).
   (merge 0597dd62ba sb/string-list-remove-unused later to maint).
   (merge db2d36fad8 bw/protocol-v2 later to maint).
   (merge 456d7cd3a9 sg/split-index-test later to maint).
   (merge 7b6057c852 tq/refs-internal-comment-fix later to maint).
   (merge 29e8dc50ad tg/t5551-with-curl-7.61.1 later to maint).
   (merge 55f6bce2c9 fe/doc-updates later to maint).
   (merge 7987d2232d jk/check-everything-connected-is-long-gone later to maint).
   (merge 4ba3c9be47 dz/credential-doc-url-matching-rules later to maint).
   (merge 4c399442f7 ma/commit-graph-docs later to maint).
   (merge fc0503b04e ma/t1400-undebug-test later to maint).
   (merge e56b53553a nd/packobjectshook-doc-fix later to maint).
   (merge c56170a0c4 ma/mailing-list-address-in-git-help later to maint).
   (merge 6e8fc70fce rs/sequencer-oidset-insert-avoids-dups later to maint).
   (merge ad0b8f9575 mw/doc-typofixes later to maint).
   (merge d9f079ad1a jc/how-to-document-api later to maint).
   (merge b1492bf315 ma/t7005-bash-workaround later to maint).
   (merge ac1f98a0df du/rev-parse-is-plumbing later to maint).
   (merge ca8ed443a5 mm/doc-no-dashed-git later to maint).
   (merge ce366a8144 du/get-tar-commit-id-is-plumbing later to maint).
   (merge 61018fe9e0 du/cherry-is-plumbing later to maint).
   (merge c7e5fe79b9 sb/strbuf-h-update later to maint).
   (merge 8d2008196b tq/branch-create-wo-branch-get later to maint).
   (merge 2e3c894f4b tq/branch-style-fix later to maint).
   (merge c5d844af9c sg/doc-show-branch-typofix later to maint).
   (merge 081d91618b ah/doc-updates later to maint).
   (merge b84c783882 jc/cocci-preincr later to maint).
   (merge 5e495f8122 uk/merge-subtree-doc-update later to maint).
   (merge aaaa881822 jk/uploadpack-packobjectshook-fix later to maint).
   (merge 3063477445 tb/char-may-be-unsigned later to maint).
   (merge 8c64bc9420 sg/test-rebase-editor-fix later to maint).
   (merge 71571cd7d6 ma/sequencer-do-reset-saner-loop-termination later to maint).
   (merge 9a4cb8781e cb/notes-freeing-always-null-fix later to maint).

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

Changes since v2.19.0 are as follows:

Aaron Lindsay (1):
      send-email: avoid empty transfer encoding header

Alban Gruin (21):
      sequencer: make three functions and an enum from sequencer.c public
      rebase -i: rewrite append_todo_help() in C
      editor: add a function to launch the sequence editor
      rebase -i: rewrite the edit-todo functionality in C
      sequencer: add a new function to silence a command, except if it fails
      rebase -i: rewrite setup_reflog_action() in C
      rebase -i: rewrite checkout_onto() in C
      sequencer: refactor append_todo_help() to write its message to a buffer
      sequencer: change the way skip_unnecessary_picks() returns its result
      t3404: todo list with commented-out commands only aborts
      rebase -i: rewrite complete_action() in C
      rebase -i: remove unused modes and functions
      rebase -i: implement the logic to initialize $revisions in C
      rebase -i: rewrite the rest of init_revisions_and_shortrevisions() in C
      rebase -i: rewrite write_basic_state() in C
      rebase -i: rewrite init_basic_state() in C
      rebase -i: implement the main part of interactive rebase as a builtin
      rebase--interactive2: rewrite the submodes of interactive rebase in C
      rebase -i: remove git-rebase--interactive.sh
      rebase -i: move rebase--helper modes to rebase--interactive
      p3400: replace calls to `git checkout -b' by `git checkout -B'

Alexander Pyhalov (1):
      t7005-editor: quote filename to fix whitespace-issue

Andreas Gruenbacher (1):
      rev-parse: clear --exclude list after 'git rev-parse --all'

Andreas Heiduk (6):
      doc: clarify boundaries of 'git worktree list --porcelain'
      doc: fix ASCII art tab spacing
      doc: fix inappropriate monospace formatting
      doc: fix descripion for 'git tag --format'
      doc: fix indentation of listing blocks in gitweb.conf.txt
      doc: fix formatting in git-update-ref

Anton Serbulov (1):
      mingw: fix getcwd when the parent directory cannot be queried

Antonio Ospite (10):
      submodule: add a print_config_from_gitmodules() helper
      submodule: factor out a config_set_in_gitmodules_file_gently function
      t7411: merge tests 5 and 6
      t7411: be nicer to future tests and really clean things up
      submodule--helper: add a new 'config' subcommand
      submodule: use the 'submodule--helper config' command
      t7506: clean up .gitmodules properly before setting up new scenario
      submodule: add a helper to check if it is safe to write to .gitmodules
      submodule: support reading .gitmodules when it's not in the working tree
      t/helper: add test-submodule-nested-repo-config

Ben Peart (19):
      checkout: optimize "git checkout -b <new_branch>"
      git-mv: allow submodules and fsmonitor to work together
      t/README: correct spelling of "uncommon"
      preload-index: use git_env_bool() not getenv() for customization
      fsmonitor: update GIT_TEST_FSMONITOR support
      read-cache: update TEST_GIT_INDEX_VERSION support
      preload-index: update GIT_FORCE_PRELOAD_TEST support
      read-cache: clean up casting and byte decoding
      eoie: add End of Index Entry (EOIE) extension
      config: add new index.threads config setting
      read-cache: load cache extensions on a worker thread
      ieot: add Index Entry Offset Table (IEOT) extension
      read-cache: load cache entries on worker threads
      reset: don't compute unstaged changes after reset when --quiet
      reset: add new reset.quiet config setting
      reset: warn when refresh_index() takes more than 2 seconds
      speed up refresh_index() by utilizing preload_index()
      add: speed up cmd_add() by utilizing read_cache_preload()
      refresh_index: remove unnecessary calls to preload_index()

Brandon Williams (1):
      config: document value 2 for protocol.version

Brendan Forster (1):
      http: add support for disabling SSL revocation checks in cURL

Carlo Marcelo Arenas Belón (8):
      unpack-trees: avoid dead store for struct progress
      multi-pack-index: avoid dead store for struct progress
      read-cache: use of memory after it is freed
      commit-slabs: move MAYBE_UNUSED out
      khash: silence -Wunused-function for delta-islands
      compat: make sure git_mmap is not expected to write
      sequencer: cleanup for gcc warning in non developer mode
      builtin/notes: remove unnecessary free

Christian Couder (3):
      pack-objects: refactor code into compute_layer_order()
      pack-objects: move tree_depth into 'struct packing_data'
      pack-objects: move 'layer' into 'struct packing_data'

Christian Hesse (2):
      subtree: add build targets 'man' and 'html'
      subtree: make install targets depend on build targets

Daniels Umanovskis (3):
      doc: move git-rev-parse from porcelain to plumbing
      doc: move git-get-tar-commit-id to plumbing
      doc: move git-cherry to plumbing

David Zych (1):
      doc: clarify gitcredentials path component matching

Denton Liu (3):
      mergetool: accept -g/--[no-]gui as arguments
      completion: support `git mergetool --[no-]gui`
      doc: document diff/merge.guitool config keys

Derrick Stolee (93):
      multi-pack-index: add design document
      multi-pack-index: add format details
      multi-pack-index: add builtin
      multi-pack-index: add 'write' verb
      midx: write header information to lockfile
      multi-pack-index: load into memory
      t5319: expand test data
      packfile: generalize pack directory list
      multi-pack-index: read packfile list
      multi-pack-index: write pack names in chunk
      midx: read pack names into array
      midx: sort and deduplicate objects from packfiles
      midx: write object ids in a chunk
      midx: write object id fanout chunk
      midx: write object offsets
      config: create core.multiPackIndex setting
      midx: read objects from multi-pack-index
      midx: use midx in abbreviation calculations
      midx: use existing midx when writing new one
      midx: use midx in approximate_object_count
      midx: prevent duplicate packfile loads
      packfile: skip loading index if in multi-pack-index
      midx: clear midx on repack
      commit-reach: move walk methods from commit.c
      commit.h: remove method declarations
      commit-reach: move ref_newer from remote.c
      commit-reach: move commit_contains from ref-filter
      upload-pack: make reachable() more generic
      upload-pack: refactor ok_to_give_up()
      upload-pack: generalize commit date cutoff
      commit-reach: move can_all_from_reach_with_flags
      test-reach: create new test tool for ref_newer
      test-reach: test in_merge_bases
      test-reach: test is_descendant_of
      test-reach: test get_merge_bases_many
      test-reach: test reduce_heads
      test-reach: test can_all_from_reach_with_flags
      test-reach: test commit_contains
      commit-reach: replace ref_newer logic
      commit-reach: make can_all_from_reach... linear
      comm