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

Re: [PATCH v2 3/8] builtin/index-pack.c: write reverse indexes

From
Taylor Blau <me@ttaylorr.com>
Date
Jan 25, 2021, 20:03 UTC
Message-ID
<YA8j+3nq8nI/hcIQ@nand.local>
In-Reply-To
<YAtlZ49mTfTGg11/@coredump.intra.peff.net>
On Fri, Jan 22, 2021 at 06:53:11PM -0500, Jeff King wrote:
Show 38 quoted lines
> On Wed, Jan 13, 2021 at 05:28:15PM -0500, Taylor Blau wrote:
>
> >  OPTIONS
> > @@ -33,7 +34,14 @@ OPTIONS
> >  	file is constructed from the name of packed archive
> >  	file by replacing .pack with .idx (and the program
> >  	fails if the name of packed archive does not end
> > -	with .pack).
> > +	with .pack). Incompatible with `--rev-index`.
>
> I wondered which option was incompatible, but couldn't see from the
> context. It is "index-pack -o", which kind of makes sense. We can derive
> "foo.rev" from "foo.idx", but normally "-o" does not do any deriving.
>
> So I was all set to say "OK, we can live without it", but...
>
> > @@ -1824,7 +1851,16 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
> >  	if (from_stdin && hash_algo)
> >  		die(_("--object-format cannot be used with --stdin"));
> >  	if (!index_name && pack_name)
> > -		index_name = derive_filename(pack_name, "idx", &index_name_buf);
> > +		index_name = derive_filename(pack_name, ".pack", "idx", &index_name_buf);
> > +
> > +	opts.flags &= ~(WRITE_REV | WRITE_REV_VERIFY);
> > +	if (rev_index) {
> > +		opts.flags |= verify ? WRITE_REV_VERIFY : WRITE_REV;
> > +		if (index_name)
> > +			rev_index_name = derive_filename(index_name,
> > +							 ".idx", "rev",
> > +							 &rev_index_name_buf);
> > +	}
>
> ...here we do end up deriving ".rev" from ".idx" anyway. So I guess we
> probably could support "-o".  I also wonder what happens with "git
> index-pack -o foo.idx" when pack.writeReverseIndex is set. It looks like
> it would just work because of this block. But then shouldn't
> "--rev-index" work, too? And indeed, there is a test for that at the end
> of the patch! So is the documentation just wrong?

Hah! The documentation is just plain wrong. It's been a while, but I have a vague recollection of writing this documentation before changing the implementation of index-pack to allow this. Clearly, I forgot to go back to update the broken documentation.

Hilariously, there is even a test in t5325 that demonstrates this working! 'git index-pack --rev-index -o other.idx' writes both 'other.idx' and 'other.rev'. That was easy :-).

Show 7 quoted lines
> I admit to finding the use of opts.flags versus the rev_index option a
> bit confusing. It seems like they are doing roughly the same thing, but
> influenced by different sources. It seems like we should be able to have
> a single local variable (then that goes on to set opts.flags for any
> sub-functions we call). Or maybe two, if we need to distinguish config
> versus command-line, but then they should have clear names
> (rev_index_config and rev_index_cmdline or something).

Yeah, I know. It's because we already pass a pointer to a struct pack_idx_option to git_index_pack_config(), so in effect the 'flags' on that struct *is* rev_index_config.

It's a little ugly, I agree, but I'm skeptical that the effort to clean it up is worth it, mostly because the pack_idx_option struct probably shouldn't be part of the index-pack builtin in the first place.

Show 6 quoted lines
> As an aside, looking at derive_filename(), it seems a bit weird that one
> argument has a dot in the suffix and the other does not. I guess you are
> following the convention from write_special_file(), which omits it in
> the newly-added suffix. But it is slightly awkward to omit it for the
> old suffix in derive_filename(), because we want to strip_suffix() it
> all at once.
Show 6 quoted lines
> Probably not that big a deal, but if anybody feels strongly, then
> derive_filename() could do:
>
>   if (!strip_suffix(pack_name, strip, &len) ||
>       !len || pack_name[len] != '.')
> 	die("does not end in .%s", strip);
That does make the callers look nicer, but it needs an extra two things:
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index ef2874a8e6..c758f3b8e9 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1441,11 +1441,10 @@ static const char *derive_filename(const char *pack_name, const char *strip,
 {
        size_t len;
        if (!strip_suffix(pack_name, strip, &len) || !len ||
-           pack_name[len] != '.')
+           pack_name[len - 1] != '.')
                die(_("packfile name '%s' does not end with '.%s'"),
                    pack_name, strip);
        strbuf_add(buf, pack_name, len);
-       strbuf_addch(buf, '.');
        strbuf_addstr(buf, suffix);
        return buf->buf;
 }

And then it does what you are looking for. I'll pull that change out
with your Suggested-by as a preparatory commit right before this one.

> > @@ -1578,6 +1591,12 @@ static int git_index_pack_config(const char *k, const char *v, void *cb)
> >  		}
> >  		return 0;
> >  	}
> > +	if (!strcmp(k, "pack.writereverseindex")) {
> > +		if (git_config_bool(k, v))
> > +			opts->flags |= WRITE_REV;
> > +		else
> > +			opts->flags &= ~WRITE_REV;
> > +	}
> >  	return git_default_config(k, v, cb);
> >  }
>
> IMHO we'll eventually want to turn this feature on by default. In which
> case we'll have to update every caller which is checking the config
> manually. Should we hide this in a function that looks up the config,
> and sets the default? Or alternatively, I guess, they could all use some
> shared initializer for "flags".

Note that there are only two such callers, so I'm not sure the effort to
extract this would be worth it.

> > +	# Intentionally corrupt the reverse index.
> > +	chmod u+w $rev &&
> > +	printf "xxxx" | dd of=$rev bs=1 count=4 conv=notrunc &&
> > +
> > +	test_must_fail git index-pack --rev-index --verify \
> > +		$packdir/pack-$pack.pack 2>err &&
> > +	grep "validation error" err
> > +'
>
> This isn't that subtle of a corruption, because we are corrupting the
> first 4 bytes, which is the magic signature. Maybe something further in
> the actual data would be interesting instead of or in addition?
>
> I dunno. There are a lot of edge cases around corruption (likewise, we
> might care how the normal reading code-path perceives a signature
> corruption like this). I'm not sure it's all that interesting to test
> all of them.

