- Notifications
You must be signed in to change notification settings - Fork1
RogerGee/php-git2
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This project provides a PHP extension implementing bindings forlibgit2. You can use this library to build native Git tooling directly into your PHP application.
This branch targets PHP 8. See other branches for other PHP major versions. Please note that this project no longer supports versions before PHP 8.
Primary author:
Since we do not bundle thelibgit2 dependency, it's up to the user to provide the correct version oflibgit2 when building (and running) the extension. Thelibgit2 version corresponds indirectly to the version ofphp-git2 being built. Consult the following table to determine the correct version oflibgit2 required byphp-git2:
php-git2 | libgit2 | Notes |
|---|---|---|
2.0.0 | ^1.5.0 | libgit2 API is now stable |
1.0.0 | 0.25.1 | libgit2 is unstable, sophp-git2@^1.0.0 exclusively uses0.25.1 |
The entries in the table above denote thelibgit2 version requirement for a particularphp-git2 release. An entry is only added when a new version oflibgit2 is required.
In theory, you should be able to use any version that fits the constraint. The minimumlibgit2 version denoted by the constraint is the one we use to develop and test the corresponding release.
Thephp-git2 version corresponds directly to the interfaces and bindings implemented by the extension. Semantic versioning is employed to allow an application to target a correct constraint in itscomposer.json file.
This project maintains multiple branches for different major versions of PHP. Look for a branch namedphpX/master for PHP versionX. Branchmaster will point to the latestphpX/master that is supported. Maintenance and development branches are organized similarly (e.g.php8/develop).
A release is issued for each PHP version separately. Look for tags organized under PHP version (e.g.php8/v2.0.0). A release branch may exist for extended maintenance on a particular major version release (e.g.php8/v2).
Thedocs/coverage.txt file contains a summary of library coverage and a list of all bindings with the implementation status of each binding.
We document API specifics in thedocs/DOCS.txt file, including the major differences between the PHP userspace API and the original C library API. Please consult this documentation before using these bindings, as there are some differences that need to be understood.
Our core design principle is to follow the original,libgit2 C API as closely as possible while at the same time making the extension behave comfortably in userspace with what PHP developers expect. At times, we add helper functions to facilitate certain tasks in userspace or to optimize an otherwise costly operation (e.g. converting values back-and-forth between userspace and the library).
- Most of the opaque
libgit2data types (i.e. handles) are implemented as resources in PHP userspace:- This allows the PHP API to closely follow the underlying C API.
- (Note that in the next major version of this project, we plan to convert all resources to opaque classes.This seems to be the trend in other PHP extensions, and it may be that resource types will be deprecated/removed in future versions of PHP.)
- Functions that return a
libgit2handle via an output parameter in the C API return a resource via the function return value in the PHP API:- (e.g.
git_repository_open()returns agit_repositoryresource).
- (e.g.
- Errors are always converted into PHP exceptions
- Custom data structures (e.g. backends) are implemented as PHP classes:
- This allows the developer to write a subclass that easily implements a custom data structure.
- For example, the
git_odb_backendstructure is a class calledGitODBBackend. - A developer could subclass
GitODBBackendto provide an alternate storage mechanism for a repository's object database (such as a MySQL or SQLite database)
- Most other data structures are implemented using arrays
We want the extension to be stable so that it can be used securely in production code. (Who wouldn't?) To that end, we've added an extra reference counting layer to track resource dependencies. This ensures PHP developers don't blow their feet off when doing something like this:
functionget_ref() {$repo =git_repository_open('/path/to/repo.git',true);$ref =git_reference_lookup($repo,'annot-tag-1');return$ref;}$ref =get_ref();$peeled =git_reference_peel($ref,GIT_OBJ_COMMIT);
The extension will keep thegit_repository object alive behind the scenes since a dependency is established between thegit_repository and thegit_reference. This allows PHP developers to use the library without worrying about low-level concerns.
Most of the extension is designed as inline code in header files. (A header file is provided for each major section of thelibgit2 API, such asgit_repository.) We use C++ metaprogramming constructs to generate extension functions. This approach is great for streamlining redundant tasks, separating the prototype for a binding from its implementation and keeping track of API changes. However, it comes with the small drawback of decreased flexibility when implementing unusual or more custom bindings.
If a binding doesn't "fit the mold" and cannot be implemented using one of the generic binding template function generators, then we recommend the binding be written directly in the header file using the conventionalPHP_FUNCTION macro.
We write PHP class implementations directly in their own compilation units. The extension provides internal PHP classes for many of the custom storage backends that can be extended in userspace.
This extension is written in C++, and it takes advantage of modern C++ features. You need to have a relatively recent C++ compiler that supports C++11 metaprogramming features. This extension has been built successfully using GCC and Clang on macOS and Linux. The extension has also been built experimentally for Windows; however, Windows builds are not actively supported.
Build the extension in the normal way usingphpize,configure andmake.
Runphpize to generate the build system:
$ phpizeThenconfigure andmake:
$ ./configure [--with-git2=/path/to/libgit2 --with-git2-static]$ makeEnsure that you configure the correct version oflibgit2 for the extension version you are building (see Versioning for more on this). You can tell the build system where to findlibgit2 via the--with-git2 option. You can also force the build system to use a static library instead of a shared library with--with-git2-static.
Example: building with static library
In this example, I've built and installedlibgit2 under/usr/local/libgit2 as a static library. (Note: the static library must be installed aslib/libgit2.a under the distribution. Also, make sure the library was compiled with position-independent code if building a shared extension.) Now I can buildphp-git2 using this static library:
$ ./configure --with-git2=/usr/local/libgit2 --with-git2-static LDFLAGS="-lssh2"$ makeNote: I needed to link againstssh2 since mylibgit2 was built with SSH support.
Other Considerations
If you are linking to a shared library, the compiler should embed the librarysoname into the resulting binary. The embedded name should correspond to thelibgit2 version you have configured. In this way, the loader will always load the correct version at runtime. It is important to ensure thesoname is specific enough to avoid accidentally loading the wrong version at runtime, in case there are multiple versions installed on the system. If yourlibgit2 is in a non-standard location, then the build system should be smart enough to inject the appropriaterpath into your binary so that the correct library loads.
When you configure the build, there are a couple of different options you should consider to make the binary useful for your purposes. Add extra compiler options to theCXXFLAGS variable to customize your build. For release builds, enable optimizations like so:
./configure CXXFLAGS='-O3'Since the code uses a lot of inline template functions, heavy optimizations will really help improve the performance of the binary (and make it a lot smaller). However, this is not great for debugging since it collapses down function calls. For a development environment, we recommend something like:
./configure CXXFLAGS='-g -O0 -Wfatal-errors -Wall -Wno-deprecated-register'This configuration will produce a huge binary, but it will be easier to trace. If you are developing, we also recommend including theMakefile.extra file (included in the repository) at the bottom of the generatedMakefile. This will give the build system some extra dependency information that makes life easier. This is done like so:
-include Makefile.extra## Bottom of generated MakefileThis project does not officially support Windows at this time. With this said, there shouldn't be anything preventing the extension from building and running on Windows; we just haven't worked out any of the inevitable, platform-specific issues.
| Item | Status |
|---|---|
| Improve unit testing | Complete (October 2022) |
Update tolibgit2 version 1 | Complete (January 2023) |
| Add support for PHP 8 | Complete (September 2023) |
Add support for customlibgit2 memory allocator utilizing PHP's memory allocation functionality | Pending |
| Create phpdoc files to generate documentation site | Pending |
| Convert resource types to opaque object types | Pending |
About
PHP bindings for libgit2
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.