Skip to content

Commit 8cf8e94

Browse files
S1ngS1ngdemongodYY
authored andcommitted
Add CONTRIBUTING.md (FreeCodeCampChina#15)
* Add CONTRIBUTING.md, add guide of git * address review comments - Pick pull --rebase among three options - Update guideline of resolving conflicts * Add git FAQ. Remove labels def as for not needed * Fix style issue, using HTML tags * Update Details w/ GFM, fix wrong command * Update FAQ with guide of resolving conflicts and clarification of git add . vs git add -A * Update CONTRIBUTING.md 更新了下排版 * Update CONTRIBUTING.md 更改符号的使用 * Update CONTRIBUTING.md continue fix some type error
1 parent 91a8634 commit 8cf8e94

File tree

1 file changed

+243
-0
lines changed

1 file changed

+243
-0
lines changed

CONTRIBUTING.md

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
# 关于 git 和 github
2+
## 常用词汇
3+
- repo:代码仓库
4+
- PR:即 pull request,合并请求
5+
- branch:分支
6+
- commit:提交记录
7+
- merge:指 PR 合并到代码仓库的操作
8+
- conflicts:(合并)冲突
9+
10+
## 开始之前
11+
* 首先,fork 一下 [challenges](https://github.com/FreeCodeCampChina/challenges.git) repo。
12+
13+
***你的 fork** 克隆到本地。
14+
```bash
15+
git clone https://github.com/your_name/challenges.git # 注意,`your_name` 是你的 github ID。
16+
```
17+
* 切换到 challenges 文件夹。
18+
```bash
19+
cd challenges
20+
```
21+
* 根据你在翻译的项目名称或者你正在做的事情,新建分支。
22+
```bash
23+
# 建议每次都从 translate 分支建立新的分支
24+
# 请参考后面的“常见问题”
25+
git checkout -b your_branch_name # `your_branch_name` 是你的分支名
26+
```
27+
* 在本地进行代码或文件修改。
28+
29+
* 添加要追踪的文件到暂存区。
30+
```bash
31+
git add . # 注:这个命令不是永远都会添加你的所有改动,请参考“常见问题”。
32+
git add my.json # 或者你也可以添加某一个文件
33+
```
34+
* 提交 commit 到本地仓库。
35+
```bash
36+
git commit -m "My commit message" # 注意,请根据实际情况填写 commit message。
37+
git commit # 或者你也可以打开你喜欢的编辑器(需要配置),在里面编写 commit message。
38+
```
39+
* 把本地仓库推送到远程仓库。
40+
```bash
41+
git push origin your_branch_name
42+
```
43+
* 打开 github 页面,创建 PR。
44+
45+
## 同步远程更新至本地
46+
* 关联上游 repo 至本地项目。
47+
```bash
48+
git remote add upstream https://github.com/FreeCodeCampChina/challenges.git
49+
```
50+
* 获取上游更新,并应用到本地。
51+
```bash
52+
git pull --rebase upstream translate
53+
```
54+
55+
## 注意
56+
* `pull``rebase` 之后,如果有 conflicts,可以先使用 `git status` 查看存在 conflicts 的文件。
57+
58+
修改成需要的版本后,使用 `git add .` 然后 `git rebase --continue`
59+
60+
* 解决冲突之后,需要更新至远程,否则只有你的本地有更新。
61+
```bash
62+
git push origin your_branch_name
63+
```
64+
* 如果出现错误提示,请先使用 `git status` 命令检查本地是否有未解决完成的 conflicts。
65+
66+
* 任何时候出现错误,不必惊慌。
67+
68+
先使用 `git status` 命令检查当前所在的分支、当前目录是否纯净(clean),以及本地是否有未解决完成的 conflicts。
69+
70+
* 如果上一步没问题,你可以用 `git push -f origin your_branch_name` 来更新远程。
71+
72+
* 如果你已经用当前的 branch 开了 PR,那么更新这个 branch 至远程的同时,你的 PR 也会自动更新。
73+
74+
## 常见问题
75+
<details><summary><b>为什么 `git add .` 命令有时会添加不上我的改动?</b></summary>
76+
77+
注意,`git add .` 中的 `.` 表示“当前路径”。
78+
79+
因此,如果你通过 `cd` 命令切换到子目录,并在里面执行 `git add .`,那么外面的改动则不会添加。
80+
81+
然而,如果你在父级目录执行 `git add .`,子级目录里的文件改动是会添加的。
82+
83+
真正的“添加所有文件”的命令是 `git add --all`,可以简写为 `git add -A`
84+
85+
对于这个翻译项目,我们很少会需要 `cd` 进子目录。因此,一般情况下使用 `git add .` 就足够了。
86+
87+
</details>
88+
89+
<details><summary><b>如何解决冲突?</b></summary>
90+
91+
对于任何多人协作项目,有 merge conflicts 是十分正常的。
92+
93+
如果你在命令行中看到了 `CONFLICTS` 这样的输出,那就表示有冲突。
94+
95+
这时,你需要先使用 `git status` 命令来查看冲突发生的文件。
96+
97+
一般来说,有冲突的文件会显示成这样:
98+
99+
```text
100+
some code ....(这里的代码是没有冲突的)
101+
<<<<<<< HEAD
102+
code version 1
103+
code version 1
104+
=======
105+
code version 2
106+
code version 2
107+
>>>>>>> your_branch_name
108+
yet some other code ....(这里的代码也是没有冲突的)
109+
```
110+
111+
注意,里面的 `HEAD``your_branch_name` 位置可能互换,也可能会是其他内容,比如一个 commit hash。
112+
113+
其中,`<<<<<<<``=======` 之间为代码的一个版本,`=======``>>>>>>>` 之间为代码的另一个版本。
114+
115+
你需要来决定使用哪个版本的代码,修改的时候,把 `<<<<<<<``=======``>>>>>>>` 这三行都删掉。
116+
117+
以及,删掉你不需要的那个版本,保留你需要的版本。
118+
119+
处理完所有的冲突文件后,(由于我们执行的是 `git pull --rebase`),那么我们需要 `git add .`,然后 `git rebase --continue`
120+
121+
</details>
122+
123+
<details><summary><b>如果某个文件我没有改动,在处理冲突的时候如何可以使用 upstream 上 translate 分支的版本?</b></summary>
124+
125+
有时,可能会存在你没修改某个文件的内容,然而它却出现在了 conflicts 里(特别是如果你之前使用过 `pull`,而不是 `pull --rebase`)。
126+
127+
这时,我们输入:。
128+
129+
```bash
130+
git fetch upstream
131+
git checkout upstream/translate -- the/path/to/that_file
132+
```
133+
134+
这时,你本地的这个文件就变成和远程一样了。
135+
136+
处理之后,记得 `git add .`
137+
138+
</details>
139+
140+
<details><summary><b>如何查看我当前处于哪个分支?</b></summary>
141+
142+
`git branch` 可以列出本地所有的分支名,前面打星号(*)的就是你当前所在的分支。
143+
144+
</details>
145+
146+
<details><summary><b>如何切换分支?</b></summary>
147+
148+
`git checkout some_branch_name` 就可以切换到对应的分支。
149+
150+
以及,`git checkout -` 可以切换到上一个切换过的分支。
151+
152+
在两个分支之间来回切换的时候,这个命令会很有用。
153+
154+
</details>
155+
156+
<details><summary><b>新建分支的时候,与我当前所在的分支有关联么?</b></summary>
157+
158+
有,新建分支的时候,当前所在分支的所有 `commit` 也会添加到新的分支里面。
159+
160+
以及,如果你本地有未 `commit` 的改动(哪怕已经 `add` 过),同样会在新建分支的时候带过去。
161+
162+
</details>
163+
164+
<details><summary><b>既然切换 branch 时代码会跟着走,我正在别的分支上翻译,突然让我去更新之前开了 PR 的另一个分支,我该怎么办?</b></summary>
165+
166+
你有两个选择,`commit` 或者 `stash`
167+
168+
* `commit` 很简单,在当前分支上 `git add .` 然后 `git commit -m "xx"`,这时候你就可以使用 `checkout` 命令切换到其他分支了。
169+
170+
* 在当前分支上 `git stash`,然后切换到其他分支。完成那边的更新后,切换回来,然后 `git stash pop`,你之前的代码改动就都回来了。
171+
172+
需要注意的是,使用 `git stash pop` 会有丢代码的潜在风险,推荐使用 `git stash apply stash@{x}`,其中 `x` 为一个数字。
173+
174+
如果你不确定你的做法是否正确,或者不了解这个命令,请在使用之前查清资料,或者在群里提问。
175+
176+
**切换分支前,为防止把本地弄乱,前先使用 `git status` 来检查本地是否 “clean”。**
177+
178+
</details>
179+
180+
<details><summary><b>我可不可以根据远程的分支(比如 upstream 的 translate 分支)来创建本地分支?</b></summary>
181+
182+
可以:
183+
```bash
184+
git fetch upstream
185+
git checkout -b my_branch_name upstream/translate
186+
```
187+
188+
</details>
189+
190+
<details><summary><b>每次都从远程创建分支太麻烦,我可不可以直接从本地创建分支?</b></summary>
191+
192+
可以。建议使用本地的 translate 分支保持与 upstream 中的 translate 分支保持更新。这样做的好处是:
193+
194+
* 每次新建分支的时候,切换到本地的 translate 分支,然后 `git checkout -b my_new_branch` 就好了。
195+
196+
* 如果 upstream 的 translate branch 有更新,你只需要在切换到 translate 分支之后,`git pull --rebase upstream translate` 即可完成对本地 translate 分支的更新。再创建新的分支,就是基于 upstream 里最新的代码了,这样可以减少 conflicts 出现的可能。
197+
198+
</details>
199+
200+
<details><summary><b>我在一个分支上 commit 了我的代码,这时候 upstream 更新了,我该怎么做?</b></summary>
201+
202+
```bash
203+
git pull --rebase upstream translate
204+
```
205+
206+
</details>
207+
208+
<details><summary><b>我的本地 translate 分支已经有我的 commit 了,那我该如何用这个分支作为与 upstream translate 同步的分支呢?</b></summary>
209+
210+
**如果你目前在 translate 提交的内容不再需要了(比如,已经 merge),那你可以先切换到 translate,然后:**
211+
212+
```bash
213+
git fetch upstream
214+
git reset --hard upstream/translate
215+
```
216+
217+
虽然 `git reset` 命令不危险,但在执行这个操作之前,建议你先在群里问一下。
218+
219+
</details>
220+
221+
<details><summary><b>命令好长,我不想记。</b></summary>
222+
223+
`alias` 了解一下。在命令行里执行:
224+
225+
```bash
226+
git config --global alias.gx 'pull --rebase upstream translate'
227+
```
228+
229+
下次,执行 `git gx`(记忆:git 更新),就会执行你定义好的命令了。
230+
231+
</details>
232+
233+
## 一些原则
234+
* 建议使用 [git workflow](https://guides.github.com/introduction/flow/) 来进行分支的管理。
235+
236+
这样我们可以提交 PR 之后继续在新的 branch 上进行后续的翻译,若需要更新当前的 PR,我们随时可以切换回来。
237+
238+
* 不建议同时开两个相同类型(比如翻译)的 PR,请等待之前的 merge 之后再开新的 PR。
239+
240+
* 如果你的 PR 已经被 review 过,请不要再添加新的翻译内容,根据 comment 修改好当前的 PR 即可。
241+
242+
后续的翻译你可以等当前翻译 merge 后再开始做,或者在另一个本地的 branch 进行后续的翻译。
243+

0 commit comments

Comments
 (0)