Git Stream Wrapper for PHPは、PHP コードがアプリケーション内から 1 つまたは複数の Git リポジトリと対話できるようにする PHP ライブラリです。このライブラリは、プログラムで Git リポジトリにアクセスするために使用できる Git リポジトリ抽象化と、PHP ストリーム インフラストラクチャにフックして、開発者が Git リポジトリ内のファイルに対してファイルおよびディレクトリ アクセス関数を直接使用できるようにするストリーム ラッパーで構成されます。このライブラリは、ログ、現在のリポジトリのステータス、コミット情報など、Git リポジトリのステータス情報にアクセスする手段を提供します。
PHP コア用の Git Stream Wrapper は、 Git コマンド ライン バイナリのラッパーであるため、PHP コードを実行するマシンに Git がインストールされている必要があります。 Git Stream Wrapper for PHP には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.
});
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 <[email protected]> '
)
));
$ 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 <[email protected]> '
)
));
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 ();
composer install
実行します。phpunit.xml.dist
phpunit.xml
にコピーしますphpunit.xml
のGIT_BINARY
、 SVN_BINARY
、およびSVN_ADMIN_BINARY
定数を Git バイナリへのパスに調整します。phpunit
実行しますこのライブラリは、バンドルされた PHP 8.0.27、8.1.14、および 8.2.1 (git バージョン 2.39.1) を備えた Mac OS X 12.6、およびいくつかの Ubuntu Linux インストール上でテストされていることに注意してください。現在のところ不明な理由により、Windows ではテストの実行が少し不安定です。すべてのテストは緑色になるはずですが、クリーンアップ中にアクセス制限がランダムに作動し、クリーンアップ コードによるテスト ディレクトリの削除が妨げられる可能性があります。
単体テスト スイートは、PHP 8.0、8.1、8.2、および 8.3 で GitHub Actions を使用して継続的にテストされており、現在のステータスは次のとおりです。
問題やエラーがあれば、遠慮なく Git 問題追跡を使用して報告してください。ライブラリの開発に積極的に貢献したい場合は、リポジトリを複製してプル リクエストを送信することをお勧めします。
Copyright (C) 2023 by TEQneers GmbH & Co. KG
本ソフトウェアおよび関連ドキュメント ファイル (以下「ソフトウェア」) のコピーを入手した人には、使用、コピー、変更、マージする権利を含むがこれらに限定されない、制限なくソフトウェアを取り扱う許可が、ここに無償で与えられます。 、以下の条件を条件として、本ソフトウェアのコピーを出版、配布、サブライセンス、および/または販売すること、および本ソフトウェアが提供される人物にそれを許可すること。
上記の著作権表示およびこの許可通知は、ソフトウェアのすべてのコピーまたは主要部分に含まれるものとします。
ソフトウェアは「現状のまま」提供され、明示的か黙示的かを問わず、商品性、特定目的への適合性、および非侵害の保証を含むがこれらに限定されない、いかなる種類の保証も行われません。いかなる場合においても、作者または著作権所有者は、契約行為、不法行為、またはその他の行為であるかどうかにかかわらず、ソフトウェアまたはソフトウェアの使用またはその他の取引に起因または関連して生じる、いかなる請求、損害、またはその他の責任に対しても責任を負わないものとします。ソフトウェア。