GIT 中的 Composer 和 composer.lock 和合并冲突

Posted

技术标签:

【中文标题】GIT 中的 Composer 和 composer.lock 和合并冲突【英文标题】:Composer & composer.lock in GIT and merge conflicts 【发布时间】:2014-11-01 22:38:48 【问题描述】:

这是我们的情况:

我们有 3 个不同的 Laravel 项目,所有 3 个项目都依赖于我们的核心项目。 这个 Core 项目是一个单独的 Laravel 包,托管在我们的私有仓库中,并用作其他项目的依赖项。

以前,每当核心项目发生变化时,我们只需在我们的服务器上运行 composer update ourvendor/ourcorepackage 来为每个项目引入核心变化。然而,最近,当我们尝试在具有 512 MB 内存的 Digital Ocean 暂存环境上运行更新时,composer 似乎遇到了严重的内存问题。见:https://github.com/composer/composer/issues/1898

我经常遇到的解决方案是人们说您应该始终在生产服务器上运行 composer install。我可以在安全性方面与此相关,因为如果您更新到某些可能会破坏您的代码的第 3 方软件包的新版本,这可能会很危险。但在我们的例子中,我们只更新了自己的核心包,所以我们知道我们在做什么,但是这个内存问题迫使我们使用 composer install 方法,因为它对内存的需求较少。

所以基本上这是我们当前的工作流程:

    当我们的核心包发生变化时,我们需要运行一个作曲家 在本地更新每个项目上的ourvendor/ourpackage 这会生成一个 composer.lock 文件

    我们在 repo 中提交 composer.lock 文件

    在每个项目的服务器上,我们运行 git pull 并运行 composer 安装。这只会更新我们的核心包并运行得更快 并且与作曲家更新相比没有内存问题

但是这个解决方案引发了 2 个问题:

    由于我们在同一个项目上与多个开发人员合作,因此在本地拉取更改时,我们有时最终会遇到 composer.lock 文件的合并冲突。 在服务器上运行 git pull 会出现错误:您对以下文件的本地更改将被合并覆盖:composer.lock 请在合并之前提交您的更改或存储它们。

那么我应该在这里做什么?在服务器上拉之前删除 composer.lock 文件? 我们应该如何处理 composer.lock 文件的合并冲突?

很遗憾,composer update 遇到内存问题,因为这种方法看起来更合乎逻辑。只需更新您想要的软件包,无需使用 composer.lock 文件..

请建议在我们的案例中,正确的 GIT 和 composer 工作流程应该如何以及如何解决上述冲突?

非常感谢您的意见

【问题讨论】:

blog.doh.ms/2016/11/28/solving-conflicts-in-composer-lock 相关:Should composer.lock be committed to version control? 【参考方案1】:

如果开发人员自己不执行此步骤,您如何测试核心更新(或任何其他更新的依赖项)不会破坏使用它的项目中的内容?

这就是为什么通常的工作流程期望 composer update 在具有足够 RAM(即可能超过 1GB 设置为 php 的内存限制)的开发机器上运行,并且应该由开发人员手动触发更新(如果由持续集成构建自动触发,内存要求也适用于这台机器)。

没有办法绕过这个内存要求。仅安装了 512 MB RAM 的 Web 服务器可能能够在几乎没有任何并发​​用户的情况下充当临时服务器,但它不应该用于更新 Composer 依赖项。

我个人用一个非常简单的系统修复了composer.lock 中的合并冲突:删除锁定文件并运行composer update。这会将所有依赖项更新到满足版本要求的最新版本,并创建一个新的工作 composer.lock 文件,该文件在合并期间被提交。

我不怕更新所有内容,因为要么它按预期工作,要么我的测试会很快发现错误。

我确实选择了我谨慎使用的 3rd 方包:

他们必须标记他们的版本,最好使用语义版本控制。 我不为发布版本使用任何分支(在开发过程中很少有人使用它们是痛苦的) 如果他们做出向后不兼容的更改,他们应该发布一个新的主要版本 本地开发的包也遵循这些要求

