Pular para o conteúdo

Primeiros passos

Instalação

Instale Pitmaster via Composer:

Shell
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

PHP
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:

PHP
// 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

PHP
if (Pitmaster::isRepository('/path/to/project')) {
    $repo = Pitmaster::open('/path/to/project');
}

Inicializar um novo repositório

PHP
$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:

PHP
$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

PHP
$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

PHP
// 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

PHP
// 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:

PHP
$from = $repo->resolve('feature/login');
$commits = $repo->log(10, $from);

Verificar o estado da árvore de trabalho

PHP
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

PHP
// 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

PHP
// 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

PHP
$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

PHP
$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:

PHP
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.