balbuf/composer-git-merge-driver

自定义git合并驱动,用于最小化composer.json和composer.lock文件中的合并冲突。

v1.1.0 2019-01-23 01:57 UTC

This package is auto-updated.

Last update: 2024-09-23 04:40:56 UTC


README

Composer JSON Git合并驱动提供了一种机制,可以更有效地合并在单独的分支/开发历史中同时修改的composer.jsoncomposer.lock文件。当composer JSON文件需要比简单的“快进”更复杂的合并时,将调用自定义git合并驱动

工作原理

合并驱动仅针对composer的JSON文件替换git的标准合并算法:不是分析文件的修改行,而是解析JSON并比较实际属性和值的变化。因此,合并驱动能够更优雅地处理大多数新、更新和删除的依赖项。只有在多个参与合并的开发历史中修改了版本约束、锁定版本号或相同依赖项的存在/不存在时,才会触发合并冲突。

例如,如果某个依赖项在一个分支中更新,而在另一个分支中删除,则会触发合并冲突,因为不清楚合并后希望对该依赖项进行哪种修改。然而,如果在两个分支的require部分都附加了一个新的、不同的依赖项,合并驱动将理解应该保留两者,而标准的git合并驱动会触发合并冲突,因为在两个分支中编辑了相同的行。

更普遍地说,所有对象数据结构都优雅地递归合并,这意味着composer JSON文件中的其他composer配置属性(例如extraconfig)也将正确合并——只要更改不是模糊的。实际上,合并驱动将在任何最外层数据结构为对象的JSON文件上工作。

Composer Lock处理

特别是对于锁定文件,执行特殊处理以最大限度地减少潜在的合并冲突。例如,锁定依赖项数据在合并过程中转换为对象,并在合并完成后转换回适当的数据结构。此外,content-hash属性被排除在合并之外,因为该属性的非常性质保证两个不同的分支会有冲突的值。内容哈希由composer用于有效地识别composer.json文件已更改,因此合并后实际值并不一定重要。作为无法生成准确哈希的解决方案,合并驱动为其哈希设置自己的唯一值,向composer发出信号,表示已发生更改;该值是一个简单的消息,指导您运行composer update --lock,以便composer可以重新生成真正的哈希!

安装

合并驱动可以全局安装或按仓库安装,并可以全局或按仓库配置和激活,即您可以全局安装驱动程序,但仅在特定项目上激活它。

1. 在您的系统上安装合并驱动。

使用composer全局安装驱动程序

$ composer global require balbuf/composer-git-merge-driver

或仅在一个特定的仓库中安装

$ composer require --dev balbuf/composer-git-merge-driver

注意:如果您通过后者(按仓库)的方法安装驱动程序,它将被添加到仓库的composer.json中,因此将作为依赖项为所有仓库用户安装。

2. 使用git配置合并驱动程序。

通过一个git config文件告知git该驱动程序的存在,使其可用。

[merge "composer_json"]
    name = composer JSON file merge driver
    driver = composer-git-merge-driver %O %A %B %L %P
    recursive = binary

要使用您的默认命令行文本编辑器打开git config文件进行编辑

$ git config -e

默认情况下,这允许您编辑当前仓库的配置文件,意味着驱动程序仅安装到本地仓库。要编辑您的用户的全局配置文件,请附加--global标志;要编辑系统范围的配置文件,请附加--system标志。

将上面的块复制并粘贴到配置文件中,并保存它。此示例假定您的$PATH包括Composer的vendor bin路径(默认情况下,全局安装为~/.composer/vendor/bin或仓库安装为./vendor/bin)。如果不是,请确保更新您的$PATH或将适当的路径添加到二进制文件的driver行。

此仓库包含一个方便的示例.gitconfig文件。如果composer-git-merge-driver作为项目依赖项安装,可以像这样安装示例.gitconfig文件

$ git config --add include.path $(git rev-parse --show-toplevel)/vendor/balbuf/composer-git-merge-driver/.gitconfig

有关git配置文件的更多信息,请参阅git文档

3. 激活合并驱动程序。

最后,必须通过一个git attributes文件激活composer.jsoncomposer.lock文件。

composer.json merge=composer_json
composer.lock merge=composer_json

要仅针对特定仓库激活,编辑仓库内的.git/info/attributes文件。要为您的用户全局激活,编辑~/.gitattributes文件;要系统范围激活,编辑$(prefix)/etc/gitattributes文件(例如,/usr/local/etc/gitattributes)。将上面的块复制并粘贴到配置文件中并保存它。在某些情况下,该文件可能尚未存在,在这种情况下,您可以在上述路径创建该文件。

有关git attributes文件的更多信息,请参阅git文档

用法

每次在激活了该驱动程序的仓库中必须合并composer.json和/或composer.lock文件时,都会自动调用合并驱动程序。如果文件中有任何合并冲突,则会启动标准的git合并冲突程序:您将被通知哪些文件包含冲突,冲突通过标准冲突标记表示(例如,<<<<<<)。

如果没有冲突并且合并可以干净地应用,则合并按正常完成。然而,更改后的锁文件会导致一个非标准的content-hash值(无论是否有冲突)。虽然保留哈希值应该没有问题,但最好让Composer重新生成哈希。要这样做,只需运行

$ composer update --lock

实际上的哈希值会告诉您执行此操作,但如果合并完成且没有冲突,您可能甚至不会注意到消息。如果有冲突,则应在解决冲突后、完成合并之前完成此步骤。如果没有冲突且合并完成,可以通过修改合并提交来避免创建额外的提交

$ composer update --lock
$ git add composer.lock
$ git commit --amend --no-edit

附加信息

要求

合并驱动程序是用PHP编写的,需要至少版本5.4。

已知限制

  • 合并驱动程序解析并重新生成JSON以完成合并。因此,在过程中可能会丢失或更改一些格式。对于composer.json文件,驱动程序尝试检测工作树中文件的缩进偏好,并在重新生成JSON时复制该缩进,这应该会最小化格式更改。然而,某些空白样式无法保留,例如行断 fewer 行或更多空白。虽然文件的解释内容不会受到影响,但格式可能导致合并后的文件出现额外的更改。(与composer的行为一致,composer.lock文件通过PHP的json_encode函数的默认行为重新生成,并且始终使用一致的缩进。)

  • 当发生合并冲突,且对象最后的属性被删除时,接受被删除的版本会导致由于前一个属性存在尾随逗号而出现无效语法。应小心检查整个文件的语法,并根据需要手动更新。

致谢

感谢@christian-blades-cb@jphass提供灵感和示例。