-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5739308
commit bfa9137
Showing
20 changed files
with
629 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
174 changes: 174 additions & 0 deletions
174
content/blog/Git-Speedrun-Guide-Part-2-Branch-And-Submodule/index.zh-cn.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
--- | ||
title: "Git 速通指南 | Part 2: 分支与子模块" | ||
--- | ||
|
||
在 [Git 速通指南 | Part 1: 基础](https://shusct.github.io/wiki/blog/git-speedrun-guide-part-1-basics/) 中, 我们已经学习了如何创建 Git 储存库, 如何 `add` 和 `commit` 更改, 以及如何进行 `push` 以及 `pull` 操作. 本文将继续介绍 Git 的分支与子模块的使用. | ||
|
||
## 0. 准备工作 | ||
|
||
请保证本地有一个与远程仓库关联的 Git 储存库. 如果没有, 请参考 [Git 速通指南 | Part 1: 基础](https://shusct.github.io/wiki/blog/git-speedrun-guide-part-1-basics/) 第 4 节创建一个远程储存库, 然后直接 `clone` 至本地. | ||
|
||
## 1. 分支 | ||
|
||
### 1.1. 创建和切换分支 | ||
|
||
在本地 Git 储存库下打开终端, 输入以下命令创建一个新分支 `feature`: | ||
|
||
```bash | ||
git switch -c feature | ||
``` | ||
|
||
|
||
> 💡 当基于当前分支创建了一个新分支时, 新分支会继承当前分支的所有 `commit` 记录; 可以认为新分支克隆了当前分支. | ||
|
||
查看本地储存库有哪些分支: | ||
|
||
```bash | ||
git branch | ||
``` | ||
|
||
查看远程储存库有哪些分支: | ||
|
||
```bash | ||
git branch -r | ||
``` | ||
|
||
通过 `git branch` 你应该观察到当前我们在本地的 `feature` 分支上; 如果没有, 通过以下命令切换到 `feature` 分支: | ||
|
||
```bash | ||
git switch feature | ||
``` | ||
|
||
在当前路径下创建一个新文件 `feature.txt` 并写入 "This is a feature file."; 将更改 `add` 和 `commit` 到本地储存库: | ||
|
||
```bash | ||
echo "This is a feature file." > feature.txt | ||
git add feature.txt | ||
git commit -m "Add feature file" | ||
``` | ||
|
||
这次 `commit` 记录仅在 `feature` 分支上, 并不会影响 `main` 分支. 切换到 `main` 分支, 可以看到 `feature.txt` 文件并不存在: | ||
|
||
```bash | ||
git switch main | ||
ls # List files in current directory | ||
``` | ||
|
||
### 1.2. `merge` 分支 | ||
|
||
由于 `feature` 分支上的更改已经 `commit`, 我们希望将 `feature` 分支上的更改合并到 `main` 分支上. 切换到 `main` 分支, 并输入以下命令: | ||
|
||
```bash | ||
git switch main | ||
git merge feature # Merge feature to main | ||
``` | ||
|
||
此时在 `main` 分支下, 通过 `ls` 命令可以查看到已有 `feature.txt` 文件. 从 `commit` 记录来看, `main` 分支上的 `commit` 记录已经包含了 `feature` 分支上的所有 `commit` 记录. | ||
|
||
### 1.3. 冲突处理 | ||
|
||
冲突发生在 `merge` 过程中. 例如, 当 `main` 分支和 `feature` 分支上的同一个文件的同一行都被修改时, Git 无法自动决定如何合并这两个更改, 从而产生冲突. | ||
|
||
接下来我们尝试模拟冲突产生过程并处理冲突. | ||
|
||
首先切换到 `main` 分支, 修改 `feature.txt` 文件, 在 "This is a feature file." 这行末尾添加 "mmm", 最终文件内容为 "This is a feature file.mmm". `add` 和 `commit` 更改. | ||
|
||
接着切换到 `feature` 分支, 修改 `feature.txt` 文件, 在 "This is a feature file." 这行末尾添加 "fff", 最终文件内容为 "This is a feature file.fff". `add` 和 `commit` 更改. | ||
|
||
切换回 `main` 分支, 输入以下命令合并 `feature` 分支: | ||
|
||
```bash | ||
git merge feature | ||
``` | ||
|
||
终端提示如下: | ||
|
||
``` | ||
Auto-merging feature.txt | ||
CONFLICT (content): Merge conflict in feature.txt | ||
Automatic merge failed; fix conflicts and then commit the result. | ||
``` | ||
|
||
说明合并过程中发生了冲突. 此时查看 `feature.txt` 文件, 会发现文件内容如下: | ||
|
||
``` | ||
<<<<<<< HEAD | ||
This is a feature file. mmm | ||
======= | ||
This is a feature file. fff | ||
>>>>>>> feature | ||
``` | ||
|
||
从上面的内容可以看出, `<<<<<<< HEAD` 到 `=======` 之间的内容是 `main` 分支上的内容 (即当前分支 `HEAD`), `=======` 到 `>>>>>>> feature` 之间的内容是 `feature` 分支上的内容. 我们需要手动解决这个冲突. | ||
|
||
解决冲突的方式非常简单, 手动选择保留哪部分内容即可. 比如把上面的内容全部删除, 只保留 `feature` 分支的更改, 最终文件内容为 "This is a feature file.fff". | ||
|
||
在 `main` 分支上 `add` 和 `commit` 更改后, 就完成了 `merge` `feature` 分支并解决冲突的所有过程. | ||
|
||
> 💬 从远程 Git 储存库 `pull` 新版本时, 也可能出现冲突情况. 此时也只需手动处理冲突即可. | ||
### 3.4. 删除本地分支 | ||
|
||
当一个分支的工作已经完成, 可以删除该分支. 删除分支前, 请确保该分支上的所有更改已经 `commit` 并合并到其他分支上. 删除本地分支 `feature`: | ||
|
||
```bash | ||
git branch -d feature | ||
``` | ||
|
||
### 3.5. 创建远程分支 | ||
|
||
本地新创建的分支 `feature` 并不会自动同步到远程仓库. 如果需要将本地分支同步到远程仓库, 需要手动 `push` 该分支: | ||
|
||
```bash | ||
git push origin feature:feature | ||
``` | ||
|
||
此时在远程仓库中应该可以看到一个新的分支 `feature`. | ||
|
||
### 3.6. 删除远程分支 | ||
|
||
删除远程分支 `feature`: | ||
|
||
```bash | ||
git push origin --delete feature | ||
``` | ||
|
||
## 2. 子模块 | ||
|
||
子模块是 Git 仓库中的一个仓库. 通过子模块, 我们可以将一个 Git 仓库嵌套到另一个 Git 仓库中. 子模块的使用可以帮助我们更好地管理项目的依赖关系. | ||
|
||
### 2.1. 添加子模块 | ||
|
||
在本地 Git 储存库下打开终端, 输入以下命令添加一个子模块: | ||
|
||
```bash | ||
git submodule add <URL> <RelativePath> | ||
``` | ||
|
||
其中 `<URL>` 是子模块的 Git 仓库地址, `<RelativePath>` 是子模块在本地储存库中的相对路径. | ||
|
||
### 2.1. 初始化子模块 | ||
|
||
直接 `clone` 包含子模块的 Git 仓库时, 子模块并不会被自动初始化. 因此需要手动初始化子模块: | ||
|
||
```bash | ||
git submodule update --init --recursive | ||
``` | ||
|
||
### 2.3. 更新子模块 | ||
|
||
如果子模块的远程仓库发生了更改, 需要手动更新子模块: | ||
|
||
```bash | ||
git submodule update --remote --recursive | ||
``` | ||
|
||
### 2.4. 删除子模块 | ||
|
||
删除子模块需要以下几个步骤: | ||
|
||
1. 删除 `.gitmodules` 文件中子模块的配置. | ||
2. 删除 `.git/config` 文件中子模块的配置. | ||
3. 删除子模块的目录. | ||
4. 删除 `.git/modules/<SubmodulePath>` 文件夹. |
127 changes: 127 additions & 0 deletions
127
content/blog/Git-Speedrun-Guide-Part-3-Contribute-as-a-Collaborator/index.zh-cn.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
--- | ||
title: "Git 速通指南 | Part 3: 作为协作者贡献" | ||
--- | ||
|
||
> 📌**注意**: 对于 SHUSCT, 我们倾向使用 GitHub Flow 进行协作. 详细内容请参考 [GitHub Flow](https://guides.github.com/introduction/flow/). | ||
## 1. 指定协作者 (Collaborator) | ||
|
||
1. 打开你的项目仓库, 点击 `Settings` 选项卡. | ||
2. 在左侧导航栏中点击 `Manage access`. | ||
3. 在右上角点击 `Invite a collaborator`. | ||
4. 输入协作者的 GitHub 用户名, 点击 `Add [username] to [repository]`. | ||
|
||
## 2. `clone` 项目仓库 | ||
|
||
参考 [Git 速通指南 | Part 1: 基础 - 4. 远程储存库](https://shusct.github.io/wiki/blog/git-speedrun-guide-part-1-basics/#4-%e8%bf%9c%e7%a8%8b%e5%82%a8%e5%ad%98%e5%ba%93) 中的内容, 将项目仓库 `clone` 至本地. | ||
|
||
## 3. 查看 `issue` | ||
|
||
在项目仓库中点击 `Issues` 选项卡. | ||
|
||
选择一个你感兴趣的 `issue`, 并在评论中表明你想要解决这个 `issue`. 你可以提出你的解决方案, 或者询问其他协作者的意见; 你还可以将 `issue` 分配给自己. | ||
|
||
如果没有与你想法相关的 `issue`, 你可以创建一个新的 `issue`. | ||
|
||
## 4. 创建分支 | ||
|
||
当你决定解决一个 `issue` 时, 请先检查是否已经有合适的分支. | ||
|
||
如果有, 可以直接在本地 `pull` 并 `switch` 到该分支进行工作: | ||
|
||
```bash | ||
# Pull the new version from the remote repository | ||
git pull origin <BranchName> --no-rebase | ||
# Switch to the branch | ||
git switch <BranchName> | ||
``` | ||
|
||
|
||
如果没有合适的分支, 你需要创建一个新的分支. 我们建议使用如下命名规范: | ||
|
||
<p align="center"> | ||
|
||
| 分支名 | 用途 | | ||
| :---: | :---: | | ||
| `feature/#<IssueNumber>-<Description>` | 添加新功能 | | ||
| `bugfix/#<IssueNumber>-<Description>` | 修复 bug | | ||
| `hotfix/#<IssueNumber>-<Description>` | 紧急修复 | | ||
| `doc/#<IssueNumber>-<Description>` | 文档更新 | | ||
|
||
</p> | ||
|
||
参考 [Git 速通指南 | Part 1: 基础 - 1. 分支]() 创建新分支并推送至远程仓库. 例如, 如果你想解决 `issue #1` (关于支持 `std::format`), 你可以创建一个名为 `feature/#1-support-std-format` 的分支并推送至远程仓库; 参考以下命令: | ||
|
||
```bash | ||
# Switch to the target branch | ||
git switch main # Take main branch as an example | ||
# Create and switch to a new branch; The branch is based on the target branch | ||
git switch -c feature/#1-support-std-format | ||
# Push the new branch to remote repository | ||
git push origin feature/#1-support-std-format:feature/#1-support-std-format | ||
``` | ||
|
||
## 5. `push` 更改 | ||
|
||
修改完成后, 请将更改 `add` 和 `commit` 到本地仓库, 接着先 `pull` 远程仓库的最新更改 (他人可能在你提交之前 `push` 到了你正在工作的分支, 你需要 `pull` 下来进行可能的[冲突处理]()), 然后再 `push` 你的更改至远程仓库: | ||
|
||
```bash | ||
# Add local changes to the staged area | ||
git add . | ||
# Commit local changes to the local Git repository; Now there is a new version of your project | ||
git commit -m "<Message>" | ||
# Pull the new version from the remote repository | ||
git pull origin <BranchName> --no-rebase | ||
# [Note]: If there are conflicts, you need to resolve them manually. | ||
# Push the new version to the remote repository | ||
git push origin <BranchName> | ||
``` | ||
|
||
## 6. 提交 `PR` | ||
|
||
当你的更改完成并 `push` 到远程仓库后, 请在 GitHub 上提交一个 `PR` (Pull Request). | ||
|
||
1. 打开项目仓库, 点击 `Pull requests` 选项卡. | ||
2. 点击 `New pull request`. | ||
3. 选择你的分支和目标分支. 由于我们采用 GitHub Flow, 通常目标分支是 `main`; `PR` 操作的目的是将你的分支 `merge` 入目标分支. | ||
4. 输入 `PR` 的标题和描述. **如果你的 `PR` 关联到某个 `issue`, 请在描述中提及, 例如: `Fix #1`, `Close #1`**. | ||
5. 点击 `Create pull request`. | ||
|
||
如果 GitHub 提示 `conflict`, 那么表示当前分支和目标分支间有无法自动解决的冲突. 以目标分支为 `main` 为例, 你需要将最新的 `main` 分支 `merge` 入你的分支, 并解决冲突后再次 `push` 到远程仓库; 参考以下代码: | ||
|
||
```bash | ||
# Switch to the target branch | ||
git switch main | ||
# Pull the new version from the remote repository | ||
git pull origin main --no-rebase | ||
# Switch to your branch | ||
git switch <BranchName> | ||
# Merge the target branch into your branch | ||
git merge main | ||
# [Note]: If there are conflicts, you need to resolve them manually. | ||
# Push the new version to the remote repository | ||
git push origin <BranchName> | ||
``` | ||
|
||
此时你的分支能够被 `merge` 入目标分支; 回到刚才的 `PR` 页面, GitHub 能够自动检测到你的分支已经能够被 `merge`. | ||
|
||
## 7. `PR` 审核与合并 | ||
|
||
作为协作者, 你可以在 `PR` 页面查看其他协作者提交的 `PR`, 并对其进行评论. 你可以提出修改建议, 或者直接 `approve` 该 `PR`. | ||
|
||
当 `PR` 经过多人 `approve` 后, 项目维护者可以 `merge` 该 `PR`. 项目维护者可以选择 `Squash and merge`, `Rebase and merge`, 或者 `Create a merge commit` 等方式进行 `merge`. | ||
|
||
## 8. `Tag` | ||
|
||
如果想要将某个版本标记为重要版本, 可以使用 `tag`. 例如, 如果你的项目完成了一个重要的版本迭代, 你可以使用 `tag` 标记该版本: | ||
|
||
```bash | ||
# Switch to the target branch | ||
git switch main # Take main branch as an example | ||
# Tag the version | ||
git tag -a v1.0 -m "Release v1.0" | ||
# Push the tag to the remote repository | ||
git push origin v1.0 | ||
``` | ||
|
||
|
Oops, something went wrong.