Git Mailing List Archive mirror
 help / color / mirror / Atom feed
From: Jonathan Tan <jonathantanmy@google.com>
To: git@vger.kernel.org
Cc: Jonathan Tan <jonathantanmy@google.com>,
	Derrick Stolee <derrickstolee@github.com>,
	Junio C Hamano <gitster@pobox.com>, Taylor Blau <me@ttaylorr.com>
Subject: [PATCH v5 0/4] Changed path filter hash fix and version bump
Date: Thu, 13 Jul 2023 14:42:07 -0700	[thread overview]
Message-ID: <cover.1689283789.git.jonathantanmy@google.com> (raw)
In-Reply-To: <cover.1684790529.git.jonathantanmy@google.com>

Sorry it took me a while to get back to this. Looking at the existing
code, Bloom filters are passed around a lot without context, especially
when writing - they are generated into a commit slab and then when it is
time to write them to disk, they are taken from that commit slab. And
rather than annotating where they are passed around, I thought it better
to stick to the single-version approach in version 4 (per Git invocation
and per repo, only one version), which also sidesteps what happens if
there so happens to be multiple commit graphs each with their own Bloom
filter version (not possible to be generated by Git but possible with
a hex editor) and what happens if we want to write a different version
than what is currently stored in the commit slab. But with an auto-
detection of that version, I think we have what we need; in regular
operation, Git will run with whatever the version on disk is, and when
it is time to migrate, the user can explicitly specify the version.

I did not implement the mitigation of not using the Bloom filters when
a high-bit path is sought because, as Stolee says, this is useful only
when mixing Git implementations and will slow down operations (without
any increase in correctness) in the absence of such a mix [1]. But I can
implement this if need be.

[1] https://lore.kernel.org/git/e57b2272-b269-b705-3d42-d32e0b410f03@github.com/

Jonathan Tan (4):
  gitformat-commit-graph: describe version 2 of BDAT
  t4216: test changed path filters with high bit paths
  repo-settings: introduce commitgraph.changedPathsVersion
  commit-graph: new filter ver. that fixes murmur3

 Documentation/config/commitgraph.txt     |  19 +++-
 Documentation/gitformat-commit-graph.txt |   9 +-
 bloom.c                                  |  65 ++++++++++++-
 bloom.h                                  |   8 +-
 commit-graph.c                           |  33 +++++--
 oss-fuzz/fuzz-commit-graph.c             |   2 +-
 repo-settings.c                          |   6 +-
 repository.h                             |   2 +-
 t/helper/test-bloom.c                    |   9 +-
 t/t0095-bloom.sh                         |   8 ++
 t/t4216-log-bloom.sh                     | 117 +++++++++++++++++++++++
 11 files changed, 256 insertions(+), 22 deletions(-)

Range-diff against v4:
1:  a5955cda3d ! 1:  52e281eef0 gitformat-commit-graph: describe version 2 of BDAT
    @@ Documentation/gitformat-commit-graph.txt: All multi-byte numbers are in network
      	hashing technique using seed values 0x293ae76f and 0x7e646e2 as
      	described in https://doi.org/10.1007/978-3-540-30494-4_26 "Bloom Filters
     -	in Probabilistic Verification"
    -+	in Probabilistic Verification". Version 1 bloom filters have a bug that appears
    ++	in Probabilistic Verification". Version 1 Bloom filters have a bug that appears
     +	when char is signed and the repository has path names that have characters >=
     +	0x80; Git supports reading and writing them, but this ability will be removed
     +	in a future version of Git.
2:  68732120f9 ! 2:  94a4c7af38 t4216: test changed path filters with high bit paths
    @@ t/t4216-log-bloom.sh: test_expect_success 'Bloom generation backfills empty comm
     +test_expect_success 'setup check value of version 1 changed-path' '
     +	(cd highbit1 &&
     +		printf "52a9" >expect &&
    -+		get_first_changed_path_filter >actual)
    ++		get_first_changed_path_filter >actual &&
    ++		test_cmp expect actual)
     +'
     +
     +# expect will not match actual if char is unsigned by default. Write the test
