{"thread":{"id":"49905","subject":"Forcing GC to always fail","startedAt":"2018-11-27T21:08:56Z","lastAt":"2018-11-29T02:51:42Z","messageCount":8,"participants":["Bryan Turner","Ævar Arnfjörð Bjarmason","Elijah Newren","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"364165","messageId":"CAGyf7-F6BiqSa7LOWxvHZPfO+UaohQR78rCgvN9En+1P4du2Nw@mail.gmail.com","threadId":"49905","inReplyTo":null,"subject":"Forcing GC to always fail","fromName":"Bryan Turner","fromEmail":"bturner@atlassian.com","sentAt":"2018-11-27T21:08:42Z","receivedAt":"2018-11-27T21:08:56Z","isPatch":false,"sender":{"key":"bturner@atlassian.com","avatar":"https://gravatar.com/avatar/16bcf3167981c1ef7c804e502642366d888a35b0d0b0a4ca01fdc442aa1acb1e?d=mp&s=160"},"body":"Something of an odd question, but is there something I can do in the\nconfiguration for a repository that forces any \"git gc\" run in that\nrepository to always fail without doing anything? (Ideally I'd like to\nmake \"git reflog expire\" _also_ fail.)\n\nBackground: For Bitbucket Server, we have a fairly recurrent issue\nwhere administrators decide they know how to manage garbage collection\nfor our repositories better than we do, so they jump on the server and\nstart running things like this:\n\ngit reflog expire --expire=now –all\ngit gc --prune=now\ngit repack -adf --window=200 --depth=200\n\nThey then come running to us with their corrupted repository expecting\nand/or hoping that we can fix it (often without proper backups).\n\nBitbucket Server itself never runs \"git gc\" (or \"git reflog expire\").\nWe've configured how reflog expiry should be handled, but of course\nthat's overridden by explicit command line options like\n\"--expire=now\". We _do_ run \"git pack-refs\", \"git repack\" and \"git\nprune\" (with various options), so those commands need to continue to\nwork.\n\nIs there anything I can set, perhaps some invalid configuration\noption/value, that will make \"git gc\" (most important) and \"git\nreflog\" (ideal, but less important) fail when they're run in our\nrepositories? Hopefully at that point customers will reach out to us\nfor help _before_ they corrupt their repositories.\n\nBryan\n"},{"id":"364175","messageId":"87efb6ytfj.fsf@evledraar.gmail.com","threadId":"49905","inReplyTo":"CAGyf7-F6BiqSa7LOWxvHZPfO+UaohQR78rCgvN9En+1P4du2Nw@mail.gmail.com","subject":"Re: Forcing GC to always fail","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-27T23:47:12Z","receivedAt":"2018-11-27T23:47:19Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Tue, Nov 27 2018, Bryan Turner wrote:\n\n> Something of an odd question, but is there something I can do in the\n> configuration for a repository that forces any \"git gc\" run in that\n> repository to always fail without doing anything? (Ideally I'd like to\n> make \"git reflog expire\" _also_ fail.)\n>\n> Background: For Bitbucket Server, we have a fairly recurrent issue\n> where administrators decide they know how to manage garbage collection\n> for our repositories better than we do, so they jump on the server and\n> start running things like this:\n>\n> git reflog expire --expire=now –all\n> git gc --prune=now\n> git repack -adf --window=200 --depth=200\n>\n> They then come running to us with their corrupted repository expecting\n> and/or hoping that we can fix it (often without proper backups).\n>\n> Bitbucket Server itself never runs \"git gc\" (or \"git reflog expire\").\n> We've configured how reflog expiry should be handled, but of course\n> that's overridden by explicit command line options like\n> \"--expire=now\". We _do_ run \"git pack-refs\", \"git repack\" and \"git\n> prune\" (with various options), so those commands need to continue to\n> work.\n>\n> Is there anything I can set, perhaps some invalid configuration\n> option/value, that will make \"git gc\" (most important) and \"git\n> reflog\" (ideal, but less important) fail when they're run in our\n> repositories? Hopefully at that point customers will reach out to us\n> for help _before_ they corrupt their repositories.\n\nYou could fix this and so many other issues by just hanging up a \"Is\nThis Good For The Company?\" banner up in Atlassian offices .\n\nBut more seriously:\n    \n    $ stahp='Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' && git -c gc.pruneExpire=$stahp gc; git -c gc.reflogExpire=$stahp reflog expire\n    error: Invalid gc.pruneexpire: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc'\n    fatal: unable to parse 'gc.pruneexpire' from command-line config\n    error: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' for 'gc.reflogexpire' is not a valid timestamp\n    fatal: unable to parse 'gc.reflogexpire' from command-line config\n"},{"id":"364176","messageId":"CAGyf7-F-zs9Xyx623HizpOrv80y3PydReFYw-64w3T7Xfr3CNg@mail.gmail.com","threadId":"49905","inReplyTo":"87efb6ytfj.fsf@evledraar.gmail.com","subject":"Re: Forcing GC to always fail","fromName":"Bryan Turner","fromEmail":"bturner@atlassian.com","sentAt":"2018-11-28T00:00:37Z","receivedAt":"2018-11-28T00:00:52Z","isPatch":false,"sender":{"key":"bturner@atlassian.com","avatar":"https://gravatar.com/avatar/16bcf3167981c1ef7c804e502642366d888a35b0d0b0a4ca01fdc442aa1acb1e?d=mp&s=160"},"body":"On Tue, Nov 27, 2018 at 3:47 PM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n>\n>\n> On Tue, Nov 27 2018, Bryan Turner wrote:\n>\n> >\n> > Is there anything I can set, perhaps some invalid configuration\n> > option/value, that will make \"git gc\" (most important) and \"git\n> > reflog\" (ideal, but less important) fail when they're run in our\n> > repositories? Hopefully at that point customers will reach out to us\n> > for help _before_ they corrupt their repositories.\n>\n> You could fix this and so many other issues by just hanging up a \"Is\n> This Good For The Company?\" banner up in Atlassian offices .\n\nNot sure I understand what this means, or what your goal was in saying\nit. No one inside Atlassian is running these commands. I'm trying to\nhelp save administrators from themselves, which reduces real world\nend-user pain that comes from decisions made without fully\nunderstanding the consequences. It feels like this comment is mocking\nmy earnest desire to help, and my genuine question looking for any\ninsight people more familiar with the code might be able to offer.\nPerhaps I'm just missing the joke, but if it's an Office Space\nreference it feels like it's in pretty poor taste.\n\n>\n> But more seriously:\n>\n>     $ stahp='Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' && git -c gc.pruneExpire=$stahp gc; git -c gc.reflogExpire=$stahp reflog expire\n>     error: Invalid gc.pruneexpire: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc'\n>     fatal: unable to parse 'gc.pruneexpire' from command-line config\n>     error: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' for 'gc.reflogexpire' is not a valid timestamp\n>     fatal: unable to parse 'gc.reflogexpire' from command-line config\n\nThanks for that! It looks like that does block both \"git gc\" and \"git\nreflog expire\" without blocking \"git pack-refs\", \"git repack\" or \"git\nprune\". Fantastic! The fact that it shows the invalid value means it\nmight also be possible to at least provide a useful hint that manual\nGC is not safe.\n\nI appreciate your help, Ævar.\n\nBryan\n"},{"id":"364177","messageId":"87d0qqysay.fsf@evledraar.gmail.com","threadId":"49905","inReplyTo":"CAGyf7-F-zs9Xyx623HizpOrv80y3PydReFYw-64w3T7Xfr3CNg@mail.gmail.com","subject":"Re: Forcing GC to always fail","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2018-11-28T00:11:33Z","receivedAt":"2018-11-28T00:11:39Z","isPatch":false,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Wed, Nov 28 2018, Bryan Turner wrote:\n\n> On Tue, Nov 27, 2018 at 3:47 PM Ævar Arnfjörð Bjarmason\n> <avarab@gmail.com> wrote:\n>>\n>>\n>> On Tue, Nov 27 2018, Bryan Turner wrote:\n>>\n>> >\n>> > Is there anything I can set, perhaps some invalid configuration\n>> > option/value, that will make \"git gc\" (most important) and \"git\n>> > reflog\" (ideal, but less important) fail when they're run in our\n>> > repositories? Hopefully at that point customers will reach out to us\n>> > for help _before_ they corrupt their repositories.\n>>\n>> You could fix this and so many other issues by just hanging up a \"Is\n>> This Good For The Company?\" banner up in Atlassian offices .\n>\n> Not sure I understand what this means, or what your goal was in saying\n> it. No one inside Atlassian is running these commands. I'm trying to\n> help save administrators from themselves, which reduces real world\n> end-user pain that comes from decisions made without fully\n> understanding the consequences. It feels like this comment is mocking\n> my earnest desire to help, and my genuine question looking for any\n> insight people more familiar with the code might be able to offer.\n> Perhaps I'm just missing the joke, but if it's an Office Space\n> reference it feels like it's in pretty poor taste.\n\nI (mis)read 'administrators' as being other people at Atlassian. Yeah\nit's a reference to Office Space. I meaning to poke some fun at the\nsituation of having to defensively configure tools least co-workers run\nthem the wrong way, which I'm sure we've all had to do at some point. I\ndidn't mean any offense by it.\n\n>>\n>> But more seriously:\n>>\n>>     $ stahp='Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' && git -c gc.pruneExpire=$stahp gc; git -c gc.reflogExpire=$stahp reflog expire\n>>     error: Invalid gc.pruneexpire: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc'\n>>     fatal: unable to parse 'gc.pruneexpire' from command-line config\n>>     error: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' for 'gc.reflogexpire' is not a valid timestamp\n>>     fatal: unable to parse 'gc.reflogexpire' from command-line config\n>\n> Thanks for that! It looks like that does block both \"git gc\" and \"git\n> reflog expire\" without blocking \"git pack-refs\", \"git repack\" or \"git\n> prune\". Fantastic! The fact that it shows the invalid value means it\n> might also be possible to at least provide a useful hint that manual\n> GC is not safe.\n>\n> I appreciate your help, Ævar.\n\nNo problem. I was going to add that you can set\ne.g. pack.windowMemory='some.message' to make this go for git-repack\ntoo, but it sounds like you don't want that.\n\nIs there a reason for why BitBucket isn't using 'git-gc'? Some other\nhosting providers use it, and if you don't run it with \"expire now\" or\nsimilarly aggressive non-default values on an active repository it won't\ncorrupt anything.\n"},{"id":"364180","messageId":"CABPp-BFBLKU5jnpr7scXJdj==qNtHJZ8R+LLMRE7qXT47eXXDg@mail.gmail.com","threadId":"49905","inReplyTo":"87d0qqysay.fsf@evledraar.gmail.com","subject":"Re: Forcing GC to always fail","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2018-11-28T01:55:38Z","receivedAt":"2018-11-28T01:55:54Z","isPatch":false,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Tue, Nov 27, 2018 at 4:16 PM Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n>\n> On Wed, Nov 28 2018, Bryan Turner wrote:\n>\n> > On Tue, Nov 27, 2018 at 3:47 PM Ævar Arnfjörð Bjarmason\n> > <avarab@gmail.com> wrote:\n> >>\n> >> On Tue, Nov 27 2018, Bryan Turner wrote:\n> >>\n> >> >\n> >> > Is there anything I can set, perhaps some invalid configuration\n> >> > option/value, that will make \"git gc\" (most important) and \"git\n> >> > reflog\" (ideal, but less important) fail when they're run in our\n> >> > repositories? Hopefully at that point customers will reach out to us\n> >> > for help _before_ they corrupt their repositories.\n> >>\n> >>     $ stahp='Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' && git -c gc.pruneExpire=$stahp gc; git -c gc.reflogExpire=$stahp reflog expire\n> >>     error: Invalid gc.pruneexpire: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc'\n> >>     fatal: unable to parse 'gc.pruneexpire' from command-line config\n> >>     error: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' for 'gc.reflogexpire' is not a valid timestamp\n> >>     fatal: unable to parse 'gc.reflogexpire' from command-line config\n> >\n> > Thanks for that! It looks like that does block both \"git gc\" and \"git\n> > reflog expire\" without blocking \"git pack-refs\", \"git repack\" or \"git\n> > prune\". Fantastic! The fact that it shows the invalid value means it\n> > might also be possible to at least provide a useful hint that manual\n> > GC is not safe.\n> >\n> > I appreciate your help, Ævar.\n>\n> No problem. I was going to add that you can set\n> e.g. pack.windowMemory='some.message' to make this go for git-repack\n> too, but it sounds like you don't want that.\n>\n> Is there a reason for why BitBucket isn't using 'git-gc'? Some other\n> hosting providers use it, and if you don't run it with \"expire now\" or\n> similarly aggressive non-default values on an active repository it won't\n> corrupt anything.\n\n...assuming no other repo has this one as an alternate, which I\nsuspect is the issue at play.  (I wrote an alternate-aware gc script\nyears ago when using Atlassian Stash to try to workaround this issue,\nbut think I only used it for a couple repos and never got around to\ndeploying it in prod for continuous use, probably worried I had missed\na corner case.  Had meant to, but at some point the powers that be\ndecided to push us toward a different repository manager tool, and\nI've long since forgotten most details.)\n"},{"id":"364181","messageId":"CAGyf7-FwGRVtFYbOGW8DmY9F-cgun0n5K-ZWBjXCR=wvWh=8dQ@mail.gmail.com","threadId":"49905","inReplyTo":"CABPp-BFBLKU5jnpr7scXJdj==qNtHJZ8R+LLMRE7qXT47eXXDg@mail.gmail.com","subject":"Re: Forcing GC to always fail","fromName":"Bryan Turner","fromEmail":"bturner@atlassian.com","sentAt":"2018-11-28T02:26:07Z","receivedAt":"2018-11-28T02:26:21Z","isPatch":false,"sender":{"key":"bturner@atlassian.com","avatar":"https://gravatar.com/avatar/16bcf3167981c1ef7c804e502642366d888a35b0d0b0a4ca01fdc442aa1acb1e?d=mp&s=160"},"body":"On Tue, Nov 27, 2018 at 5:55 PM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Tue, Nov 27, 2018 at 4:16 PM Ævar Arnfjörð Bjarmason\n> <avarab@gmail.com> wrote:\n> >\n> > On Wed, Nov 28 2018, Bryan Turner wrote:\n> >\n> > > On Tue, Nov 27, 2018 at 3:47 PM Ævar Arnfjörð Bjarmason\n> > > <avarab@gmail.com> wrote:\n> > >>\n> > >> On Tue, Nov 27 2018, Bryan Turner wrote:\n> > >>\n> > >> >\n> > >> > Is there anything I can set, perhaps some invalid configuration\n> > >> > option/value, that will make \"git gc\" (most important) and \"git\n> > >> > reflog\" (ideal, but less important) fail when they're run in our\n> > >> > repositories? Hopefully at that point customers will reach out to us\n> > >> > for help _before_ they corrupt their repositories.\n> > >>\n> > >>     $ stahp='Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' && git -c gc.pruneExpire=$stahp gc; git -c gc.reflogExpire=$stahp reflog expire\n> > >>     error: Invalid gc.pruneexpire: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc'\n> > >>     fatal: unable to parse 'gc.pruneexpire' from command-line config\n> > >>     error: 'Bryan.Turner.will.hunt.you.down.if.you.manually.run.gc' for 'gc.reflogexpire' is not a valid timestamp\n> > >>     fatal: unable to parse 'gc.reflogexpire' from command-line config\n> > >\n> > > Thanks for that! It looks like that does block both \"git gc\" and \"git\n> > > reflog expire\" without blocking \"git pack-refs\", \"git repack\" or \"git\n> > > prune\". Fantastic! The fact that it shows the invalid value means it\n> > > might also be possible to at least provide a useful hint that manual\n> > > GC is not safe.\n> > >\n> > > I appreciate your help, Ævar.\n> >\n> > No problem. I was going to add that you can set\n> > e.g. pack.windowMemory='some.message' to make this go for git-repack\n> > too, but it sounds like you don't want that.\n> >\n> > Is there a reason for why BitBucket isn't using 'git-gc'? Some other\n> > hosting providers use it, and if you don't run it with \"expire now\" or\n> > similarly aggressive non-default values on an active repository it won't\n> > corrupt anything.\n\nWe did use \"git gc\" (sans options; its configuration was applied via\n\"config\") for several years, but there were some rough edges.\n\nThe biggest one was that \"git gc\" has a canned set of steps it runs\nthat can't be disabled, even when they add no value (or are actively\ndetrimental).\n\nFor us, the biggest issue was \"git gc\"'s insistence on trying to run\n\"git reflog expire\". That triggers locking behaviors that resulted in\nvery frequent GC failures--and the only reflogs Bitbucket Server (by\ndefault) creates are all configured to never ex[ire or be pruned, so\nthe effort is all wasted anyway.\n\nCounting objects: 3, done.\nDelta compression using up to 8 threads.\nCompressing objects: 100% (2/2), done.\nWriting objects: 100% (3/3), 270 bytes | 0 bytes/s, done.\nTotal 3 (delta 1), reused 0 (delta 0)\nremote: error: cannot lock ref 'stash-refs/pull-requests/13996/merge':\nref 'stash-refs/pull-requests/13996/merge' is at\n2ec6a74b453d76f7a5247baa9f396361027ffdf but expected\n1678f303202010c6d7e6201226df08dc8fc49ae3\nremote: error: cannot lock ref 'stash-refs/pull-requests/13996/to':\nref 'stash-refs/pull-requests/13996/to' is at\nbd32d53e4fe63b15be029085f1b6d795d526adbc but expected\nf55ec06e89a11b8bdbcd97680a900361307d28c4\nremote: error: cannot lock ref 'stash-refs/pull-requests/14006/merge':\nref 'stash-refs/pull-requests/14006/merge' is at\n1cc907e2a7082033d70a164f222d3cce17a453a9 but expected\nae057003d7ed7d096b5b952191d784113f25b982\nremote: error: cannot lock ref 'stash-refs/pull-requests/14006/to':\nref 'stash-refs/pull-requests/14006/to' is at\nbd32d53e4fe63b15be029085f1b6d795d526adbc but expected\nf55ec06e89a11b8bdbcd97680a900361307d28c4\nremote: error: cannot lock ref 'stash-refs/pull-requests/14043/merge':\nref 'stash-refs/pull-requests/14043/merge' is at\na2e510b1b2b583b273f6d6d28e13151619e8d143 but expected\n7735a5bde21815d307c68244e8fd2d67a09d5a39\nremote: error: cannot lock ref 'stash-refs/pull-requests/14043/to':\nref 'stash-refs/pull-requests/14043/to' is at\nbd32d53e4fe63b15be029085f1b6d795d526adbc but expected\nf55ec06e89a11b8bdbcd97680a900361307d28c4\nremote: error: cannot lock ref 'stash-refs/pull-requests/14047/merge':\nref 'stash-refs/pull-requests/14047/merge' is at\nbd4f0e9bcbed34fd9befa65763f5aee6c9ebd8ce but expected\n649dea948e8e6b54506615e5d61c6779c242d5af\nremote: error: cannot lock ref 'stash-refs/pull-requests/14047/to':\nref 'stash-refs/pull-requests/14047/to' is at\nbd32d53e4fe63b15be029085f1b6d795d526adbc but expected\nf55ec06e89a11b8bdbcd97680a900361307d28c4\nremote: error: failed to run reflog\nTo https://...\n   f55ec06..bd32d53  master -> master\n\n(Note: That example was from when \"git gc --auto\" was running attached\nto a push, because auto-detach doesn't always detach, but our explicit\n\"git gc\" processing would fail with the same \"cannot lock ref\"\nmessages.)\n\nThe worktree and rerere cleanup \"git gc\" does is also unnecessary\noverhead, but was less of a concern because it wouldn't make GC\n_fail_.\n\nAnother issue with the canned steps for \"git gc\" is that it means it\ncan't be used to do specific types of cleanup on a different schedule\nfrom others. For example, we use \"git pack-refs\" directly to\nfrequently pack the refs in our repositories, separate from \"git\nrepack\" + \"git prune\" for repacking objects. That allows us to keep\nour refs packed better without incurring the full overhead of\nconstantly building new packs.\n\nIt may be possible to make \"git gc\" run more targeted operations, but\neven looking through the C code I couldn't find a way.\n\n>\n> ...assuming no other repo has this one as an alternate, which I\n> suspect is the issue at play.  (I wrote an alternate-aware gc script\n> years ago when using Atlassian Stash to try to workaround this issue,\n> but think I only used it for a couple repos and never got around to\n> deploying it in prod for continuous use, probably worried I had missed\n> a corner case.  Had meant to, but at some point the powers that be\n> decided to push us toward a different repository manager tool, and\n> I've long since forgotten most details.)\n\n\"git gc\" should be perfectly safe to run in a Bitbucket Server\nrepository which has forks; we \"simply\" configure it to never prune\n(and that's applied in \"config\", so even if an administrator runs \"git\ngc\" manually, _as long as they don't provide explicit arguments to the\ncontrary_, it still won't prune). When Git 2.10 or newer is installed\non the server we use \"git repack --keep-unreachable\" to prevent\nwriting unreachable objects as loose, and we skip running \"git prune\"\nat all. For older versions of Git, we detect where the \"objects/17\"\nheuristic would still want to run GC immediately after GC has already\nrun and we stream the loose object IDs to \"git pack-objects\" to write\na \"garbage\" pack, and then run \"git prune-packed\" to remove all the\nloose objects.\n\nIt's on the backlog to actually start pruning again, even in forked\nrepositories, but there are some other design changes we need to make\nfirst before we can ship that. (Not to mention the enormous amount of\ntesting we need to do to ensure it's safe...)\n\nBryan\n"},{"id":"364277","messageId":"xmqqtvk0r87v.fsf@gitster-ct.c.googlers.com","threadId":"49905","inReplyTo":"CAGyf7-FwGRVtFYbOGW8DmY9F-cgun0n5K-ZWBjXCR=wvWh=8dQ@mail.gmail.com","subject":"Re: Forcing GC to always fail","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-11-29T01:19:32Z","receivedAt":"2018-11-29T01:19:41Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Bryan Turner <bturner@atlassian.com> writes:\n\n> For us, the biggest issue was \"git gc\"'s insistence on trying to run\n> \"git reflog expire\". That triggers locking behaviors that resulted in\n> very frequent GC failures--and the only reflogs Bitbucket Server (by\n> default) creates are all configured to never ex[ire or be pruned, so\n> the effort is all wasted anyway.\n\nDetecting that the expiry threshold is set to \"never\" before\nspending cycles and seeks to sift between old and new and not\nspawning the expire command?\n\nThis seems like an obvious low-hanging fruit to me.\n\n> Another issue with the canned steps for \"git gc\" is that it means it\n> can't be used to do specific types of cleanup on a different schedule\n> from others. For example, we use \"git pack-refs\" directly to\n> frequently pack the refs in our repositories, separate from \"git\n> repack\" + \"git prune\" for repacking objects. That allows us to keep\n> our refs packed better without incurring the full overhead of\n> constantly building new packs.\n\nI am not sure if the above is an example of things that are good.\nWe keep individual \"pack-refs\" and \"rev-list | pack-objects\"\navailable exactly to give finer grained control to repository\nowners, and \"gc\" is meant to be one-size-fits-all easy to run\nby end users.  Adding options to \"git gc --no-reflog --pack-refs\"\nto complicate it sounds somewhat backwards.\n"},{"id":"364280","messageId":"CAGyf7-FVxHak7zN7jpEe4xu7mWn4T7H4szvsLqNGM1UH_0_5eg@mail.gmail.com","threadId":"49905","inReplyTo":"xmqqtvk0r87v.fsf@gitster-ct.c.googlers.com","subject":"Re: Forcing GC to always fail","fromName":"Bryan Turner","fromEmail":"bturner@atlassian.com","sentAt":"2018-11-29T02:51:28Z","receivedAt":"2018-11-29T02:51:42Z","isPatch":false,"sender":{"key":"bturner@atlassian.com","avatar":"https://gravatar.com/avatar/16bcf3167981c1ef7c804e502642366d888a35b0d0b0a4ca01fdc442aa1acb1e?d=mp&s=160"},"body":"On Wed, Nov 28, 2018 at 5:19 PM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> > Another issue with the canned steps for \"git gc\" is that it means it\n> > can't be used to do specific types of cleanup on a different schedule\n> > from others. For example, we use \"git pack-refs\" directly to\n> > frequently pack the refs in our repositories, separate from \"git\n> > repack\" + \"git prune\" for repacking objects. That allows us to keep\n> > our refs packed better without incurring the full overhead of\n> > constantly building new packs.\n>\n> I am not sure if the above is an example of things that are good.\n> We keep individual \"pack-refs\" and \"rev-list | pack-objects\"\n> available exactly to give finer grained control to repository\n> owners, and \"gc\" is meant to be one-size-fits-all easy to run\n> by end users.  Adding options to \"git gc --no-reflog --pack-refs\"\n> to complicate it sounds somewhat backwards.\n\nI think we're in agreement there. I was citing the fact that GC isn't\ngood for targeted maintenance as a reason why we use \"pack-refs\"\ndirectly, which sounds like what you're saying as well. I don't think\nthat inflating GC with options to skip specific steps is a good idea,\nbut that does mean that, for those targeted operations, we need to use\nthe lower-level commands directly, rather than GC.\n\nBryan\n"}]}