Your perspective is just right in my opinion (and apparently most of the commenters).

I have worked in several small companies with 1-20 devs and have seen this again and again.
I have been thinking a lot about all this, so in case you're interested, here's my thoughts on the subject.

For context:

I use git for almost any size projects, unless it's a couple of files, for an internal non-critical project.
I create tests for at least the critical paths and usually benchmarks for hot paths.
I use docker to separate dev from prod, while keeping a realistic environment.
I use code formatters to avoid spending brain power, thinking about details that are irrelevant to the solution.
I monitor and log as much as possible from the start.

Early on I was a part of the "code, then deploy" group, thinking that it was the clearest, easiest path to get as much done as possible.
Slowly I have learned to use version control as a helper while coding, rather than a chore to be done after changes.
E.g. by not being afraid of large re-factoring, when I see a way to clean up code or as an easy way to just try something out as it can easily be discarded again.
It has also put my brain into a "segment changes into similar things" or maybe rather "do one thing, then another", instead of changing 7 things at once.
This is not always true of course, but I try as it makes it easier to keep track of changes.

The same thing with separation of dev and prod (and test, etc.) - it makes it safer, simpler and easier to try things out, when you aren't afraid of breaking things.

On top of what you have mentioned, I've also always been the ops. guy, which has taught me to monitor and log as much as possible, then remove unnecessary monitoring or logging, when it becomes obvious noise.
It also helps you understand WHY it's important to have working code in production ;-)

What I have experienced:

ALL of the above have ALWAYS been seen as "extra" from the business side and usually from other devs as well.
It's hard to make (some) people understand the value of checking for correctness now, is better than having to find bugs and fix them 3 months from now (after they've usually caused data loss or corruption).

It's even harder to argue for the value of changing existing code AND write tests for it.
It can easily seem like so much extra time in which nothing new is being produced.

I think the issue can be summed up in just a few points:

We as developers can be very averse to changes in our daily routine and/or how we do our job.
Also: to get any size team to be effective, everybody has to be on board with 1 way of doing things.

Both dev and biz needs to understand and trust, that what seems to be slow progress, compared to "code, then deploy", is actually a streamlined process that makes development safer, faster and less buggy (and more fun) in the larger perspective.

Possible solutions:

It all becomes a cost / benefit analysis for biz and/or a question of getting devs to see the benefit in their daily work.
Biz can usually understands the reasoning behind spending more time now to save even more down the road and avoid bugs in productions as that equals happier customers.
Even better: tell biz devs, they'll have a less buggy system to present, when they meet with potential customers!
The most resilient idea I have fought against, is the the thinking that you can keep adding low quality code to low quality code at the same pace without creating more/new problems.

I think that the 1 thing that concerns most developers is what held me back from all of this to begin with:
We want coding to be easy and fast. We want compile times to be as fast as possible, trying code and testing to be snappy.
Everything that is not code should be the absolutely minimal amount possible.
So... If you are used to "code, then deploy", then testing, version control, code review, CI, CD, etc. can seem like a lot of extra work, that will take time away from solving a problem in code.

If you can show what each step accomplishes, a lot of developers can see the reasoning and if asked if they're willing to try, will actually be willing to try.
The next step is to make sure that each step is impossible to avoid.
E.g. Somebody has to be responsible for code review, pushing to production, etc.
It should be impossible to commit directly to master branch or whatever is used for live.
Pull requests should simply not be accepted, until it meets the requirements agreed upon.

Sometimes a clear path can remove the perception of e.g. creating a pull request, being a roadblock rather than a safeguard that helps you code faster and more safely.