Gemfile.lock应该包含在.gitignore中吗?

时间:2010-11-11 05:03:33

标签: git version-control bundler

我对bundler及其生成的文件不熟悉。我有一个来自GitHub的git repo的副本,这是由很多人贡献的,所以我很惊讶地发现bundler创建了一个在repo中不存在且不在.gitignore列表中的文件。

由于我已将它分叉,我知道将它添加到repo不会破坏主要仓库的任何内容,但如果我执行拉取请求,是否会导致问题?

Gemfile.lock应该包含在内吗?

9 个答案:

答案 0 :(得分:520)

假设您没有编写rubygem,Gemfile.lock应该在您的存储库中。它用作所有必需宝石及其依赖项的快照。这样,Bundler不必在每次部署时重新计算所有gem依赖项等。

来自cowboycoded的评论。

  

如果你正在研究宝石,那么DO   不要检查你的Gemfile.lock。

这是一个很好的article,解释锁文件是什么。

答案 1 :(得分:49)

当您处理需要具有可配置数据库适配器的开源Rails应用程序时,会发生真正的问题。我正在开发Fat Free 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]
# -----------------------------------------------------------------------------

我不能说这是否是既定的最佳做法,但对我来说效果很好。

答案 2 :(得分:32)

我和我的同事有不同的Gemfile.lock,因为我们使用不同的平台,windows和mac,而我们的服务器是linux。

我们决定在repo中删除Gemfile.lock并在git repo中创建Gemfile.lock.server,就像database.yml一样。然后在将其部署到服务器上之前,我们使用cap deploy hook将Gemfile.lock.server复制到服务器上的Gemfile.lock

答案 3 :(得分:11)

同意r-dub,将其保留在源代码管理中,但对我而言,真正的好处是:

在相同的环境中进行协作(无视windohs和linux / mac的东西)。在Gemfile.lock之前,下一个安装项目的人可能会看到各种令人困惑的错误,责备自己,但他只是那个幸运的家伙获得下一个版本的超级宝石,破坏了现有的依赖。

更糟糕的是,这发生在服务器上,获得未经测试的版本,除非遵守纪律并安装确切的版本。 Gemfile.lock使这个显式化,它会明确地告诉你你的版本是不同的。

注意:记得将内容分组为:development和:test

答案 4 :(得分:11)

Bundler文档也解决了这个问题:

ORIGINAL:http://gembundler.com/v1.3/rationale.html

编辑:http://web.archive.org/web/20160309170442/http://bundler.io/v1.3/rationale.html

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

  

在开发应用程序一段时间后,请检查   应用程序与Gemfile和Gemfile.lock快照一起使用。现在,   您的存储库记录了所有gem的确切版本   您最后一次使用时确认该应用程序   工作。请记住,虽然你的Gemfile只列出了三个宝石   (具有不同程度的版本严格性),您的应用程序取决于   一旦你考虑到了所有的宝石,就会有数十种宝石   你所依赖的宝石的隐含要求。

     

这很重要:Gemfile.lock使您的应用程序成为一个   包含您自己的代码和最后运行的第三方代码   时间你肯定知道一切都有效。指定准确   您在Gemfile中依赖的第三方代码的版本   不提供相同的保证,因为宝石通常声明一个范围   其依赖项的版本。

     

下次在同一台机器上运行bundle install时,bundler会   看到它已经拥有你需要的所有依赖项,并跳过   安装过程。

     

请勿检入.bundle目录或其中的任何文件。   这些文件特定于每台特定的机器,并且习惯于使用   在bundle install的运行之间保持安装选项   命令。

     

如果您运行了捆绑包,那么宝石(虽然不是git宝石)   您的捆绑包所需的内容将下载到供应商/缓存中。捆绑   如果没有连接到互联网(或RubyGems服务器)可以运行   您需要的所有宝石都存在于该文件夹中并签入   你的源代码控制。这是可选步骤,不推荐,   由于源控件存储库的大小增加。

答案 5 :(得分:4)

No Gemfile.lock表示:

  • 新的贡献者无法运行测试,因为奇怪的事情会失败,所以他们不会贡献或失败的PR ...糟糕的第一次体验。
  • 如果您丢失了本地Gemfile.lock,则无法返回x岁的项目并修复错误而无需更新/重写项目

- >总是检查Gemfile.lock,如果你想要更加全面,请让travis删除它https://grosser.it/2015/08/14/check-in-your-gemfile-lock/

答案 6 :(得分:3)

派对有点晚了,但答案仍然花了我时间和外国读书来理解这个问题。所以我想总结一下我发现的关于Gemfile.lock的内容。

在构建Rails应用程序时,您在本地计算机中使用某些版本的gem。如果你想避免生产模式和其他分支中的错误,你必须在任何地方使用那个Gemfile.lock文件,并告诉bundler bundle每次更改时重建gems。

如果您的生产计算机上的Gemfile.lock发生了更改,并且Git不允许您git pull,则应编写git reset --hard以避免该文件更改并再次写入git pull

答案 7 :(得分:2)

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 clone;bundle;rake 测试”序列不能保证通过,因为您的数十个依赖项中的一个已升级并使您的代码中断。此外,正如@chancancode 所说,将其一分为二要困难得多。

Rails 在 git 中也有 Gemfile.lock:

答案 8 :(得分:0)

这里的其他答案是正确的:是的,您的Ruby应用(而不是Ruby gem)应该在仓库中包含Gemfile.lock。要扩展为什么为什么应该这样做,请继续阅读:

我误以为每个环境(开发,测试,暂存,生产...)每个人都执行bundle install来构建自己的Gemfile.lock。我的假设基于以下事实:Gemfile.lock不包含任何分组数据,例如:test,:prod等。这种假设是错误,我在一个痛苦的本地问题中发现。

在进一步的调查中,我感到困惑,为什么我的Jenkins版本显示成功获取特定的gem(ffaker,FWIW),但是当应用程序加载并需要更高级的文件时,却说找不到文件。 WTF?

更多的调查和实验表明了这两个文件的作用:

首先,它使用Gemfile.lock来获取所有宝石,甚至包括那些不会在该特定环境中使用的宝石。 然后它使用Gemfile选择要在此环境中实际使用的那些提取宝石。

因此,即使它首先基于Gemfile.lock提取了gem,但基于Gemfile中的组,它也不包含在我的:test环境中。

解决方法(以我为例)是将gem 'ffaker'从:development组移到主要组,以便所有环境都可以使用它。 (或者,仅将其添加到:development,:test)