我对bundler及其生成的文件还比较新。我有一个来自GitHub的git仓库副本,许多人正在对其进行贡献,所以我很惊讶发现bundler创建了一个在仓库中不存在且不在.gitignore
列表中的文件。
由于我已经fork了它,我知道将其添加到仓库中不会对主仓库造成任何影响,但如果我提交pull request,会引起问题吗?
Gemfile.lock
应该包含在仓库中吗?
我对bundler及其生成的文件还比较新。我有一个来自GitHub的git仓库副本,许多人正在对其进行贡献,所以我很惊讶发现bundler创建了一个在仓库中不存在且不在.gitignore
列表中的文件。
由于我已经fork了它,我知道将其添加到仓库中不会对主仓库造成任何影响,但如果我提交pull request,会引起问题吗?
Gemfile.lock
应该包含在仓库中吗?
2022年更新来自TrinitronX
快进到2021年,现在Bundler文档[网络存档]中建议将Gemfile.lock提交到gem内...¯_(ツ)_/¯ 我猜这对开发人员和项目的易用性是有意义的。然而,现在CI任务需要确保删除任何杂散的Gemfile.lock文件以测试其他版本。
2010年左右
假设你不是写Ruby gem,那么Gemfile.lock应该在你的代码仓库中。它被用作所有所需gem及其依赖项的快照。这样一来,每次部署等操作时,bundler就不必重新计算所有gem的依赖关系。
以下是cowboycoded的评论:
如果你正在开发一个gem,则不要检入你的Gemfile.lock。 如果你正在开发Rails应用程序,则应检入Gemfile.lock。
这篇文章解释了锁定文件的作用。
bundle install; bundle exec
命令并忽略 Gemfile.lock
的 Ruby gem 吗? - Ciro Santilli OurBigBook.comGemfile.lock
提交到gem中... ¯\(ツ)/¯ 我想这对于开发人员和项目启动时的使用方便是有意义的。然而,现在CI作业需要确保删除任何杂散的Gemfile.lock
文件以测试其他版本。 - TrinitronX当你在使用一个需要可配置数据库适配器的开源 Rails 应用程序时,实际问题出现了。我正在开发 Fat Free CRM 的 Rails 3 分支。
我更喜欢 postgres,但我们希望默认数据库是 mysql2。
在这种情况下,Gemfile.lock
仍然需要与默认的一组 gems 一起检入,但我需要忽略我在本地所做的更改。为了实现这一点,我运行:
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]
# -----------------------------------------------------------------------------
我不确定这是否是一个已经确立的最佳实践,但对我来说它运作良好。
我和我的同事因为使用不同的操作系统(Windows和Mac),所以我们的Gemfile.lock文件不同。而我们的服务器是Linux系统。
我们决定在代码仓库中删除Gemfile.lock文件,并创建一个名为Gemfile.lock.server的文件,就像database.yml一样。然后,在部署到服务器之前,我们使用cap deploy hook将Gemfile.lock.server复制到服务器上的Gemfile.lock文件中。
同意r-dub的观点,将其存储在源代码控制中,但对我来说,真正的好处是:
相同环境下的协作(忽略windohs和linux/mac等不同操作系统)。在Gemfile.lock之前,安装项目的下一个人可能会看到各种令人困惑的错误,怪罪自己,但他只是那个非常幸运的人获得了超级宝石的下一个版本,破坏了现有的依赖关系。
更糟糕的是,这种情况发生在服务器上,除非遵循纪律并安装完全相同的版本,否则会得到未经测试的版本。而Gemfile.lock明确地指出了这一点,并且它会明确告诉您版本的差异。
注意:要将内容分组,如:开发(:development)和测试(:test)。
打包程序文档也提到了这个问题:
原文链接:http://gembundler.com/v1.3/rationale.html
编辑后链接:http://web.archive.org/web/20160309170442/http://bundler.io/v1.3/rationale.html
请查看名为“将您的代码提交到版本控制”的部分:
开发应用一段时间后,将应用和 Gemfile 以及 Gemfile.lock 快照一起提交。这样,你的代码库就记录了所有 gem 的确切版本,这些 gem 是上次你确定应用程序正常工作时使用的。请记住,尽管 Gemfile 列出的仅有三个 gem(具有不同程度的版本严格性),但是考虑到你所依赖的所有 gem 的隐式要求,你的应用程序实际上依赖于数十个 gem。因此,尽管它基于Gemfile.lock在第一步中获取了gem,但由于Gemfile中的分组,在我的:test环境中并没有包含它。
解决方法(在我的情况下)是将 gem 'ffaker'
从:development组移动到主要组,以便所有环境都可以使用它。(或者根据实际情况将其仅添加到 :development、:test 中)