{"thread":{"id":"56338","subject":"[RFC PATCH] multi-pack-index: allow operating without pack files","startedAt":"2021-08-20T19:56:05Z","lastAt":"2021-08-23T09:22:06Z","messageCount":7,"participants":["Johannes Berg","Derrick Stolee","Martin Fick","Taylor Blau"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"433275","messageId":"20210820195558.44275-1-johannes@sipsolutions.net","threadId":"56338","inReplyTo":null,"subject":"[RFC PATCH] multi-pack-index: allow operating without pack files","fromName":"Johannes Berg","fromEmail":"johannes@sipsolutions.net","sentAt":"2021-08-20T19:55:58Z","receivedAt":"2021-08-20T19:56:05Z","isPatch":true,"sender":{"key":"johannes@sipsolutions.net","avatar":"https://avatars.githubusercontent.com/u/5159728?v=4"},"body":"Technically, multi-pack-index doesn't need pack files to exist,\nbut add_packed_git() today checks whether it exists or not.\n\nIn bup, a git pack format based backup tool, we'd really like\nto take advantage of the multi-pack-index, since bup needs it\nto save new objects to the repository efficiently (to check if\nsomething already exists), and uses git to access the repo, so\nthe multi-pack-index can make more efficient.\n\nAlternatively, bup has its own 'midx' format, of which multiple\ncan exist in a repository, predating the multi-pack-index.\n\nAll of this works well as long as the bup repository is just a\nnormal git repository. However, I've been adding encrypted and\nencrypted remote repositories to bup, where the pack files are\nnot local, similar to promisor remotes, but not really done in\nthe same way.\n\nIn this case, the local storage is only the idx files, no pack\nfiles (it's just a cache), and we access the pack files and\nobjects within in different ways. Unfortunately, in this case\nwe also cannot reuse bup's midx format very well: it only has\ninformation on which objects exists, not where to find them,\nand so reading from the repository requires reading all of the\nidx files, something that git's multi-pack-index solves.\n\nWhile we'll need to add read access to git's multi-pack-index\nto bup, having a call to 'git multi-pack-index' write it would\nbe nice and save some duplication. However, in the case of the\nremote/encrypted repositories, git currently cannot do that as\nit requires the pack files to exist.\n\nAdd a command-line option to be able to not require pack files\nto exist, to make that easier (rather than requiring writing\nsome dummy pack files, git even accepts empty files.)\n\nSigned-off-by: Johannes Berg <johannes@sipsolutions.net>\n---\n Documentation/git-multi-pack-index.txt |  6 +++++-\n builtin/multi-pack-index.c             |  5 ++++-\n midx.c                                 |  9 ++++++---\n midx.h                                 |  1 +\n packfile.c                             | 10 ++++++++--\n packfile.h                             |  2 ++\n 6 files changed, 26 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-multi-pack-index.txt b/Documentation/git-multi-pack-index.txt\nindex ffd601bc17b4..23db70fbebc2 100644\n--- a/Documentation/git-multi-pack-index.txt\n+++ b/Documentation/git-multi-pack-index.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n --------\n [verse]\n 'git multi-pack-index' [--object-dir=<dir>] [--[no-]progress]\n-\t[--preferred-pack=<pack>] <subcommand>\n+\t<subcommand> [<subcommand options>]\n \n DESCRIPTION\n -----------\n@@ -40,6 +40,10 @@ write::\n \t\tmultiple packs contain the same object. If not given,\n \t\tties are broken in favor of the pack with the lowest\n \t\tmtime.\n+\n+\t--no-require-packs::\n+\t\tDon't require pack files to exist, useful only for\n+\t\tcertain non-repository caches.\n --\n \n verify::\ndiff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c\nindex 8ff0dee2ecbb..2c9293b20c49 100644\n--- a/builtin/multi-pack-index.c\n+++ b/builtin/multi-pack-index.c\n@@ -7,7 +7,7 @@\n #include \"object-store.h\"\n \n #define BUILTIN_MIDX_WRITE_USAGE \\\n-\tN_(\"git multi-pack-index [<options>] write [--preferred-pack=<pack>]\")\n+\tN_(\"git multi-pack-index [<options>] write [--preferred-pack=<pack>] [--no-require-packs]\")\n \n #define BUILTIN_MIDX_VERIFY_USAGE \\\n \tN_(\"git multi-pack-index [<options>] verify\")\n@@ -68,6 +68,9 @@ static int cmd_multi_pack_index_write(int argc, const char **argv)\n \t\tOPT_STRING(0, \"preferred-pack\", &opts.preferred_pack,\n \t\t\t   N_(\"preferred-pack\"),\n \t\t\t   N_(\"pack for reuse when computing a multi-pack bitmap\")),\n+\t\tOPT_BIT(0, \"no-require-packs\", &opts.flags,\n+\t\t\tN_(\"don't require pack files to exist\"),\n+\t\t\tMIDX_DONT_REQUIRE_PACKS),\n \t\tOPT_END(),\n \t};\n \ndiff --git a/midx.c b/midx.c\nindex 902e1a7a7d9d..98b3cb33201f 100644\n--- a/midx.c\n+++ b/midx.c\n@@ -468,6 +468,7 @@ struct write_midx_context {\n \tuint32_t num_large_offsets;\n \n \tint preferred_pack_idx;\n+\tunsigned flags;\n };\n \n static void add_pack_to_midx(const char *full_path, size_t full_path_len,\n@@ -482,9 +483,10 @@ static void add_pack_to_midx(const char *full_path, size_t full_path_len,\n \n \t\tALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);\n \n-\t\tctx->info[ctx->nr].p = add_packed_git(full_path,\n-\t\t\t\t\t\t      full_path_len,\n-\t\t\t\t\t\t      0);\n+\t\tctx->info[ctx->nr].p = _add_packed_git(full_path,\n+\t\t\t\t\t\t       full_path_len,\n+\t\t\t\t\t\t       0,\n+\t\t\t\t\t\t       !(ctx->flags & MIDX_DONT_REQUIRE_PACKS));\n \n \t\tif (!ctx->info[ctx->nr].p) {\n \t\t\twarning(_(\"failed to add packfile '%s'\"),\n@@ -924,6 +926,7 @@ static int write_midx_internal(const char *object_dir, struct multi_pack_index *\n \tctx.nr = 0;\n \tctx.alloc = ctx.m ? ctx.m->num_packs : 16;\n \tctx.info = NULL;\n+\tctx.flags = flags;\n \tALLOC_ARRAY(ctx.info, ctx.alloc);\n \n \tif (ctx.m) {\ndiff --git a/midx.h b/midx.h\nindex 8684cf0fefe8..aa6382d99386 100644\n--- a/midx.h\n+++ b/midx.h\n@@ -41,6 +41,7 @@ struct multi_pack_index {\n \n #define MIDX_PROGRESS     (1 << 0)\n #define MIDX_WRITE_REV_INDEX (1 << 1)\n+#define MIDX_DONT_REQUIRE_PACKS (1 << 2)\n \n char *get_midx_rev_filename(struct multi_pack_index *m);\n \ndiff --git a/packfile.c b/packfile.c\nindex 9ef6d9829280..dfe994205914 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -687,7 +687,8 @@ void unuse_pack(struct pack_window **w_cursor)\n \t}\n }\n \n-struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n+struct packed_git *_add_packed_git(const char *path, size_t path_len, int local,\n+\t\t\t\t   int require_pack)\n {\n \tstruct stat st;\n \tsize_t alloc;\n@@ -717,7 +718,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n \t\tp->pack_promisor = 1;\n \n \txsnprintf(p->pack_name + path_len, alloc - path_len, \".pack\");\n-\tif (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {\n+\tif (require_pack && (stat(p->pack_name, &st) || !S_ISREG(st.st_mode))) {\n \t\tfree(p);\n \t\treturn NULL;\n \t}\n@@ -734,6 +735,11 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n \treturn p;\n }\n \n+struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n+{\n+\treturn _add_packed_git(path, path_len, local, 1);\n+}\n+\n void install_packed_git(struct repository *r, struct packed_git *pack)\n {\n \tif (pack->pack_fd != -1)\ndiff --git a/packfile.h b/packfile.h\nindex 3ae117a8aef0..a921077a05ef 100644\n--- a/packfile.h\n+++ b/packfile.h\n@@ -96,6 +96,8 @@ void close_object_store(struct raw_object_store *o);\n void unuse_pack(struct pack_window **);\n void clear_delta_base_cache(void);\n struct packed_git *add_packed_git(const char *path, size_t path_len, int local);\n+struct packed_git *_add_packed_git(const char *path, size_t path_len, int local,\n+\t\t\t\t   int require_pack);\n \n /*\n  * Unlink the .pack and associated extension files.\n-- \n2.31.1\n\n"},{"id":"433336","messageId":"edb9c412-70c8-4fc6-04ab-417eca05ee15@gmail.com","threadId":"56338","inReplyTo":"20210820195558.44275-1-johannes@sipsolutions.net","subject":"Re: [RFC PATCH] multi-pack-index: allow operating without pack files","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2021-08-23T00:34:43Z","receivedAt":"2021-08-23T00:34:48Z","isPatch":true,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 8/20/2021 3:55 PM, Johannes Berg wrote:\n> Technically, multi-pack-index doesn't need pack files to exist,\n> but add_packed_git() today checks whether it exists or not.\n\nHaving a multi-pack-index is supposed to indicate that we have\nthese objects in the objects/pack directory within the specified\npack-files.\n\nI understand your goal to relax a condition of the multi-pack-index\nfile, but it's triggered by a flag during write and that choice\nisn't persisted into the file. There is no way for a later Git\nprocess to understand that the multi-pack-index doesn't actually\nguarantee object existence.\n\nAnd in a completely other side: one would think that including\na pack-file in the multi-pack-index would allow deleting the .idx\nfile, but there are a few reasons why we do not (including\ninteractions with third-party tools).\n\nSo, I'm not necessarily on board with this change unless\nsomething is added to the multi-pack-index file (such as a new\nversion 2 and an optional chunk understood by that version) that\ntells future Git processes that the .pack files might not exist.\nI'm still not sure what Git should do about that other than stop\nreading the multi-pack-index and ignore its contents.\n\n> -struct packed_git *add_packed_git(const char *path, size_t path_len, int local)\n> +struct packed_git *_add_packed_git(const char *path, size_t path_len, int local,\n> +\t\t\t\t   int require_pack)\n\nThe only obvious thing that I noticed in the code is that we\ntypically use <function name>_1() as a way to create a static\nversion that is called by the global version.\n\n>  struct packed_git *add_packed_git(const char *path, size_t path_len, int local);\n> +struct packed_git *_add_packed_git(const char *path, size_t path_len, int local,\n> +\t\t\t\t   int require_pack);\n\n...oh, but that's not what you're doing. What you could do\ninstead is convert the 'local' parameter into a 'flags' parameter\n(I think we have started to prefer 'enum's recently) and create\nMIDX_FLAG_LOCAL and MIDX_FLAG_PACKS_OPTIONAL flag values. That\navoids multiple methods and minimizes the change to existing\ncallers.\n\nThanks,\n-Stolee\n"},{"id":"433339","messageId":"3649958.14eQuSAvaI@mfick-lnx","threadId":"56338","inReplyTo":"edb9c412-70c8-4fc6-04ab-417eca05ee15@gmail.com","subject":"Re: [RFC PATCH] multi-pack-index: allow operating without pack files","fromName":"Martin Fick","fromEmail":"mfick@codeaurora.org","sentAt":"2021-08-23T01:11:09Z","receivedAt":"2021-08-23T01:11:17Z","isPatch":true,"sender":{"key":"mfick@codeaurora.org","avatar":null},"body":"On Sunday, August 22, 2021 8:34:43 PM MDT Derrick Stolee wrote:\n> On 8/20/2021 3:55 PM, Johannes Berg wrote:\n> > Technically, multi-pack-index doesn't need pack files to exist,\n> > but add_packed_git() today checks whether it exists or not.\n> \n> Having a multi-pack-index is supposed to indicate that we have\n> these objects in the objects/pack directory within the specified\n> pack-files.\n\nHmm, isn't it a normal supported use case for repacking to potentially delete \npackfiles which are in the MIDX (I'm specifically thinking about when someone \nruns git gc with an older git version which knows nothing about MIDX files)?\n\n -Martin\n\n-- \nThe Qualcomm Innovation Center, Inc. is a member of Code \nAurora Forum, hosted by The Linux Foundation\n\n"},{"id":"433341","messageId":"YSMenndGYr14okwv@nand.local","threadId":"56338","inReplyTo":"edb9c412-70c8-4fc6-04ab-417eca05ee15@gmail.com","subject":"Re: [RFC PATCH] multi-pack-index: allow operating without pack files","fromName":"Taylor Blau","fromEmail":"me@ttaylorr.com","sentAt":"2021-08-23T04:05:50Z","receivedAt":"2021-08-23T04:05:53Z","isPatch":true,"sender":{"key":"me@ttaylorr.com","avatar":"https://avatars.githubusercontent.com/u/301000140?v=4"},"body":"On Sun, Aug 22, 2021 at 08:34:43PM -0400, Derrick Stolee wrote:\n> On 8/20/2021 3:55 PM, Johannes Berg wrote:\n> > Technically, multi-pack-index doesn't need pack files to exist,\n> > but add_packed_git() today checks whether it exists or not.\n>\n> Having a multi-pack-index is supposed to indicate that we have\n> these objects in the objects/pack directory within the specified\n> pack-files.\n>\n> I understand your goal to relax a condition of the multi-pack-index\n> file, but it's triggered by a flag during write and that choice\n> isn't persisted into the file. There is no way for a later Git\n> process to understand that the multi-pack-index doesn't actually\n> guarantee object existence.\n\nWe're going to run into problems much earlier than that, though: the\nMIDX needs to load information about objects from packs in order to\nbreak ties when multiple copies of the same object exist in multiple\npacks (according to that pack's mtime).\n\nSo I'm not sure how we would even write a MIDX without physical packs on\ndisk that we can open and stat, let along how we would teach Git to\nhandle a situation where packs that did exist when writing a MIDX went\naway when we tried to read from the same MIDX later on.\n\nThanks,\nTaylor\n"},{"id":"433352","messageId":"dc146642f6aa9ac49d02cca47779071258e7541e.camel@sipsolutions.net","threadId":"56338","inReplyTo":"3649958.14eQuSAvaI@mfick-lnx","subject":"Re: [RFC PATCH] multi-pack-index: allow operating without pack files","fromName":"Johannes Berg","fromEmail":"johannes@sipsolutions.net","sentAt":"2021-08-23T08:21:00Z","receivedAt":"2021-08-23T08:21:06Z","isPatch":true,"sender":{"key":"johannes@sipsolutions.net","avatar":"https://avatars.githubusercontent.com/u/5159728?v=4"},"body":"On Sun, 2021-08-22 at 19:11 -0600, Martin Fick wrote:\n> On Sunday, August 22, 2021 8:34:43 PM MDT Derrick Stolee wrote:\n> > On 8/20/2021 3:55 PM, Johannes Berg wrote:\n> > > Technically, multi-pack-index doesn't need pack files to exist,\n> > > but add_packed_git() today checks whether it exists or not.\n> > \n> > Having a multi-pack-index is supposed to indicate that we have\n> > these objects in the objects/pack directory within the specified\n> > pack-files.\n> \n> Hmm, isn't it a normal supported use case for repacking to potentially delete \n> packfiles which are in the MIDX (I'm specifically thinking about when someone \n> runs git gc with an older git version which knows nothing about MIDX files)?\n\nYeah, the multi-pack-index contains all the pack names that are there\n(and then which one the object is in), and when git tries to use it,\nthen it doesn't really seem to have any issues?\n\nYou can \"git repack -a -d\" with an old version, or save the multi-pack-\nindex temporarily elsewhere and copy it back after repack, and things\nwork just fine, except of course \"git multi-pack-index verify\" will\ncomplain loudly.\n\njohannes\n\n"},{"id":"433353","messageId":"3505a827a42096938746691acf4b1a2f5bf9d04f.camel@sipsolutions.net","threadId":"56338","inReplyTo":"YSMenndGYr14okwv@nand.local","subject":"Re: [RFC PATCH] multi-pack-index: allow operating without pack files","fromName":"Johannes Berg","fromEmail":"johannes@sipsolutions.net","sentAt":"2021-08-23T08:23:10Z","receivedAt":"2021-08-23T08:23:15Z","isPatch":true,"sender":{"key":"johannes@sipsolutions.net","avatar":"https://avatars.githubusercontent.com/u/5159728?v=4"},"body":"On Mon, 2021-08-23 at 00:05 -0400, Taylor Blau wrote:\n> \n> We're going to run into problems much earlier than that, though: the\n> MIDX needs to load information about objects from packs in order to\n> break ties when multiple copies of the same object exist in multiple\n> packs (according to that pack's mtime).\n\nHuh, I guess I never ran into a need - we make sure in bup that each\nobject only exists once, that's kind of the point :)\n\nI guess we could break ties by \"lower hash of the pack\" instead of\n\"mtime\"? It doesn't really matter how they're broken, as long as it's\nconsistent?\n\nArguably, mtime is not a good measure anyway, since the same repo\nelsewhere would have different mtimes.\n\n> So I'm not sure how we would even write a MIDX without physical packs on\n> disk that we can open and stat, let along how we would teach Git to\n> handle a situation where packs that did exist when writing a MIDX went\n> away when we tried to read from the same MIDX later on.\n\nIt handles that just fine on the read side.\n\njohannes\n\n"},{"id":"433354","messageId":"dbb24573efc3dd945acd8acdfd9fe627ad7cbcd2.camel@sipsolutions.net","threadId":"56338","inReplyTo":"edb9c412-70c8-4fc6-04ab-417eca05ee15@gmail.com","subject":"Re: [RFC PATCH] multi-pack-index: allow operating without pack files","fromName":"Johannes Berg","fromEmail":"johannes@sipsolutions.net","sentAt":"2021-08-23T09:22:01Z","receivedAt":"2021-08-23T09:22:06Z","isPatch":true,"sender":{"key":"johannes@sipsolutions.net","avatar":"https://avatars.githubusercontent.com/u/5159728?v=4"},"body":"On Sun, 2021-08-22 at 20:34 -0400, Derrick Stolee wrote:\n> On 8/20/2021 3:55 PM, Johannes Berg wrote:\n> > Technically, multi-pack-index doesn't need pack files to exist,\n> > but add_packed_git() today checks whether it exists or not.\n> \n> Having a multi-pack-index is supposed to indicate that we have\n> these objects in the objects/pack directory within the specified\n> pack-files.\n\nYeah, so, like I tried to explain in the patch email, this is\n(partially) for a non-git use case.\n\nThe way you could think of it is that I'm trying to make a local index\ncache, so we know locally which objects we have, but the actual packs\nand their contents are stored in some slow/expensive (remote) storage\nsystem.\n\nWith the local cache, I'd like to understand whether or not I have a\ngiven object (in particular to avoid storing it again if I see it), and\nalso I'd like to know _where_ it is (which pack and where in the pack)\nso that I can access only parts, instead of downloading everything.\n\nThe server isn't necessarily able to run something 'smart', it might\njust be S3 blob storage, but storing pack files, not individual objects.\n\n> I understand your goal to relax a condition of the multi-pack-index\n> file, but it's triggered by a flag during write and that choice\n> isn't persisted into the file. There is no way for a later Git\n> process to understand that the multi-pack-index doesn't actually\n> guarantee object existence.\n\nIt does, since the pack files are recorded. I've tested this briefly,\nand it doesn't really seem to have any problems with it.\n\nWhile I understand the concern, I'd also envision that this tool\ncommand-line option is never set when this is used on normal git\nrepositories, only when used in this special use case I tried explaining\nabove.\n\n> And in a completely other side: one would think that including\n> a pack-file in the multi-pack-index would allow deleting the .idx\n> file, but there are a few reasons why we do not (including\n> interactions with third-party tools).\n\nWell, arguably you can always restore it from the pack file, so you can\nalways delete it ;) Not sure git is set up for that though. Also, even\nold versions of git would probably choke since they don't read the\nmulti-pack-index.\n\n> So, I'm not necessarily on board with this change unless\n> something is added to the multi-pack-index file (such as a new\n> version 2 and an optional chunk understood by that version) that\n> tells future Git processes that the .pack files might not exist.\n> I'm still not sure what Git should do about that other than stop\n> reading the multi-pack-index and ignore its contents.\n\nIt seems to do that today, or at least try to find in the idx if it goes\nlooking for an object and the multi-pack-index references a pack file\nthat doesn't exist - and as Martin also pointed out, that really is\nnecessary for this to work with older versions of git.\n\n> [snip comments on the code]\n\nFair enough. I think we need to figure out the conceptual question\nthough - whether or not this is something that's acceptable in git in\nthe first place.\n\nLike I said, the intent isn't to break git repositories or to even use\nthis on a git repository that's also normally being read by git (even\nthough I don't see any problems with that, but my testing wasn't very\ndeep). The intent (and the reason for this being [RFC]) is to see if git\nupstream would be amenable to such a change that lets other tools use\ngit's index - especially multi-pack-index - machinery to operate on such\na thing as the \"index cache\" I described above.\n\nIn particular, in bup's [1] use case, we currently support our own\n\"midx\" format which is similar to multi-pack-index, but only contains\n*object existence*, not *object location*. Thus, there are two problems:\n\n   1. In a normal bup/git repository, when bup is used to write objects\n      (it only ever writes packs), then the midx is also updated to\n      allow bup itself to check for object existence without opening all\n      the *.idx files, allowing it to deduplicate objects efficiently.\n      In this case, bup always uses git to retrieve objects pack, and\n      this leads to inefficiencies: git will not be able to use the midx\n      files (and they don't contain object location anyway), but git\n      will open all the *.idx files. If we ask it, it might maintain its\n      own multi-pack-index.\n      \n      Obviously, in this mode, there's no reason to have this patch - we\n      can just ask git to create the multi-pack-index and add code to\n      bup to understand how to read it in order to check for object\n      existence (for deduplication).\n      \n   2. However, I'm working on adding encrypted repositories to bup, and\n      there the objects are stored differently - still in something like\n      a pack file, but it's encrypted, in a way that's done at the\n      object level.\n      \n      In this mode, bup maintains an object index in a clear-text cache,\n      i.e. all the *.idx files, and currently adds its own midx to be\n      able to efficiently check for object existence.\n      \n      However, in this case, bup cannot use git to access objects, since\n      there's no real git directory, only a folder containing the *.idx\n      files, the data is \"elsewhere\".\n      \n      Since the *.idx file format is still the same (no reason to change\n      it), with this patch we can use git to efficiently (in both\n      developer time, I don't need to rewrite it, and runtime, since\n      it's in C not python) ask git to write the multi-pack-index that\n      then bup can use to do both: a) check for object existence during\n      further backups while adding new objects, and b) look for object\n      location while accessing the repository for reading.\n\nI completely understand that this is a non-git use case, and I'm\nentirely happy for you to tell me to get lost, but I figured it was such\na small change I had to try, rather than rewriting the entire multi-\npack-index maintenance code for bup (or importing git's there).\n\nReally for (2) I don't even care about using git's multi-pack-index,\nsince git never uses it, but I wanted to have the same between (1) and\n(2), and if we want git - called on a bup/git repo - to have a multi-\npack-index, then we need git's format, of course.\n\nThe other hack I considered was to just create empty *.pack files for\neach *.idx file in the index cache because then git is (currently) happy\nto accept this, so it never really validates anything there even when\nthe pack files \"exist\", but that felt even worse and like something git\nmight break with just a little more validity checking.\n\n\nSo basically I had choices between:\n   A. implement multi-pack-index in bup, to cover both (1) and (2)\n   B. implement a new midx format in bup, to cover just (2)\n   C. call unmodified git in bup, to cover just (1)\n   D. this patch to cover both (1) and (2)\n   E. create dummy *.pack files for the *.idx files in the cache, so\n      that git will accept it.\n\nObviously, I can also do any combination of these, e.g. B & C, but this\nwas the least amount of work ;)\n\n\nBut really, it's up to you, I'm just asking. If you feel this doesn't\nfit into git's machinery (despite being so simple), I'll just do\n\"something else\", not sure which one I might do. Quite possibly A., if\nonly because then I can write tests with \"git multi-index-pack verify\"\n:-)\n\njohannes\n\n[1] https://bup.github.io/, not to be confused with bupstash.io\n\n"}]}