composer.lock应该提交版本控制吗?

时间:2012-10-15 13:36:43

标签: git version-control composer-php

我对使用存储库的应用程序中使用的composer.lock感到困惑。

我看到很多人说我们不应该从存储库中.gitignore composer.lock

如果我在开发环境中更新我的库,我将有一个新的composer.lock,但我将无法将它们更新到生产中,是吗?

它不会在这个文件上产生冲突吗?

9 个答案:

答案 0 :(得分:611)

如果更新lib,则也要提交锁文件。它基本上表明您的项目已锁定到您正在使用的库的特定版本。

如果您提交更改,并且有人提取您的代码并更新依赖项,则应该不修改lockfile。如果它被修改,则意味着你有一个新版本的东西。

将它放在存储库中可以确保每个开发人员使用相同的版本。

答案 1 :(得分:172)

对于应用程序/项目:肯定是。

composer documentation州(重点):

  

将应用程序的composer.lock(以及composer.json)提交到版本控制中。

喜欢@meza说:你应该提交锁定文件,这样你和你的协作者就可以使用同一套版本,并阻止你说“但它在我的电脑上工作”这样的说法。 ; - )

对于图书馆:可能不是。

作曲家文档记录了这件事:

  

注意:对于库,不一定建议提交锁定文件(...)

并说明here

  

对于您的库,如果您愿意,可以提交composer.lock文件。这可以帮助您的团队始终针对相同的依赖版本进行测试。但是,此锁定文件不会对依赖它的其他项目产生任何影响。它只对主项目产生影响。

对于图书馆,我同意@Josh Johnson的回答。

答案 2 :(得分:69)

在为两个项目做两种方式之后,我的立场是composer.lock不应该作为项目的一部分提交。我知道这样做比较容易,但在我为此提出理由时请耐心等待。

composer.lock是构建元数据,不属于项目的一部分。依赖关系的状态应该通过你如何对它们进行版本控制(手动或作为自动构建过程的一部分)来控制,而不是由最后一个开发人员任意更新它们并提交锁文件。

如果您担心作曲家更新之间的依赖关系发生变化,那么您对版本控制方案缺乏信心。版本(1.0,1.1,1.2等)应该是不可变的,你应该避免在初始功能开发之外使用“dev-”和“X. *”通配符。

提交锁定文件是依赖关系管理系统的回归,因为依赖关系版本现在又回到了隐含定义。

此外,您的项目永远不需要重建或在每个环境中都需要它的依赖项,尤其是prod。您的可交付成果(tar,zip,phar,目录等)应该是不可变的,并且可以在不改变状态的情况下通过环境进行推广。

编辑:我知道这不会是一个受欢迎的答案,但是如果你投票失败,你会在评论中提供一个理由,指出其中的缺陷回答?谢谢!

