You can see the below text from the codepush documentation here
Target binary version parameter
This specifies the store/binary version of the application you are
releasing the update for, so that only users running that version will
receive the update, while users running an older and/or newer version
of the app binary will not. This is useful for the following
reasons:
1) If a user is running an older binary version, it's possible
that there are breaking changes in the CodePush update that wouldn't
be compatible with what they're running.
2) If a user is running a newer
binary version, then it's presumed that what they are running is newer
(and potentially incompatible) with the CodePush update. If you don't
specify the targetBinaryVersion in the release command, it takes from
the build.gradle (or) If you specify the target version, the current
release would be mapped to it.
Assuming you have a new release which would be sent to users via play store, it is inferred that the version code and build number would be updated and the earlier code-push release will no longer point to this build.
So to answer your questions.
A user that downloads v3 from google playstore, upon app open, will he get v2 from codepush ?
No they wouldn't get it as the code push release would be mapped to earlier binary version
I can't push v3 to codepush because it has native changes that might break.
You can with changes made over v3 which is already there in market