본문으로 건너뛰기

프로토콜

Pitmaster은 git 서버와 통신하기 위한 여러 네트워크 전송 프로토콜을 지원합니다. Smart HTTP이 기본 전송 방식이며, 더 폭넓은 호환성을 위한 추가 프로토콜도 제공됩니다.

Smart HTTP(기본)

권장 전송 방식입니다. HTTPS을 통해 작동하며 가장 널리 배포된 프로토콜입니다. 사용자 지정 헤더나 인증 정보를 위한 API은 없습니다. 인증 정보는 URL(https://user:token@host/repo.git)로만 전달할 수 있으며, PHP은 이를 Basic 인증으로 보냅니다. clone()은 인증 정보를 포함한 URL을 .git/config의 remote.origin.url로 저장합니다. 요청에는 PHP의 스트림 래퍼를 사용하므로 allow_url_fopen을 활성화해야 합니다.

PHP
use Pitmaster\Protocol\SmartHttpClient;

$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');

자세한 내용은 Smart HTTP을 참조하세요.

프로토콜 v1

기존 smart HTTP 프로토콜입니다. 검색 중에 모든 ref를 전송하고 want/have/done 행으로 협상합니다.

PHP
use Pitmaster\Protocol\ProtocolV1;

프로토콜 v2

구조화된 명령(ls-refs, fetch)을 사용하는 최신 프로토콜입니다. 클라이언트가 ref 목록을 필터링할 수 있어 ref가 많은 저장소에서 더 효율적입니다.

clone() 및 fetch()은 항상 프로토콜 v1을 사용합니다. 프로토콜 v2은 SmartHttpClient::discoverRefsV2() 및 UploadPackClient::fetchV2()을 통한 smart HTTP에서 명시적으로 사용할 수 있습니다.

바보 HTTP

smart HTTP 프로토콜을 지원하지 않는 서버를 위한 대체 방식입니다. dumb 프로토콜은 일반 HTTP GET 요청으로 객체와 pack을 하나씩 가져옵니다.

PHP
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();

Dumb HTTP의 제한 사항:

  • 협상이 없습니다(클라이언트가 모든 항목을 다운로드해야 함)
  • 전송 중 델타 압축이 없습니다
  • smart HTTP보다 훨씬 느립니다
  • 일부 서버(GitHub, GitLab)는 이를 지원하지 않습니다

dumb 프로토콜은 다음을 가져옵니다:

  1. GET /info/refs(일반 텍스트, pkt-line 없음)
  2. GET /HEAD(기본 브랜치)
  3. GET /objects/info/packs(사용 가능한 pack 목록)
  4. GET /objects/pack/pack-<hash>.pack 및 .idx(목록에 있는 각 pack과 해당 인덱스)
  5. GET /objects/<xx>/<rest>(ref 끝점에서 순회하는 개별 느슨한 객체)

5단계는 서버에 pack 목록이 없을 때만 실행됩니다. pack 목록이 있으면 서버에 느슨한 파일로만 존재하는 객체는 다운로드되지 않습니다(#18). dumb 클라이언트는 40자(SHA-1) 객체 ID만 허용합니다. smart HTTP 교환에 실패하면 clone() 및 fetch()는 dumb HTTP로 대체합니다.

SSH

SSH 전송 방식은 로드된 경우 ssh2 PHP 확장을 사용합니다. 그렇지 않으면 proc_open()를 통해 시스템 ssh 클라이언트를 시작합니다. 두 경우 모두 원격에서 git-upload-pack 또는 git-receive-pack을 실행합니다.

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

SSH URL:

코드
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git

확장이 필요하지 않습니다. 두 경로의 동작은 서로 다릅니다:

시스템 ssh 클라이언트(ssh2이 로드되지 않은 경우 사용). Pitmaster은 ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>을 실행하므로 인증 및 호스트 키 확인은 사용자의 SSH 설정과 에이전트를 따릅니다. 다음 환경 변수로 명령을 조정할 수 있습니다:

변수 효과
PITMASTER_SSH_COMMAND ssh 대신 실행할 실행 파일
PITMASTER_SSH_IDENTITY_FILE -i <file>으로 전달됩니다
PITMASTER_SSH_KNOWN_HOSTS -o UserKnownHostsFile=<file>로 전달됩니다
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING -o StrictHostKeyChecking=<value>로 전달됩니다

이 경로는 프로세스를 시작하므로 ['processes' => false]로 연 핸들에서는 사용할 수 없습니다.

ssh2 확장(로드된 경우 항상 우선 사용). Pitmaster은 ~/.ssh/id_rsa로 인증을 시도하고, RSA 키가 있지만 거부된 경우 ~/.ssh/id_ed25519으로 시도하며, 그 외에는 SSH 에이전트를 사용합니다. PITMASTER_SSH_* 변수는 무시되며 이 경로에서는 서버의 호스트 키를 확인하지 않습니다(#22).

SSH 전송 방식은 git-upload-pack 또는 git-receive-pack를 원격 명령으로 실행하고, smart HTTP과 동일한 pkt-line 프로토콜을 사용해 SSH 채널로 통신합니다.

Git 프로토콜(TCP)

기본 git 프로토콜은 PHP 소켓을 사용해 TCP 포트 9418으로 통신합니다. GitProtocolClient은 ref 검색과 upload-pack(페치)를 지원하지만 푸시는 할 수 없습니다. clone() 및 fetch()는 git:// URL을 이 프로토콜로 전달하지 않으므로 클라이언트를 직접 사용하세요.

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

Git URL:

코드
git://github.com/user/repo.git

특징:

  • 인증이 없습니다(실제로는 읽기 전용)
  • 암호화되지 않습니다
  • 대부분의 호스팅 제공업체에서 사용이 중단되었습니다
  • smart HTTP과 동일한 pkt-line 프레이밍을 사용합니다

git 프로토콜은 초기 요청으로 서비스 이름과 저장소 경로를 전송한 다음, 표준 pkt-line ref 검색 및 pack 협상을 진행합니다.

번들

Git 번들은 ref 정보가 포함된 오프라인 pack 파일입니다. 네트워크 연결 없이 저장소 데이터를 전송할 수 있습니다.

PHP
use Pitmaster\Protocol\Bundle;

// Read a bundle file
$bundle = Bundle::open('/path/to/repo.bundle');
$refs = $bundle->refs();
$packData = $bundle->packData();
$prerequisites = $bundle->prerequisites();

// Create one
$bundle = Bundle::create(['refs/heads/main' => $commitId], $packData);
$bundle->writeTo('/path/to/out.bundle');

Pitmaster은 v2 및 v3 번들 헤더를 읽습니다. 번들을 가져오는 Repository 메서드는 없습니다. packData()를 .git/objects/pack/에 기록하고 PackIndexer::writeIndex()으로 인덱스를 만든 다음 직접 ref를 업데이트하세요.

번들 형식:

코드
# v2 git bundle\n
-<prerequisite hash>\n    (zero or more)
<hash> <refname>\n        (one or more)
\n
<pack data>               (standard pack file format)

번들은 다음과 같은 경우에 유용합니다:

  • USB 드라이브를 통한 물리적 매체 전송
  • 증분 백업
  • 네트워크와 분리된 환경에서 클론에 데이터 미리 채우기

얕은 클론

Pitmaster은 제한된 깊이의 커밋 기록만 가져오는 얕은 클론을 지원합니다.

PHP
use Pitmaster\Protocol\ShallowClone;

Pitmaster::clone($url, $path, $depth) 또는 $repo->fetch($remote, $depth)에 깊이를 전달하세요. 요청에 shallow 기능과 deepen 행이 추가됩니다:

코드
want <hash>
deepen <depth>

서버는 이력이 잘린 위치를 나타내는 shallow <hash> 줄을 응답으로 보냅니다. Pitmaster은 깊이만으로 얕은 경계를 계산하고, 계산 결과가 없으면 서버의 shallow 줄을 사용합니다. 결과는 .git/shallow에 저장됩니다. ShallowClone::readShallow(), writeShallow(), isShallow()은 해당 파일을 직접 사용합니다.

프로토콜 비교

프로토콜 인증 암호화 푸시 일반적인 용도
Smart HTTP URL의 인증 정보 HTTPS 예 기본 전송 방식
Dumb HTTP URL의 인증 정보 HTTPS 아니요 이전 버전 호환용 대체 방식
SSH SSH 키 또는 에이전트 SSH 예 비공개 저장소, CI
Git (TCP) 없음 없음 아니요 읽기 전용 미러
Bundle 해당 없음 해당 없음 해당 없음 오프라인 전송

전송 방식 선택

Pitmaster::clone(), $repo->fetch(), $repo->push()은 URL에서 전송 방식을 선택합니다:

URL 패턴 전송 방식
ssh://... SSH
user@host:path SSH
그 외 (https://..., http://...) Smart HTTP; clone 및 fetch는 dumb HTTP으로 대체 시도

git:// URL 및 로컬 경로는 이 메서드에서 지원되지 않습니다. smart HTTP 클라이언트로 전달되어 실패합니다. git://에는 GitProtocolClient를 직접 사용하세요. 사용자 이름과 포트를 모두 포함하는 HTTPS URL(https://user@host:8443/repo.git)는 현재 SSH URL(#17)로 잘못 인식됩니다.