Skip to content

Commit

Permalink
Update Git Tutor
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesnulliu committed Jun 30, 2024
1 parent dc11ca5 commit c45581f
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 2 deletions.
27 changes: 25 additions & 2 deletions content/blog/Git-Speedrun-Guide-Part-1-Basics/index.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,29 @@ Fig.4 中的 Version 2 是当前项目的最新版本.

很多时候, 我们需要在不同的电脑上部署某个项目进行多人协同开发. 因此出现 "将本地 Git 储存库同步到一个远程储存库 (例如 GitHub)" 的想法.

## 4.1. 基础命令

在实际创建和使用远程储存库之前, 我们先了解一些基础命令:

本地更改 `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>
# Push the new version to the remote repository
git push origin <BranchName>
```

远程储存库的更改 `pull` 到本地:

```bash
# Pull the new version from the remote repository
git pull origin <BranchName> --no-rebase
```

总结来说, 当你的储存库中版本更新, 你应该 `push` 到远程储存库; 当远程储存库中版本更新, 你应该 `pull` 到本地储存库.

### 4.1. 生成 SSH 密钥并连接 GitHub

Expand Down Expand Up @@ -176,7 +199,7 @@ git remote add origin <SSHAddress>
假设远程储存库的默认分支名为 `main`, 先 `pull` 远程储存库中的内容:

```bash
git pull origin main
git pull origin main --no-rebase
```

> 💡 `pull` 操作会把远程储存库中的较新内容拉取到本地储存库.
Expand All @@ -203,7 +226,7 @@ git push origin main

> 💡 `push` 操作会把本地储存库中较新的内容推送至远程储存库.
4.4. `clone` 远程储存库
### 4.4. 直接 `clone` 远程储存库

对于一个已有的远程储存库, 你可以直接通过以下命令将其 `clone` 至本地:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
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` 分支下, 通过 `ll` 可以查看到已有 `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` 新版本时, 也可能出现冲突情况. 此时也只需手动处理冲突即可.
## 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>` 文件夹.

0 comments on commit c45581f

Please sign in to comment.