diff mbox series

BreakingChanges: early adopter option

Message ID xmqq7cb77810.fsf@gitster.g (mailing list archive)
State Superseded
Headers show
Series BreakingChanges: early adopter option | expand

Commit Message

Junio C Hamano Sept. 19, 2024, 7:33 p.m. UTC
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 <gitster@pobox.com>
---

 * 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.

 Documentation/BreakingChanges.txt | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

Comments

Junio C Hamano Sept. 20, 2024, 9:33 p.m. UTC | #1
Junio C Hamano <gitster@pobox.com> 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 <gitster@pobox.com>
> ---
>
>  * 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-<.
Junio C Hamano Sept. 22, 2024, 5:51 p.m. UTC | #2
Junio C Hamano <gitster@pobox.com> writes:

> Junio C Hamano <gitster@pobox.com> 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.
>> ...
> ... to see what it involves
> to allow early adopters to experience Git 3.0 features/removals
> before it actually happens.

Sorry for a long monologue on this important topic, while everybody
is away.  Hopefully we'll see more comments when they get back once
the week starts ;-)

> 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".
> ...
> 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...

While I still am with the position that we can do this either at
runtime or at build time, with the trade-off being that it is more
costly for developers to do it at runtime and more cumbersome for
early adopters to do it at build time, I realize that the last point
above is unrelated.  If one or some of the features behind either
feature.git3 runtime option or GIT_BUILD_FOR_GIT3 build-time option
makes a repository inaccessible to versions of Git without these
features, we have the extension.* mechanism to make sure nothing
breaks, and testing that such a Git3 feature is properly protected
by the extension.* mechanism is part of the early adopter testing.

How much more costly to do at runtime is still subject to further
analysis, I think.  I know that it means we need to build and
install the docs twice to support "git -c feature.git3=on help", for
example, but I am not sure what the best way to use CI would be
(write tests that check features with different behaviour by
explicitly running them with "git -c feature.git3=on"?  Run the same
set of tests in a separate job that has "[feature] git3" in its
$HOME/.gitconfig?).
Patrick Steinhardt Sept. 26, 2024, 11:57 a.m. UTC | #3
On Sun, Sep 22, 2024 at 10:51:52AM -0700, Junio C Hamano wrote:
> Junio C Hamano <gitster@pobox.com> writes:
> > Junio C Hamano <gitster@pobox.com> 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.
> >> ...
> > ... to see what it involves
> > to allow early adopters to experience Git 3.0 features/removals
> > before it actually happens.

Thanks for putting together this document! We also had this discussion
during the contributor's summit, and I certainly agree that having such
a toggle makes a ton of sense.

> Sorry for a long monologue on this important topic, while everybody
> is away.  Hopefully we'll see more comments when they get back once
> the week starts ;-)
> 
> > 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".
> > ...
> > 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...
> 
> While I still am with the position that we can do this either at
> runtime or at build time, with the trade-off being that it is more
> costly for developers to do it at runtime and more cumbersome for
> early adopters to do it at build time, I realize that the last point
> above is unrelated.  If one or some of the features behind either
> feature.git3 runtime option or GIT_BUILD_FOR_GIT3 build-time option
> makes a repository inaccessible to versions of Git without these
> features, we have the extension.* mechanism to make sure nothing
> breaks, and testing that such a Git3 feature is properly protected
> by the extension.* mechanism is part of the early adopter testing.
> 
> How much more costly to do at runtime is still subject to further
> analysis, I think.  I know that it means we need to build and
> install the docs twice to support "git -c feature.git3=on help", for
> example, but I am not sure what the best way to use CI would be
> (write tests that check features with different behaviour by
> explicitly running them with "git -c feature.git3=on"?  Run the same
> set of tests in a separate job that has "[feature] git3" in its
> $HOME/.gitconfig?).

One problem with runtime toggles are commands that go away entirely. We
can of course hide them away in various different places and make it
impossible to call them. But one of the downsides is that it is not
"true" to the actual removal, as for example the dashed builtins may
still exist.

That makes me personally lean into the direction fo making this a build
time knob. The big downside of course is that we'll have less exposure
as almost nobody ever would build their Git in such a way. But the big
upside is that we end up executing the code exactly as it would look
like if it were removed, so the coverage we get e.g. both from Git devs
and from our CI would be much more telling.

Patrick
Phillip Wood Sept. 26, 2024, 2:16 p.m. UTC | #4
On 26/09/2024 12:57, Patrick Steinhardt wrote:
> On Sun, Sep 22, 2024 at 10:51:52AM -0700, Junio C Hamano wrote:
>> Junio C Hamano <gitster@pobox.com> writes:
>>> Junio C Hamano <gitster@pobox.com> writes:
>> How much more costly to do at runtime is still subject to further
>> analysis, I think.  I know that it means we need to build and
>> install the docs twice to support "git -c feature.git3=on help", for
>> example, but I am not sure what the best way to use CI would be
>> (write tests that check features with different behaviour by
>> explicitly running them with "git -c feature.git3=on"?  Run the same
>> set of tests in a separate job that has "[feature] git3" in its
>> $HOME/.gitconfig?).
> 
> One problem with runtime toggles are commands that go away entirely. We
> can of course hide them away in various different places and make it
> impossible to call them. But one of the downsides is that it is not
> "true" to the actual removal, as for example the dashed builtins may
> still exist.

We should be able to make sure those dashed builtins fail though, while 
that isn't exactly the same as the command not existing it would signal 
that the command does not work in git3.

> That makes me personally lean into the direction fo making this a build
> time knob.

That's certainly easier to implement.

