# Git 工作流程

本文档旨在帮助您开始将 Git 与 Gutenberg 结合使用。Git 是一款强大的源代码管理工具；要深入学习 Git，请查阅遵循 CC BY-NC-SA 3.0 许可免费在线提供的 [Pro Git 书籍](https://git-scm.com/book/en/v2)。

如果您不熟悉 Git 的使用，值得花时间探索和实践。请尝试 [Git 教程](https://git-scm.com/docs/gittutorial) 以及 [Git 用户手册](https://git-scm.com/docs/user-manual) 来帮助您入门。

Gutenberg 项目遵循标准的拉取请求流程进行贡献。有关拉取请求的更多详细信息，请参阅 GitHub 的[相关文档](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests)。

## 概述

贡献者参与流程概述如下：

-   复刻 Gutenberg 仓库。
-   克隆复刻的仓库。
-   创建新分支。
-   进行代码修改。
-   确认测试通过。
-   在新分支中提交代码更改。
-   将分支推送到复刻的仓库。
-   向 Gutenberg 仓库提交拉取请求。

有关 Gutenberg 项目如何使用 GitHub 的更多信息，请参阅[仓库管理文档](/docs/contributors/repository-management)。

## Git 工作流程详解

代码和文档的工作流程是相同的，因为两者都在 GitHub 中进行管理。你可以观看[贡献文档的视频讲解](https://wordpress.tv/2020/09/02/marcus-kazmierczak-contribute-developer-documentation-to-gutenberg/)以及配套的[为 Gutenberg 做贡献的教程](https://mkaz.blog/wordpress/contribute-developer-documentation-to-gutenberg/)。

以下是 Git 工作流程的视觉概览：

![Git 工作流程视觉概览](https://developer.wordpress.org/files/2020/09/git-workflow.png)

**步骤 1**：访问 GitHub 上的 Gutenberg 仓库并点击 Fork。这会在你的账户下创建主 Gutenberg 仓库的一个副本。

![GitHub 上显示 fork 按钮的截图](https://developer.wordpress.org/files/2020/09/gutenberg-fork.png)

**步骤 2**：将你 fork 的仓库克隆到本地。它位于：`https://github.com/YOUR-USER-NAME/gutenberg`。克隆操作会将所有文件复制到你的计算机上。打开终端并运行：

```bash
git clone https://github.com/YOUR-USER-NAME/gutenberg
```

这将创建一个名为 `gutenberg` 的目录，其中包含项目的所有文件。这可能需要几分钟，因为它正在下载 Gutenberg 项目的完整历史记录。

**步骤 3**：为你的更改创建一个分支（分支命名规则见下文）。在这个例子中，分支名称是完整的字符串：`update/my-branch`

```bash
git switch -c update/my-branch
```

**步骤 4**：进行代码更改。彻底地构建、确认和测试你的更改。请参阅[编码指南](/docs/contributors/code/coding-guidelines)和[测试概览](/docs/contributors/code/testing-overview)以获取指导。

**步骤 5**：使用[良好的提交信息](https://make.wordpress.org/core/handbook/best-practices/commit-messages/)提交你的更改。这会将你的更改提交到你的本地仓库副本。

```bash
git commit -m "Your Good Commit Message" path/to/FILE
```

**步骤 6**：将你的更改推送到 GitHub。更改将被推送到你在 GitHub 上的仓库 fork。

```bash
git push -u origin update/my-branch
```

**步骤 7**：访问你在 GitHub 上的 fork 仓库——它会自动检测到更改，并为你提供一个创建拉取请求的链接。

![显示拉取请求链接的截图](https://developer.wordpress.org/files/2020/09/pull-request-create.png)

**步骤 8**：创建拉取请求。这将在 WordPress Gutenberg 仓库上创建一个请求，以集成来自你 fork 仓库的更改。

**步骤 9**：跟进拉取请求上的新动态。如果要求进行任何额外的更改或更新，则在本地进行更改并推送到 GitHub，遵循步骤 4-6。

不要为更新创建新的拉取请求；通过将更改推送到你的仓库，它将更新同一个 PR。从这个意义上说，PR 是 WordPress Gutenberg 仓库指向你副本的一个指针。所以当你更新你的副本时，PR 也会被更新。

就是这样！一旦审核通过并合并，您的更改就会被纳入主仓库。🎉

## 分支命名

您应该使用前缀和简短描述来命名分支，例如：`[类型]/[变更]`。

建议的前缀：

-   `add/` = 添加新功能
-   `try/` = 实验性功能，“尝试性添加”
-   `update/` = 更新现有功能
-   `remove/` = 移除现有功能
-   `fix/` = 修复现有问题

例如，`add/gallery-block` 表示您正在添加一个新的画廊区块。

## 保持分支最新状态

当多人同时在一个项目上工作时，拉取请求可能会很快过时。"过时"的拉取请求是指不再与开发主线保持同步的请求，需要先更新才能合并到项目中。

有两种更新方式：合并和变基。在 Gutenberg 中，推荐使用变基。变基意味着将你的更改重写为基于开发主线的最新状态，这能确保提交历史始终保持整洁和线性。在开发拉取请求期间，可以根据需要多次执行变基操作。**请尽早分享你的工作**——先创建拉取请求，并在开发过程中持续保持历史记录的变基状态。

开发主线被称为 `trunk` 分支。如果你的拉取请求分支因冲突无法合并到 `trunk`（长期运行的拉取请求可能出现这种情况），则需要在变基过程中手动解决本地副本中的冲突。更多信息请参阅《如何对拉取请求进行变基》中的[章节《执行变基》](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request#perform-a-rebase)。

在本地解决所有冲突后，可以使用 `git push --force-with-lease` 更新拉取请求。使用 `--force-with-lease` 参数非常重要，它能确保你不会意外覆盖他人的工作。

总结来说，你需要获取仓库中的新更改，将你的分支变基到 `trunk` 之上，然后将结果推回仓库。具体命令如下：

```sh
git fetch
git rebase trunk
git push --force-with-lease origin 你的分支名称
```

## 保持你的复刻仓库同步更新

处理拉取请求的第一步是复刻 Gutenberg 仓库，创建你的独立工作副本。随着新的拉取请求被合并到主仓库，你的工作副本很容易变得不同步。这里你的工作仓库是 `fork`，而主 Gutenberg 仓库是 `upstream`。在处理新的拉取请求时，你应该在运行 `git checkout -b my-new-branch` 创建分支进行功能开发或修复之前，始终先更新你的复刻仓库。

你需要添加一个 `upstream` 远程仓库来保持你的复刻仓库同步更新。

```sh
git remote add upstream https://github.com/WordPress/gutenberg.git
git remote -v
origin	git@github.com:your-account/gutenberg.git (fetch)
origin	git@github.com:your-account/gutenberg.git (push)
upstream	https://github.com/WordPress/gutenberg.git (fetch)
upstream	https://github.com/WordPress/gutenberg.git (push)
```

要同步你的复刻仓库，首先需要获取上游的更改并将其合并到你的本地副本中：

```sh
git fetch upstream
git checkout trunk
git merge upstream/trunk
```

本地副本更新完成后，推送你的更改以更新你在 GitHub 上的复刻仓库：

```
git push
```

以上命令将从 _upstream_ 更新你的 `trunk` 分支。要更新任何其他分支，请将 `trunk` 替换为相应的分支名称。

## 杂项

### Git 考古学

在寻找引入特定更改的提交时，忽略仅包含样式或格式更改的修订版本可能会有所帮助。

幸运的是，新版本的 `git` 获得了跳过历史提交的能力：

```
git blame --ignore-rev f63053cace3c02e284f00918e1854284c85b9132 -L 66,73 packages/api-fetch/src/middlewares/media-upload.js
```

所有样式和格式修订版本都使用 Gutenberg 仓库中的 `.git-blame-ignore-revs` 文件进行跟踪。你可以使用此文件一次性忽略它们：

```
git blame --ignore-revs-file .git-blame-ignore-revs -L 66,73 packages/api-fetch/src/middlewares/media-upload.js
```