答案 3 :(得分:27)

  1. 您不应直接在Production上更新您的依赖项。
  2. 您应该对 composer.lock 文件进行版本控制。
  3. 您不应该版本控制您的实际依赖项。
  4. <强> 1。您不应直接在Production 上更新依赖项,因为您不知道这将如何影响代码的稳定性。可能存在新依赖项引入的错误,它可能会改变代码行为影响您自己的方式,它可能与其他依赖项等不兼容。您应该在开发环境中执行此操作,然后执行适当的QA和回归测试等

    <强> 2。您应该对 composer.lock 文件进行版本控制,因为它存储有关依赖项的信息以及依赖项的依赖项,这些依赖项将允许您复制代码的当前状态。这很重要,因为您的所有测试和开发都是针对特定代码完成的。不关心您所拥有的代码的实际版本类似于将代码更改上载到您的应用程序而不是测试它们。如果你要升级你的依赖版本,这应该是一个自愿的行为,你应该采取必要的谨慎,以确保一切仍然有效。失去一到两个小时的正常运行时间可能会花费你很多钱。

    您将看到不需要 composer.lock 的一个论点是您可以在 composer.json 文件中设置所需的确切版本,并且通过这种方式,每当有人运行composer install时,它将为它们安装相同的代码。事实并非如此,因为您的依赖项具有自己的依赖项,并且它们的配置可能以允许更新颠覆或甚至整个版本的格式指定。

    这意味着即使您在 composer.json 中指定要Laravel 4.1.31,Laravel在其 composer.json 文件中也可能有自己的依赖项作为Symfony事件调度员:2. *。 使用这种配置,您最终可以使用Symfony事件调度程序2.4.1来使用Laravel 4.1.31,并且您团队中的其他人可以使用事件调度程序2.6.5来使用Laravel 4.1.31,这将取决于何时是你最后一次运行作曲家安装。

    因此,在版本系统中使用 composer.lock 文件将存储此子依赖项的确切版本,因此,当您和您的队友进行作曲家安装时(这就是您将基于 composer.lock 安装依赖项。您将获得相同的版本。

    如果你想更新怎么办?然后在您的开发环境中运行:composer update,这将生成一个新的 composer.lock 文件(如果有新内容)并在您测试之后,并进行QA测试和回归测试东西。您可以将其推送给其他人下载新的 composer.lock ,因为它可以安全升级。

    第3。你不应该版本控制你的实际依赖,因为它没有任何意义。使用 composer.lock ,您可以安装确切版本的依赖项,而不需要提交它们。当你不应该更新它们时,为什么要添加你的repo 10000依赖项文件。如果您需要更改其中一个,您应该将其分叉并在那里进行更改。如果您担心每次构建或发布时都必须获取实际的依赖项,那么编写者可以采用不同的方法来缓解此问题,缓存,压缩文件等。

答案 4 :(得分:7)

  

然后将composer.json提交到您的项目,团队中的其他人都可以运行composer install来安装您的项目依赖项。

     

锁定文件的目的是记录安装的确切版本,以便重新安装。这意味着,如果您的版本规格为1. *并且您的同事运行安装1.2.4的composer update,然后提交composer.lock文件,那么当您编写作曲家安装时,您也将获得1.2.4,甚至如果1.3.0已经发布。这可以确保每个参与项目的人都拥有相同的版本。

     

这意味着如果自上次完成作曲家安装以来已经提交了任何内容,则没有锁定文件,您将获得新的第三方代码被删除

     

如果您担心代码中断,这也是一个问题。这也是为什么将Composer视为以composer.lock文件为中心的重要原因之一。

来源:Composer: It’s All About the Lock File

  

将应用程序的composer.lock(以及composer.json)提交到版本控制中。这很重要,因为install命令检查是否存在锁文件,如果存在,则下载其中指定的版本(无论composer.json是什么)。这意味着设置项目的任何人都将下载相同版本的依赖项。您的CI服务器,生产计算机,团队中的其他开发人员,所有人和每个人都运行相同的依赖关系,这减少了仅影响部署的某些部分的错误的可能性。即使您单独开发,在重新安装项目的六个月内,即使您的依赖项从那时起发布了许多新版本,您仍然可以确信安装的依赖项仍然有效。

来源:Composer - Basic Usage

答案 5 :(得分:1)

如果您担心代码中断,则应将@Input提交到版本控制系统,以确保所有项目协作者都使用相同版本的代码。如果没有锁定文件,您每次都会获得新的第三方代码。

例外情况是当您使用元应用程序时,应在安装时更新依赖项的库(如Zend Framework 2 Skeleton App)。因此,每次想要开始开发时,目标都是获取最新的依赖项。

来源:Composer: It’s All About the Lock File

另请参阅:What are the differences between composer update and composer install?

答案 6 :(得分:0)

对此没有确切答案。

通常来说,作曲家不应该执行构建系统要执行的操作,也不应该在VCS中放置composer.lock。作曲家可能会奇怪地将其倒退。最终用户而不是生产者不应该使用锁定文件。通常,您的构建系统会保留快照,可重复使用的目录等,而不是每次都保留一个空目录。人们从作曲家签出一个库时,可能希望该库使用锁,以便针对库加载的依赖项进行测试。

另一方面,这极大地增加了版本管理的负担,您几乎肯定会希望每个库都有多个版本,因为依赖关系将被严格锁定。如果每个库的版本可能都略有不同,那么您需要一些库版本支持,并且还可以快速查看所需依赖项的大小,因此建议将其保留在页面上。

在船上,我真的没有发现锁文件对库或您自己的工作目录都没有用。它仅对我有用,是在我的构建/测试平台中,该平台可持久存储任何外部获取的资产,仅在需要时对其进行更新,从而提供可重复的构建以进行测试,构建和部署。尽管可以将其保留在VCS中,但并不总是与源树保持在一起,但是构建树将位于VCS结构中的其他位置,或由其他位置的其他系统管理。如果将其存储在VCS中,是否将其保存在与源树相同的存储库中是有争议的,因为否则每次拉动都会带来大量的构建资产。我非常喜欢将一切都安排在一个精心安排的仓库中,除了生产/敏感凭证和过大的东西。

SVN可以比git做得更好,因为它不会强迫您获取整个仓库(尽管我怀疑git并不是严格要求的,但是对此的支持是有限的,并且不常用)。简单的构建库通常只是您将构建树合并/导出到其中的覆盖分支。有些人在其源代码树中合并外部资源,或者将其他,外部,构建和源代码树分开。它通常用于两个目的,即构建缓存和可重复的构建,但有时至少在一定程度上将其分开也可以允许全新/空白构建和多个构建。

有许多策略可以解决此问题,除非您将外部源保留在源代码树中,否则这些策略都不能很好地与持久化源列表配合使用。

他们还具有文件哈希值之类的东西,当两个人更新软件包时如何合并?仅此一项就应该让您认为这可能是错误的解释。

人们对于锁定文件提出的论点是他们对问题采取了非常具体和严格的看法的情况。是否需要可重复的构建和一致的构建?在VCS中包括供应商文件夹。然后,您还可以加快获取资源的速度,并且不必在构建过程中依赖于可能损坏的外部资源。除非绝对必要,否则我创建的构建和部署管道均不需要外部访问。如果必须更新外部资源,则只需一次。作曲家试图实现的目标对于分布式系统来说是有意义的,除非之前没有提到,否则它最终将导致库依赖地狱,导致库更新出现常见冲突,并且更新的速度与最慢的更新包一样慢。

此外,我还进行了激烈的更新。每次开发时,我都会更新并测试所有内容。有一个很小的窗口可让您轻松潜入大量版本。同样,实际上,当维护语义版本控制时(通常是作曲者使用的),您不会有太多的兼容性问题或损坏。

在composer.json中,放入所需的软件包及其版本。您可以在那里锁定版本。但是这些软件包也具有依赖于动态版本的依赖关系,这些依赖关系不会被composer.json锁定(尽管我不明白为什么如果您希望将它们锁定版本,为什么自己也不能将它们放在那里),所以其他人正在运行composer安装没有锁就得到一些不同的东西。您可能对此不太在意,或者您可能在乎,这取决于。你应该在乎吗?可能至少要足够一点,足以确保您在任何情况下都知道它,并可能产生影响,但是如果您始终有时间仅先运行DRY并修复所有更新的内容,则可能不是问题。

麻烦的作曲家试图避免有时只是不存在,而拥有作曲家锁文件的麻烦很重要。他们绝对无权告诉用户他们应该做或不应该做的关于构建资产与源资产(无论是在VCS中加入独立资产)的事务,因为这与他们无关,他们不是您或我的老板。 “作曲家说”不是权威,他们不是您的上司,也不给任何人任何关于此主题的优势。只有您知道自己的真实情况,以及什么才是最好的。但是,对于不了解事物工作原理的用户,他们可能会建议采取默认的操作方式,在这种情况下,您可能希望遵循该方法,但就我个人而言,我认为这并不是真正了解事物工作原理并能够正常运行的替代方法满足您的要求。最终,他们对这个问题的答案是最好的猜测。作曲家的人不知道您应该将composer.lock放在哪里,他们也不应该。他们唯一的责任是告诉您它是什么以及它是做什么的。除此之外,您需要决定最适合您的情况。

保留锁文件对于可用性来说是个问题,因为作曲家对于使用锁还是使用JSON非常秘密,并且不能总是很好地结合使用两者。如果您运行install,它将仅使用锁定文件,因此它将出现,因此,如果将内容添加到composer.json,则将不会安装该文件,因为它不在您的锁定中。对于json / lock文件,实际上什么操作以及它们在做什么都是完全不直观的,有时甚至看起来没有任何意义(帮助说install需要一个软件包名称,但是在尝试使用它时,它说没有)。

要更新锁或从json基本应用更改,您必须使用update,并且您可能不想更新所有内容。该锁优先于选择应安装的内容。如果有一个锁定文件,那就使用它。您可以限制更新,但是系统仍然很混乱。

更新需要一定的时间,需要大量的RAM。我还怀疑,如果您从一个已经存在的版本中挑选了一段时间未涉及的项目,那么随着时间的流逝,将会发现更多的项目,并且它可能无法有效地完成工作,从而扼杀了它。 / p>

当涉及到秘密的复合命令时,他们非常不知所措。默认情况下,例如,composer remove命令显示为映射到composer update和composer remove。

您真正要问的问题不是您是否应该将锁保留在源树中,或者是否应该以某种方式将其保留在某个地方,而是应该问它的实际作用,那么您可以自己决定何时需要保留它以及在何处。

我将指出,拥有强大的外部依赖项持久化策略时,具有锁的功能非常方便,因为它会跟踪您有用的信息,这些信息对于跟踪(起源)和更新有用,但是如果您那就不要不都在这里。当它被迫下咽以使其污染源树时,这是没有用的。在遗留代码库中发现这是很平常的事情,在该代码库中,人们对composer.json进行了许多更改,这些更改尚未真正应用,并且在人们尝试使用composer时被破坏。没有composer.lock,没有同步问题。

答案 7 :(得分:0)

显然是。

那是因为本地安装的作曲家将优先于composer.lock文件而不是composer.json。

如果vcs中没有可用的锁定文件,则作曲家将指向composer.json文件以安装最新的依赖项或版本。

文件composer.lock可以更深入地维护依赖关系,即它指向我们在软件中包含的软件包版本的实际提交,因此,这是最重要的文件,可以更好地处理依赖关系。

答案 8 :(得分:0)

对于 Heroku 上的任何人来说,答案很明确:“是的,应该提交”:

<块引用>

如果 composer.json 在其 require 部分指定任何类型的依赖项,则通过运行 composer.lock 生成的相应 composer update 也必须提交到存储库,或者推送将被拒绝。

来源:Heroku PHP Support: Activation