PHP的GIT流包装器
PHP的GIT流包装器是PHP库,允许PHP代码与应用程序内部的一个或多个GIT存储库进行交互。该库由GIT存储库抽象组成,该抽象可用于编程访问GIT存储库和流包装器,该流程包装器可以挂载到PHP流基础架构中,以允许开发人员在GIT存储库中的文件上直接使用文件和目录访问功能。该库提供了访问GIT存储库的状态信息的方法,例如日志,当前存储库状态或提交信息。
PHP Core的GIT流包装器是围绕GIT命令行二进制的包装器,因此需要在运行PHP代码的机器上安装GIT。 PHP的GIT流包装器不包括GIT协议抽象,它依赖于Git命令行二进制的所有功能。
该代码当前正在运行稳定(请参阅下面的Windows上的注释),应为API稳定。但是,它不是完整的 - 因此,请随时请求您需要的功能。
例子
使用存储库抽象
use TQ Git Repository Repository ;
// open an already initialized repository
$ git = Repository:: open ( ' /path/to/your/repository ' , ' /usr/bin/git ' );
// open repository and create path and init repository if necessary
$ git = Repository:: open ( ' /path/to/your/repository ' , ' /usr/bin/git ' , 0755 );
// get current branch
$ branch = $ git -> getCurrentBranch ();
// get status of working directory
$ status = $ git -> getStatus ();
// are there uncommitted changes in the staging area or in the working directory
$ isDirty = $ git -> isDirty ();
// retrieve the commit log limited to $limit entries skipping the first $skip
$ log = $ git -> getLog ( $ limit , $ skip );
// retrieve the second to last commit
$ commit = $ git -> showCommit ( ' HEAD^ ' );
// list the directory contents two commits before
$ list = $ git -> listDirectory ( ' . ' , ' HEAD^^ ' );
// show contents of file $file at commit abcd123...
$ contents = $ git -> showFile ( $ file , ' abcd123 ' );
// write a file and commit the changes
$ commit = $ git -> writeFile ( ' test.txt ' , ' Test ' , ' Added test.txt ' );
// remove multiple files
$ commit = $ git -> removeFile ( ' file_* ' , ' Removed all files not needed any more ' );
// rename a file
$ commit = $ c -> renameFile ( ' test.txt ' , ' test.txt-old ' , ' Made a backup copy ' );
// do some file operations and commit all changes at once
$ result = $ git -> transactional ( function ( TQ Vcs Repository Transaction $ t ) {
file_put_contents ( $ t -> getRepositoryPath (). ' /text1.txt ' , ' Test 1 ' );
file_put_contents ( $ t -> getRepositoryPath (). ' /text2.txt ' , ' Test 2 ' );
unlink ( $ t -> resolvePath ( ' old.txt ' ));
rename ( $ t -> resolvePath ( ' to_keep.txt ' ), $ t -> resolvePath ( ' test3.txt ' ));
$ t -> setCommitMsg ( ' Don ' t know what to write here ' );
// if we throw an exception from within the callback the changes are discarded
// throw new Exception('No we don't want to make these changes');
// note: the exception will be re-thrown by the repository so you have to catch
// the exception yourself outside the transactional scope.
});使用StreamWrapper
use TQ Git StreamWrapper StreamWrapper ;
// register the wrapper
StreamWrapper:: register ( ' git ' , ' /usr/bin/git ' );
// read the contents of a file
$ content = file_get_contents ( ' git:///path/to/your/repository/file_0.txt ' );
// show contents of a file at commit abcd123...
$ content = file_get_contents ( ' git:///path/to/your/repository/file_0.txt#abcd123 ' );
// show contents of a file two commits before
$ content = file_get_contents ( ' git:///path/to/your/repository/file_0.txt#HEAD^^ ' );
// show the directory information two commits before
$ directory = file_get_contents ( ' git:///path/to/your/repository/#HEAD^^ ' );
// list directory contents two commits before
$ dir = opendir ( ' git:///path/to/your/repository/subdir#HEAD^^ ' );
while ( $ f = readdir ( $ dir )) {
echo $ f . PHP_EOL ;
}
closedir ( $ dir );
// recursively traverse the repository two commits before
$ dir = new RecursiveDirectoryIterator ( ' git:///path/to/your/repository#HEAD^^ ' );
$ it = new RecursiveIteratorIterator ( $ dir , RecursiveIteratorIterator:: SELF_FIRST );
foreach ( $ it as $ fileInfo ) {
echo str_repeat ( ' ' , $ it -> getDepth () * 3 ). $ fileInfo -> getFilename (). PHP_EOL ;
}
// retrieve the second to last commit
$ commit = file_get_contents ( ' git:///path/to/your/repository?commit&ref=HEAD^^ ' );
// retrieve the commit log limited to 5entries skipping the first 2
$ log = file_get_contents ( ' git:///path/to/your/repository?log&limit=5&skip=2 ' );
// remove a file - change is committed to the repository
unlink ( ' git:///path/to/your/repository/file_to_delete.txt ' );
// rename a file - change is committed to the repository
rename ( ' git:///path/to/your/repository/old.txt ' , ' git:///path/to/your/repository/new.txt ' );
// remove a directory - change is committed to the repository
rmdir ( ' git:///path/to/your/repository/directory_to_delete ' );
// create a directory - change is committed to the repository
// this creates a .gitkeep file in new_directory because Git does not track directories
mkdir ( ' git:///path/to/your/repository/new_directory ' );
// write to a file - change is committed to the repository when file is closed
$ file = fopen ( ' git:///path/to/your/repository/test.txt ' , ' w ' );
fwrite ( $ file , ' Test ' );
fclose ( $ file );
// support for stream context
$ context = stream_context_create ( array (
' git ' => array (
' commitMsg ' => ' Hello World ' ,
' author ' => ' Luke Skywalker '
)
));
$ file = fopen ( ' git:///path/to/your/repository/test.txt ' , ' w ' , false , $ context );
fwrite ( $ file , ' Test ' );
fclose ( $ file ); // file gets committed with the preset commit message and author
// append to a file using file_put_contents using a custom author and commit message
$ context = stream_context_create ( array (
' git ' => array (
' commitMsg ' => ' Hello World ' ,
' author ' => ' Luke Skywalker '
)
));
file_put_contents ( ' git:///path/to/your/repository/test.txt ' , ' Test ' , FILE_APPEND , $ context );
// it is now possible to register repository-specific paths on the stream wrapper
StreamWrapper:: getRepositoryRegistry ()-> addRepositories (
array (
' repo1 ' => Repository:: open ( ' /path/to/repository/1 ' , ' /usr/bin/git ' , false ),
' repo2 ' => Repository:: open ( ' /path/to/repository/2 ' , ' /usr/bin/git ' , false ),
)
);
$ content1 = file_get_contents ( ' git://repo1/file_0.txt ' );
$ content2 = file_get_contents ( ' git://repo2/file_0.txt ' );
// unregister the wrapper if needed
StreamWrapper:: unregister ();要求
- PHP> = 8.0.0
- 作曲家可包括依赖项
- 在运行PHP代码的机器上安装了GIT
- 如果要使用SVN组件,则在运行PHP代码的机器上安装了SVN
运行测试
- 克隆存储库
- 运行
composer install以安装依赖项并创建自动加载器 - 复制
phpunit.xml.dist到phpunit.xml - 将
phpunit.xml中的GIT_BINARY,SVN_BINARY和SVN_ADMIN_BINARY常数调整到git二进制的路径 - 从克隆的项目文件夹中运行
phpunit
请注意,该库已在Mac OS X 12.6上进行了测试,其中包含捆绑的PHP 8.0.27、8.1.14和8.2.1(GIT版本2.39.1)和几个Ubuntu Linux安装。由于目前未知原因,该测试在Windows上运行有些不稳定。所有测试均应为绿色,但是在清理过程中,可能会有一些访问限制随机启动并防止清理代码删除测试目录。
单位测试套件在PHP 8.0、8.1、8.2和8.3上的GITHUB操作不断测试,其当前状态为:
贡献
请随时使用GIT问题跟踪来报告任何问题或错误。如果您想积极地开发图书馆,则鼓励您克隆存储库并发送拉动请求。
执照
Teqneers GmbH&Co。KG版权(C)2023
特此免费获得许可,免费授予任何获得此软件副本和相关文档文件(“软件”)的人,以无限制地处理软件,包括无限制的使用权,复制,复制,修改,合并,发布,分发,分发,分发,分配,sublicense和/或允许软件允许与以下条件相关的软件,以下是以下条件。
上述版权通知和此许可通知应包含在软件的所有副本或大量部分中。
该软件是“原样”提供的,没有任何形式的明示或暗示保证,包括但不限于适销性,特定目的的适用性和非侵权的保证。在任何情况下,作者或版权持有人都不应对任何索赔,损害赔偿或其他责任责任,无论是在合同,侵权的诉讼中还是其他责任,是由软件,使用或与软件中的使用或其他交易有关的。
通过命令行克隆项目: