본문으로 건너뛰기

시작하기

설치

Pitmaster을 Composer을 통해 설치하세요.

셸
composer require pitmaster/pitmaster

요구 사항

  • PHP 8.2+(읽기 전용 클래스, 열거형, 생성자 프로퍼티 승격 지원)
  • ext-zlib 객체 압축 및 압축 해제용(대부분의 설치에 기본 포함)
  • ext-json 작업 상태 파일과 Git LFS API 페이로드용
  • ext-mbstring은 composer.json에 선언되어 있어 Composer 설치 시 필요합니다.
  • ext-ctype 해시 검증용(대부분의 PHP 빌드에서 활성화되지만 composer.json에는 선언되지 않음)

핵심 저장소 작업에는 git 바이너리, FFI 또는 외부 도우미가 필요하지 않습니다. 선택적 기능에는 추가 런타임 요구 사항이 있습니다. 훅 실행에는 proc_open()을 사용하며, SSH 전송은 ext-ssh2이 로드되면 이를 사용하고, 그렇지 않으면 proc_open()을 통해 시스템 ssh 바이너리를 시작합니다.

기존 저장소 열기

PHP
use Pitmaster\Pitmaster;

$repo = Pitmaster::open('/path/to/project');

지정한 경로의 저장소를 엽니다. Pitmaster은 .git 디렉터리를 찾거나(연결된 worktree의 경우 .git 파일을 확인해 해결), 객체 데이터베이스, ref 데이터베이스, 설정을 초기화합니다.

open(), init(), clone()는 마지막 인수로 옵션 배열을 받습니다.

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());

기본적으로 훅이 실행됩니다. Pitmaster::processFreeOptions()은 ['processes' => false, 'hooks' => false]을 반환하며, 이러한 핸들에서도 로컬 읽기 및 쓰기는 계속 작동합니다.

경로가 저장소인지 확인

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

새 저장소 초기화

PHP
$repo = Pitmaster::init('/path/to/new-project');

객체, refs, HEAD(refs/heads/main을 가리킴), 기본 설정이 포함된 .git 디렉터리 구조를 만듭니다.

SHA-256 저장소를 만들려면 객체 형식을 두 번째 인수로 전달합니다.

PHP
$repo = Pitmaster::init('/path/to/new-project', 'sha256');

이 저장소의 객체 ID는 64자 16진수이며, 설정에는 extensions.objectformat = sha256이 기록됩니다. 나중에 연 저장소는 해당 설정 항목에서 형식을 가져옵니다.

HEAD commit 읽기

PHP
$head = $repo->head();

echo "Commit: {$head->id->hex}\n";
echo "Author: {$head->author}\n";
echo "Message: {$head->message}\n";

head() 메서드는 HEAD를 해석하고(심볼릭 refs를 따라감) Commit 객체를 반환합니다.

브랜치와 tag 목록 보기

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']

Commit 기록 순회

PHP
// Last 20 commits from HEAD
$commits = $repo->log(20);

foreach ($commits as $commit) {
    echo substr($commit->id->hex, 0, 7) . " {$commit->message}\n";
}

특정 commit에서 시작할 수도 있습니다.

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

작업 트리 상태 확인

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";
    }
}

파일 스테이징 및 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";

작성자 이름과 이메일은 다음 순서로 확인합니다. PITMASTER_AUTHOR_NAME / PITMASTER_AUTHOR_EMAIL 환경 변수, GIT_AUTHOR_NAME / GIT_AUTHOR_EMAIL 환경 변수, PITMASTER_AUTHOR_NAME / PITMASTER_AUTHOR_EMAIL 상수, 저장소 자체의 .git/config(user.name 및 user.email), 마지막으로 Pitmaster <pitmaster@localhost>입니다. 저장소 설정 파일과 여기에 포함된 파일만 읽으며 ~/.gitconfig은 읽지 않습니다. 커미터 정보도 같은 방식으로 *_COMMITTER_* 이름을 확인하고, 없으면 작성자 상수로 대체합니다.

Diff 계산

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();

원격 저장소 복제

PHP
$repo = Pitmaster::clone('https://github.com/user/repo.git', '/path/to/destination');

이 작업은 ref를 검색하고, pack 파일을 가져오고, 원격 추적 브랜치를 설정한 다음 기본 브랜치를 체크아웃합니다. HTTP(S) URL은 smart HTTP을 사용하고 실패하면 dumb HTTP로 대체합니다. SSH URL은 SSH 전송 방식을 사용합니다. 얕은 클론을 만들려면 세 번째 인수로 깊이를 전달하세요: Pitmaster::clone($url, $path, 1).

해시로 모든 객체 읽기

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;
}

구성

Pitmaster은 작성자 정보와 원격 URL에 대해 저장소의 .git/config을 따릅니다. Pitmaster이 실행되기 전에 정의한 PHP 상수로 전역 기본값을 설정할 수도 있습니다:

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');
상수 기본값 효과
PITMASTER_AUTHOR_NAME, PITMASTER_AUTHOR_EMAIL 없음 작성자 신원(위 순서 참조)
PITMASTER_COMMITTER_NAME, PITMASTER_COMMITTER_EMAIL 작성자 값 커미터 신원
PITMASTER_HTTP_TIMEOUT 30 Smart HTTP 제한 시간(초, 정수)
PITMASTER_MAX_DELTA_CHAIN 50 pack을 읽을 때 최대 델타 체인 깊이(정수)
PITMASTER_OBJECT_CACHE_ENTRIES 1024 메모리 내 객체 캐시에 보관되는 객체 수
PITMASTER_OBJECT_CACHE_BYTES 16M 객체 캐시의 바이트 한도
PITMASTER_PACK_RESOLVED_CACHE_ENTRIES 4096 pack별로 캐시되는 해석된 델타 객체 수
PITMASTER_PACK_RESOLVED_CACHE_BYTES 32M 해당 pack 캐시의 바이트 한도
PITMASTER_MAX_PACK_MEMORY 없음 pack 캐시 바이트 한도의 이전 이름. PITMASTER_PACK_RESOLVED_CACHE_BYTES이 정의되지 않은 경우에만 사용됩니다

바이트 값은 정수 또는 '256M'(k, m 또는 g 접미사 포함) 문자열로 지정할 수 있습니다. 잘못된 값은 기본값으로 대체됩니다.

환경 변수는 신원 상수를 재정의합니다: PITMASTER_AUTHOR_NAME, PITMASTER_AUTHOR_EMAIL, PITMASTER_AUTHOR_DATE, 이에 대응하는 PITMASTER_COMMITTER_* 항목, 그리고 git 자체의 GIT_AUTHOR_* 및 GIT_COMMITTER_* 변수입니다. SSH 전송 방식은 PITMASTER_SSH_* 변수를 읽으며, 자세한 내용은 프로토콜에서 확인할 수 있습니다.

해시 알고리즘을 설정하는 상수는 없습니다. 객체 형식은 저장소를 만들 때(CLI에서 Pitmaster::init($path, 'sha256') 또는 init --object-format=sha256) 선택되고, 이후에는 저장소 설정에서 읽어 옵니다.