This is a solid argument. Except in cases where you're upgrading everything in a small to mid sized codebase that needs a major dependency updated that affects everything from syntax to other things, and cannot be done discretely.
For a Python 2 to 3 migration a few years back we did it in a branch with many commits. We didn't obsess about telling a story we just got the work done and the tests passing.
Before this there was some work to bring the codebase as close to 3.x paradigms as possible.
As long as the two points before and after the work are copacetic we were satisfied. In that sense it was discreet.