应该作曲家。锁被提交到版本控制?

我对在带有存储库的应用程序中使用composer.lock有点困惑。

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

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

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

180783 次浏览

如果你更新了你的库,你也想提交锁文件。它基本上说明您的项目被锁定到您正在使用的库的特定版本。

如果您提交了更改,并且有人提取了您的代码并更新了依赖项,那么锁文件应该是未修改的。如果它被修改了,这意味着您有了某个东西的新版本。

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

在做了几个项目后,我的立场是composer.lock不应该作为项目的一部分。

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

如果你担心在编写器更新之间依赖关系的变化,那么你对自己的版本控制方案缺乏信心。版本(1.0、1.1、1.2等)应该是不可变的,你应该避免在初始特性开发之外使用“dev-”和“x *”通配符。

提交锁文件是依赖项管理系统的回归,因为依赖项版本现在已经回到隐式定义的状态。

此外,你的项目永远不应该在每个环境中重新构建或重新获取其依赖项,尤其是prodd。你的交付品(tar, zip, phar,一个目录等)应该是不可变的,并在环境中进行推广而不需要更改。

当然可以。

作曲家的文档声明了这一点(强调):

提交应用程序的编写器。锁定(连同composer.json)到版本控制。

就像@meza说的:你应该提交锁文件,这样你和你的合作者就可以在同一组版本上工作,并防止你说“但它在我的电脑上工作”。: -)

图书馆:可能不会。

作曲家的文档中提到了这个问题:

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

并声明在这里:

对于你的库,你可以提交作曲家。如果你想锁定文件。这可以帮助您的团队始终针对相同的依赖版本进行测试。但是,这个锁文件不会对依赖于它的其他项目产生任何影响。它只对主要项目有影响。

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

  1. 不应该直接在生产端更新依赖项。
  2. 您应该对composer.lock文件进行版本控制。
  3. 您不应该对实际依赖项进行版本控制。

1. 不应该直接在生产端更新依赖项,因为你不知道这会如何影响你代码的稳定性。新的依赖关系可能会引入错误,它可能会改变代码行为的方式,影响你自己的行为,它可能与其他依赖关系不兼容,等等。你应该在开发环境中完成这些工作,然后进行适当的QA和回归测试等。

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

关于不需要composer.lock,您将看到的一个参数是,您可以在composer.json文件中设置所需的确切版本,这样,每当有人运行composer install时,它将为他们安装相同的代码。这是不对的,因为您的依赖项有它们自己的依赖项,并且它们的配置可能以允许更新到反版本,甚至可能是整个版本的格式指定。

这意味着即使您指定在composer.json中使用Laravel 4.1.31,它的composer.json文件中的Laravel可能需要自己的依赖项作为Symfony事件分派器:2.*。 有了这种配置,你可能会得到Laravel 4.1.31和Symfony事件分派器2.4.1,而你团队中的其他人可能会得到Laravel 4.1.31和事件分派器2.6.5,这完全取决于你最后一次运行composer install是什么时候

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

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

3.您不应该对实际依赖项进行版本控制,因为它毫无意义。使用composer.lock,您可以安装依赖项的确切版本,并且不需要提交它们。为什么你要添加到你的repo 10000文件的依赖,当你不应该更新他们。如果你需要改变其中的一个,你应该在那里做出你的改变。如果你担心每次构建或发布时都必须获取实际的依赖项,composer有不同的方法来缓解这个问题,缓存,zip文件等。

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

锁定文件的目的是记录已安装的确切版本,以便可以重新安装。这意味着如果您的版本规范为1。*然后你的同事运行composer update,安装1.2.4,然后提交composer。锁文件,当你安装composer时,你也会得到1.2.4,即使1.3.0已经发布了。这确保了每个参与项目的人都有相同的版本。

这意味着,如果自上次安装编写器以来提交了任何东西,则如果没有锁定文件,您将获得新的第三方代码

同样,如果您担心代码破坏,这也是一个问题。这也是为什么把作曲家看作是以作曲家为中心的重要原因之一。锁文件。

来源:# EYZ0。


提交应用程序的编写器。锁定(连同composer.json)到版本控制。这很重要,因为install命令检查锁文件是否存在,如果存在,它就下载指定的版本(不管什么编写器)。json表示)。这意味着任何建立项目的人都将下载完全相同版本的依赖项。您的CI服务器、生产机器、团队中的其他开发人员,所有东西和每个人都运行在相同的依赖项上,这减轻了仅影响部署的某些部分的潜在错误。即使你独自开发,在六个月后重新安装项目时,即使你的依赖项发布了许多新版本,你也可以确信安装的依赖项仍然可以工作。

