
# Git

Rudel 通过 Pitmaster 执行原生 PHP Git 操作。无需主机上的 `git` 二进制文件。远程仓库通过 HTTP(S) 或 SSH 访问。

每个沙盒只有一个分支名称 `rudel/{sandbox-id}`，供下方所有 Git 工作流使用。

## 将远程仓库克隆到新沙盒

```bash
wp rudel create --name=feature-x --git=https://example.test/my-theme.git
```

Rudel 会创建沙盒，将远程仓库克隆到沙盒目录中的 `themes/my-theme`（目录名称就是仓库名称），从默认分支创建分支 `rudel/{id}` 并检出该分支。使用 `--type=plugin` 时，检出会改为放在 `plugins/my-theme`。远程仓库、目录和基础分支会保存在沙盒中，以供之后推送使用。如果克隆失败，沙盒会保留，命令会打印警告。

该检出是供 `wp rudel push` 使用的工作副本。当前版本中，沙盒不会从该副本提供内容（[问题 #11](https://github.com/inline0/rudel/issues/11)）：

- 沙盒提供使用 `--theme` 选择的主题，或者主机当前启用的主题；该主题会在创建沙盒时从主机复制。`--theme` 必须指向主机上已安装的主题，因此只有当仓库名称与该主题代号一致，并且克隆操作随后写入已复制的主题目录时，才会从检出内容提供主题。
- 插件始终从主机的插件目录加载，因此 `--type=plugin` 检出不会运行。

## 关联工作树

克隆主题目录为 Git 仓库的沙盒时，Rudel 会为新沙盒创建关联工作树，而不是复制文件：

```bash
wp rudel create --name=feature-y --clone-from=feature-x-3be7
```

工作树位于分支 `rudel/{new-id}` 上。Rudel 会将其记录在新沙盒的元数据中，并使用基于沙盒 ID、内容类型和主题代号的明确工作树名称，因此两个使用相同主题代号的沙盒不会发生冲突。销毁沙盒时会移除工作树并删除其分支。

`wp rudel cleanup --merged` 只会考虑这些关联工作树。参见 [清理](https://rudel.inline0.dev/zh/docs/features/cleanup)。

## 推送变更

```bash
wp rudel push feature-x-3be7 --message="Update checkout template"
```

`push` 会提交检出中的所有变更，并将分支 `rudel/{id}` 推送到 `origin`。如果没有变更，则返回 `No changes to push.`。

- 如果尚未保存远程仓库，`--git=<remote>` 会设置该远程仓库；首次成功推送后会记住它。
- `--dir=<dir>` 用于选择相对于沙盒目录的目录，例如 `themes/my-theme`。默认使用 `--git` 保存的目录；否则使用整个沙盒目录。
- `--message` 默认值为 `Update from Rudel sandbox`。

在 PHP 中，`Rudel::push( $id, $remote_url, $message, $subdir )` 会执行相同操作并触发 `rudel_*_environment_push` 钩子。

## 提交身份

如果检出的 Git 配置中没有 `user.name` 或 `user.email`，Rudel 会写入 `Rudel` 和 `rudel@localhost`。在 `wp-config.php` 中定义 `RUDEL_GIT_AUTHOR_NAME` 和 `RUDEL_GIT_AUTHOR_EMAIL` 可使用其他值。
