Gemfile.lock是否应包含在.gitignore中?


500

我对捆绑程序及其生成的文件有点陌生。我有一个来自GitHub的git repo的副本,很多人对此都做出了贡献,因此我很惊讶地发现捆绑程序创建的文件在该repo中不存在,并且不在.gitignore列表中。

由于已经分叉了,所以我知道将它添加到仓库中不会破坏主仓库的任何内容,但是如果我执行拉取请求,会不会引起问题?

应该Gemfile.lock包含在资源库中吗?



2
如果您因为在Linux和Windows机器上共享同一仓库而在这里找到了自己的出路,请参阅Joe Yang的回答。在撰写本文时,它排名第三。另请参阅stackoverflow.com/questions/14034561/...
彼得·伯格

Answers:


549

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

来自Cowboycoded的以下评论:

如果您正在处理宝石,则不要签入Gemfile.lock。如果您正在使用Rails应用程序,请务必签入Gemfile.lock。

这是一篇很好的文章,解释了什么是锁定文件。


88
取决于您的工作。如果您正在处理宝石,则不要签入Gemfile.lock。如果您正在使用Rails应用程序,请务必签入Gemfile.lock。这里更多的信息- yehudakatz.com/2010/12/16/...
johnmcaliley

谢谢有用的文章。
ashisrai_

1
您应该在答案中加上牛仔编码所说的:宝石。
阿罗纳2011年

文章链接需要新的href。
罗斯

4
请不要那样做!!保持您的Gemfile.lock所在位置!就像这里这里所说的。
里卡多·鲁威尔

50

真正的问题发生在使用需要具有可配置数据库适配器的开源Rails应用程序时。我正在开发Fat Free CRM的Rails 3分支。我的首选是postgres,但我们希望默认数据库为mysql2。

在这种情况下,Gemfile.lock仍然需要使用默认的gem组进行检入,但是我需要忽略在计算机上对其所做的更改。为此,我运行:

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
非常有用的信息...不确定为什么只有3分,而不太有用的答案有50分。哦,是的,看看日期戳。(SO的最大失败之一是在提出问题后不久就获得了不成比例的收益。)
iconoclast

1
@iconoclast:我真的很高兴您发布了您的工作。我认为,很多人(包括我本人在内)都被问题标题“蒙蔽了”。现在,我意识到我的答案只能回答特定的用例,而不一定是对这个问题的正确答案。我将在不久的将来进行更新。就是说,如果OP不能满足他/她的需求,则不应将我的答案标记为正确。
rwilliams 2012年

34

我的同事和我有不同的Gemfile.lock,因为我们使用不同的平台,Windows和Mac,并且我们的服务器是Linux。

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


5
我有一个在OSX中开发的应用程序,然后必须在Windows服务器上进行部署。用git跟踪Gemfile.lock是一个坏主意,因此它确实存在于我的.gitignore文件中。许多宝石在不同的环境中需要不同的版本。理想情况下,您应该避免遇到这种情况,但我别无选择(该死的IT部门!)
brad 2012年

11

同意r-dub,将其保留在源代码控制中,但对我来说,真正的好处是:

在相同的环境中进行协作(不考虑windohs和linux / mac东西)。在Gemfile.lock之前,下一个安装该项目的家伙可能会看到各种令人困惑的错误,都归咎于自己,但他只是那个幸运的家伙,正在获得下一版的super gem,打破了现有的依赖关系。

更糟糕的是,这发生在服务器上,除非经过严格检查并安装准确的版本,否则将获得未经测试的版本。Gemfile.lock使其明确,并将明确告诉您您的版本不同。

注意:记住将东西分组,如:development和:test


11

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

原文: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仅列出了三个gem(版本严格程度不同),但是您的应用程序依赖于数十个gem,一旦您考虑了所依赖的gem的所有隐式要求。

这很重要:Gemfile.lock使您的应用程序成为您自己的代码和上次运行的第三方代码的单个包,以确保一切正常。在Gemfile中指定您依赖的第三方代码的确切版本不会提供相同的保证,因为gem通常会为其依赖项声明一系列版本。

下次在同一台计算机上运行捆绑安装时,捆绑程序将看到它已经具有所需的所有依赖关系,并跳过安装过程。

不要检入.bundle目录或其中的任何文件。这些文件特定于每台特定的计算机,并用于在bundle install命令运行之间保留安装选项。

如果您已运行捆绑包,捆绑包所需的gems(尽管不是git gems)将下载到供应商/缓存中。如果您需要的所有gems都存在于该文件夹中并签入到源代码管理中,则Bundler可以在不连接互联网(或RubyGems服务器)的情况下运行。由于源代码控制存储库的大小增加,因此这是可选步骤,不建议这样做。


4

没有Gemfile.lock意味着:

  • 新的贡献者无法运行测试,因为奇怪的事情失败了,所以他们将不会贡献或获得失败的PR……糟糕的初体验。
  • 如果您丢失了本地Gemfile.lock,则无法返回到具有ax年历史的项目并修复错误,而无需更新/重写项目。

->始终签入Gemfile.lock,如果要更彻底, travis删除它https://grosser.it/2015/08/14/check-in-your-gemfile-lock/


3

派对晚了一点,但是答案仍然使我花了一些时间,并且外国人读书来理解这个问题。因此,我想总结一下我对Gemfile.lock的了解。

在构建Rails应用程序时,您正在本地计算机中使用特定版本的gem。如果要避免生产模式和其他分支中的错误,则必须在各处使用该Gemfile.lock文件,并告诉bundler在bundle每次更改时重新构建gem。

如果Gemfile.lock您的生产机器上发生了更改,而Git不允许您这样做git pull,则应进行写操作git reset --hard以避免该文件更改,然后git pull再次写。


如果文件自动更改(例如,通过生成过程更改),则明确表明不应将其添加到版本控制中。
托马斯·S。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.