来源:# EYZ0。

如果你担心你的代码被破坏,你应该将composer.lock提交给你的版本控制系统,以确保你所有的项目合作者都在使用相同版本的代码。如果没有锁定文件,您每次都会得到新的第三方代码。

例外情况是当你使用元应用程序时,其中的依赖关系应该在安装时更新(如Zend框架2骨架应用程序)。因此,目标是在每次开始开发时获取最新的依赖项。

来源:Composer: It 's All About Lock File

参见:编写器更新和安装之间有什么区别?

这个问题没有确切的答案。

一般来说,composer不应该做构建系统应该做的事情,你也不应该把composer放在上面。锁定VCS。作曲家可能会奇怪地把它写反了。最终用户而不是产品不应该使用锁文件。通常你的构建系统会保存快照、可重用的dirs等等,而不是每次都保存一个空的dir。从composer签出库的人可能希望该库使用锁,以便对库加载的依赖项进行测试。

另一方面,这会显著增加版本管理的负担,因为依赖关系将被严格锁定,因此几乎可以肯定每个库都需要多个版本。如果每个库可能都有一个稍微不同的版本,那么你需要一些多库版本支持,你也可以很快看到需要的依赖关系的大小,因此建议将它保留在叶子上。

考虑到这一点,我真的不认为锁文件是有用的库或您自己的workdirs。它只在我的构建/测试平台上使用,该平台支持任何外部获取的资产,只在需要时更新它们,为测试、构建和部署提供可重复的构建。虽然它可以保存在VCS中,但并不总是保存在源树中,构建树要么在VCS结构的其他地方,要么由其他系统在其他地方管理。如果它存储在VCS中,是否将其保留在与源代码树相同的回购中是有争议的,因为否则每次拉都可能带来大量的构建资产。除了生产/敏感凭证和膨胀之外,我很喜欢把所有的东西都安排在一个良好的回购中。

SVN比git做得更好,因为它不强迫你获取整个回购(尽管我怀疑git实际上也不是严格需要的,但对它的支持是有限的,它不常用)。简单的构建回购通常只是一个覆盖分支,你合并/导出构建树。有些人将外部资源合并到源树中,或者进一步分离外部、构建和源树。它通常有两个目的,构建缓存和可重复构建,但有时至少在某种程度上保持分离也可以轻松地允许新的/空白的构建和多个构建。

对此有许多策略,但没有一种特别适合持久化源代码列表,除非您在源代码树中保留外部源代码。

文件中还有哈希值,两个人更新包时如何合并?光这一点就足以让你认为这可能是误解了。

人们对锁文件提出的论点是他们对问题采取了非常具体和限制性的观点。想要可重复的构建和一致的构建?在VCS中包含供应商文件夹。然后,您还可以加快获取资产的速度,并且不必在构建期间依赖可能损坏的外部资源。除非绝对必要,否则我创建的构建和部署管道都不需要外部访问。如果你必须更新一个外部资源,那就只有一次。编码器试图实现的东西对于分布式系统是有意义的,除了前面提到的,它没有意义,因为它最终会导致库更新的依赖关系地狱,经常发生冲突,更新速度和最慢的更新包一样慢。

此外,我更新猛烈。每次开发时,我都会更新和测试所有内容。有一个非常非常小的窗口,显著的版本漂移潜入。实际上,当支持语义版本时,这往往是为作曲家准备的,你不应该有那么多兼容性问题或损坏。

在作曲家。Json你把你需要的包和他们的版本。您可以在那里锁定版本。然而,这些包也有动态版本的依赖关系,不会被作曲家锁定。json(虽然我不明白为什么你不能自己也把它们放在那里,如果你想要它们被版本锁定),所以其他人运行composer安装得到一些不同的东西没有锁。你可能不太在意,也可能在意,这要看情况。你应该关心吗?可能至少有一点,足以确保您在任何情况下都能意识到它及其潜在影响,但如果您总是有时间先DRY run并修复任何更新的内容,那么它也可能不是问题。

