Primeiros passos
Instalação
Instale Pitmaster via Composer:
composer require pitmaster/pitmaster
Requisitos
- PHP 8.2+ com classes somente leitura, enums e promoção de construtor
- ext-zlib para compactação/descompactação de objetos (incluído na maioria das instalações)
- ext-json para arquivos de estado da operação e payloads Git LFS API
- ext-mbstring, declarado em
composer.json, portanto Composer exige-o no momento da instalação - ext-ctype para validação de hash (habilitado na maioria das compilações de PHP, mas não declarado em
composer.json)
As operações principais do repositório não exigem o binário git, FFI ou auxiliares externos. Recursos opcionais têm requisitos adicionais de execução: a execução de hooks usa proc_open(), e o transporte SSH usa ext-ssh2 quando carregado; caso contrário, inicia o binário ssh do sistema por meio de proc_open().
Abrir um repositório existente
use Pitmaster\Pitmaster;
$repo = Pitmaster::open('/path/to/project');
Isso abre o repositório no caminho indicado. Pitmaster localiza o diretório .git (ou resolve um arquivo .git para worktrees vinculadas) e inicializa o banco de dados de objetos, o banco de dados de refs e a configuração.
open(), init() e clone() aceitam um array de opções como último argumento:
// Do not run .git/hooks scripts for this handle
$repo = Pitmaster::open('/path/to/project', ['hooks' => false]);
// Do not start any process: no hooks, no fsmonitor hook, no clone/fetch/push, no SSH
$repo = Pitmaster::open('/path/to/project', Pitmaster::processFreeOptions());
Hooks são executados por padrão. Pitmaster::processFreeOptions() retorna ['processes' => false, 'hooks' => false]; leituras e gravações locais continuam funcionando nesse identificador.
Verificar se um caminho é um repositório
if (Pitmaster::isRepository('/path/to/project')) {
$repo = Pitmaster::open('/path/to/project');
}
Inicializar um novo repositório
$repo = Pitmaster::init('/path/to/new-project');
Isso cria a estrutura de diretórios .git com objetos, refs, HEAD (apontando para refs/heads/main) e uma configuração padrão.
Para criar um repositório SHA-256, passe o formato de objeto como segundo argumento:
$repo = Pitmaster::init('/path/to/new-project', 'sha256');
Os IDs de objeto nesse repositório têm 64 caracteres hexadecimais, e a configuração registra extensions.objectformat = sha256. Repositórios abertos posteriormente obtêm o formato dessa entrada de configuração.
Ler o commit de HEAD
$head = $repo->head();
echo "Commit: {$head->id->hex}\n";
echo "Author: {$head->author}\n";
echo "Message: {$head->message}\n";
O método head() resolve HEAD (seguindo refs simbólicas) e retorna um objeto Commit.
Listar branches e tags
// All branch names
$branches = $repo->branches();
// ['main', 'feature/login', 'bugfix/typo']
// Current branch name (null if detached)
$current = $repo->branch();
// 'main'
// All tag names
$tags = $repo->tags();
// ['v1.0.0', 'v1.1.0']
Percorrer o histórico de commits
// Last 20 commits from HEAD
$commits = $repo->log(20);
foreach ($commits as $commit) {
echo substr($commit->id->hex, 0, 7) . " {$commit->message}\n";
}
Você também pode começar de um commit específico:
$from = $repo->resolve('feature/login');
$commits = $repo->log(10, $from);
Verificar o estado da árvore de trabalho
use Pitmaster\Status\FileStatus;
$entries = $repo->status();
foreach ($entries as $entry) {
if ($entry->index === FileStatus::Untracked) {
echo "?? {$entry->path}\n";
} elseif ($entry->index === FileStatus::Modified) {
echo "M {$entry->path}\n";
} elseif ($entry->worktree === FileStatus::Modified) {
echo " M {$entry->path}\n";
}
}
Preparar arquivos e criar um commit
// Stage specific files
$repo->add('src/Feature.php', 'tests/FeatureTest.php');
// Create a commit
$commitId = $repo->commit('Add new feature with tests');
echo "Created commit: {$commitId->hex}\n";
O nome e o e-mail do autor são determinados nesta ordem: as variáveis de ambiente PITMASTER_AUTHOR_NAME / PITMASTER_AUTHOR_EMAIL, as variáveis de ambiente GIT_AUTHOR_NAME / GIT_AUTHOR_EMAIL, as constantes PITMASTER_AUTHOR_NAME / PITMASTER_AUTHOR_EMAIL, o próprio .git/config do repositório (user.name e user.email) e, por fim, Pitmaster <pitmaster@localhost>. Apenas o arquivo de configuração do repositório (e os arquivos incluídos nele) é lido, não ~/.gitconfig. O committer é determinado da mesma forma a partir dos nomes *_COMMITTER_* e recorre às constantes do autor.
Calcular diffs
// Unstaged changes (worktree vs index)
$diffs = $repo->diff();
foreach ($diffs as $diff) {
echo $diff->format(); // Unified diff output
}
// Staged changes (index vs HEAD)
$staged = $repo->diffStaged();
Clonar um repositório remoto
$repo = Pitmaster::clone('https://github.com/user/repo.git', '/path/to/destination');
Isso descobre refs, busca o arquivo pack, configura branches de rastreamento remoto e faz checkout da branch padrão. URLs HTTP(S) usam HTTP inteligente e recorrem a HTTP simples; URLs SSH usam o transporte SSH. Passe uma profundidade como terceiro argumento para um clone raso: Pitmaster::clone($url, $path, 1).
Ler qualquer objeto pelo hash
$object = $repo->readObject($fullHash); // full 40-character (or 64 for SHA-256) hex hash
if ($object instanceof \Pitmaster\Object\Blob) {
echo $object->content;
} elseif ($object instanceof \Pitmaster\Object\Commit) {
echo $object->message;
}
Configuração
Pitmaster respeita a .git/config do repositório para informações do autor e URLs remotas. Você também pode definir padrões globais com as constantes PHP, definidas antes da execução de Pitmaster:
define('PITMASTER_AUTHOR_NAME', 'Your Name');
define('PITMASTER_AUTHOR_EMAIL', 'you@example.com');
define('PITMASTER_HTTP_TIMEOUT', 60); // Seconds
define('PITMASTER_MAX_DELTA_CHAIN', 50); // Max delta chain depth
define('PITMASTER_OBJECT_CACHE_BYTES', '64M');
| Constante | Padrão | Efeito |
|---|---|---|
PITMASTER_AUTHOR_NAME, PITMASTER_AUTHOR_EMAIL |
nenhum | Identidade do autor (veja a ordem acima) |
PITMASTER_COMMITTER_NAME, PITMASTER_COMMITTER_EMAIL |
valores do autor | Identidade do committer |
PITMASTER_HTTP_TIMEOUT |
30 |
Tempo limite do HTTP inteligente em segundos (inteiro) |
PITMASTER_MAX_DELTA_CHAIN |
50 |
Profundidade máxima da cadeia delta ao ler packs (inteiro) |
PITMASTER_OBJECT_CACHE_ENTRIES |
1024 |
Objetos mantidos no cache de objetos em memória |
PITMASTER_OBJECT_CACHE_BYTES |
16M |
Limite de bytes do cache de objetos |
PITMASTER_PACK_RESOLVED_CACHE_ENTRIES |
4096 |
Objetos delta resolvidos em cache por pack |
PITMASTER_PACK_RESOLVED_CACHE_BYTES |
32M |
Limite de bytes desse cache de pack |
PITMASTER_MAX_PACK_MEMORY |
nenhum | Nome anterior para o limite de bytes do cache de pack, usado somente quando PITMASTER_PACK_RESOLVED_CACHE_BYTES não está definido |
Valores de bytes aceitam um inteiro ou uma string com sufixo k, m ou g ('256M'). Valores inválidos recorrem ao padrão.
Variáveis de ambiente substituem as constantes de identidade: PITMASTER_AUTHOR_NAME, PITMASTER_AUTHOR_EMAIL, PITMASTER_AUTHOR_DATE, os equivalentes PITMASTER_COMMITTER_* e as próprias variáveis GIT_AUTHOR_* e GIT_COMMITTER_* de git. O transporte SSH lê variáveis PITMASTER_SSH_*, descritas em Protocolos.
Não há uma constante para o algoritmo de hash. O formato do objeto é escolhido quando o repositório é criado (Pitmaster::init($path, 'sha256') ou init --object-format=sha256 em CLI) e, depois, lido da configuração do repositório.