Agreed, I think what is here (even though it's not a severe corruption)
would be sufficient to make me feel good about our error handling in
general.

Thanks,
Taylor
Previous: Jeff KingNext: Taylor Blau
Message 46 of 82 in “pack-revindex: introduce on-disk '.rev' format”
  1. 0/8 pack-revindex: introduce on-disk '.rev' formatTaylor Blau, Jan 8, 2021
  2. 2/8 pack-write.c: prepare to write 'pack-*.rev' filesTaylor Blau, Jan 8, 2021
  3. 8/8 pack-revindex: ensure that on-disk reverse indexes are given precedenceTaylor Blau, Jan 8, 2021
  4. 3/8 builtin/index-pack.c: write reverse indexesTaylor Blau, Jan 8, 2021
  5. 1/8 packfile: prepare for the existence of '*.rev' filesTaylor Blau, Jan 8, 2021
  6. 4/8 builtin/pack-objects.c: respect 'pack.writeReverseIndex'Taylor Blau, Jan 8, 2021
  7. 7/8 t: support GIT_TEST_WRITE_REV_INDEXTaylor Blau, Jan 8, 2021
  8. Derrick StoleeJan 12, 2021
  9. Taylor BlauJan 12, 2021
  10. Ævar Arnfjörð BjarmasonJan 12, 2021
  11. Derrick StoleeJan 12, 2021
  12. Taylor BlauJan 12, 2021
  13. 6/8 t: prepare for GIT_TEST_WRITE_REV_INDEXTaylor Blau, Jan 8, 2021
  14. Ævar Arnfjörð BjarmasonJan 12, 2021
  15. Taylor BlauJan 12, 2021
  16. 5/8 Documentation/config/pack.txt: advertise 'pack.writeReverseIndex'Taylor Blau, Jan 8, 2021
  17. 0/8 pack-revindex: introduce on-disk '.rev' formatTaylor Blau, Jan 13, 2021
  18. 8/8 pack-revindex: ensure that on-disk reverse indexes are given precedenceTaylor Blau, Jan 13, 2021
  19. 6/8 t: prepare for GIT_TEST_WRITE_REV_INDEXTaylor Blau, Jan 13, 2021
  20. 1/8 packfile: prepare for the existence of '*.rev' filesTaylor Blau, Jan 13, 2021
  21. Junio C HamanoJan 14, 2021
  22. Derrick StoleeJan 14, 2021
  23. Jeff KingJan 14, 2021
  24. Taylor BlauJan 14, 2021
  25. Junio C HamanoJan 14, 2021
  26. Taylor BlauJan 14, 2021
  27. Junio C HamanoJan 14, 2021
  28. Jeff KingJan 22, 2021
  29. Taylor BlauJan 25, 2021
  30. Jeff KingJan 25, 2021
  31. Junio C HamanoJan 25, 2021
  32. Taylor BlauJan 25, 2021
  33. 5/8 Documentation/config/pack.txt: advertise 'pack.writeReverseIndex'Taylor Blau, Jan 13, 2021
  34. 4/8 builtin/pack-objects.c: respect 'pack.writeReverseIndex'Taylor Blau, Jan 13, 2021
  35. Jeff KingJan 22, 2021
  36. Jeff KingJan 23, 2021
  37. Taylor BlauJan 25, 2021
  38. Jeff KingJan 25, 2021
  39. 2/8 pack-write.c: prepare to write 'pack-*.rev' filesTaylor Blau, Jan 13, 2021
  40. Jeff KingJan 22, 2021
  41. Taylor BlauJan 25, 2021
  42. Jeff KingJan 26, 2021
  43. 7/8 t: support GIT_TEST_WRITE_REV_INDEXTaylor Blau, Jan 13, 2021
  44. 3/8 builtin/index-pack.c: write reverse indexesTaylor Blau, Jan 13, 2021
  45. Jeff KingJan 22, 2021
  46. Taylor BlauJan 25, 2021
  47. 00/10 pack-revindex: introduce on-disk '.rev' formatTaylor Blau, Jan 25, 2021
  48. 01/10 packfile: prepare for the existence of '*.rev' filesTaylor Blau, Jan 25, 2021
  49. Jeff KingJan 29, 2021
  50. Taylor BlauJan 29, 2021
  51. Jeff KingJan 30, 2021
  52. 08/10 t: support GIT_TEST_WRITE_REV_INDEXTaylor Blau, Jan 25, 2021
  53. Jeff KingJan 29, 2021
  54. 07/10 t: prepare for GIT_TEST_WRITE_REV_INDEXTaylor Blau, Jan 25, 2021
  55. Jeff KingJan 29, 2021
  56. Eric SunshineJan 29, 2021
  57. Taylor BlauJan 29, 2021
  58. Jeff KingJan 30, 2021
  59. Junio C HamanoJan 29, 2021
  60. 05/10 builtin/pack-objects.c: respect 'pack.writeReverseIndex'Taylor Blau, Jan 25, 2021
  61. 09/10 pack-revindex: ensure that on-disk reverse indexes are given precedenceTaylor Blau, Jan 25, 2021
  62. Jeff KingJan 29, 2021
  63. Taylor BlauJan 29, 2021
  64. Jeff KingJan 30, 2021
  65. 10/10 t5325: check both on-disk and in-memory reverse indexTaylor Blau, Jan 25, 2021
  66. Jeff KingJan 29, 2021
  67. Jeff KingJan 29, 2021
  68. Taylor BlauJan 29, 2021
  69. Jeff KingJan 30, 2021
  70. 06/10 Documentation/config/pack.txt: advertise 'pack.writeReverseIndex'Taylor Blau, Jan 25, 2021
  71. Jeff KingJan 29, 2021
  72. Taylor BlauJan 29, 2021
  73. Jeff KingJan 30, 2021
  74. 02/10 pack-write.c: prepare to write 'pack-*.rev' filesTaylor Blau, Jan 25, 2021
  75. 04/10 builtin/index-pack.c: write reverse indexesTaylor Blau, Jan 25, 2021
  76. 03/10 builtin/index-pack.c: allow stripping arbitrary extensionsTaylor Blau, Jan 25, 2021
  77. Jeff KingJan 29, 2021
  78. Taylor BlauJan 29, 2021
  79. Junio C HamanoJan 26, 2021
  80. Taylor BlauJan 26, 2021
  81. Jeff KingJan 29, 2021
  82. Taylor BlauJan 29, 2021

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.