解决合并冲突#
当团队在同一个 Composer 项目上协作时,最终会遇到多个成员在多个分支中添加、更新或删除了 `composer.json` 和 `composer.lock` 文件中的内容的情况。当这些分支最终合并在一起时,就会出现合并冲突。解决这些合并冲突并不像处理其他文件那样简单,特别是对于 `composer.lock` 文件而言。
注意: 对于锁定文件,为什么文本 based 的合并不可行可能并不立即显而易见,所以让我们想象以下示例,我们希望合并两个分支:
- 分支 1 添加了包 A,它依赖于包 B。包 B 被锁定在版本 `1.0.0`。
- 分支 2 添加了包 C,它与包 B 的所有低于 `1.2.0` 的版本冲突。
基于文本的合并会导致包 A 版本 `1.0.0`,包 B 版本 `1.0.0` 以及包 C 版本 `1.0.0`。这是一个无效的结果,因为包 C 的冲突没有被考虑,需要升级包 B。
1. 重新应用更改#
合并 Composer 文件最安全的方法是接受一个分支的版本,然后应用另一个分支的更改。
例如,我们有两个分支:
- 添加了包 'A'
- 删除了包 'B',添加了包 'C'。
要解决合并这两个分支时的冲突:
- 我们选择更改最多的分支,并接受该分支的 `composer.json` 和 `composer.lock` 文件。在本例中,我们选择分支 2 的 Composer 文件。
- 我们重新应用另一个分支(分支 1)的更改。在本例中,我们需要再次运行 `composer require package/A`。
2. 验证合并后的文件#
在提交之前,请确保生成的 `composer.json` 和 `composer.lock` 文件有效。为此,请运行以下命令:
php composer.phar validate
php composer.phar install [--dry-run]
使用 Git 自动化解决合并冲突#
可以使用自定义的 Git 合并驱动程序对 Git 的冲突解决进行一些改进。
可以在 balbuf 的 Composer Git 合并驱动程序 中找到一个示例。
重要事项#
请记住,每当锁定文件上出现合并冲突时,有关在一个分支中锁定新包的具体版本的的信息都会丢失。当分支 1 中的包 A 被约束为 `^1.2.0` 并锁定为 `1.2.0` 时,如果使用分支 2 作为基准,并且执行了新的 `composer require package/A:^1.2.0`,它可能会被更新,因为这将使用约束允许的最新版本(如果可能)。现在可能存在该包的 1.3.0 版本,它将被使用。
选择正确的 版本约束 并确保在使用 下一个重要版本运算符 时,包符合 语义版本控制,可以确保合并分支不会通过意外更新依赖项而破坏任何东西。
从错误解决的合并冲突中恢复#
如果未遵循上述步骤,并且仍然进行了基于文本的合并,那么您的 Composer 项目可能处于一种状态,其中观察到意外的行为,因为 `composer.lock` 文件未(完全)与 `composer.json` 文件同步。
这里可能发生两种情况:
- `composer.json` 文件的 `require` 或 `require-dev` 部分中存在不在锁定文件中的包,因此从未安装过这些包。
注意: 从 Composer 2.5 版本开始,如果存在必需但不在 `composer.lock` 中的包,则在运行 `install` 时会导致错误。
- `composer.lock` 文件中存在并非任何必需包的直接或间接依赖项的包。因此,即使运行 `composer why vendor/package` 说明它不是必需的,该包也会被安装。
有几种方法可以解决这些问题:
A. 从头开始#
最简单但影响最大的选项是运行 `composer update` 以从头开始解决到正确状态。
这样做的缺点是以前锁定的包版本现在会更新,因为有关以前包版本的信息已经丢失。如果所有依赖项都遵循 语义版本控制 并且您的 版本约束 使用 下一个重要版本运算符,这应该不是问题,否则您可能会无意中破坏您的应用程序。
B. 从 Git 历史记录中重建#
在很多情况下可能不太可行,但值得一提的一个选项:
可能可以通过回到 Git 历史记录并找到最新的有效 `composer.lock` 文件,然后重新要求新的依赖项来重建正确的包状态。
C. 手动解决问题#
可以选择在不查看 Git 历史记录或从头开始的情况下,从 `composer.json` 和 `composer.lock` 文件之间的差异中恢复。为此,我们需要分别解决问题 1 和 2。
1. 检测和修复丢失的必需包#
要检测任何必需但未安装的包,您可以简单地运行:
php composer.phar validate
如果存在必需但未安装的包,您应该会看到类似于以下内容的输出:
./composer.json is valid but your composer.lock has some errors
# Lock file errors
- Required package "vendor/package-name" is not present in the lock file.
This usually happens when composer files are incorrectly merged or the composer.json file is manually edited.
Read more about correctly resolving merge conflicts https://getcomposer.org.cn/doc/articles/resolving-merge-conflicts.md
and prefer using the "require" command over editing the composer.json file directly https://getcomposer.org.cn/doc/03-cli.md#require
要解决此问题,只需对这里列出的每个包运行 `composer update vendor/package-name`。完成对这里列出的每个包的操作后,再次运行 `composer validate` 应该不会出现锁定文件错误。
./composer.json is valid
2. 检测和修复多余的包#
要检测和修复已锁定但不是直接/间接依赖项的包,您可以运行以下命令:
php composer.phar remove --unused
如果不存在已锁定但不是依赖项的包,该命令将输出以下内容:
No unused packages to remove
如果存在要清理的包,则输出将如下所示:
vendor/package-name is not required in your composer.json and has not been removed
./composer.json has been updated
Running composer update vendor/package-name
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 0 updates, 1 removal
- Removing vendor/package-name (1.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
发现打字错误?文档有错误?分叉并编辑 它!