应该Gemfile。锁包含在。gitignore?

我对捆绑器和它生成的文件有点陌生。我有一个副本的git回购从GitHub,这是由许多人贡献,所以我很惊讶地发现,捆绑器创建了一个文件,不存在于回购,不在.gitignore列表。

因为我已经fork了它,我知道将它添加到回购中不会破坏主回购的任何东西,但如果我做一个pull请求,它会引起问题吗?

是否应该将Gemfile.lock包含在存储库中?

111790 次浏览

2022年更新 from TrinitronX < / > < / p >

快进到2021年,现在打包机文档 (web archive)现在说提交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。< / p >

在这种情况下,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文档也解决了这个问题:

原:# EYZ0

编辑:# EYZ0

请参阅“将代码检入版本控制”一节:

在开发应用程序一段时间后,检入 应用程序连同Gemfile和Gemfile。锁快照。现在, 您的存储库有所有宝石的确切版本的记录 你上次用过的,你肯定知道这个应用程序 工作。请记住,虽然你的Gemfile只列出了三个宝石 (版本严格程度不同),您的应用程序取决于 关于几十个宝石,一旦你考虑到所有的 你所依赖的gems的隐含需求。

这很重要:Gemfile。Lock使您的应用程序成为单一的 包含您自己的代码和上次运行的第三方代码 是时候确定一切都正常了。指定的 您在Gemfile中所依赖的第三方代码的版本 不提供相同的保证,因为宝石通常声明一个范围

下次你在同一台机器上运行bundle install, bundle将会 查看它已经具有所需的所有依赖项,然后跳过 安装过程。< / p > 不要检查.bundle目录或其中的任何文件。 这些文件是特定于每台特定机器的,用于 在包安装的运行之间持久化安装选项 命令。< / p >

如果你已经运行bundle pack, gems(虽然不是git gems) 你的包需要下载到vendor/cache中。打包机 可以在不连接互联网(或RubyGems服务器)的情况下运行,如果 你需要的所有宝石都在这个文件夹中,并签入 你的源代码控制。这是一个可选步骤,不推荐, 由于您的源代码控制存储库的大小增加

有点晚了,但答案仍然花了我时间和外国阅读来理解这个问题。因此,我想总结一下我对Gemfile.lock的了解。

当您构建Rails应用程序时,您正在本地机器中使用特定版本的gems。如果希望避免在生产模式和其他分支中出现错误,就必须使用那个Gemfile。锁文件无处不在,并告诉捆绑者bundle重建宝石每次它的变化。

如果在您的生产机上Gemfile.lock已经更改,而Git不允许您更改git pull,那么您应该编写git reset --hard以避免文件更改,然后再次编写git pull

没有Gemfile。锁的意思是:

  • 新的贡献者不能运行测试,因为奇怪的事情失败了,所以他们不会贡献或者得到失败的pr……糟糕的初次体验。
  • 如果你丢失了本地的Gemfile.lock,你就不能回到x年前的项目,在不更新/重写项目的情况下修复一个错误

->总是检入Gemfile。锁,让特拉维斯删除它,如果你想更彻底https://grosser.it/2015/08/14/check-in-your-gemfile-lock/

这里的其他答案是正确的:是的,你的Ruby应用程序(不是你的Ruby宝石)应该在回购中包含Gemfile.lock。要扩展为什么,它应该这样做,请继续阅读:

我错误地认为每个环境(开发、测试、阶段、测试……)都使用bundle install来构建自己的Gemfile.lock。我的假设是基于Gemfile。Lock不包含任何分组数据,如:test、:prod等。这个假设是错误的,因为我在一个痛苦的本地问题中发现了这个假设。

经过进一步调查,我很困惑为什么我的Jenkins构建显示获取一个特定的宝石(ffaker, FWIW)成功,但当应用程序加载并要求ffaker时,它说文件未找到。WTF ?

更多的调查和实验显示了这两个文件的功能:

第一个它使用Gemfile。锁定去获取所有的宝石,即使是那些不会使用在这个特定的环境。然后它使用Gemfile来选择在这个环境中实际使用的那些获取的宝石。

因此,尽管它在第一步中基于Gemfile获取了宝石。锁,它不包括在我的:测试环境,基于组在Gemfile。

解决办法(在我的情况下)是将gem 'ffaker'从:development组移到main组,这样所有的env都可以使用它。(或者,将其添加到:development,:test,视情况而定)

2021年的简单答案: Gemfile。对于Rubygems, lock也应该在版本控制中。现在公认的答案是11年。

这里有一些理由(从评论中挑选出来):

@josevalim # EYZ0

Gemfile。Lock应该留在存储库中,因为贡献者和开发人员应该能够派生项目,并使用保证有效的版本运行它。

@rafaelfranca # EYZ0

我不认为忽略锁文件是一个好主意,即使是插件。

这意味着一个&;git克隆;包;rake test"序列不能保证通过,因为您的几十个依赖项中的一个被升级并使您的代码中断。此外,正如@chancancode所说,它使平分更加困难。

Rails也有Gemfile。锁定git: