glip: repositorios Git desde PHP

Recientemente se me había ocurrido la idea de poder trabajar con repositorios Git con PHP, para poder hacer algún tipo de sistema web con el que intentar administrar los repositorios y poner un poco de orden en lo que hago. glip es una librería-interfaz de código abierto para trabajar con repositorios Git usando PHP.

A su favor está su portabilidad: glip puede ejecutarse en una máquina que no tenga instalado el software de Git gracias a que no lo necesita, sino que accede directamente a los archivos binarios y trabaja con ellos. De hecho, todo el código fuente está escrito en puro PHP, sin ninguna librería externa, por lo que funciona en cualquier servidor PHP, incluso en el de un hosting gratuito o barato.

Usar glip es muy fácil gracias a su simplificado API. Todo lo que tenemos que hacer es crear un objeto de tipo Git, que será nuestro repositorio. Podemos hacer esto indicandole la ruta del repositorio con el que queremos que trabaje. Por ejemplo, un repositorio desnudo (bare repo) situado en ‘/var/git/repo.git’ puede ser cargado con glip simplemente con el siguiente código:

<?php
$repo_ruta = '/var/git/repo.git';
$repo_obj = new Git($repo_ruta);

Una vez instanciado el repositorio Git, podemos acceder a los diferentes objetos si conocemos su hash SHA-1. Puesto que Git se basa en punteros, conoceremos muchos objetos dado que unos objetos contendrán los objetos de otros objetos. De todos modos, es muy posible que no conozcamos el blob de la rama principal. Podemos obtener su código blob con getTip(). En conjunto, podríamos recuperar el último commit de la rama master con:

<?php
$master_sha = $repo_obj->getTip('master');
$master_lastcommit = $repo_obj->getObject($master_sha);

Esto devuelve un objeto de tipo GitCommit, que contiene información sobre el commit más reciente hecho en master. Los campos que hay en GitCommit nos permitirían obtener información sobre el autor de un commit (tanto nombre, como e-mail, como fecha del commit), la descripción del commit, y el blob de la estructura tree, que es quien guarda los archivos.

<?php
$commit_tree = $repo_obj->tree;
$tree_obj = $repo_obj-&gt;getObject($commit_tree);

Con esto se puede acceder al árbol que hay en el commit. Un árbol es una estructura de datos que referencia blobs de archivos. El objeto de tipo GitTree que obtenemos contiene un conjunto de nodos, en los que se sitúan los blobs que referencian los archivos del árbol en los que se encuentran los datos.

<?php
$tree_nodes = $tree_obj->nodes;
foreach($tree_nodes as $node) {
   $blob_obj = $git_repo->getObject($node);
   print_r($blob_obj); // para ver todos los campos del objeto
}

Aunque no lo he probado, todos los objetos de glip (básicamente, GitBlob, GitCommit y GitTree, los cuales en cualquier caso extienden a GitObject), soportan serialización y deserialización. Eso implicaría que probablemente odamos crear nuestros propios blobs, nuestros propios árboles y nuestros propios commits, lo que permitiría hacer commits a través de un navegador web.

Para más información, puedes consultar la documentación de glip.