2

I'm trying to get an old version from a repository using bundler.

For instance, in my Gemfile I have:

...
gem "custom-metrics", "~> 0.14.0", git: "https://gitlab.custom.co/gems/custom-metrics.git"
...

This is properly installing the version 0.14.0. Then I pushed a 0.14.1 version in the dependency repository, and it's still the same, as expected.

In the dependency, I'm setting the version in my .gemspec file as:

Gem::Specification.new do |spec|
  spec.name = "custom-metrics"
  spec.version = 0.14.0
  ...
end

If I now push a 0.15.0 version, it would stop working. In this case, I have to specify the ref: to the previous commit. So it seems it's not that bundler can't install the version, but that it only looks for versions in the last MINOR version (in this case, it would be in 0.15.*)

I couldn't find any doc that confirms my hypothesis.

> Am I missing something?

> Would it be possible to specify a version and be sure that bundler will always find it?

anothermh
  • 9,815
  • 3
  • 33
  • 52
Javi Ortiz
  • 568
  • 1
  • 7
  • 22

1 Answers1

2

When loading a gem directly from a git repository, then Bundler loads exactly the version that it find in the defined branch, at the ref or tag.

When you define that a specific version of the gem should be used, then Bundler will check if the version of gem found in the repository matches that condition.

Therefore, you likely do not want to simply install the latest available version of a gem directly from a main branch from GitHub. But instead defining to install from a specific branch, tag, or ref might be easier to manage.

How to install gems from git repositories from the Bundler docs.

spickermann
  • 100,941
  • 9
  • 101
  • 131
  • Thank you for your answer. This is what I got from the docs as well. What I don't get it, is why it works for a previous version within the same MINOR. Let's say that `master` is at `0.14.1`, and that I ask for `~> 0.14.0`, it is actually able to find it in a previous commit/SHA – Javi Ortiz Jan 20 '23 at 08:40
  • That worked because the `~>` (sometimes called [pessimistic operator](https://thoughtbot.com/blog/rubys-pessimistic-operator)) in the `~> 0.14.0` version definition means the same as `>= 1.14.0 and < 1.15` and the patch release `0.14.1` still matches that condition. But a later `0.15.0` minor release would not match anymore. – spickermann Jan 20 '23 at 09:04
  • Sorry, just to be clear. It's actually getting the version from a previous commit. For instance, in my git history I have: `398fadb 1.14.1 / 49c0s0a 1.14.0`. And if I set `~> 1.14.0`, it works as you said: `Using custom-metrics 1.14.1 from https://gitlab.com/xxxx.git (at master@398fadb)`. But if I now set version `1.14.0`, I'll have: `Using custom-metrics 1.14.0 from https://gitlab.com/xxxx.git (at master@49c0s0a)`. So it's indeed capable of going back in time. It will stop working if I add a new commit with `1.15.0`, though. – Javi Ortiz Jan 20 '23 at 13:46
  • Are you sure that Bundler just didn't pull the previous version from your local cache? Because I would be very surprised if Bundler would scan through the whole commit history of a given branch to find a matching version, instead of just picking the latest version. That would be extremely slow and error-prone. – spickermann Jan 20 '23 at 13:49
  • Thank you for pointing me in the right direction. I think I got confused since I was caching results. I couldn't reproduce the first behavior in a brand new ruby container. – Javi Ortiz Jan 24 '23 at 20:26
  • [This answer](https://stackoverflow.com/a/28442337/6243352) provides gemfile code to specify tag/ref/branch. – ggorlen May 28 '23 at 05:07