> The big downside of course is that we'll have less exposure
> as almost nobody ever would build their Git in such a way.

Yes, it's hard to see many people doing that, though if we're lucky some 
companies that build their own git will test the git3 build. It's also 
hard to judge how many people would turn on the config option - if we go 
with that route we could be doing (a lot?) of extra work for not much 
benefit.

I remember the 1.0 to 2.0 transition as a user. I recall seeing advice 
massages describing the upcoming changes to "git add -u" and 
push.default before the 2.0 release. We should check if any of the 
proposed changes for 3.0 would benefit from something similar.

> But the big
> upside is that we end up executing the code exactly as it would look
> like if it were removed, so the coverage we get e.g. both from Git devs
> and from our CI would be much more telling.

Indeed

Best Wishes

Phillip
Junio C Hamano Sept. 26, 2024, 3:57 p.m. UTC | #5
Patrick Steinhardt <ps@pks.im> writes:

>> How much more costly to do at runtime is still subject to further
>> analysis, I think.  I know that it means we need to build and
>> install the docs twice to support "git -c feature.git3=on help", for
>> example, but I am not sure what the best way to use CI would be
>> (write tests that check features with different behaviour by
>> explicitly running them with "git -c feature.git3=on"?  Run the same
>> set of tests in a separate job that has "[feature] git3" in its
>> $HOME/.gitconfig?).
>
> One problem with runtime toggles are commands that go away entirely. We
> can of course hide them away in various different places and make it
> impossible to call them. But one of the downsides is that it is not
> "true" to the actual removal, as for example the dashed builtins may
> still exist.

Yes, as I said, such a change to various infrastructure that are not
specific to Git 3.0 boundary (e.g. run_builtin() dispatch needs to
tell which new commands are from the future and hide them unless
configured) is costly but reusable once written.  A new or removed
command that is not a built-in is even harder to manage at runtime.

> That makes me personally lean into the direction fo making this a build
> time knob. The big downside of course is that we'll have less exposure
> as almost nobody ever would build their Git in such a way. But the big
> upside is that we end up executing the code exactly as it would look
> like if it were removed, so the coverage we get e.g. both from Git devs
> and from our CI would be much more telling.

Sad but I tend to agree.
Junio C Hamano Sept. 26, 2024, 4:25 p.m. UTC | #6
Phillip Wood <phillip.wood123@gmail.com> writes:

>> One problem with runtime toggles are commands that go away
>> entirely. We
>> can of course hide them away in various different places and make it
>> impossible to call them. But one of the downsides is that it is not
>> "true" to the actual removal, as for example the dashed builtins may
>> still exist.
>
> We should be able to make sure those dashed builtins fail though,
> while that isn't exactly the same as the command not existing it would
> signal that the command does not work in git3.

Yes, that is what Patrick means by "we can of course hide" and what
I meant by "it is more costly for developers to do it at runtime".

> Yes, it's hard to see many people doing that, though if we're lucky
> some companies that build their own git will test the git3 build. It's
> also hard to judge how many people would turn on the config option -
> if we go with that route we could be doing (a lot?) of extra work for
> not much benefit.

That is certainly a thing worth considering.
Junio C Hamano Sept. 26, 2024, 4:26 p.m. UTC | #7
Phillip Wood <phillip.wood123@gmail.com> writes:

>> One problem with runtime toggles are commands that go away
>> entirely. We
>> can of course hide them away in various different places and make it
>> impossible to call them. But one of the downsides is that it is not
>> "true" to the actual removal, as for example the dashed builtins may
>> still exist.
>
> We should be able to make sure those dashed builtins fail though,
> while that isn't exactly the same as the command not existing it would
> signal that the command does not work in git3.

Yes, that is what Patrick means by "we can of course hide" and what
I meant by "it is more costly for developers to do it at runtime".

> Yes, it's hard to see many people doing that, though if we're lucky
> some companies that build their own git will test the git3 build. It's
> also hard to judge how many people would turn on the config option -
> if we go with that route we could be doing (a lot?) of extra work for
> not much benefit.

That is certainly a thing worth considering.

Thanks.
diff mbox series

Patch

diff --git i/Documentation/BreakingChanges.txt w/Documentation/BreakingChanges.txt
index 2b64665694..9f1e9a0fb8 100644
--- i/Documentation/BreakingChanges.txt
+++ w/Documentation/BreakingChanges.txt
@@ -59,10 +59,31 @@  over time. If circumstances change, an earlier decision to deprecate or change
 something may need to be revisited from time to time. So do not take items on
 this list to mean "it is settled, do not waste our time bringing it up again".
 
+== Procedure
+
+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.
+Because such changes are expected to be numerous, and the design and
+implementation of them are expected to span over time, they have to
+be deployable trivially at such a version boundary.
+
+The breaking changes MUST be guarded with the configuration
+variable, `feature.git<version>` to help this process.  Each
+individual breaking change must be implemented in such a way that
+for a user who has this configuration variable set to true, it goes
+in effect even before Git <version>.  Note that setting the
+configuration to `false` MUST have no effect, either before or AFTER
+Git <version>.  In other words, this is purely an option to recruit
+early adopters and not a mechanism to keep the old behaviour after
+the announced version boundary for breaking changes.
+
+
 == Git 3.0
 
 The following subsections document upcoming breaking changes for Git 3.0. There
-is no planned release date for this breaking version yet.
+is no planned release date for this breaking version yet.  The early
+adopter configuration used for changes for this release is `feature.git3`.
 
 Proposed changes and removals only include items which are "ready" to be done.
 In other words, this is not supposed to be a wishlist of features that should