
# 快速入门

## 安装

通过 Composer 安装 Pitmaster：

```bash
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` 目录（或为链接的工作树解析 `.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');
```

这会创建 `.git` 目录结构，其中包含 objects、refs、HEAD（指向 `refs/heads/main`）和默认配置。

要创建 SHA-256 仓库，请将对象格式作为第二个参数传入：

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

该仓库中的对象 ID 为 64 个十六进制字符，配置中会记录 `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（沿符号引用查找），并返回一个 `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";
    }
}
```

## 暂存文件并提交

```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_*` 名称解析，缺省时使用作者常量。

## 计算差异

```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');
```

此操作会发现 refs、获取 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 会遵循仓库的 `.git/config`，获取作者信息和远程 URL。你也可以通过全局默认值设置这些信息：在运行 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 时允许的最大 delta 链深度（整数） |
| `PITMASTER_OBJECT_CACHE_ENTRIES` | `1024` | 内存对象缓存中保留的对象数 |
| `PITMASTER_OBJECT_CACHE_BYTES` | `16M` | 对象缓存的字节数上限 |
| `PITMASTER_PACK_RESOLVED_CACHE_ENTRIES` | `4096` | 每个 pack 缓存的已解析 delta 对象数 |
| `PITMASTER_PACK_RESOLVED_CACHE_BYTES` | `32M` | 此 pack 缓存的字节数上限 |
| `PITMASTER_MAX_PACK_MEMORY` | 无 | pack 缓存字节数上限的旧名称，仅在未定义 `PITMASTER_PACK_RESOLVED_CACHE_BYTES` 时使用 |

字节数值可以是整数，也可以是带 `k`、`m` 或 `g` 后缀的字符串（`'256M'`）。无效值会回退到默认值。

环境变量会覆盖身份常量：`PITMASTER_AUTHOR_NAME`、`PITMASTER_AUTHOR_EMAIL`、`PITMASTER_AUTHOR_DATE`、对应的 `PITMASTER_COMMITTER_*` 变量，以及 git 自己的 `GIT_AUTHOR_*` 和 `GIT_COMMITTER_*` 变量。SSH 传输方式会读取 `PITMASTER_SSH_*` 变量，详见[协议](https://pitmaster.inline0.dev/zh/docs/network/protocols)。

没有用于指定哈希算法的常量。对象格式在创建仓库时选定（`Pitmaster::init($path, 'sha256')` 或在 CLI 上使用 `init --object-format=sha256`），之后从仓库配置中读取。