3:  44cbcc6a69 ! 3:  131095666d repo-settings: introduce commitgraph.changedPathsVersion
    @@ Commit message
         repo-settings: introduce commitgraph.changedPathsVersion
     
         A subsequent commit will introduce another version of the changed-path
    -    filter in the commit graph file. In order to control which version is
    -    to be accepted when read (and which version to write), a config variable
    -    is needed.
    +    filter in the commit graph file. In order to control which version to
    +    write (and read), a config variable is needed.
     
         Therefore, introduce this config variable. For forwards compatibility,
         teach Git to not read commit graphs when the config variable
    @@ Commit message
         This commit does not change the behavior of writing (Git writes changed
         path filters when explicitly instructed regardless of any config
         variable), but a subsequent commit will restrict Git such that it will
    -    only write when commitgraph.changedPathsVersion is 0, 1, or 2.
    +    only write when commitgraph.changedPathsVersion is a recognized value.
     
         Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
         Signed-off-by: Junio C Hamano <gitster@pobox.com>
    @@ Documentation/config/commitgraph.txt: commitGraph.maxNewFilters::
     -	If true, then git will use the changed-path Bloom filters in the
     -	commit-graph file (if it exists, and they are present). Defaults to
     -	true. See linkgit:git-commit-graph[1] for more information.
    -+	Deprecated. Equivalent to changedPathsVersion=1 if true, and
    ++	Deprecated. Equivalent to changedPathsVersion=-1 if true, and
     +	changedPathsVersion=0 if false.
     +
     +commitGraph.changedPathsVersion::
     +	Specifies the version of the changed-path Bloom filters that Git will read and
    -+	write. May be 0 or 1. Any changed-path Bloom filters on disk that do not
    ++	write. May be -1, 0 or 1. Any changed-path Bloom filters on disk that do not
     +	match the version set in this config variable will be ignored.
     ++
    -+Defaults to 1.
    ++Defaults to -1.
    +++
    ++If -1, Git will use the version of the changed-path Bloom filters in the
    ++repository, defaulting to 1 if there are none.
     ++
     +If 0, git will write version 1 Bloom filters when instructed to write.
     ++
    @@ commit-graph.c: struct commit_graph *parse_commit_graph(struct repo_settings *s,
      	}
      
     -	if (s->commit_graph_read_changed_paths) {
    -+	if (s->commit_graph_changed_paths_version == 1) {
    ++	if (s->commit_graph_changed_paths_version != 0) {
      		pair_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
      			   &graph->chunk_bloom_indexes);
      		read_chunk(cf, GRAPH_CHUNKID_BLOOMDATA,
    @@ repo-settings.c: void prepare_repo_settings(struct repository *r)
     +	repo_cfg_bool(r, "commitgraph.readchangedpaths", &readChangedPaths, 1);
     +	repo_cfg_int(r, "commitgraph.changedpathsversion",
     +		     &r->settings.commit_graph_changed_paths_version,
    -+		     readChangedPaths ? 1 : 0);
    ++		     readChangedPaths ? -1 : 0);
      	repo_cfg_bool(r, "gc.writecommitgraph", &r->settings.gc_write_commit_graph, 1);
      	repo_cfg_bool(r, "fetch.writecommitgraph", &r->settings.fetch_write_commit_graph, 0);
      
4:  6dee3bfa70 ! 4:  47ba89c565 commit-graph: new filter ver. that fixes murmur3
    @@ Commit message
         So this patch does not include any mechanism to "salvage" changed path
         filters from repositories. There is also no "mixed" mode - for each
         invocation of Git, reading and writing changed path filters are done
    -    with the same version number.
    +    with the same version number; this version number may be explicitly
    +    stated (typically if the user knows which version they need) or
    +    automatically determined from the version of the existing changed path
    +    filters in the repository.
     
         There is a change in write_commit_graph(). graph_read_bloom_data()
         makes it possible for chunk_bloom_data to be non-NULL but
    @@ Documentation/config/commitgraph.txt: commitGraph.readChangedPaths::
      
      commitGraph.changedPathsVersion::
      	Specifies the version of the changed-path Bloom filters that Git will read and
    --	write. May be 0 or 1. Any changed-path Bloom filters on disk that do not
    -+	write. May be 0, 1, or 2. Any changed-path Bloom filters on disk that do not
    +-	write. May be -1, 0 or 1. Any changed-path Bloom filters on disk that do not
    ++	write. May be -1, 0, 1, or 2. Any changed-path Bloom filters on disk that do not
      	match the version set in this config variable will be ignored.
      +
    - Defaults to 1.
    + Defaults to -1.
     
      ## bloom.c ##
     @@ bloom.c: static int load_bloom_filter_from_graph(struct commit_graph *g,
    @@ commit-graph.c: static int graph_read_oid_lookup(const unsigned char *chunk_star
      
     +struct graph_read_bloom_data_data {
     +	struct commit_graph *g;
    -+	int commit_graph_changed_paths_version;
    ++	int *commit_graph_changed_paths_version;
     +};
     +
      static int graph_read_bloom_data(const unsigned char *chunk_start,
    @@ commit-graph.c: static int graph_read_oid_lookup(const unsigned char *chunk_star
      	hash_version = get_be32(chunk_start);
      
     -	if (hash_version != 1)
    -+	if (hash_version != d->commit_graph_changed_paths_version)
    - 		return 0;
    +-		return 0;
    ++	if (*d->commit_graph_changed_paths_version == -1) {
    ++		*d->commit_graph_changed_paths_version = hash_version;
    ++	} else if (hash_version != *d->commit_graph_changed_paths_version) {
    ++ 		return 0;
    ++	}
      
      	g->bloom_filter_settings = xmalloc(sizeof(struct bloom_filter_settings));
    + 	g->bloom_filter_settings->hash_version = hash_version;
     @@ commit-graph.c: struct commit_graph *parse_commit_graph(struct repo_settings *s,
    - 			graph->read_generation_data = 1;
      	}
      
    --	if (s->commit_graph_changed_paths_version == 1) {
    -+	if (s->commit_graph_changed_paths_version == 1
    -+	    || s->commit_graph_changed_paths_version == 2) {
    + 	if (s->commit_graph_changed_paths_version != 0) {
     +		struct graph_read_bloom_data_data data = {
     +			.g = graph,
    -+			.commit_graph_changed_paths_version = s->commit_graph_changed_paths_version
    ++			.commit_graph_changed_paths_version = &s->commit_graph_changed_paths_version
     +		};
      		pair_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES,
      			   &graph->chunk_bloom_indexes);
    @@ commit-graph.c: int write_commit_graph(struct object_directory *odb,
      	ctx->write_generation_data = (get_configured_generation_version(r) == 2);
      	ctx->num_generation_data_overflows = 0;
      
    -+	if (r->settings.commit_graph_changed_paths_version < 0
    ++	if (r->settings.commit_graph_changed_paths_version < -1
     +	    || r->settings.commit_graph_changed_paths_version > 2) {
     +		warning(_("attempting to write a commit-graph, but 'commitgraph.changedPathsVersion' (%d) is not supported"),
     +			r->settings.commit_graph_changed_paths_version);
    @@ t/t0095-bloom.sh: test_expect_success 'compute unseeded murmur3 hash for test st
      	Hashes:0x5615800c|0x5b966560|0x61174ab4|0x66983008|0x6c19155c|0x7199fab0|0x771ae004|
     
      ## t/t4216-log-bloom.sh ##
    +@@ t/t4216-log-bloom.sh: get_bdat_offset () {
    + 		.git/objects/info/commit-graph
    + }
    + 
    ++get_changed_path_filter_version () {
    ++	BDAT_OFFSET=$(get_bdat_offset) &&
    ++	perl -0777 -ne \
    ++		'print unpack("H*", substr($_, '$BDAT_OFFSET', 4))' \
    ++		.git/objects/info/commit-graph
    ++}
    ++
    + get_first_changed_path_filter () {
    + 	BDAT_OFFSET=$(get_bdat_offset) &&
    + 	perl -0777 -ne \
    +@@ t/t4216-log-bloom.sh: test_expect_success 'set up repo with high bit path, version 1 changed-path' '
    + 	git -C highbit1 commit-graph write --reachable --changed-paths
    + '
    + 
    +-test_expect_success 'setup check value of version 1 changed-path' '
    ++test_expect_success 'check value of version 1 changed-path' '
    + 	(cd highbit1 &&
    + 		printf "52a9" >expect &&
    + 		get_first_changed_path_filter >actual &&
     @@ t/t4216-log-bloom.sh: test_expect_success 'version 1 changed-path used when version 1 requested' '
      		test_bloom_filters_used "-- $CENT")
      '
    @@ t/t4216-log-bloom.sh: test_expect_success 'version 1 changed-path used when vers
     +		test_bloom_filters_not_used "-- $CENT")
     +'
     +
    ++test_expect_success 'version 1 changed-path used when autodetect requested' '
    ++	(cd highbit1 &&
    ++		git config --add commitgraph.changedPathsVersion -1 &&
    ++		test_bloom_filters_used "-- $CENT")
    ++'
    ++
    ++test_expect_success 'when writing another commit graph, preserve existing version 1 of changed-path' '
    ++	test_commit -C highbit1 c1double "$CENT$CENT" &&
    ++	git -C highbit1 commit-graph write --reachable --changed-paths &&
    ++	(cd highbit1 &&
    ++		git config --add commitgraph.changedPathsVersion -1 &&
    ++		printf "00000001" >expect &&
    ++		get_changed_path_filter_version >actual &&
    ++		test_cmp expect actual)
    ++'
    ++
     +test_expect_success 'set up repo with high bit path, version 2 changed-path' '
     +	git init highbit2 &&
     +	git -C highbit2 config --add commitgraph.changedPathsVersion 2 &&
    @@ t/t4216-log-bloom.sh: test_expect_success 'version 1 changed-path used when vers
     +		git config --add commitgraph.changedPathsVersion 1 &&
     +		test_bloom_filters_not_used "-- $CENT")
     +'
    ++
    ++test_expect_success 'version 2 changed-path used when autodetect requested' '
    ++	(cd highbit2 &&
    ++		git config --add commitgraph.changedPathsVersion -1 &&
    ++		test_bloom_filters_used "-- $CENT")
    ++'
    ++
    ++test_expect_success 'when writing another commit graph, preserve existing version 2 of changed-path' '
    ++	test_commit -C highbit2 c2double "$CENT$CENT" &&
    ++	git -C highbit2 commit-graph write --reachable --changed-paths &&
    ++	(cd highbit2 &&
    ++		git config --add commitgraph.changedPathsVersion -1 &&
    ++		printf "00000002" >expect &&
    ++		get_changed_path_filter_version >actual &&
    ++		test_cmp expect actual)
    ++'
     +
      test_done
-- 
2.41.0.255.g8b1d071c50-goog


  parent reply	other threads:[~2023-07-13 21:43 UTC|newest]

Thread overview: 116+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-22 21:48 [PATCH 0/2] Changed path filter hash fix and version bump Jonathan Tan
2023-05-22 21:48 ` [PATCH 1/2] t4216: test wrong bloom filter version rejection Jonathan Tan
2023-05-22 21:48 ` [PATCH 2/2] commit-graph: fix murmur3, bump filter ver. to 2 Jonathan Tan
2023-05-23 13:00   ` Derrick Stolee
2023-05-23 23:00     ` Jonathan Tan
2023-05-23 23:51     ` Junio C Hamano
2023-05-24 21:26       ` Jonathan Tan
2023-05-26 13:19         ` Derrick Stolee
2023-05-30 17:26           ` Jonathan Tan
2023-05-23  4:42 ` [PATCH 0/2] Changed path filter hash fix and version bump Junio C Hamano
2023-05-31 23:12 ` [PATCH v2 0/3] " Jonathan Tan
2023-05-31 23:12   ` [PATCH v2 1/3] t4216: test changed path filters with high bit paths Jonathan Tan
2023-05-31 23:12   ` [PATCH v2 2/3] repo-settings: introduce commitgraph.changedPathsVersion Jonathan Tan
2023-05-31 23:12   ` [PATCH v2 3/3] commit-graph: new filter ver. that fixes murmur3 Jonathan Tan
2023-06-03  1:01   ` [PATCH v2 0/3] Changed path filter hash fix and version bump Junio C Hamano
2023-06-03  2:24     ` Junio C Hamano
2023-06-07 16:30       ` Jonathan Tan
2023-06-07 21:37         ` Jonathan Tan
2023-06-08 19:21 ` [PATCH v3 0/4] " Jonathan Tan
2023-06-08 19:21   ` [PATCH v3 1/4] gitformat-commit-graph: describe version 2 of BDAT Jonathan Tan
2023-06-08 19:52     ` Ramsay Jones
2023-06-12 21:26       ` Junio C Hamano
2023-06-08 19:21   ` [PATCH v3 2/4] t4216: test changed path filters with high bit paths Jonathan Tan
2023-06-08 19:21   ` [PATCH v3 3/4] repo-settings: introduce commitgraph.changedPathsVersion Jonathan Tan
2023-06-08 19:21   ` [PATCH v3 4/4] commit-graph: new filter ver. that fixes murmur3 Jonathan Tan
2023-06-08 19:50   ` [PATCH v3 0/4] Changed path filter hash fix and version bump Ramsay Jones
2023-06-09  0:08     ` Jonathan Tan
2023-06-12 21:31     ` Junio C Hamano
2023-06-13 17:16       ` Jonathan Tan
2023-06-13 17:29         ` [PATCH] CodingGuidelines: use octal escapes, not hex Jonathan Tan
2023-06-13 18:16           ` Eric Sunshine
2023-06-13 18:43             ` Jonathan Tan
2023-06-13 19:15               ` Eric Sunshine
2023-06-13 19:29                 ` Junio C Hamano
2023-06-13 19:16         ` [PATCH v3 0/4] Changed path filter hash fix and version bump Junio C Hamano
2023-06-13 17:39 ` [PATCH v4 " Jonathan Tan
2023-06-13 17:39   ` [PATCH v4 1/4] gitformat-commit-graph: describe version 2 of BDAT Jonathan Tan
2023-06-13 21:58     ` Junio C Hamano
2023-06-20 13:22       ` Derrick Stolee
2023-06-21 12:08       ` Taylor Blau
2023-06-22 22:26         ` Jonathan Tan
2023-06-23 13:05           ` Derrick Stolee
2023-06-13 17:39   ` [PATCH v4 2/4] t4216: test changed path filters with high bit paths Jonathan Tan
2023-06-13 17:39   ` [PATCH v4 3/4] repo-settings: introduce commitgraph.changedPathsVersion Jonathan Tan
2023-06-20 13:28     ` Derrick Stolee
2023-06-21 12:14     ` Taylor Blau
2023-06-13 17:39   ` [PATCH v4 4/4] commit-graph: new filter ver. that fixes murmur3 Jonathan Tan
2023-06-20 13:39     ` Derrick Stolee
2023-06-20 18:37       ` Junio C Hamano
2023-06-13 19:21   ` [PATCH v4 0/4] Changed path filter hash fix and version bump Junio C Hamano
2023-06-20 13:43     ` Derrick Stolee
2023-06-20 21:56       ` Jonathan Tan
2023-06-21 12:19       ` Taylor Blau
2023-06-21 17:53         ` Derrick Stolee
2023-06-22 22:27           ` Jonathan Tan
2023-06-23 13:18             ` Derrick Stolee
2023-07-13 21:42 ` Jonathan Tan [this message]
2023-07-13 21:42   ` [PATCH v5 1/4] gitformat-commit-graph: describe version 2 of BDAT Jonathan Tan
2023-07-19 17:25     ` Taylor Blau
2023-07-20 20:20       ` Jonathan Tan
2023-07-21  1:38         ` Taylor Blau
2023-07-13 21:42   ` [PATCH v5 2/4] t4216: test changed path filters with high bit paths Jonathan Tan
2023-07-13 22:50     ` Junio C Hamano
2023-07-19 17:27       ` Taylor Blau
2023-07-19 17:55         ` [PATCH 0/4] commit-graph: avoid looking at Bloom filter data directly Taylor Blau
2023-07-19 17:55           ` [PATCH 1/4] t/helper/test-read-graph.c: extract `dump_graph_info()` Taylor Blau
2023-07-19 17:55           ` [PATCH 2/4] bloom.h: make `load_bloom_filter_from_graph()` public Taylor Blau
2023-07-19 17:55           ` [PATCH 3/4] t/helper/test-read-graph: implement `bloom-filters` mode Taylor Blau
2023-07-19 17:55           ` [PATCH 4/4] fixup! t4216: test changed path filters with high bit paths Taylor Blau
2023-07-19 19:24           ` [PATCH 0/4] commit-graph: avoid looking at Bloom filter data directly Junio C Hamano
2023-07-20 20:22           ` Jonathan Tan
2023-07-13 21:42   ` [PATCH v5 3/4] repo-settings: introduce commitgraph.changedPathsVersion Jonathan Tan
2023-07-19 18:10     ` Taylor Blau
2023-07-20 20:42       ` Jonathan Tan
2023-07-20 21:02         ` Taylor Blau
2023-07-13 21:42   ` [PATCH v5 4/4] commit-graph: new filter ver. that fixes murmur3 Jonathan Tan
2023-07-19 18:24     ` Taylor Blau
2023-07-20 21:27       ` Jonathan Tan
2023-07-26 23:32         ` Taylor Blau
2023-07-13 22:16   ` [PATCH v5 0/4] Changed path filter hash fix and version bump Junio C Hamano
2023-07-13 22:59     ` Junio C Hamano
2023-07-14 18:48     ` Jonathan Tan
2023-07-20 21:46 ` [PATCH v6 0/7] " Jonathan Tan
2023-07-20 21:46   ` [PATCH v6 1/7] gitformat-commit-graph: describe version 2 of BDAT Jonathan Tan
2023-07-20 21:46   ` [PATCH v6 2/7] t/helper/test-read-graph.c: extract `dump_graph_info()` Jonathan Tan
2023-07-26 23:26     ` Taylor Blau
2023-07-20 21:46   ` [PATCH v6 3/7] bloom.h: make `load_bloom_filter_from_graph()` public Jonathan Tan
2023-07-20 21:46   ` [PATCH v6 4/7] t/helper/test-read-graph: implement `bloom-filters` mode Jonathan Tan
2023-07-20 21:46   ` [PATCH v6 5/7] t4216: test changed path filters with high bit paths Jonathan Tan
2023-07-26 23:28     ` Taylor Blau
2023-07-20 21:46   ` [PATCH v6 6/7] repo-settings: introduce commitgraph.changedPathsVersion Jonathan Tan
2023-07-20 21:46   ` [PATCH v6 7/7] commit-graph: new filter ver. that fixes murmur3 Jonathan Tan
2023-07-25 20:52   ` [PATCH v6 0/7] Changed path filter hash fix and version bump Junio C Hamano
2023-07-26 20:39   ` Junio C Hamano
2023-07-27  0:17     ` Taylor Blau
2023-07-27  0:49       ` Junio C Hamano
2023-07-27 17:39         ` Jonathan Tan
2023-07-27 17:56           ` Taylor Blau
2023-07-27 20:53             ` Jonathan Tan
2023-08-01 18:08               ` Taylor Blau
2023-08-01 18:52                 ` Jonathan Tan
2023-08-03  0:01                 ` Taylor Blau
2023-08-03 13:18                   ` Derrick Stolee
2023-08-03 18:45                     ` Taylor Blau
2023-07-27 18:44         ` Junio C Hamano
2023-08-01 18:41 ` [PATCH v7 " Jonathan Tan
2023-08-01 18:41   ` [PATCH v7 1/7] gitformat-commit-graph: describe version 2 of BDAT Jonathan Tan
2023-08-01 18:41   ` [PATCH v7 2/7] t/helper/test-read-graph.c: extract `dump_graph_info()` Jonathan Tan
2023-08-01 18:41   ` [PATCH v7 3/7] bloom.h: make `load_bloom_filter_from_graph()` public Jonathan Tan
2023-08-01 18:41   ` [PATCH v7 4/7] t/helper/test-read-graph: implement `bloom-filters` mode Jonathan Tan
2023-08-01 18:41   ` [PATCH v7 5/7] t4216: test changed path filters with high bit paths Jonathan Tan
2023-08-01 18:41   ` [PATCH v7 6/7] repo-settings: introduce commitgraph.changedPathsVersion Jonathan Tan
2023-08-01 18:41   ` [PATCH v7 7/7] commit-graph: new filter ver. that fixes murmur3 Jonathan Tan
2023-08-01 18:44   ` [PATCH v7 0/7] Changed path filter hash fix and version bump Junio C Hamano
2023-08-01 20:58     ` Taylor Blau
2023-08-01 21:07       ` Junio C Hamano

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

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

  git send-email \
    --in-reply-to=cover.1689283789.git.jonathantanmy@google.com \
    --to=jonathantanmy@google.com \
    --cc=derrickstolee@github.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=me@ttaylorr.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.
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).