git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v5 0/4] Changed path filter hash fix and version bump

From
JTJonathan Tan <jonathantanmy@google.com>
Date
Jul 13, 2023, 21:42 UTC
Message-ID
<cover.1689283789.git.jonathantanmy@google.com>
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
Previous: Derrick StoleeNext: Jonathan Tan
Message 57 of 116 in “Changed path filter hash fix and version bump”
  1. 0/2 Changed path filter hash fix and version bumpJonathan Tan, May 22, 2023
  2. 1/2 t4216: test wrong bloom filter version rejectionJonathan Tan, May 22, 2023
  3. 2/2 commit-graph: fix murmur3, bump filter ver. to 2Jonathan Tan, May 22, 2023
  4. Derrick StoleeMay 23, 2023
  5. Jonathan TanMay 23, 2023
  6. Junio C HamanoMay 23, 2023
  7. Jonathan TanMay 24, 2023
  8. Derrick StoleeMay 26, 2023
  9. Jonathan TanMay 30, 2023
  10. Junio C HamanoMay 23, 2023
  11. 0/3 Changed path filter hash fix and version bumpJonathan Tan, May 31, 2023
  12. 1/3 t4216: test changed path filters with high bit pathsJonathan Tan, May 31, 2023
  13. 2/3 repo-settings: introduce commitgraph.changedPathsVersionJonathan Tan, May 31, 2023
  14. 3/3 commit-graph: new filter ver. that fixes murmur3Jonathan Tan, May 31, 2023
  15. Junio C HamanoJun 3, 2023
  16. Junio C HamanoJun 3, 2023
  17. Jonathan TanJun 7, 2023
  18. Jonathan TanJun 7, 2023
  19. 0/4 Changed path filter hash fix and version bumpJonathan Tan, Jun 8, 2023
  20. 1/4 gitformat-commit-graph: describe version 2 of BDATJonathan Tan, Jun 8, 2023
  21. Ramsay JonesJun 8, 2023
  22. Junio C HamanoJun 12, 2023
  23. 2/4 t4216: test changed path filters with high bit pathsJonathan Tan, Jun 8, 2023
  24. 3/4 repo-settings: introduce commitgraph.changedPathsVersionJonathan Tan, Jun 8, 2023
  25. 4/4 commit-graph: new filter ver. that fixes murmur3Jonathan Tan, Jun 8, 2023
  26. Ramsay JonesJun 8, 2023
  27. Jonathan TanJun 9, 2023
  28. Junio C HamanoJun 12, 2023
  29. Jonathan TanJun 13, 2023
  30. CodingGuidelines: use octal escapes, not hexJonathan Tan, Jun 13, 2023
  31. Eric SunshineJun 13, 2023
  32. Jonathan TanJun 13, 2023
  33. Eric SunshineJun 13, 2023
  34. Junio C HamanoJun 13, 2023
  35. Junio C HamanoJun 13, 2023
  36. 0/4 Changed path filter hash fix and version bumpJonathan Tan, Jun 13, 2023
  37. 2/4 t4216: test changed path filters with high bit pathsJonathan Tan, Jun 13, 2023
  38. 1/4 gitformat-commit-graph: describe version 2 of BDATJonathan Tan, Jun 13, 2023
  39. Junio C HamanoJun 13, 2023
  40. Derrick StoleeJun 20, 2023
  41. Taylor BlauJun 21, 2023
  42. Jonathan TanJun 22, 2023
  43. Derrick StoleeJun 23, 2023
  44. 3/4 repo-settings: introduce commitgraph.changedPathsVersionJonathan Tan, Jun 13, 2023
  45. Derrick StoleeJun 20, 2023
  46. Taylor BlauJun 21, 2023
  47. 4/4 commit-graph: new filter ver. that fixes murmur3Jonathan Tan, Jun 13, 2023
  48. Derrick StoleeJun 20, 2023
  49. Junio C HamanoJun 20, 2023
  50. Junio C HamanoJun 13, 2023
  51. Derrick StoleeJun 20, 2023
  52. Jonathan TanJun 20, 2023
  53. Taylor BlauJun 21, 2023
  54. Derrick StoleeJun 21, 2023
  55. Jonathan TanJun 22, 2023
  56. Derrick StoleeJun 23, 2023
  57. 0/4 Changed path filter hash fix and version bumpJonathan Tan, Jul 13, 2023
  58. 3/4 repo-settings: introduce commitgraph.changedPathsVersionJonathan Tan, Jul 13, 2023
  59. Taylor BlauJul 19, 2023
  60. Jonathan TanJul 20, 2023
  61. Taylor BlauJul 20, 2023
  62. 2/4 t4216: test changed path filters with high bit pathsJonathan Tan, Jul 13, 2023
  63. Junio C HamanoJul 13, 2023
  64. Taylor BlauJul 19, 2023
  65. 0/4 commit-graph: avoid looking at Bloom filter data directlyTaylor Blau, Jul 19, 2023
  66. 1/4 t/helper/test-read-graph.c: extract `dump_graph_info()`Taylor Blau, Jul 19, 2023
  67. 2/4 bloom.h: make `load_bloom_filter_from_graph()` publicTaylor Blau, Jul 19, 2023
  68. 3/4 t/helper/test-read-graph: implement `bloom-filters` modeTaylor Blau, Jul 19, 2023
  69. 4/4 fixup! t4216: test changed path filters with high bit pathsTaylor Blau, Jul 19, 2023
  70. Junio C HamanoJul 19, 2023
  71. Jonathan TanJul 20, 2023
  72. 1/4 gitformat-commit-graph: describe version 2 of BDATJonathan Tan, Jul 13, 2023
  73. Taylor BlauJul 19, 2023
  74. Jonathan TanJul 20, 2023
  75. Taylor BlauJul 21, 2023
  76. 4/4 commit-graph: new filter ver. that fixes murmur3Jonathan Tan, Jul 13, 2023
  77. Taylor BlauJul 19, 2023
  78. Jonathan TanJul 20, 2023
  79. Taylor BlauJul 26, 2023
  80. Junio C HamanoJul 13, 2023
  81. Junio C HamanoJul 13, 2023
  82. Jonathan TanJul 14, 2023
  83. 0/7 Changed path filter hash fix and version bumpJonathan Tan, Jul 20, 2023
  84. 1/7 gitformat-commit-graph: describe version 2 of BDATJonathan Tan, Jul 20, 2023
  85. 2/7 t/helper/test-read-graph.c: extract `dump_graph_info()`Jonathan Tan, Jul 20, 2023
  86. Taylor BlauJul 26, 2023
  87. 3/7 bloom.h: make `load_bloom_filter_from_graph()` publicJonathan Tan, Jul 20, 2023
  88. 5/7 t4216: test changed path filters with high bit pathsJonathan Tan, Jul 20, 2023
  89. Taylor BlauJul 26, 2023
  90. 4/7 t/helper/test-read-graph: implement `bloom-filters` modeJonathan Tan, Jul 20, 2023
  91. 6/7 repo-settings: introduce commitgraph.changedPathsVersionJonathan Tan, Jul 20, 2023
  92. 7/7 commit-graph: new filter ver. that fixes murmur3Jonathan Tan, Jul 20, 2023
  93. Junio C HamanoJul 25, 2023
  94. Junio C HamanoJul 26, 2023
  95. Taylor BlauJul 27, 2023
  96. Junio C HamanoJul 27, 2023
  97. Jonathan TanJul 27, 2023
  98. Taylor BlauJul 27, 2023
  99. Jonathan TanJul 27, 2023
  100. Taylor BlauAug 1, 2023
  101. Jonathan TanAug 1, 2023
  102. Taylor BlauAug 3, 2023
  103. Derrick StoleeAug 3, 2023
  104. Taylor BlauAug 3, 2023
  105. Junio C HamanoJul 27, 2023
  106. 0/7 Changed path filter hash fix and version bumpJonathan Tan, Aug 1, 2023
  107. 1/7 gitformat-commit-graph: describe version 2 of BDATJonathan Tan, Aug 1, 2023
  108. 2/7 t/helper/test-read-graph.c: extract `dump_graph_info()`Jonathan Tan, Aug 1, 2023
  109. 3/7 bloom.h: make `load_bloom_filter_from_graph()` publicJonathan Tan, Aug 1, 2023
  110. 4/7 t/helper/test-read-graph: implement `bloom-filters` modeJonathan Tan, Aug 1, 2023
  111. 5/7 t4216: test changed path filters with high bit pathsJonathan Tan, Aug 1, 2023
  112. 6/7 repo-settings: introduce commitgraph.changedPathsVersionJonathan Tan, Aug 1, 2023
  113. 7/7 commit-graph: new filter ver. that fixes murmur3Jonathan Tan, Aug 1, 2023
  114. Junio C HamanoAug 1, 2023
  115. Taylor BlauAug 1, 2023
  116. Junio C HamanoAug 1, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.