PHP용 Git Stream Wrapper는 PHP 코드가 애플리케이션 내에서 하나 이상의 Git 저장소와 상호 작용할 수 있게 해주는 PHP 라이브러리입니다. 라이브러리는 프로그래밍 방식으로 Git 저장소에 액세스하는 데 사용할 수 있는 Git 저장소 추상화와 개발자가 Git 저장소의 파일에 대해 직접 파일 및 디렉터리 액세스 기능을 사용할 수 있도록 PHP 스트림 인프라에 연결할 수 있는 스트림 래퍼로 구성됩니다. 라이브러리는 로그, 현재 저장소 상태 또는 커밋 정보와 같은 Git 저장소의 상태 정보에 액세스할 수 있는 수단도 제공합니다.
PHP 코어용 Git Stream Wrapper는 Git 명령줄 바이너리를 둘러싼 래퍼이므로 PHP 코드를 실행하는 시스템에 Git을 설치해야 합니다. PHP용 Git Stream Wrapper에는 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 문제 추적을 사용하세요. 라이브러리 개발에 적극적으로 기여하고 싶다면 저장소를 복제하고 끌어오기 요청을 보내는 것이 좋습니다.
저작권 (C) 2023 by TEQneers GmbH & Co. KG
본 소프트웨어 및 관련 문서 파일("소프트웨어")의 사본을 취득한 모든 사람에게 사용, 복사, 수정, 병합에 대한 권리를 포함하되 이에 국한되지 않고 제한 없이 소프트웨어를 취급할 수 있는 권한이 무료로 부여됩니다. , 소프트웨어 사본을 게시, 배포, 재라이센스 부여 및/또는 판매하고, 소프트웨어를 제공받은 사람에게 다음 조건에 따라 그렇게 하도록 허용합니다.
위의 저작권 고지와 본 허가 고지는 소프트웨어의 모든 사본 또는 상당 부분에 포함됩니다.
소프트웨어는 상품성, 특정 목적에의 적합성 및 비침해에 대한 보증을 포함하되 이에 국한되지 않고 명시적이든 묵시적이든 어떠한 종류의 보증 없이 "있는 그대로" 제공됩니다. 어떠한 경우에도 작성자나 저작권 보유자는 계약, 불법 행위 또는 기타 행위로 인해 소프트웨어나 사용 또는 기타 거래와 관련하여 발생하는 모든 청구, 손해 또는 기타 책임에 대해 책임을 지지 않습니다. 소프트웨어.