A widely used class has a bad API. You refactor it to make a cleaner API, but your change isn't backwards compatible. Your options are:

- Change everything all at once. This creates a large PR. - Split it up into multiple small PRs. Now your individual PRs don't compile, and make less sense on their own. - Create a new class, and then split up multiple PRs that transition code to use the new class, and then finally a PR to remove the old class. This is more work for both the author and the reviewer and the individual PRs are harder to understand on their own.

This is interesting. I believe one way to deal with such breaking changes is to have multiple PRs, where the breaking change in each is hidden (protected) by a feature flag and tested by unit tests. Once all the PRs are committed, end to end testing can be done by enabling the flag. Any problems in production can be quickly reverted by disabling the flag. Eventually, a final PR removes the now-useless flag.

Of course, your mileage may vary; this technique is certainly not suitable for all breaking changes or all workfkows.

API changes breaking BC feel like they should be using versioning. I don't see enough people putting versioning support in to their API stuff at the outset. I've been chastised for doing that with "YAGNI". And then... one day, we do need it, and trying to introduce versioning support becomes... that much harder.

The context here was a class API, not a REST API, so versioning is not relevant.

You're right... misread that.

Does seem like you could namespace classes in to versions. Then it's much clearer which version of a class a caller is using.