I ran into this issue in an internal project. We did a workaround so I can't test, but I just traced some bundler source code. The code for ref:, tag:, and branch: is all the same. They are treated as synonyms.
This failed:
gem 'my-gem', :git => "https://my-server/my-gem.git", :tag => 'v0.1.0'
The error looked like this...
Fetching https://my-server/my-gem.git
fatal: Needed a single revision
Git error: command `git rev-parse --verify v0.1.0` in directory
We discovered that by default branches are pulled by the git clone, but not all tags. Tags that are not on a branch don't always get pulled. To workaround we just created a branch that contained the tag in question.
In the future it might work if you specify the reference like this...
gem 'my-gem', :git => "https://my-server/my-gem.git", :tag => 'refs/tags/v0.1.0'
If you look at the code I link to in github, you see that triggers the value extra_ref to be set, which triggers an additional git fetch to get that ref specifically.
https://github.com/rubygems/rubygems/blob/6a655a698e952f897d0d014fc11bae4b608528ce/bundler/lib/bundler/source/git/git_proxy.rb#L88-L104
It does a two step process. First it does something like this... (The ./foo is a target directory. It can be anything.)
git clone --bare --no-hardlinks --quiet -- https://my-server/my-gem.git ./foo
Then it does this...
git --git-dir=./foo fetch --force --quiet --tags -- https://my-server/my-gem.git refs/heads/*:refs/heads/* refs/tags/v0.1.0:refs/tags/v0.1.0
which will explicitly get the tag in question.
This second step is done whenever the reference begins with ref/.