编写器试图避免的麻烦有时并不存在,编写器锁文件可能带来的麻烦是显著的。他们绝对没有权利告诉用户他们应该或不应该做什么关于构建和源资产(是否加入或分开在风投),因为这不关他们的事,他们不是你或我的老板。"作曲家说"不是权威,他们不是你的上级也不会在这个问题上给任何人任何优势。只有你自己知道你的真实情况,知道什么是最好的。然而,他们可能会为不了解事物如何工作的用户提供默认的行动方案,在这种情况下,您可能会想要遵循它,但我个人认为这并不能真正替代了解事物如何工作并能够正确地满足您的需求。最终,他们对这个问题的答案是最好的猜测。制作作曲家的人不知道你应该把作曲家放在哪里。他们也不应该锁上。他们唯一的责任就是告诉你它是什么,它能做什么。除此之外,你需要决定什么对你是最好的。

保留锁文件对于可用性是有问题的,因为作曲者对它是使用锁还是JSON非常保密,并且并不总是很好地同时使用这两种文件。如果你运行安装,它只使用锁文件,它会出现,所以如果你添加一些作曲。Json,那么它就不会被安装,因为它不在你的锁中。对于json/lock文件来说,操作的真正作用和作用并不直观,有时甚至看起来没有意义(帮助说安装需要一个包名,但试图使用它时,它说没有)。

要更新锁或应用json中的更改,你必须使用update,你可能不想更新所有内容。锁优先选择应该安装什么。如果有一个锁文件,它就是所使用的。你可以在一定程度上限制更新,但系统仍然一团糟。

更新需要一段时间,几gb的内存。我也怀疑,如果你拿起一个项目,它已经有一段时间没有被碰过了,从它的版本来看,随着时间的推移,它可能不会有效地做到这一点,这只是扼杀它。

当涉及到秘密的复合命令时,它们非常非常狡猾,你不能期望它是复合的。默认情况下,composer remove命令似乎映射到composer update和composer remove。

你真正需要问的问题不是你是否应该把锁保存在你的源树中,或者你是否应该以某种方式将它保存在某个地方,而是你应该问它实际上是做什么的,然后你可以自己决定什么时候需要将它保存在哪里。

我要指出的是,当你有一个强大的外部依赖持久性策略时,拥有锁的能力是非常方便的,因为它可以跟踪你的信息,用于跟踪(起源)和更新它,但如果你没有,那么它既不在这里也不在那里。当它作为强制选项强行进入您的喉咙以污染您的源树时,它是没有用处的。这在遗留代码库中很常见,人们对composer做了很多更改。Json还没有真正应用,当人们尝试使用composer时就会被破坏。没有作曲家。锁定,没有不同步问题。

是的很明显。

这是因为本地安装的编写器将优先选择编写器。在composer.json上锁定文件。

如果锁文件在vcs中不可用,composer将指向composer。Json文件来安装最新的依赖项或版本。

文件编写器。Lock更深入地维护依赖关系,即它指向我们软件中包含的包版本的实际提交,因此这是最重要的文件之一,它更精细地处理依赖关系。

对于任何在Heroku上的人来说,答案都是明确的“是的,它应该被承诺”:

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

来源:# EYZ0。

这一点在这里已经得到了充分的回答。

博士TL;

当然,你应该vc composer.lock

但我要讲的是为什么

作曲家。json的作用

作曲家。json是php包的依赖项清单的入口点。

它已经为包开发人员开出了遵循 语义版本控制的处方。

所以通过这种方式,如果x.y.z中的api版本(x)发生了变化,你就会明白有一些事情需要注意,否则你可以将你的版本锁定到"~x"版本。

并非所有包都遵循semversion

但是,有很多包不遵循规则(5.3 &5.4 API等级改变或损坏):

  1. 不尊重semversioning原则(api级别更改)
  2. 新的包与旧的API不兼容(没有经过很好的测试和损坏)

解决方案composer.lock

作曲家想出了一个解决办法。另一个用于锁定包版本的文件。(composer.lock)

它保存了确切的包版本,因此如果任何人想拥有相同的依赖版本,都可以从中受益。

在所有部署之间保持清单相同

值得一提的是,12个因素现代web开发原则之一是在所有部署中保持依赖关系相同,这样每个部署都可以测试它。

:

你必须留下作曲者。在版本控制下锁定

在生产方面:

composer install --no-dev

安装所有vc控制的锁文件。

作曲家的最终用户。json,composer.lock

composer.json开发人员用来总结deps和版本的精简文件。

composer.lock将被部署(机器)用于在部署上安装确切的版本号。

类比

它就像知识产权,域的类比:

供机器使用的IP(锁文件)

打算由人类使用的域(json)

然而,人(开发人员)和机器(部署人员)都可以从两者中读取并受益,但两者都有更可取的版本。