git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Derrick Stolee <stolee@gmail.com>
To: Jonathan Tan <jonathantanmy@google.com>, git@vger.kernel.org
Subject: Re: [PATCH v2 6/6] commit-graph: add repo arg to graph readers
Date: Mon, 9 Jul 2018 20:48:22 -0400	[thread overview]
Message-ID: <75ef9935-342a-bbda-4ce6-e5a033f273a9@gmail.com> (raw)
In-Reply-To: <f1ccfdccc851039cf62978d162cd9de99ea619de.1531168854.git.jonathantanmy@google.com>

On 7/9/2018 4:44 PM, Jonathan Tan wrote:
> Add a struct repository argument to the functions in commit-graph.h that
> read the commit graph. (This commit does not affect functions that write
> commit graphs.)
>
> Because the commit graph functions can now read the commit graph of any
> repository, the global variable core_commit_graph has been removed.
> Instead, the config option core.commitGraph is now read on the first
> time in a repository that a commit is attempted to be parsed using its
> commit graph.
>
> This commit includes a test that exercises the functionality on an
> arbitrary repository that is not the_repository.
>
> Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
> ---
>   Makefile                   |  1 +
>   builtin/fsck.c             |  2 +-
>   cache.h                    |  1 -
>   commit-graph.c             | 60 ++++++++++++++------------
>   commit-graph.h             |  7 +--
>   commit.c                   |  6 +--
>   config.c                   |  5 ---
>   environment.c              |  1 -
>   ref-filter.c               |  2 +-
>   t/helper/test-repository.c | 88 ++++++++++++++++++++++++++++++++++++++
>   t/helper/test-tool.c       |  1 +
>   t/helper/test-tool.h       |  1 +
>   t/t5318-commit-graph.sh    | 35 +++++++++++++++
>   13 files changed, 168 insertions(+), 42 deletions(-)
>   create mode 100644 t/helper/test-repository.c
>
> diff --git a/Makefile b/Makefile
> index 0cb6590f24..bb8bd67201 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -719,6 +719,7 @@ TEST_BUILTINS_OBJS += test-prio-queue.o
>   TEST_BUILTINS_OBJS += test-read-cache.o
>   TEST_BUILTINS_OBJS += test-ref-store.o
>   TEST_BUILTINS_OBJS += test-regex.o
> +TEST_BUILTINS_OBJS += test-repository.o
>   TEST_BUILTINS_OBJS += test-revision-walking.o
>   TEST_BUILTINS_OBJS += test-run-command.o
>   TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
> diff --git a/builtin/fsck.c b/builtin/fsck.c
> index eca7900ee0..2abfb2d782 100644
> --- a/builtin/fsck.c
> +++ b/builtin/fsck.c
> @@ -825,7 +825,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
>   
>   	check_connectivity();
>   
> -	if (core_commit_graph) {
> +	if (!git_config_get_bool("core.commitgraph", &i) && i) {
>   		struct child_process commit_graph_verify = CHILD_PROCESS_INIT;
>   		const char *verify_argv[] = { "commit-graph", "verify", NULL, NULL, NULL };
>   
> diff --git a/cache.h b/cache.h
> index d49092d94d..8dc59bedba 100644
> --- a/cache.h
> +++ b/cache.h
> @@ -813,7 +813,6 @@ extern char *git_replace_ref_base;
>   
>   extern int fsync_object_files;
>   extern int core_preload_index;
> -extern int core_commit_graph;
>   extern int core_apply_sparse_checkout;
>   extern int precomposed_unicode;
>   extern int protect_hfs;
> diff --git a/commit-graph.c b/commit-graph.c
> index af97a10603..8eab199b1b 100644
> --- a/commit-graph.c
> +++ b/commit-graph.c
> @@ -183,15 +183,15 @@ struct commit_graph *load_commit_graph_one(const char *graph_file)
>   	exit(1);
>   }
>   
> -static void prepare_commit_graph_one(const char *obj_dir)
> +static void prepare_commit_graph_one(struct repository *r, const char *obj_dir)
>   {
>   	char *graph_name;
>   
> -	if (the_repository->objects->commit_graph)
> +	if (r->objects->commit_graph)
>   		return;
>   
>   	graph_name = get_commit_graph_filename(obj_dir);
> -	the_repository->objects->commit_graph =
> +	r->objects->commit_graph =
>   		load_commit_graph_one(graph_name);
>   
>   	FREE_AND_NULL(graph_name);
> @@ -203,26 +203,34 @@ static void prepare_commit_graph_one(const char *obj_dir)
>    * On the first invocation, this function attemps to load the commit
>    * graph if the_repository is configured to have one.
>    */
> -static int prepare_commit_graph(void)
> +static int prepare_commit_graph(struct repository *r)
>   {
>   	struct alternate_object_database *alt;
>   	char *obj_dir;
> +	int config_value;
>   
> -	if (the_repository->objects->commit_graph_attempted)
> -		return !!the_repository->objects->commit_graph;
> -	the_repository->objects->commit_graph_attempted = 1;
> +	if (r->objects->commit_graph_attempted)
> +		return !!r->objects->commit_graph;
> +	r->objects->commit_graph_attempted = 1;
>   
> -	if (!core_commit_graph)
> +	if (repo_config_get_bool(r, "core.commitgraph", &config_value) ||
> +	    !config_value)
> +		/*
> +		 * This repository is not configured to use commit graphs, so
> +		 * do not load one. (But report commit_graph_attempted anyway
> +		 * so that commit graph loading is not attempted again for this
> +		 * repository.)
> +		 */

I reacted first to complain about this extra config lookup, but it is 
only run once per repository, so that should be fine.

>   		return 0;
>   
> -	obj_dir = get_object_directory();
> -	prepare_commit_graph_one(obj_dir);
> -	prepare_alt_odb(the_repository);
> -	for (alt = the_repository->objects->alt_odb_list;
> -	     !the_repository->objects->commit_graph && alt;
> +	obj_dir = r->objects->objectdir;
> +	prepare_commit_graph_one(r, obj_dir);
> +	prepare_alt_odb(r);
> +	for (alt = r->objects->alt_odb_list;
> +	     !r->objects->commit_graph && alt;
>   	     alt = alt->next)
> -		prepare_commit_graph_one(alt->path);
> -	return !!the_repository->objects->commit_graph;
> +		prepare_commit_graph_one(r, alt->path);
> +	return !!r->objects->commit_graph;
>   }
>   
>   static void close_commit_graph(void)
> @@ -323,8 +331,6 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item
>   {
>   	uint32_t pos;
>   
> -	if (!core_commit_graph)
> -		return 0;
>   	if (item->object.parsed)
>   		return 1;
>   
> @@ -334,20 +340,20 @@ static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item
>   	return 0;
>   }
>   
> -int parse_commit_in_graph(struct commit *item)
> +int parse_commit_in_graph(struct repository *r, struct commit *item)
>   {
> -	if (!prepare_commit_graph())
> +	if (!prepare_commit_graph(r))
>   		return 0;
> -	return parse_commit_in_graph_one(the_repository->objects->commit_graph, item);
> +	return parse_commit_in_graph_one(r->objects->commit_graph, item);
>   }
>   
> -void load_commit_graph_info(struct commit *item)
> +void load_commit_graph_info(struct repository *r, struct commit *item)
>   {
>   	uint32_t pos;
> -	if (!prepare_commit_graph())
> +	if (!prepare_commit_graph(r))
>   		return;
> -	if (find_commit_in_graph(item, the_repository->objects->commit_graph, &pos))
> -		fill_commit_graph_info(item, the_repository->objects->commit_graph, pos);
> +	if (find_commit_in_graph(item, r->objects->commit_graph, &pos))
> +		fill_commit_graph_info(item, r->objects->commit_graph, pos);
>   }
>   
>   static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c)
> @@ -373,9 +379,9 @@ static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g,
>   	return load_tree_for_commit(g, (struct commit *)c);
>   }
>   
> -struct tree *get_commit_tree_in_graph(const struct commit *c)
> +struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c)
>   {
> -	return get_commit_tree_in_graph_one(the_repository->objects->commit_graph, c);
> +	return get_commit_tree_in_graph_one(r->objects->commit_graph, c);
>   }
>   
>   static void write_graph_chunk_fanout(struct hashfile *f,
> @@ -691,7 +697,7 @@ void write_commit_graph(const char *obj_dir,
>   	oids.alloc = approximate_object_count() / 4;
>   
>   	if (append) {
> -		prepare_commit_graph_one(obj_dir);
> +		prepare_commit_graph_one(the_repository, obj_dir);
>   		if (the_repository->objects->commit_graph)
>   			oids.alloc += the_repository->objects->commit_graph->num_commits;
>   	}
> diff --git a/commit-graph.h b/commit-graph.h
> index 94defb04a9..76e098934a 100644
> --- a/commit-graph.h
> +++ b/commit-graph.h
> @@ -19,7 +19,7 @@ char *get_commit_graph_filename(const char *obj_dir);
>    *
>    * See parse_commit_buffer() for the fallback after this call.
>    */
> -int parse_commit_in_graph(struct commit *item);
> +int parse_commit_in_graph(struct repository *r, struct commit *item);
>   
>   /*
>    * It is possible that we loaded commit contents from the commit buffer,
> @@ -27,9 +27,10 @@ int parse_commit_in_graph(struct commit *item);
>    * checked and filled. Fill the graph_pos and generation members of
>    * the given commit.
>    */
> -void load_commit_graph_info(struct commit *item);
> +void load_commit_graph_info(struct repository *r, struct commit *item);
>   
> -struct tree *get_commit_tree_in_graph(const struct commit *c);
> +struct tree *get_commit_tree_in_graph(struct repository *r,
> +				      const struct commit *c);
>   
>   struct commit_graph {
>   	int graph_fd;
> diff --git a/commit.c b/commit.c
> index 598cf21cee..b3bbfefc27 100644
> --- a/commit.c
> +++ b/commit.c
> @@ -319,7 +319,7 @@ struct tree *get_commit_tree(const struct commit *commit)
>   	if (commit->graph_pos == COMMIT_NOT_FROM_GRAPH)
>   		BUG("commit has NULL tree, but was not loaded from commit-graph");
>   
> -	return get_commit_tree_in_graph(commit);
> +	return get_commit_tree_in_graph(the_repository, commit);
>   }
>   
>   struct object_id *get_commit_tree_oid(const struct commit *commit)
> @@ -413,7 +413,7 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s
>   	item->date = parse_commit_date(bufptr, tail);
>   
>   	if (check_graph)
> -		load_commit_graph_info(item);
> +		load_commit_graph_info(the_repository, item);
>   
>   	return 0;
>   }
> @@ -429,7 +429,7 @@ int parse_commit_internal(struct commit *item, int quiet_on_missing, int use_com
>   		return -1;
>   	if (item->object.parsed)
>   		return 0;
> -	if (use_commit_graph && parse_commit_in_graph(item))
> +	if (use_commit_graph && parse_commit_in_graph(the_repository, item))
>   		return 0;
>   	buffer = read_object_file(&item->object.oid, &type, &size);
>   	if (!buffer)
> diff --git a/config.c b/config.c
> index a0a6ae1980..fcf863b667 100644
> --- a/config.c
> +++ b/config.c
> @@ -1308,11 +1308,6 @@ static int git_default_core_config(const char *var, const char *value)
>   		return 0;
>   	}
>   
> -	if (!strcmp(var, "core.commitgraph")) {
> -		core_commit_graph = git_config_bool(var, value);
> -		return 0;
> -	}
> -
>   	if (!strcmp(var, "core.sparsecheckout")) {
>   		core_apply_sparse_checkout = git_config_bool(var, value);
>   		return 0;
> diff --git a/environment.c b/environment.c
> index 2a6de2330b..d6e5b39425 100644
> --- a/environment.c
> +++ b/environment.c
> @@ -66,7 +66,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
>   enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
>   char *notes_ref_name;
>   int grafts_replace_parents = 1;
> -int core_commit_graph;
>   int core_apply_sparse_checkout;
>   int merge_log_config = -1;
>   int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
> diff --git a/ref-filter.c b/ref-filter.c
> index fa3685d91f..889d97b005 100644
> --- a/ref-filter.c
> +++ b/ref-filter.c
> @@ -1710,7 +1710,7 @@ static enum contains_result contains_tag_algo(struct commit *candidate,
>   
>   	for (p = want; p; p = p->next) {
>   		struct commit *c = p->item;
> -		load_commit_graph_info(c);
> +		load_commit_graph_info(the_repository, c);
>   		if (c->generation < cutoff)
>   			cutoff = c->generation;
>   	}

The changes above are mostly obvious. They don't need too much reading 
to know they are correct.

The tests below form a decently-large patch on their own. Perhaps split 
them out so it is easier to know that we have some interesting things to 
check here.

It's worth spending some extra time looking at this test pattern as I 
believe we will want to follow it with other arbitrary repository changes.


> diff --git a/t/helper/test-repository.c b/t/helper/test-repository.c
> new file mode 100644
> index 0000000000..5fff540a26
> --- /dev/null
> +++ b/t/helper/test-repository.c
> @@ -0,0 +1,88 @@
> +#include "test-tool.h"
> +#include "cache.h"
> +#include "commit-graph.h"
> +#include "commit.h"
> +#include "config.h"
> +#include "object-store.h"
> +#include "object.h"
> +#include "repository.h"
> +#include "tree.h"
> +
> +static void test_parse_commit_in_graph(const char *gitdir, const char *worktree,
> +				       const struct object_id *commit_oid)
> +{
> +	struct repository r;
> +	struct commit *c;
> +	struct commit_list *parent;
> +
> +	/*
> +	 * Create a commit independent of any repository.
> +	 */
> +	c = lookup_commit(commit_oid);
> +
> +	repo_init(&r, gitdir, worktree);
> +
> +	if (!parse_commit_in_graph(&r, c))
> +		die("Couldn't parse commit");
> +
> +	printf("%lu", c->date);
> +	for (parent = c->parents; parent; parent = parent->next)
> +		printf(" %s", oid_to_hex(&parent->item->object.oid));
> +	printf("\n");
> +
> +	repo_clear(&r);
> +}
> +
> +static void test_get_commit_tree_in_graph(const char *gitdir,
> +					  const char *worktree,
> +					  const struct object_id *commit_oid)
> +{
> +	struct repository r;
> +	struct commit *c;
> +	struct tree *tree;
> +
> +	/*
> +	 * Create a commit independent of any repository.
> +	 */
> +	c = lookup_commit(commit_oid);

Would this be more accurate to say we are creating a commit object 
stored in the object cache of the_repository? How would you expect this 
to work if/when lookup_commit() takes an arbitrary repository? You want 
to provide &r, right (after initializing)?

Also, this will conflict with sb/object-store-lookup, won't it? I'm 
guessing this is why you didn't touch the "git commit-graph 
[write|verify]"code paths.

> +
> +	repo_init(&r, gitdir, worktree);

I think you want to move the lookup_commit() to after this.

> +
> +	/*
> +	 * get_commit_tree_in_graph does not automatically parse the commit, so
> +	 * parse it first.
> +	 */
> +	if (!parse_commit_in_graph(&r, c))
> +		die("Couldn't parse commit");
> +	tree = get_commit_tree_in_graph(&r, c);
> +	if (!tree)
> +		die("Couldn't get commit tree");
> +
> +	printf("%s\n", oid_to_hex(&tree->object.oid));
> +
> +	repo_clear(&r);
> +}
> +
> +int cmd__repository(int argc, const char **argv)
> +{
> +	if (argc < 2)
> +		die("must have at least 2 arguments");

I think this "test-tool repository <verb>" pattern is a good way to get 
some testing here.

> +	if (!strcmp(argv[1], "parse_commit_in_graph")) {
> +		struct object_id oid;
> +		if (argc < 5)
> +			die("not enough arguments");
> +		if (parse_oid_hex(argv[4], &oid, &argv[4]))
> +			die("cannot parse oid '%s'", argv[4]);
> +		test_parse_commit_in_graph(argv[2], argv[3], &oid);
> +	} else if (!strcmp(argv[1], "get_commit_tree_in_graph")) {
> +		struct object_id oid;
> +		if (argc < 5)
> +			die("not enough arguments");
> +		if (parse_oid_hex(argv[4], &oid, &argv[4]))
> +			die("cannot parse oid '%s'", argv[4]);
> +		test_get_commit_tree_in_graph(argv[2], argv[3], &oid);
> +	} else {
> +		die("unrecognized '%s'", argv[1]);
> +	}
> +	return 0;
> +}
> diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
> index 805a45de9c..dafc91c240 100644
> --- a/t/helper/test-tool.c
> +++ b/t/helper/test-tool.c
> @@ -29,6 +29,7 @@ static struct test_cmd cmds[] = {
>   	{ "read-cache", cmd__read_cache },
>   	{ "ref-store", cmd__ref_store },
>   	{ "regex", cmd__regex },
> +	{ "repository", cmd__repository },
>   	{ "revision-walking", cmd__revision_walking },
>   	{ "run-command", cmd__run_command },
>   	{ "scrap-cache-tree", cmd__scrap_cache_tree },
> diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
> index 7116ddfb94..80cbcf0857 100644
> --- a/t/helper/test-tool.h
> +++ b/t/helper/test-tool.h
> @@ -23,6 +23,7 @@ int cmd__prio_queue(int argc, const char **argv);
>   int cmd__read_cache(int argc, const char **argv);
>   int cmd__ref_store(int argc, const char **argv);
>   int cmd__regex(int argc, const char **argv);
> +int cmd__repository(int argc, const char **argv);
>   int cmd__revision_walking(int argc, const char **argv);
>   int cmd__run_command(int argc, const char **argv);
>   int cmd__scrap_cache_tree(int argc, const char **argv);
> diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
> index 5947de3d24..4f17d7701e 100755
> --- a/t/t5318-commit-graph.sh
> +++ b/t/t5318-commit-graph.sh
> @@ -431,4 +431,39 @@ test_expect_success 'git fsck (checks commit-graph)' '
>   	test_must_fail git fsck
>   '
>   
> +test_expect_success 'setup non-the_repository tests' '
> +	rm -rf repo &&
> +	git init repo &&
> +	test_commit -C repo one &&
> +	test_commit -C repo two &&
> +	git -C repo config core.commitGraph true &&
> +	git -C repo rev-parse two | \
> +		git -C repo commit-graph write --stdin-commits
> +'
> +
> +test_expect_success 'parse_commit_in_graph works for non-the_repository' '
> +	test-tool repository parse_commit_in_graph \
> +		repo/.git repo "$(git -C repo rev-parse two)" >actual &&
> +	echo $(git -C repo log --pretty="%ct" -1) \
> +		$(git -C repo rev-parse one) >expect &&
> +	test_cmp expect actual &&
> +
> +	test-tool repository parse_commit_in_graph \
> +		repo/.git repo "$(git -C repo rev-parse one)" >actual &&
> +	echo $(git -C repo log --pretty="%ct" -1 one) >expect &&
> +	test_cmp expect actual
> +'
> +
> +test_expect_success 'get_commit_tree_in_graph works for non-the_repository' '
> +	test-tool repository get_commit_tree_in_graph \
> +		repo/.git repo "$(git -C repo rev-parse two)" >actual &&
> +	echo $(git -C repo rev-parse two^{tree}) >expect &&
> +	test_cmp expect actual &&
> +
> +	test-tool repository get_commit_tree_in_graph \
> +		repo/.git repo "$(git -C repo rev-parse one)" >actual &&
> +	echo $(git -C repo rev-parse one^{tree}) >expect &&
> +	test_cmp expect actual
> +'
> +
>   test_done

  reply	other threads:[~2018-07-10  0:48 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-21 21:29 [PATCH 0/5] Object store refactoring: commit graph Jonathan Tan
2018-06-21 21:29 ` [PATCH 1/5] object-store: add missing include Jonathan Tan
2018-06-21 21:29 ` [PATCH 2/5] commit-graph: add missing forward declaration Jonathan Tan
2018-06-21 21:43   ` Stefan Beller
2018-06-21 22:39     ` Jonathan Tan
2018-06-22  0:17       ` Derrick Stolee
2018-06-21 21:29 ` [PATCH 3/5] commit-graph: add free_commit_graph Jonathan Tan
2018-06-21 21:29 ` [PATCH 4/5] commit-graph: store graph in struct object_store Jonathan Tan
2018-06-25 20:57   ` Junio C Hamano
2018-06-25 22:09     ` Jonathan Tan
2018-06-26 16:40       ` Junio C Hamano
2018-06-21 21:29 ` [PATCH 5/5] commit-graph: add repo arg to graph readers Jonathan Tan
2018-06-21 22:41   ` Stefan Beller
2018-06-21 23:06     ` Jonathan Tan
2018-06-22  0:33       ` Derrick Stolee
2018-06-22  1:01         ` Derrick Stolee
2018-06-22 17:21         ` Jonathan Tan
2018-07-09 20:44 ` [PATCH v2 on ds/commit-graph-fsck 0/6] Object store refactoring: commit graph Jonathan Tan
2018-07-09 20:44   ` [PATCH v2 1/6] commit-graph: refactor preparing " Jonathan Tan
2018-07-09 21:41     ` Stefan Beller
2018-07-10  0:23       ` Derrick Stolee
2018-07-09 20:44   ` [PATCH v2 2/6] object-store: add missing include Jonathan Tan
2018-07-09 20:44   ` [PATCH v2 3/6] commit-graph: add missing forward declaration Jonathan Tan
2018-07-09 20:44   ` [PATCH v2 4/6] commit-graph: add free_commit_graph Jonathan Tan
2018-07-09 20:44   ` [PATCH v2 5/6] commit-graph: store graph in struct object_store Jonathan Tan
2018-07-09 20:44   ` [PATCH v2 6/6] commit-graph: add repo arg to graph readers Jonathan Tan
2018-07-10  0:48     ` Derrick Stolee [this message]
2018-07-10 17:31       ` Jonathan Tan
2018-07-11 19:41         ` Derrick Stolee
2018-07-11 21:08           ` Jonathan Tan
2018-07-10 11:53     ` SZEDER Gábor
2018-07-10 13:18       ` Johannes Schindelin
2018-07-10 17:23         ` Jonathan Tan
2018-07-09 21:47   ` [PATCH v2 on ds/commit-graph-fsck 0/6] Object store refactoring: commit graph Stefan Beller
2018-07-09 22:27   ` Junio C Hamano
2018-07-10  0:30     ` Derrick Stolee
2018-07-10  0:32       ` Derrick Stolee
2018-07-11 22:42 ` [PATCH v3 " Jonathan Tan
2018-07-11 22:42   ` [PATCH v3 1/6] commit-graph: refactor preparing " Jonathan Tan
2018-07-11 22:42   ` [PATCH v3 2/6] object-store: add missing include Jonathan Tan
2018-07-11 22:42   ` [PATCH v3 3/6] commit-graph: add missing forward declaration Jonathan Tan
2018-07-11 22:42   ` [PATCH v3 4/6] commit-graph: add free_commit_graph Jonathan Tan
2018-07-11 22:42   ` [PATCH v3 5/6] commit-graph: store graph in struct object_store Jonathan Tan
2018-07-11 22:42   ` [PATCH v3 6/6] commit-graph: add repo arg to graph readers Jonathan Tan
2018-08-13  0:30     ` [PATCH] t5318: avoid unnecessary command substitutions SZEDER Gábor
2018-08-13 11:23       ` Derrick Stolee
2018-08-13 19:05       ` Junio C Hamano
2018-07-12 16:56   ` [PATCH v3 0/6] Object store refactoring: commit graph Junio C Hamano
2018-07-12 17:43   ` Derrick Stolee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=75ef9935-342a-bbda-4ce6-e5a033f273a9@gmail.com \
    --to=stolee@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jonathantanmy@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).