{"thread":{"id":"46057","subject":"[RFC/PATCH] WIP: add deprecation & experimental process/interface","startedAt":"2017-05-27T11:10:56Z","lastAt":"2017-05-30T00:57:06Z","messageCount":8,"participants":["Ævar Arnfjörð Bjarmason","Junio C Hamano","Duy Nguyen","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"320867","messageId":"20170527111032.30897-1-avarab@gmail.com","threadId":"46057","inReplyTo":null,"subject":"[RFC/PATCH] WIP: add deprecation & experimental process/interface","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2017-05-27T11:10:32Z","receivedAt":"2017-05-27T11:10:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"This is the WIP start of a deprecation & experimental interface to\ngit. The goal is to formalize the workflow around deprecating\nfeatures, or around introducing new experimental features.\n\nThis is much more idea than code at the moment, but included is an\nexample showing how :/ might be deprecated[1] (let's not discuss /if/\nwe should do that here, this is just an example).\n\nThe plan, subject to RFC feedback is to:\n\n * Add a new config variable `core.version`. E.g. `core.version =\n   2.14.0` With this the user can specify that they'd like\n   new/experimental features introduced in that version (and below),\n   as well as immediately getting new deprecations added in that\n   version as errors.\n\n   This is similar to perl's \"use v<VERSION>\".\n\n * Add a deprecated() function to to mark deprecated features.\n\n   This will emit an arbitrary warning about the use of a feature once\n   per-process (via static variable). The call needs to declare in\n   what version the deprecation was added, and in what version it\n   should start warning/dying.\n\n   This sets up a well-defined path to deprecation, and allows users &\n   packagers to plan upgrades, and e.g. set `core.version` to N\n   versions in the future to see what would start warning/dying in\n   those releases.\n\n * TODO: Add an experimental() function to mark experimental features.\n\n   Depending on parameters & config an experimental feature might be\n   off by default unless `core.use_experimental_<NAME> = true`, or it\n   might warn unless that config is set.\n\n * TODO: Add new documentation (gitdeprecated.txt /\n   gitexperimental.txt) aiming to exhaustively list deprecated &\n   experimental features, and when it's planned that each of those\n   will be fully removed or start/stop warning when used.\n\n * TODO: Subject to RFC feedback add a gitpolicy.txt similar to\n   \"perlpolicy\" (mainly\n   http://perldoc.perl.org/perlpolicy.html#BACKWARD-COMPATIBILITY-AND-DEPRECATION)\n   describing how this deprecation/experimental process works. See\n   also [2].\n\n1. https://public-inbox.org/git/CACBZZX6K7ppVB0qYah76_+pjTKjsco3rHT0xRyKtF2H1dS4k_w@mail.gmail.com/\n2. https://public-inbox.org/git/CACBZZX5oVKGZLKgS4aF0=XXtHO67ynS+zxSopDN9ErJGzV9n-A@mail.gmail.com/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n GIT-VERSION-GEN |  1 +\n Makefile        |  5 +++++\n deprecate.c     | 34 ++++++++++++++++++++++++++++++++++\n deprecate.h     |  7 +++++++\n sha1_name.c     |  3 +++\n 5 files changed, 50 insertions(+)\n create mode 100644 deprecate.c\n create mode 100644 deprecate.h\n\ndiff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN\nindex 4f94fc7574..c76bbedf86 100755\n--- a/GIT-VERSION-GEN\n+++ b/GIT-VERSION-GEN\n@@ -37,4 +37,5 @@ fi\n test \"$VN\" = \"$VC\" || {\n \techo >&2 \"GIT_VERSION = $VN\"\n \techo \"GIT_VERSION = $VN\" >$GVF\n+\techo \"GIT_VERSION_INT = $(echo $VN | sed -e 's/^\\([0-9]*\\)\\.\\([0-9]*\\)\\..*/\\1\\2/')\" >>$GVF\n }\ndiff --git a/Makefile b/Makefile\nindex e35542e631..1614b2b067 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -739,6 +739,7 @@ LIB_OBJS += csum-file.o\n LIB_OBJS += ctype.o\n LIB_OBJS += date.o\n LIB_OBJS += decorate.o\n+LIB_OBJS += deprecate.o\n LIB_OBJS += diffcore-break.o\n LIB_OBJS += diffcore-delta.o\n LIB_OBJS += diffcore-order.o\n@@ -1793,6 +1794,10 @@ version.sp version.s version.o: EXTRA_CPPFLAGS = \\\n \t'-DGIT_VERSION=\"$(GIT_VERSION)\"' \\\n \t'-DGIT_USER_AGENT=$(GIT_USER_AGENT_CQ_SQ)'\n \n+deprecate.sp deprecate.s deprecate.o: GIT-VERSION-FILE\n+deprecate.sp deprecate.s deprecate.o: EXTRA_CPPFLAGS = \\\n+\t'-DGIT_VERSION_INT=\"$(GIT_VERSION_INT)\"'\n+\n $(BUILT_INS): git$X\n \t$(QUIET_BUILT_IN)$(RM) $@ && \\\n \tln $< $@ 2>/dev/null || \\\ndiff --git a/deprecate.c b/deprecate.c\nnew file mode 100644\nindex 0000000000..035a1adea1\n--- /dev/null\n+++ b/deprecate.c\n@@ -0,0 +1,34 @@\n+#include \"cache.h\"\n+#include \"deprecate.h\"\n+\n+void deprecate(int *state, const char *message,\n+\t\tint dep_at, int warn_at, int die_at, int remove_at)\n+{\n+\t/*\n+\t * If we're going to warn let's do it once per-process, not\n+\t * spew lots of warnings in a loop.\n+\t */\n+\tif (*state == 1)\n+\t\treturn;\n+\telse\n+\t\t*state = 1;\n+\n+\tif (remove_at >= GIT_VERSION_INT) {\n+\t\tdie(\"BUG: The '%s' deprecation should be removed in this release!\");\n+\t} else if (die_at >= GIT_VERSION_INT) {\n+\t\tdie(_(\"Deprecation error: %s\"), message);\n+\t} else if (warn_at >= GIT_VERSION_INT) {\n+\t\twarning(_(\"Deprecation warning: %s\"), message);\n+\t} else if (1) {\n+\t\t/*\n+\t\t * TODO: Instead of `if 1` we should check a\n+\t\t * core.version variable here.\n+\t\t *\n+\t\t * I.e. if set to core.version=2.13 the user is opting\n+\t\t * in to get deprecations set at dep_at right away,\n+\t\t * and also perhaps experimental features from a\n+\t\t * sister experimental() interface.\n+\t\t */\n+\t\tdie(_(\"Early bird deprecation error: %s\"), message);\n+\t}\n+}\ndiff --git a/deprecate.h b/deprecate.h\nnew file mode 100644\nindex 0000000000..7d565ef0ed\n--- /dev/null\n+++ b/deprecate.h\n@@ -0,0 +1,7 @@\n+#ifndef DEPRECATE_H\n+#define DEPRECATE_H\n+\n+extern void deprecate(int *state, const char *message,\n+\t\t      int dep_at, int warn_at, int die_at, int remove_at);\n+\n+#endif\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 35c1e2a9e3..b381c39bd4 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -1505,6 +1505,7 @@ static int get_sha1_with_context_1(const char *name,\n \tint namelen = strlen(name);\n \tconst char *cp;\n \tint only_to_die = flags & GET_SHA1_ONLY_TO_DIE;\n+\tstatic int dep_state = 0;\n \n \tif (only_to_die)\n \t\tflags |= GET_SHA1_QUIETLY;\n@@ -1527,6 +1528,8 @@ static int get_sha1_with_context_1(const char *name,\n \t\tchar *new_path = NULL;\n \t\tint pos;\n \t\tif (!only_to_die && namelen > 2 && name[1] == '/') {\n+\t\t\tdeprecate(&dep_state, _(\":/<text> is deprecated. Use ^{/<text>} instead!\"),\n+\t\t\t\t  213, 214, 215, 216);\n \t\t\tstruct commit_list *list = NULL;\n \n \t\t\tfor_each_ref(handle_one_ref, &list);\n-- \n2.13.0.303.g4ebf302169\n\n"},{"id":"320878","messageId":"xmqqy3thaie0.fsf@gitster.mtv.corp.google.com","threadId":"46057","inReplyTo":"20170527111032.30897-1-avarab@gmail.com","subject":"Re: [RFC/PATCH] WIP: add deprecation & experimental process/interface","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-28T01:18:31Z","receivedAt":"2017-05-28T01:18:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> The plan, subject to RFC feedback is to:\n>\n>  * Add a new config variable `core.version`. E.g. `core.version =\n>    2.14.0` With this the user can specify that they'd like\n>    new/experimental features introduced in that version (and below),\n>    as well as immediately getting new deprecations added in that\n>    version as errors.\n>\n>    This is similar to perl's \"use v<VERSION>\".\n\nAs long as this does not require very new version like v3.0.0 of Git\nto pretend as if the user is still running an ancient v2.14.0, it is\na sensible proposal, I would think.\n\n>  * Add a deprecated() function to to mark deprecated features.\n>  * TODO: Add an experimental() function to mark experimental features.\n\nHaving burned by bitter experience during v1.6.0 transition, I do\nwelcome an attempt to make it easier to communicate deprecation\nplans to end-users.\n"},{"id":"320915","messageId":"xmqq4lw4a2pd.fsf@gitster.mtv.corp.google.com","threadId":"46057","inReplyTo":"20170527111032.30897-1-avarab@gmail.com","subject":"Re: [RFC/PATCH] WIP: add deprecation & experimental process/interface","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-29T01:09:34Z","receivedAt":"2017-05-29T01:09:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN\n> index 4f94fc7574..c76bbedf86 100755\n> --- a/GIT-VERSION-GEN\n> +++ b/GIT-VERSION-GEN\n> @@ -37,4 +37,5 @@ fi\n>  test \"$VN\" = \"$VC\" || {\n>  \techo >&2 \"GIT_VERSION = $VN\"\n>  \techo \"GIT_VERSION = $VN\" >$GVF\n> +\techo \"GIT_VERSION_INT = $(echo $VN | sed -e 's/^\\([0-9]*\\)\\.\\([0-9]*\\)\\..*/\\1\\2/')\" >>$GVF\n>  }\n\nUnlike Perl's v1.2.3.4 notation, this forces us worry when we go\nfrom v2.99.0 to v2.100.0 and eventually to v3.0, no?\n\n> +\t} else if (1) {\n> +\t\t/*\n> +\t\t * TODO: Instead of `if 1` we should check a\n> +\t\t * core.version variable here.\n> +\t\t *\n> +\t\t * I.e. if set to core.version=2.13 the user is opting\n> +\t\t * in to get deprecations set at dep_at right away,\n> +\t\t * and also perhaps experimental features from a\n> +\t\t * sister experimental() interface.\n> +\t\t */\n\nThis essentially forces us to always read _some_ configuration.\nSome commands are meant to work outside repositories, so those who\nwant to affect them needs to write core.version in their global\nconfiguration.  Some low-level plumbing commands may want to do\nabsolute minimum without configurablity.\n\nI am not saying that it is absolutely a bad design decision to force\nus to read some configuration (yet); it's just that it is something\nthat we have to keep in mind and always think about the\nramifications of.\n\n> +\t\tdie(_(\"Early bird deprecation error: %s\"), message);\n> +\t}\n> +}\n"},{"id":"320938","messageId":"CACsJy8CUpHNDfvN+P7=Jub4+Z281rzExFV9x3_hdVKw6ORUSqQ@mail.gmail.com","threadId":"46057","inReplyTo":"20170527111032.30897-1-avarab@gmail.com","subject":"Re: [RFC/PATCH] WIP: add deprecation & experimental process/interface","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2017-05-29T10:23:09Z","receivedAt":"2017-05-29T10:23:50Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, May 27, 2017 at 6:10 PM, Ævar Arnfjörð Bjarmason\n<avarab@gmail.com> wrote:\n> This is the WIP start of a deprecation & experimental interface to\n> git. The goal is to formalize the workflow around deprecating\n> features, or around introducing new experimental features.\n>\n> This is much more idea than code at the moment, but included is an\n> example showing how :/ might be deprecated[1] (let's not discuss /if/\n> we should do that here, this is just an example).\n>\n> The plan, subject to RFC feedback is to:\n>\n>  * Add a new config variable `core.version`. E.g. `core.version =\n>    2.14.0` With this the user can specify that they'd like\n>    new/experimental features introduced in that version (and below),\n>    as well as immediately getting new deprecations added in that\n>    version as errors.\n\nWe have extensions.* for this purpose (or close to this purpose). I\nthink it's more flexible to go with extensions.* instead of a single\n\"core.version\". extensions.* are non-optional though (if a git binary\ndoes not understand it, the repo can't be accessed). So it's more\nabout fundamental experiments (like sha256 transition). I'm guessing\nwe can have a \"soft\" extensions (warn if not understand, instead of\ndie), like what we have in $GIT_DIR/index.\n\nDeprecation via extension.* though may be unintuitive. But I think\nsomething along that line (e.g. deprecation.*) might work.\n-- \nDuy\n"},{"id":"320944","messageId":"CACBZZX70Ak2AEcDg_fRmA_XyM7dUuyZD4jVxQAZn1yFbXYSWZQ@mail.gmail.com","threadId":"46057","inReplyTo":"xmqq4lw4a2pd.fsf@gitster.mtv.corp.google.com","subject":"Re: [RFC/PATCH] WIP: add deprecation & experimental process/interface","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2017-05-29T11:11:06Z","receivedAt":"2017-05-29T11:11:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Mon, May 29, 2017 at 3:09 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN\n>> index 4f94fc7574..c76bbedf86 100755\n>> --- a/GIT-VERSION-GEN\n>> +++ b/GIT-VERSION-GEN\n>> @@ -37,4 +37,5 @@ fi\n>>  test \"$VN\" = \"$VC\" || {\n>>       echo >&2 \"GIT_VERSION = $VN\"\n>>       echo \"GIT_VERSION = $VN\" >$GVF\n>> +     echo \"GIT_VERSION_INT = $(echo $VN | sed -e 's/^\\([0-9]*\\)\\.\\([0-9]*\\)\\..*/\\1\\2/')\" >>$GVF\n>>  }\n>\n> Unlike Perl's v1.2.3.4 notation, this forces us worry when we go\n> from v2.99.0 to v2.100.0 and eventually to v3.0, no?\n\nYeah it's just a dirty hack to get that WIP working, although at this\nrate it'll take us ~20 years to reach 3.0 if we go up to 99, and this\nwould purely be internal to the codebase.\n\nI think it make sense for core.version to be e.g. 2.13, and parsed\ninternally to 2013, then we have room to go to 2.999 or ~200 years at\nthe current dev pace.\n\n>> +     } else if (1) {\n>> +             /*\n>> +              * TODO: Instead of `if 1` we should check a\n>> +              * core.version variable here.\n>> +              *\n>> +              * I.e. if set to core.version=2.13 the user is opting\n>> +              * in to get deprecations set at dep_at right away,\n>> +              * and also perhaps experimental features from a\n>> +              * sister experimental() interface.\n>> +              */\n>\n> This essentially forces us to always read _some_ configuration.\n> Some commands are meant to work outside repositories, so those who\n> want to affect them needs to write core.version in their global\n> configuration.  Some low-level plumbing commands may want to do\n> absolute minimum without configurablity.\n\nDoesn't making sure that those codepaths just don't call\nexperimental() or deprecate() solve that issue? Presumably if\nsomething is such low-level plumbing that it can't call deprecate() or\nexperimental() we'd just create a new incompatible command under a\ndifferent name if we'd like to change it.\n\nOr are there some edge cases I'm missing?\n\n> I am not saying that it is absolutely a bad design decision to force\n> us to read some configuration (yet); it's just that it is something\n> that we have to keep in mind and always think about the\n> ramifications of.\n\n*Nod*. It's definitely a bit of a chicken & egg problem, especially if\nwe ever wanted to have experimental or deprecated config-parsing\ndirectives, but for most parts of the codebase it should be fine.\n\n>> +             die(_(\"Early bird deprecation error: %s\"), message);\n>> +     }\n>> +}\n"},{"id":"320947","messageId":"CACBZZX5SbYo5fVPtK6LW1FF96nR5591RHHC-5wdjW-fmg1R0EQ@mail.gmail.com","threadId":"46057","inReplyTo":"CACsJy8CUpHNDfvN+P7=Jub4+Z281rzExFV9x3_hdVKw6ORUSqQ@mail.gmail.com","subject":"Re: [RFC/PATCH] WIP: add deprecation & experimental process/interface","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2017-05-29T11:20:02Z","receivedAt":"2017-05-29T11:20:35Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Mon, May 29, 2017 at 12:23 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Sat, May 27, 2017 at 6:10 PM, Ævar Arnfjörð Bjarmason\n> <avarab@gmail.com> wrote:\n>> This is the WIP start of a deprecation & experimental interface to\n>> git. The goal is to formalize the workflow around deprecating\n>> features, or around introducing new experimental features.\n>>\n>> This is much more idea than code at the moment, but included is an\n>> example showing how :/ might be deprecated[1] (let's not discuss /if/\n>> we should do that here, this is just an example).\n>>\n>> The plan, subject to RFC feedback is to:\n>>\n>>  * Add a new config variable `core.version`. E.g. `core.version =\n>>    2.14.0` With this the user can specify that they'd like\n>>    new/experimental features introduced in that version (and below),\n>>    as well as immediately getting new deprecations added in that\n>>    version as errors.\n>\n> We have extensions.* for this purpose (or close to this purpose). I\n\nFrom reading repository-version.txt it seems unrelated to what I'd\nlike to do. I.e. there you'd like to introduce a hard breakage and\nit's already documented that if you encounter some extensions.* keys\nyou don't understand you *must not* proceed.\n\nWhereas for this you'd like to e.g. turn on some experimental feature\nin 2.16, but if you're running a 2.14 git you'd like it to just ignore\nthat config key it doesn't know about instead of git breaking.\n\n> think it's more flexible to go with extensions.* instead of a single\n> \"core.version\". extensions.* are non-optional though (if a git binary\n\nI'd like there to be both, and the experimental() function would\ndefine this on the source level, i.e. the call would include a\ncorresponding version where it was introduced, and a config key to\ntoggle it individually.\n\nThe reason to have both is that you can just upgrade git and say \"I'm\nnot concerned about backcompat here, please give me all the latest\nfeatures\" without having to exhaustively hunt down the list of things\nwe're shipping with that version.\n\n> does not understand it, the repo can't be accessed). So it's more\n> about fundamental experiments (like sha256 transition). I'm guessing\n> we can have a \"soft\" extensions (warn if not understand, instead of\n> die), like what we have in $GIT_DIR/index.\n\n> Deprecation via extension.* though may be unintuitive. But I think\n> something along that line (e.g. deprecation.*) might work.\n"},{"id":"320957","messageId":"20170529143832.65hjawks74co6tqe@sigill.intra.peff.net","threadId":"46057","inReplyTo":"CACBZZX5SbYo5fVPtK6LW1FF96nR5591RHHC-5wdjW-fmg1R0EQ@mail.gmail.com","subject":"Re: [RFC/PATCH] WIP: add deprecation & experimental process/interface","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-05-29T14:38:33Z","receivedAt":"2017-05-29T14:38:42Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, May 29, 2017 at 01:20:02PM +0200, Ævar Arnfjörð Bjarmason wrote:\n\n> >>  * Add a new config variable `core.version`. E.g. `core.version =\n> >>    2.14.0` With this the user can specify that they'd like\n> >>    new/experimental features introduced in that version (and below),\n> >>    as well as immediately getting new deprecations added in that\n> >>    version as errors.\n> >\n> > We have extensions.* for this purpose (or close to this purpose). I\n> \n> From reading repository-version.txt it seems unrelated to what I'd\n> like to do. I.e. there you'd like to introduce a hard breakage and\n> it's already documented that if you encounter some extensions.* keys\n> you don't understand you *must not* proceed.\n> \n> Whereas for this you'd like to e.g. turn on some experimental feature\n> in 2.16, but if you're running a 2.14 git you'd like it to just ignore\n> that config key it doesn't know about instead of git breaking.\n\nRight. repostoryformatversion (and extensions) is about the on-disk\nformat of a repo. If I understand correctly, this is about the user\nspecifying their preferred behaviors. Which is totally orthogonal.\n\nThe former must be set in the repo-level .git/config, and would\ngenerally be set by Git itself when it writes a repo using that feature\n(e.g., upcoming ref backends).  But this new thing would likely be set\nin the ~/.gitconfig explicitly by the user, when they want to change the\nbehavior profile.\n\nFor that reason, I'd suggest using a name that is a little different\nfrom \"core.version\", since it's easily missed up with\n\"core.repositoryformatversion\". But that's a minor detail.\n\n-Peff\n"},{"id":"320979","messageId":"xmqqwp8zduwd.fsf@gitster.mtv.corp.google.com","threadId":"46057","inReplyTo":"CACsJy8CUpHNDfvN+P7=Jub4+Z281rzExFV9x3_hdVKw6ORUSqQ@mail.gmail.com","subject":"Re: [RFC/PATCH] WIP: add deprecation & experimental process/interface","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-30T00:56:50Z","receivedAt":"2017-05-30T00:57:06Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Duy Nguyen <pclouds@gmail.com> writes:\n\n>>  * Add a new config variable `core.version`. E.g. `core.version =\n>>    2.14.0` With this the user can specify that they'd like\n>>    new/experimental features introduced in that version (and below),\n>>    as well as immediately getting new deprecations added in that\n>>    version as errors.\n>\n> We have extensions.* for this purpose (or close to this purpose). I\n> think it's more flexible to go with extensions.* instead of a single\n> \"core.version\". extensions.* are non-optional though (if a git binary\n> does not understand it, the repo can't be accessed). So it's more\n> about fundamental experiments (like sha256 transition). I'm guessing\n> we can have a \"soft\" extensions (warn if not understand, instead of\n> die), like what we have in $GIT_DIR/index.\n>\n> Deprecation via extension.* though may be unintuitive. But I think\n> something along that line (e.g. deprecation.*) might work.\n\nThe difference/orthogonal-ness of what Ævar wants to do and what the\nextension mechanism wants to do has been covered by others correctly\nso I won't repeat.  But I do agree with you that \"run at this\nversion level\" is probably less useful than a la carte \"I want to\nenroll in this and that experiment but not the other one\".\n\nI also agree with Peff that we should name it as distinctively as\nthe names used by extensions mechaism---we must strongly discourage\nthe latter from being futzed by the end users, while this opt-in\nthing is very much open to them.\n\n"}]}