Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Docs] zh-cn document translate: git parts #15576

Merged
merged 5 commits into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/zh-cn/newbs_git_best_practices.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# QMK所采用的Git最佳实践

epiciskandar marked this conversation as resolved.
Show resolved Hide resolved
<!---
original document: 0.15.17:docs/newbs_git_best_practices.md
git diff 0.15.17 HEAD -- docs/newbs_git_best_practices.md | cat
-->

*译者注:对于git相关的部分,除广为接受的名词外,会尽量保留git命令及各种术语的英文版本,部分名词及关键部分会附带中文翻译*

## 或者讲,"怎么才能不害怕并喜欢上Git"

本节旨在以最佳方式指导新手在为QMK做贡献时获得流畅的体验。我们将进行一次完整的QMK贡献操作流程,并在部分环节中详细讲述几种便捷的方法,之后我们会故意搞砸一些东西,并教导你如何回到正轨。

该章节做了如下假设:

1. 你已有Github账号且已[fork了qmk_firmware仓库](zh-cn/getting_started_github.md)到你的账号下。
2. 已完成了[构建环境](zh-cn/newbs_getting_started.md#set-up-your-environment)及[QMK](zh-cn/newbs_getting_started.md#set-up-qmk)配置。

---

- 第一节:[在你Fork的主干上:频繁更新,不要提交](zh-cn/newbs_git_using_your_master_branch.md)
- 第二节:[解决合并冲突](zh-cn/newbs_git_resolving_merge_conflicts.md)
- 第三节:[重新同步一个脱离同步状态的Git分支](zh-cn/newbs_git_resynchronize_a_branch.md)
86 changes: 86 additions & 0 deletions docs/zh-cn/newbs_git_resolving_merge_conflicts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# 解决合并冲突

epiciskandar marked this conversation as resolved.
Show resolved Hide resolved
<!---
original document: 0.15.17:docs/newbs_git_resolving_merge_conflicts.md
git diff 0.15.17 HEAD -- docs/newbs_git_resolving_merge_conflicts.md | cat
-->

有时在你致力于一个较长周期才能完成的分支时,其它人提交的变更会与你提交的pull request中的变更发生冲突。我们将这种多个人编辑同一个模块同一个文件时产生的场景叫做 *合并冲突*

?> 本文中的场景基于[在你Fork的主干上:频繁更新,不要提交](zh-cn/newbs_git_using_your_master_branch.md)一文。如果你对那篇文章不熟悉,请先阅读它,再回来继续。

## 变基/衍合(rebase)


Git的*变基*操作会将提交历史中的提交节点摘除并回滚,然后统一提交到一个新节点上。在解决合并冲突时,可以通过对当前分支进行变基,来获取从分支拉取到当前时刻的所有变更。

从执行如下命令开始:

```
git fetch upstream
git rev-list --left-right --count HEAD...upstram/master
```

此处输入的 `git rev-list` 命令可以得到当前分支与QMK主干分支间的提交数量差。而先执行 `git fetch` 是为了确保我们有上游仓库(upstream repo)的最新状态。`git rev-list` 命令会返回两个数字:

```
$ git rev-list --left-right --count HEAD...upstream/master
7 35
```

第一个数字为当前分支自创建后新增的提交数量。第二个数字为当前分支创建后在 `upstream/master` 上的提交数量,而这部分就是我们当前分支上缺失的提交记录。

在我们了解了当前分支以及上游仓库的状态后,可以发起变基操作了:

```
git rebase upstream/master
```

这样可以让Git回滚该分支的提交,然后基于QMK的主干版本重新应用这些提交。

*译注:以下内容在中文Git下大同小异,且仅作为示例,不进行翻译*
```
$ git rebase upstream/master
First, rewinding head to replay your work on top of it...
Applying: Commit #1
Using index info to reconstruct a base tree...
M conflicting_file_1.txt
Falling back to patching base and 3-way merge...
Auto-merging conflicting_file_1.txt
CONFLICT (content): Merge conflict in conflicting_file_1.txt
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch' to see the failed patch
Patch failed at 0001 Commit #1

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
```

以上内容是在告诉我们有合并冲突存在,并给出了冲突所在的文件名。在编辑器中打开该文件,可以在某处发现类似如下形式的内容:

```
<<<<<<< HEAD
<p>For help with any issues, email us at [email protected].</p>
=======
<p>Need help? Email [email protected].</p>
>>>>>>> Commit #1
```

`<<<<<<< HEAD` 标记了合并冲突的起始行,直至 `>>>>>>> Commit #1` 标记的结束行,中间通过 `=======` 分隔开冲突双方。其中 `HEAD` 部分为QMK主干上的版本,标记了提交日志的部分为当前分支的本地提交。

由于Git存储的是*文件差异部分*而非整个文件,所以当Git无法在文件中找到一个变更发生前的内容时,就无法知道如何去进行文件变更,重新编辑一下可以解决问题。在更改完成后,保存文件。

```
<p>Need help? Email [email protected].</p>
```

之后,执行:

```
git add conflicting_file_1.txt
git rebase --continue
```

Git即会记录对文件冲突做出的变更,并继续处理剩余的提交,直至全部完成。
76 changes: 76 additions & 0 deletions docs/zh-cn/newbs_git_resynchronize_a_branch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# 重新同步已失去同步状态的Git分支

epiciskandar marked this conversation as resolved.
Show resolved Hide resolved
<!---
original document: 0.15.17:docs/newbs_git_resynchronize_a_branch.md
git diff 0.15.17 HEAD -- docs/newbs_git_resynchronize_a_branch.md | cat
-->

假设你在自己的 `master` 分支之上有提交,并且想和QMK仓库进行同步,可以通过 `git pull` 拉取QMK的 `master` 分支到你的库,但同时Github也会提醒你当前分支相比 `qmk:master` 有几个领先的提交,会在你向QMK发起pr时造成麻烦。

?> 本文中的场景基于[在你Fork的主干上:频繁更新,不要提交](zh-cn/newbs_git_using_your_master_branch.md)一文。如果你对那篇文章不熟悉,请先阅读它,再回来继续。

## 备份你在自己的主干分支上的所有变更(可选)

不会有人想把有用的成果弄丢的。如果你想将你的 `master` 分支上的变更另存一份,简便的方法是直接创建一个当前“脏” `master` 分支的副本:

```
git branch old_master master
```

现在 `master` 分支拥有了一个副本分支 `old_master`。

## 重新同步分支

现在可以重新同步 `master` 分支了,这里,我们将QMK仓库设置为Git的远程仓库。通过执行 `git remote -v` 可以确认远程仓库配置,输出信息应类似于:

```
QMKuser ~/qmk_firmware (master)
$ git remote -v
origin https://github.com/<your_username>/qmk_firmware.git (fetch)
origin https://github.com/<your_username>/qmk_firmware.git (push)
upstream https://github.com/qmk/qmk_firmware.git (fetch)
upstream https://github.com/qmk/qmk_firmware.git (push)
```

如果你只能看到一个仓库:

```
QMKuser ~/qmk_firmware (master)
$ git remote -v
origin https://github.com/qmk/qmk_firmware.git (fetch)
origin https://github.com/qmk/qmk_firmware.git (push)
```

通过如下命令添加新的远程仓库:

```
git remote add upstream https://github.com/qmk/qmk_firmware.git
```

然后,重新将 `origin` 远程仓库设置为自己的fork:

```
git remote set-url origin https://github.com/<your_username>/qmk_firmware.git
```

在两个远程仓库配置完毕后,需要从QMK的 upstream 仓库中获取到更新,执行:

```
git fetch upstream
```

此时,重新同步你的分支到QMK的版本:

```
git reset --hard upstream/master
```

以上操作会更新你的本地仓库,而你的Github远程仓库仍然处于未同步状态,通过推送,可以让其进入已同步状态。可以通过如下命令来指引Git强行覆盖掉那些仅在你远程仓库中存在的提交:

```
git push --force-with-lease
```

!> **不要**在其它使用者也会提交的分支上执行 `git push --force-with-lease`,否则会覆盖掉他人的提交。

此时你的Github fork,本地文件副本,以及QMK仓库就是一致的了。之后再进行变更([在分支上!](zh-cn/newbs_git_using_your_master_branch.md#making-changes))和提交。
79 changes: 79 additions & 0 deletions docs/zh-cn/newbs_git_using_your_master_branch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# 在你Fork的主干上:频繁更新,不要提交

epiciskandar marked this conversation as resolved.
Show resolved Hide resolved
<!---
original document: 0.15.17:docs/newbs_git_using_your_master_branch.md
git diff 0.15.17 HEAD -- docs/newbs_git_using_your_master_branch.md | cat
-->

我们强烈推荐所有QMK开发者,无论在哪里做什么改动,频繁更新你的 `master` 分支,但***不要***在其上提交。相对地,将你所有的改动提交到开发分支上并提交一个pull request。

为了减少冲突 &mdash; 多人同时编辑同一个文件 &mdash; 保持你的 `master` 分支更新到最新,并在新创建的分支上进行开发。

## 更新master分支

为了保持 `master` 更新到最新,推荐将QMK固件仓库("repo")设置为git远程仓库。打开Git命令行界面并键入:

```
git remote add upstream https://github.com/qmk/qmk_firmware.git
```

?> 名称 `upstream` 部分可以任意,这里给的是常用的;你可以将QMK远程仓库名称改成你想要的。Git的 `remote` 命令语法为 `git remote add <name> <url>`, `<name>` 是远程仓库的简写名称,这个名称可以在很多Git命令中使用,包括但不限于 `fetch`,`pull` 及 `push`,以指定目标远程仓库。

要验证是否添加成功,可以执行 `git remote -v`,输出应该类似于:

```
$ git remote -v
origin https://github.com/<your_username>/qmk_firmware.git (fetch)
origin https://github.com/<your_username>/qmk_firmware.git (push)
upstream https://github.com/qmk/qmk_firmware.git (fetch)
upstream https://github.com/qmk/qmk_firmware.git (push)
```

在以上操作完成后,可以通过执行 `git fetch upstream` 来检查仓库是否有更新。该命令从QMK仓库拉取的分支(branches)及标签(tags) &mdash; 统称为“refs(引用)” &mdash;现在也被称作 `upstream`(上游)。此时我们可以比对自己fork版本的 `origin` 与QMK维护的分支的差异了。

要更新你的fork的master分支,执行以下指令,每一行结束都需要按回车:

```
git checkout master
git fetch upstream
git pull upstream master
git push origin master
```

以上操作会切换到 `master` 分支,从QMK仓库拉取refs,下载QMK `master` 分支的当前版本,并上传至你的fork中。

## 进行编辑 :id=making-changes

要进行编辑,通过如下命令创建一个新分支:

```
git checkout -b dev_branch
git push --set-upstream origin dev_branch
```

以上操作会创建 `dev_branch` 新分支,检出(check out)并保存到你的for中。`--set-upstream` 参数用于告知git使用你的for仓库来处理 `dev_branch` 分支下的 `git push` 及 `git pull` 命令,且仅需要在第一次执行push命令时指定,之后再次执行 `git push` 或是 `git pull` 都无需加入该参数了。
epiciskandar marked this conversation as resolved.
Show resolved Hide resolved

?> 在 `git push` 时,可以使用 `-u` 替代 `--set-upstram` &mdash; `-u` 为 `--set-upsream` 参数的别名。

你可以任意命名该分支,但仍建议对分支起一个可以描述将在该分支下要做的工作的名称。

默认情况下 `git checkout -b` 会基于你当前检出的分支作为新分支的基准。可以在后面追加已存在但未检出的分支名来指定新分支的基准:

```
git checkout -b dev_branch master
```

此时你便有了一个开发用分支,可以打开编辑器并进行你期望的变更了。通常推荐提交大量的小规模提交(commit),这样在需要时会更容易地定位并回滚造成问题的提交。若要提交更改,编辑并保存要更新的文件,并将其添加到*暂存区(staged area)*,然后提交到分支中:

```
git add path/to/updated_file
git commit -m "My commit message."
```

`git add` 会将更改后的文件放到Git的*暂存区*,也称作Git的“装载区”。这里留存着即将通过 `git commit` 所提交并保存到仓库中的变更。请使用确切的描述来填写提交日志,以便于快速了解改动内容。

?> 如果更改了多个文件,可以通过 `git add -- path/to/file1 path/to/file2 ...` 来添加所有项目。

## 发布变更

最后一步为上传你的变更到你的fork中。通过执行 `git push`,Git将发布 `dev_branch` 分支的所有变更至你的fork中。