我对捆绑器和它生成的文件有点陌生。我有一个副本的git回购从GitHub,这是由许多人贡献,所以我很惊讶地发现,捆绑器创建了一个文件,不存在的回购,不在.gitignore列表。
因为我已经fork了它,我知道将它添加到回购中不会破坏主回购的任何东西,但如果我做一个pull请求,它会引起问题吗?
应该Gemfile。锁包含在存储库中?
我对捆绑器和它生成的文件有点陌生。我有一个副本的git回购从GitHub,这是由许多人贡献,所以我很惊讶地发现,捆绑器创建了一个文件,不存在的回购,不在.gitignore列表。
因为我已经fork了它,我知道将它添加到回购中不会破坏主回购的任何东西,但如果我做一个pull请求,它会引起问题吗?
应该Gemfile。锁包含在存储库中?
来自TrinitronX的2022年更新
快进到2021年,现在Bundler文档(web存档)现在说要提交Gemfile。锁在宝石里面…¯_()_/¯我想这对开发人员来说是有意义的,并且在开始一个项目时易于使用。然而,现在CI作业需要确保删除任何丢失的Gemfile。锁定文件以针对其他版本进行测试。
遗产答案~2010
假设你不是在写rubygem, Gemfile。Lock应该在存储库中。它被用作所有所需宝石及其依赖关系的快照。这样,bundle就不必在每次部署时重新计算所有gem依赖项。
下面是cowboycoded的评论:
如果你正在使用宝石,那么不要签入你的Gemfile.lock。如果你正在开发一个Rails应用程序,那么一定要检入你的Gemfile.lock。
这里有一篇很好的文章解释了什么是锁文件。
同意r-dub,把它放在源代码控制中,但对我来说,真正的好处是:
在相同的环境下协作(忽略windows和linux/mac的东西)。Gemfile之前。Lock,下一个安装项目的人可能会看到各种令人困惑的错误,责怪自己,但他只是一个幸运的人,得到了下一个版本的super gem,打破了现有的依赖关系。
更糟糕的是,这发生在服务器上,得到未经测试的版本,除非遵守规则并安装准确的版本。Gemfile。Lock使这个显式,它会显式地告诉你你的版本不同。
注意:记得把东西分类,比如:development和:test
真正的问题发生在需要配置数据库适配器的开源Rails应用程序上。我正在开发无脂肪CRM的Rails 3分支。 我的首选是postgres,但我们希望默认数据库是mysql2。
在本例中,是Gemfile。lock仍然需要用默认的宝石集检入,但我需要忽略我在我的机器上对它所做的更改。为了实现这一点,我运行:
git update-index --assume-unchanged Gemfile.lock
反过来说:
git update-index --no-assume-unchanged Gemfile.lock
在Gemfile中包含以下代码也是很有用的。这将根据您的database.yml加载适当的数据库适配器gem。
# Loads the database adapter gem based on config/database.yml (Default: mysql2)
# -----------------------------------------------------------------------------
db_gems = {"mysql2" => ["mysql2", ">= 0.2.6"],
"postgresql" => ["pg", ">= 0.9.0"],
"sqlite3" => ["sqlite3"]}
adapter = if File.exists?(db_config = File.join(File.dirname(__FILE__),"config","database.yml"))
db = YAML.load_file(db_config)
# Fetch the first configured adapter from config/database.yml
(db["production"] || db["development"] || db["test"])["adapter"]
else
"mysql2"
end
gem *db_gems[adapter]
# -----------------------------------------------------------------------------
我不能说这是否是一个公认的最佳实践,但它对我来说很有效。
我的同事和我有不同的Gemfile。锁,因为我们使用不同的平台,Windows和mac,我们的服务器是linux。
我们决定删除Gemfile。锁在repo并在git repo中创建Gemfile.lock.server,就像database.yml一样。然后,在将其部署到服务器之前,我们将Gemfile.lock.server复制到Gemfile。使用cap部署钩子锁定服务器
Bundler文档也解决了这个问题:
原:http://gembundler.com/v1.3/rationale.html
编辑:http://web.archive.org/web/20160309170442/http: / / bundler.io / v1.3 / rationale.html
请参阅“将代码检入版本控制”一节:
After developing your application for a while, check in the application together with the Gemfile and Gemfile.lock snapshot. Now, your repository has a record of the exact versions of all of the gems that you used the last time you know for sure that the application worked. Keep in mind that while your Gemfile lists only three gems (with varying degrees of version strictness), your application depends on dozens of gems, once you take into consideration all of the implicit requirements of the gems you depend on. This is important: the Gemfile.lock makes your application a single package of both your own code and the third-party code it ran the last time you know for sure that everything worked. Specifying exact versions of the third-party code you depend on in your Gemfile would not provide the same guarantee, because gems usually declare a range of versions for their dependencies. The next time you run bundle install on the same machine, bundler will see that it already has all of the dependencies you need, and skip the installation process. Do not check in the .bundle directory, or any of the files inside it. Those files are specific to each particular machine, and are used to persist installation options between runs of the bundle install command. If you have run bundle pack, the gems (although not the git gems) required by your bundle will be downloaded into vendor/cache. Bundler can run without connecting to the internet (or the RubyGems server) if all the gems you need are present in that folder and checked in to your source control. This is an optional step, and not recommended, due to the increase in size of your source control repository.
有点晚了,但答案仍然花了我时间和外国阅读来理解这个问题。因此,我想总结一下我对Gemfile.lock的了解。
当您构建Rails应用程序时,您正在本地机器中使用特定版本的gems。如果希望避免在生产模式和其他分支中出现错误,就必须使用那个Gemfile。锁文件无处不在,并告诉捆绑器捆绑重建宝石每次它的变化。
如果Gemfile。你的生产机器上的锁已经改变了,Git不允许你Git pull,你应该写Git reset——很难避免文件改变和再次写Git pull。
没有Gemfile。锁的意思是:
新的贡献者不能运行测试,因为奇怪的事情失败了,所以他们不会贡献或者得到失败的pr……糟糕的初次体验。 如果你丢失了本地的Gemfile.lock,你就不能回到x年前的项目,在不更新/重写项目的情况下修复一个错误
->总是检入Gemfile。锁,让特拉维斯删除它如果你想更彻底https://grosser.it/2015/08/14/check-in-your-gemfile-lock/
这里的其他答案是正确的:是的,你的Ruby应用程序(不是你的Ruby gem)应该包含Gemfile。锁定回购。要详细说明为什么它应该这样做,请继续阅读:
我错误地认为,每个环境(开发、测试、阶段、测试……)都进行了捆绑安装来构建自己的Gemfile.lock。我的假设是基于Gemfile。Lock不包含任何分组数据,如:test、:prod等。这种假设是错误的,因为我在一个令人痛苦的地方问题中发现了这一点。
经过进一步调查,我很困惑为什么我的Jenkins构建显示获取一个特定的宝石(ffaker, FWIW)成功,但当应用程序加载并需要ffaker时,它说文件未找到。WTF ?
更多的调查和实验显示了这两个文件的功能:
首先,它使用Gemfile。锁定去获取所有的宝石,即使是那些不会使用在这个特定的环境。然后它使用Gemfile选择在这个环境中实际使用哪些获取的宝石。
因此,尽管它在第一步中基于Gemfile获取了宝石。锁,它不包括在我的:测试环境,基于组在Gemfile。
修复(在我的情况下)是移动宝石'ffaker'从:开发组到主组,所以所有的env都可以使用它。(或者,将其添加到:development,:test,视情况而定)
2021年的答案很简单: Gemfile。lock也应该在Rubygems的版本控制中。现在公认的答案是11年。
这里有一些理由(从评论中挑选出来):
@josevalim https://github.com/heartcombo/devise/pull/3147 # issuecomment - 52193788
Gemfile。Lock应该留在存储库中,因为贡献者和开发人员应该能够派生项目,并使用保证有效的版本运行它。
@rafaelfranca https://github.com/rails/rails/pull/18951#issuecomment-74888396
我不认为忽略锁文件是一个好主意,即使是插件。 这意味着“git克隆;包;Rake test”序列不能保证通过,因为您的几十个依赖项中的一个被升级并使您的代码中断。此外,正如@chancancode所说,它使平分更加困难。
Rails也有Gemfile。锁定git:
https://github.com/rails/rails/commit/0ad6d27643057f2eccfe8351409a75a6d1bbb9d0