Important Note: I'm sure you know this but I think it's worth mentioning that you haven't actually tested exactly what you intend to release. You may benefit from having another branch, say release, where you put the stuff you decide to release, and then you can periodically reset dev to master to clean it up. (And if you do this I would consider calling dev something like next like gitworkflows, which is a similar concept.)
Solution 1 (Most General):
Create a new branch from master, cherry-pick the commits you want from dev, and merge this "release" branch into master.
Solution 2 (Works if your dev branch has merge commits for each commit brought into dev, and those commits' parent is master.):
Create a new branch from master, merge in each of the branches for the commits, and merge this "release" branch into master.
Solution 3 (Works if your dev history is linear after master, and if you never intend to bring in commit 2):
Disclaimer: this is more of an academic answer and I likely wouldn't actually use this solution in your scenario...
Create a new branch from master, and then perform 3 merges:
git switch -c release master
git merge Commit1 # take commit1
git merge -s ours Commit2 # merge commit2 but ignore it's changes!
git merge Commit3 # take commit3
# merge release branch into master
git switch master
git merge release