Subject: Re: [PATCH] BreakingChanges: early adopter option

From: Junio C Hamano <[email-masked]>
Date: Fri, 20 Sep 2024 14:33:52 -0700

Junio C Hamano <[email-masked]> writes:

> Discussing the desire to make breaking changes, declaring that
> breaking changes are made at a certain version boundary, and
> recording these decisions in this document, are necessary but not
> sufficient.  We need to make sure that we can implement, test, and
> deploy such impactful changes.
>
> Formalize the mechanism based on the `feature.*` configuration
> variable to allow early adopters to opt into the breaking change in
> a version of Git before the planned version for the breaking change.
>
> Signed-off-by: Junio C Hamano <[email-masked]>
> ---
>
>  * Before I forget.  I'll find time to rewrite the "we no longer
>    honor core.preferSymlinkRefs" topic to follow this new guideline
>    when we see a rough concensus that both the procedure outlined
>    here and the idea to remove core.preferSymlinkRefs are good.

So I was looking at my other topic that prepares to deprecate and
remove core.preferSymlinkRefs configuration (i.e. we would still be
able to work with a repository whose HEAD is a symbolic link
pointing at refs/heads/main, but we would never be able to use a
symbolic link to represent a symref ourselves, so "git checkout
next" would replace HEAD with a textual symref, a file that has a
single line "ref: refs/heads/next" in it), to see what it involves
to allow early adopters to experience Git 3.0 features/removals
before it actually happens.

Switching behaviour at runtime with feature.git3 should work well,
and we can also add tests that checks the new behaviour by doing
"test_config feature.git3 true".

One trouble is what to do with "git $cmd --help" for those who
choose to be early adopters.

For "git $cmd --help" and "git -c feature.git3=true $cmd --help" to
show documents describing the behaviour before and after Git 3.0
version boundary, we'd need to install separate set of documents and
switch between them at runtime in builtin/help.c:setup_man_path()
and friends [*].  If we are going to have such a transition often
(e.g., more frequently than every few years), laying such an
infrastructure would certainly be worth it, but an obvious
alternative is to say that, even though the toggling of behaviour
can be done at runtime to allow the early adopters from going back
to the current behaviour to make their life less risky, the contents
of the manual pages are defined at the compile time.

If we are willing to burden early adopters a bit more, we could make
it a build-time option.  With "make GIT_BUILD_FOR_GIT3=YesPlease",
binaries will be built for all the then-current Git 3.0 features and
documentation under development.  It certainly is a simpler-to-build
option that is easier for us, but I am not sure if that is acceptable
by those who volunteer to test the upcoming big version.

One thing to note is that depending on the nature of a change, once
you start using a feature only available in a newer version of Git
in your repository, the resulting repository may not be understood
by an older version of Git (imagine you started using index v4---now
you are locked out of your repository if you want to go back to a
version of Git before 1.7.11).  So in that sense, it might be a
disservice to promise that an early adopter can experience the
future with feature.git3=on and then can safely go back to the
current world by flipping it off, and we might be better off to
control this with a single big red build-time switch.

Opinions?

[Footnote]

 * Alternatively we could tweak system_path() to hack the value we
   return when asked about GIT_INFO_PATH, GIT_MAN_PATH, and
   GIT_HTML_PATH, but I somehow feel dirty just for mentioning such
   an implementation possibility X-<.