这适用于我们本地 Satis 实例提供的大约 270 个包(可能也是尝试减少内存占用时要考虑的一个因素 - 只有 Composer 已知的包才能最终进入内存:比较 packageagist 上可能提供的一万个包.org 包含 270 个本地软件包)。 270个包中的60个包由20个开发者在本地开发,并随机发布新版本。最近 2 年的更新失败非常罕见,应该像处理其他 bug 一样处理:如果检测到标记的版本不兼容,我们会发布一个 bugfix 版本来还原更改,并用新的主要版本标记原始更改,如果需要进行不兼容的更改。

所以你要求的工作流程大概是这样的:

任何时候,任何开发人员都应该能够在他们的本地计算机上运行composer update。 他们应该能够检测到这是否会破坏本地计算机上的内容。 如果没有任何问题,他们会将包括 composer.lock 文件在内的更改提交到 Git 暂存服务器仅运行 composer install,并将使用开发人员在其计算机上使用的版本。 如果暂存时没有任何问题,则该版本已准备好用于生产。

在另一台开发人员机器上合并已经提交的版本可能会显示与 composer.lock 的合并冲突。

解决所有其他文件的冲突。 应该删除composer.lock 文件。 从这里开始,工作流程如上,即: 开发者应该能够在他的本地机器上运行composer update。 他们应该能够检测到这是否会破坏他的本地计算机上的东西。 如果没有损坏...等等。

【讨论】:

感谢您的回答。我们还对我们的包使用严格的版本控制,并且只在本地测试后更新它们。我刚刚查了一下,你可以通过运行轻松更新你的 composer.lock 文件:在 composer.lock 上合并冲突? 应该删除 composer.lock 文件。 添加一个新包怎么样?删除 composer.lock 会导致其他开发人员丢失工作。 要正确处理与 composer.lock 的合并冲突很困难。删除文件不是解决方案,因为这可能会安装与其他开发人员使用的不同的版本。 composer.lock 文件旨在跟踪哪些版本已安装并应提交给 git。见:blog.theodo.fr/2013/03/resolving-composer-merge-conflicts @LukeH ...在写完答案三年后,出现了更好的做法。另一方面,即使应用了在合并期间删除锁定文件的压路机策略,定期更新其依赖项并进行足够测试以发现导致错误的项目也不太可能受到合并冲突的影响。 删除 composer.lock 并运行 composer update 让我的生活更轻松 +1【参考方案2】:

另一种方法(不做composer update):

    composer.json 中的新(和已删除)行复制到单独的文本文件中。 使用整个远程composer.jsoncomposer.lock 文件。 在合并冲突模式下: composer install 对于您在第 1 步中记下的每个新包,请运行 composer require vendor/package:version 对于您在步骤 1 中记下的每个已删除的包,运行 composer remove vendor/package 测试!,提交,完成!

此方法将保留远程分支(可能是masterdevelop 分支)的锁,并且只更新您的新包。

【讨论】:

IMO 这是一个更安全的选择,在大型项目上使用composer update 可能会适得其反。我也更喜欢只接受来自上游的作曲家文件的所有更改,然后通过composer require一一介绍我的composer.json更改我会说这是最安全的方法并且始终有效。【参考方案3】:

有时composer update 会破坏事物。 我要做的是。

    放弃我对composer.lock的所有更改 合并composer.json 运行composer install,以便根据composer.lock安装软件包。 拿一个你的包然后运行composer require vendor/package如果你 添加该软件包或 composer remove vendor/package 如果您删除了它。 如果有多个包,它将自动从composer.json 安装

【讨论】:

和@Xover 之前的回答差不多

以上是关于GIT 中的 Composer 和 composer.lock 和合并冲突的主要内容,如果未能解决你的问题,请参考以下文章

composer引用私有git

Composer - 添加没有 composer.json 的 git 存储库

更改包的 Composer git 源

Laravel 5.2 - 使用 composer 和 git bash 安装 laravel 时出错

如何使用 Composer 从本地 Git 存储库安装标记提交?

composer引用本地git做为源库