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

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

应该Gemfile。锁包含在存储库中?


当前回答

没有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,视情况而定)

真正的问题发生在需要配置数据库适配器的开源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部署钩子锁定服务器

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

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

如果Gemfile。你的生产机器上的锁已经改变了,Git不允许你Git pull,你应该写Git reset——很难避免文件改变和再次写Git pull。

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