Theres no solution to this problem where you automatically get the fixes you apply to earlier versions in later versions.
You have to fix v2 and release v2.0.1 and seperately fix v2.1 releasing 2.1.1
For all you know v2.1 has been completely refactored internally. The code change you did to fix 2.1 might not even compile in 2.1
The Cherry Pick is a Lie!
Deprecated means in its general sense to disapprove something or to give it little value. In the software context, it means to discourage the use of a feature.
In the Java Community, for example, deprecated has indeed frequently the meaning of a future removal. But this is not the only reason:
the API has been superseded by another API,
I think that it is not the job of the SCM to maintain version numbers of executables.
In my experience with Java, it is Maven or Gradle that does the build, tags files in SCM and produces the executable artifact for a particular software version. The built executable is typically deployed to a container like Nexus.
However this does not mean it is easy to ...
There are three main options:
Run the git application itself using subprocesses. Most languages have ways to start new processes, you could run git this way. However, groking the output produced by git may be a problem.
Include git in your program as a library. Several languages have git libraries available, such as Python. You could also link to a C ...