From 8b0381040cd953d36cf4c714d834c26d0cc7096c Mon Sep 17 00:00:00 2001 From: SoraShu Date: Sun, 31 Mar 2024 20:01:47 +0800 Subject: [PATCH 1/9] fix: add venv/ to .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b7d4db7..fb154f9 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,7 @@ site/ # autocorrect need node involved on Windows node_modules yarn.lock -package.json \ No newline at end of file +package.json + +# pyyhon venv +venv/ From 30a13370059e4dd02319f066c74c370ab46d0d0c Mon Sep 17 00:00:00 2001 From: SoraShu Date: Mon, 1 Apr 2024 01:06:31 +0800 Subject: [PATCH 2/9] add: git-tourial --- docs/guide-for-beginner/git-tutorial.md | 168 ++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 docs/guide-for-beginner/git-tutorial.md diff --git a/docs/guide-for-beginner/git-tutorial.md b/docs/guide-for-beginner/git-tutorial.md new file mode 100644 index 0000000..63b1147 --- /dev/null +++ b/docs/guide-for-beginner/git-tutorial.md @@ -0,0 +1,168 @@ +# Git 教程 + + + +## 初识 Git + +Git 是一个分布式版本控制系统,用于跟踪文件的变化并协作开发。它是由 Linus Torvalds 于 2005 年创建的。 + +在 Windows 上,可以通过 [Git for Windows](https://gitforwindows.org/) 安装 Git,在 Linux 上,可以通过包管理器安装 Git,例如: + +```bash +# Debian/Ubuntu +sudo apt install git +``` + +在 MacOS 上,可以通过 [Homebrew](https://brew.sh/) 安装 Git,或者使用 Xcode 自带的 Git。 + +对于刚下载的 Git,需要进行一些配置: + +```bash +git config --global user.name "Your Name" +git config --global user.email "user@example.com" +``` + +这里的 `--global` 选项表示这些配置将应用于所有的 Git 仓库。若要对特定仓库进行配置,可以去掉 `--global` 选项。 + +## Git 基础概念 + +### 仓库 + +Git 的管理是基于仓库(Repository)的,仓库可以看成一个储存了 Git 元信息的目录。可以在需要进行版本控制的目录下执行 `git init` 命令,将其初始化为一个 Git 仓库。 + +### 工作区与暂存区 + +一个文件在 Git 中有三种状态:已提交(committed)、已修改(modified)和已暂存(staged),这三种状态对应 Git 三个工作区域的概念: + +- 工作区(Working Directory):即我们的工作目录,我们对文件的修改都发生在这里。 +- 暂存区(Staging Area):即我们的缓存区,我们可以通过 `git add` 命令将工作区的文件添加到暂存区。暂存区存储了我们对文件的修改。 +- 仓库(Repository):即我们的版本库,我们可以通过 `git commit` 命令将暂存区的文件提交到仓库。 + +所以我们想要修改一个文件,实际上需要经历三个步骤: + +1. 在工作目录中修改文件。 +2. 使用 `git add` 将修改的文件添加到暂存区。 +3. 使用 `git commit` 将暂存区的文件提交到仓库。 + +### Commit 与 HEAD 与 Reset + +Commit 是 Git 中最小的版本单元,它包含了一个快照(snapshot)和一个指向该快照的指针。每次提交都会生成一个唯一的 SHA-1 值,这个值可以用来标识提交。 + +我们可以将目前的 Git 仓库想象为一个树状结构,每个 Commit 都是一个节点,每个节点都有一个指向父节点的指针。这样就形成了一个有向无环图。当前的 Commit 节点通过一个名为 `HEAD` 的指针指出。通过这样的树状结构,我们可以很方便地查看并回溯历史记录。 + +回溯历史记录的方法为使用 `git reset` 命令,它有三种模式: + +- `--soft`:仅仅将 `HEAD` 指针移动到指定的 Commit,不改变暂存区和工作区。 +- `--mixed`:将 `HEAD` 指针移动到指定的 Commit,同时重置暂存区,但不改变工作区。这是默认的模式。 +- `--hard`:将 `HEAD` 指针移动到指定的 Commit,同时重置暂存区和工作区。 + +我们可以看见,只有 `--hard` 模式会改变工作区。如果我们希望回溯历史记录时同时改变工作区,记得加上 `--hard` 选项。但这同时也会删除工作区的修改,所以当你想要回溯历史记录时,记得先将工作区的修改 `commit` 到仓库,这也是我们说的保持工作区干净的原因。 + +### 分支与切换 + +分支实际上与 HEAD 指针类似,它也指向一个 Commit。可以说分支的存在是为了更简单地在不同的 Commit 之间切换,在 Git 为基础的协同开发中,分支一般代表不同的开发任务与进度。例如在开发一个新功能时,我们在 `master` 分支上新建一个 `feature-a` 分支,然后在 `feature-a` 分支上进行开发,这时开发这个 `feature-a` 的人可以在不影响 `master` 分支的情况下进行开发,并且可以随时切换回 `master` 分支。 + +在 Git 中,分支的切换是通过 `git checkout` 命令实现的: + +```bash +# 在 master 分支上新建 feature-a 分支 +git checkout -b feature-a +# 进行开发 +some-development +# 切换回 master 分支 +git checkout master +``` + +由于分支本身只是一个指针,所以也可以使用 `git checkout commit-id` 来切换到某个 Commit,这样我们就可以在不同的 Commit 之间切换。 + +事实上,`git checkout` 命令还可以作用于文件,所以在新版本的 Git 中,切换分支有一个新的命令 `git switch`,它只能作用于分支。可以通过 `git switch --help` 查看相关信息,这里先按下不表。 + +### Merge 与 Rebase + +这里可以算是 Git 中最复杂的部分了。许多大型项目进行一次 Rebase 可能要花费数小时,甚至数天的时间。 + +延续上述场景,当 `feature-a` 开发完成后,我们需要将 `feature-a` 分支上完成的工作合并到 `master` 分支上。我们使用 `git merge` 命令来合并分支: + +```bash +# 切换到 master 分支 +git checkout master +# 合并 feature-a 分支 +git merge feature-a +``` + +这样就能将 `feature-a` 分支上的工作合并到 `master` 分支上。但这样的合并会产生一个新的 Commit,这个 Commit 会有两个父节点,一个是 `master` 分支的 Commit,一个是 `feature-a` 分支的 Commit。这样的合并方式叫做合并提交(Merge Commit)。 + +> 例外:Fast-forward 合并 +> +> 当 `feature-a` 分支的 Commit 是 `master` 分支的 Commit 的直接后继时,Git 会使用 Fast-forward 合并,这样的合并不会产生新的 Commit,只是将 `master` 分支的指针直接指向 `feature-a` 分支的 Commit。 + +另一种合并方式是 Rebase,Rebase 会将 `feature-a` 分支上的 Commit 逐个应用到 `master` 分支上,这样的合并方式会产生新的 Commit,但这些 Commit 不会有两个父节点,这样的合并方式叫做变基(Rebase)。 + +```bash +# 切换到 master 分支 +git checkout master +# 变基 feature-a 分支 +git rebase feature-a +``` + +Rebase 的好处是可以保持 Commit 的线性,这样的 Commit 更容易理解,但 Rebase 也有一个缺点,那就是 Rebase 会改变 Commit 的 SHA-1 值,如上述操作可以说 Rebase 是诸葛将修改应用到 master 分支上,这样会重写 master 分支的历史记录,于是当进行多人协作时,就会发现两个人的 master 分支不一致。所以在协作中多使用 Merge 合并。不过也有另一种操作,即先 Rebase 后 Merge,这样可以保持 Commit 的线性,又不会改变历史记录。 + +```bash +# 在 feature-a 分支上变基 +git rebase master +# 切换到 master 分支 +git checkout master +# 合并 feature-a 分支 +git merge feature-a +``` + +由于 Rebase 后的 feature-a 是 master 的直接后继,所以这里会使用 Fast-forward 合并。 + +在合并之后,若不再需要 `feature-a` 分支,可以使用 `git branch -d feature-a` 删除分支。 + +### 远程仓库 + +在多人协作中,通常会有一个远程仓库,这个远程仓库是所有人共享的。这里以 Gitee 为例,GitHub 是一个提供 Git 仓库托管服务的网站。远程仓库有三种协议:HTTP、SSH 和 Git,为了方便起见,我们这里使用 SSH 协议。 + +首先需要正确配置 SSH 密钥。可以通过 `ssh-keygen` 命令生成 SSH 密钥: + +```bash +ssh-keygen -t rsa -b 4096 -C ""comment" +``` + +这里的 "comment" 是注释,用来标识这个密钥,帮助你区分不同的密钥。这次生成的密钥会保存在 `$HOME/.ssh/id_rsa` 和 `$HOME/.ssh/id_rsa.pub` 文件中(`$HOME$` 代表家目录)。`id_rsa` 是私钥,`id_rsa.pub` 是公钥。复制 `id_rsa.pub` 中的内容,然后在 Gitee 的设置中添加 SSH 密钥。为了测试是否配置成功,使用 + +```bash +ssh -T git@gitee.com +``` + +验证是否配置成功。若配置成功,将出现 `Hi userxxx! You've successfully authenticated, but GITEE.COM does not provide shell access.` 的提示。 + +我们在 Gitee 上新建一个仓库,按照仓库创建后的提示即可将本地仓库与远程仓库关联: + +```bash +# 关联远程仓库 使用 SSH 协议 +git remote add origin git@gitee.com:userxxx/test-project.git +git push -u origin "master" +``` + +这样就将本地仓库与远程仓库关联起来了。事实上,目前只是将本地仓库的 `master` 分支推送到了远程仓库的 `master` 分支上,并且 `-u` 选项表示将本地的 `master` 分支与远程的 `master` 分支关联起来,作为这个分支的默认远程分支。当后续对 `master` 分支进行修改后,可以直接使用 `git push` 命令将修改推送到远程仓库。同理可以将其他分支推送到远程仓库。 + +```bash +# 推送 feature-a 分支到远程仓库 +git checkout feature-a +git push origin feature-a +``` + +当远程仓库发生了修改,可以通过 `git pull` 命令将远程仓库的修改拉取到本地仓库。 + +```bash +# 切换到 master 分支 +git checkout master +# 拉取远程仓库的修改 +git pull +``` + + + + From 173bf4d3fdd6269242ad1c9c2fffcacb6bd81001 Mon Sep 17 00:00:00 2001 From: SoraShu Date: Mon, 1 Apr 2024 01:28:11 +0800 Subject: [PATCH 3/9] update: update index --- mkdocs.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 72577ef..44a4e91 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -15,12 +15,12 @@ theme: - search.highlight - content.tabs.link palette: - - media: "(prefers-color-scheme: light)" + - media: "(prefers-color-scheme: light)" scheme: default toggle: icon: material/lightbulb-outline name: Switch to dark mode - - media: "(prefers-color-scheme: dark)" + - media: "(prefers-color-scheme: dark)" scheme: slate toggle: icon: material/lightbulb @@ -41,7 +41,7 @@ nav: - 主页: index.md - 关于我们: about.md - 参与指引: - - Markdown 规范: contribute-guide/markdown.md + - Markdown 规范: contribute-guide/markdown.md - Customized Debian: - 基本说明与变更日志: customized-debian/principle-and-changelogs.md - 快速上手: customized-debian/quick-start.md @@ -54,6 +54,7 @@ nav: - WSL 安装教程: guide-for-beginner/wsl-install-guide.md - VirtualBox + Ubuntu 安装教程: guide-for-beginner/vbox-ubuntu-guide.md - Windows C/C++ 开发环境配置实用指南: guide-for-beginner/practical-guide-to-cppdev-on-win.md + - Git 使用指南: guide-for-beginner/git-guide.md - 科普: - 编译,静态链接,可执行文件的生成: popular-science/compile.md - 程序的机器级表示: @@ -85,12 +86,11 @@ nav: - Anaconda3 & Jupyter 环境配置: hpc-doc/anaconda.md - PyTorch on SLURM: hpc-doc/pytorch.md - 非官方实验环境指南: - - 计算机组成原理lab1: unofficial-lab-env/comp-organ-lab1.md - + - 计算机组成原理lab1: unofficial-lab-env/comp-organ-lab1.md plugins: - search: - lang: + lang: - en # 选择日语来建立中文索引 - ja @@ -113,7 +113,7 @@ markdown_extensions: - pymdownx.tasklist: custom_checkbox: true - pymdownx.tabbed: - alternate_style: true + alternate_style: true - pymdownx.tilde - admonition - toc: From 9b1c6c113ec9527416a6efc1fa8041705fa0565a Mon Sep 17 00:00:00 2001 From: SoraShu Date: Mon, 1 Apr 2024 01:44:17 +0800 Subject: [PATCH 4/9] fix: fix index --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 44a4e91..e8a5b28 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -54,7 +54,7 @@ nav: - WSL 安装教程: guide-for-beginner/wsl-install-guide.md - VirtualBox + Ubuntu 安装教程: guide-for-beginner/vbox-ubuntu-guide.md - Windows C/C++ 开发环境配置实用指南: guide-for-beginner/practical-guide-to-cppdev-on-win.md - - Git 使用指南: guide-for-beginner/git-guide.md + - Git 使用指南: guide-for-beginner/git-tutorial.md - 科普: - 编译,静态链接,可执行文件的生成: popular-science/compile.md - 程序的机器级表示: From 9fa96ec8771b0e53870b713abd80e898bcac76f0 Mon Sep 17 00:00:00 2001 From: SoraShu Date: Mon, 1 Apr 2024 02:05:40 +0800 Subject: [PATCH 5/9] update: update git tutorial --- docs/guide-for-beginner/git-tutorial.md | 46 ++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/docs/guide-for-beginner/git-tutorial.md b/docs/guide-for-beginner/git-tutorial.md index 63b1147..f57d8db 100644 --- a/docs/guide-for-beginner/git-tutorial.md +++ b/docs/guide-for-beginner/git-tutorial.md @@ -143,7 +143,7 @@ ssh -T git@gitee.com ```bash # 关联远程仓库 使用 SSH 协议 git remote add origin git@gitee.com:userxxx/test-project.git -git push -u origin "master" +git push -u origin master ``` 这样就将本地仓库与远程仓库关联起来了。事实上,目前只是将本地仓库的 `master` 分支推送到了远程仓库的 `master` 分支上,并且 `-u` 选项表示将本地的 `master` 分支与远程的 `master` 分支关联起来,作为这个分支的默认远程分支。当后续对 `master` 分支进行修改后,可以直接使用 `git push` 命令将修改推送到远程仓库。同理可以将其他分支推送到远程仓库。 @@ -163,6 +163,50 @@ git checkout master git pull ``` +除了将本地仓库与远程仓库关联,还可以通过 `git clone` 命令将远程仓库克隆到本地: +```bash +git clone git@gitee.com:userxxx/test-project.git +``` + +## Git 协同开发工作流 + +在你了解了 Git 的基本概念后,你可以开始使用 Git 进行协同开发了。在学习 Git 基础知识时,你已经了解到 Git 稍显繁杂的操作,但你真正入门 Git 协同开发只需要掌握几个基本操作。这里推荐一种简单的基于 Feature 分支的工作流。 + +### 主分支只接受合并请求 + +在这种工作流中,主分支(`master`)只接受来自其他分支的合并,不允许直接向主分支提交代码。这样可以保证主分支代码的稳定性。 + +### 每个 Feature 都有一个独立的分支 + +在这种工作流中,每个 Feature 都有一个独立的分支,这样可以保证不同 Feature 之间的代码不会相互影响。在给项目添加新功能时,从主分支新建一个 Feature 分支,然后在这个分支上进行开发。 + +```bash +# 切换到 master 分支 +git checkout master +# 更新 确保 master 分支是最新的 +git pull +# 新建一个 Feature 分支 +git checkout -b feature-a +# 进行开发 +some-development +``` + +### 合并请求 + +当 Feature 开发完成后,需要将 Feature 分支合并到主分支上。在协作开发中,这种合并在某个人的本地仓库中进行并不方便审阅,我们一般在远程仓库中进行合并请求(Pull Request)。 + +在 Gitee 的仓库页面上点击 `Pull Request`,新建一个合并请求,源分支选择 Feature 分支,目标分支选择主分支,然后填写合并请求的标题与描述。这样就可以发起一个合并请求了。你们可以在这个合并请求中讨论代码的修改,审阅代码,最终在页面中点击合并按钮将 Feature 分支合并到主分支上。这种合并方式可以避免复杂的合并操作,并且当多个 feature 同时进行开发时也不容易产生合并冲突。在完成合并后,可以删除 Feature 分支。 + +## Git 技巧 + +这里列举几个不错的教程: + +- [git - 简明指南(中文翻译)](https://rogerdudler.github.io/git-guide/index.zh.html) +- [Git 的奇技淫巧(中文翻译)](https://github.com/521xueweihan/git-tips) +- [Git - Book](https://git-scm.com/book/zh/v2) + +同时推荐在熟悉 Git 的基本概念后使用 Git 的图形化工具,如 VsCode 的 Git 插件、JetBrains 的 Git 集成等。 +更多的 Git 使用技巧等待你在使用中发现。 From 96262f41aa20c1aacb74f69667590e6494fa181c Mon Sep 17 00:00:00 2001 From: Shiroki Satsuki Date: Sun, 31 Mar 2024 23:23:37 -0700 Subject: [PATCH 6/9] style: add space to git-tutorial.md --- docs/guide-for-beginner/git-tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide-for-beginner/git-tutorial.md b/docs/guide-for-beginner/git-tutorial.md index f57d8db..1f55e39 100644 --- a/docs/guide-for-beginner/git-tutorial.md +++ b/docs/guide-for-beginner/git-tutorial.md @@ -202,8 +202,8 @@ some-development 这里列举几个不错的教程: -- [git - 简明指南(中文翻译)](https://rogerdudler.github.io/git-guide/index.zh.html) -- [Git 的奇技淫巧(中文翻译)](https://github.com/521xueweihan/git-tips) +- [git - 简明指南 (中文翻译)](https://rogerdudler.github.io/git-guide/index.zh.html) +- [Git 的奇技淫巧 (中文翻译)](https://github.com/521xueweihan/git-tips) - [Git - Book](https://git-scm.com/book/zh/v2) 同时推荐在熟悉 Git 的基本概念后使用 Git 的图形化工具,如 VsCode 的 Git 插件、JetBrains 的 Git 集成等。 From e4ce6125f1ab77d32215294f942d71a80159d9ef Mon Sep 17 00:00:00 2001 From: SoraShu Date: Mon, 6 May 2024 10:02:32 +0800 Subject: [PATCH 7/9] fix typo --- docs/guide-for-beginner/git-tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide-for-beginner/git-tutorial.md b/docs/guide-for-beginner/git-tutorial.md index 1f55e39..eca728e 100644 --- a/docs/guide-for-beginner/git-tutorial.md +++ b/docs/guide-for-beginner/git-tutorial.md @@ -105,7 +105,7 @@ git checkout master git rebase feature-a ``` -Rebase 的好处是可以保持 Commit 的线性,这样的 Commit 更容易理解,但 Rebase 也有一个缺点,那就是 Rebase 会改变 Commit 的 SHA-1 值,如上述操作可以说 Rebase 是诸葛将修改应用到 master 分支上,这样会重写 master 分支的历史记录,于是当进行多人协作时,就会发现两个人的 master 分支不一致。所以在协作中多使用 Merge 合并。不过也有另一种操作,即先 Rebase 后 Merge,这样可以保持 Commit 的线性,又不会改变历史记录。 +Rebase 的好处是可以保持 Commit 的线性,这样的 Commit 更容易理解,但 Rebase 也有一个缺点,那就是 Rebase 会改变 Commit 的 SHA-1 值,如上述操作可以说 Rebase 是逐个将修改应用到 master 分支上,这样会重写 master 分支的历史记录,于是当进行多人协作时,就会发现两个人的 master 分支不一致。所以在协作中多使用 Merge 合并。不过也有另一种操作,即先 Rebase 后 Merge,这样可以保持 Commit 的线性,又不会改变历史记录。 ```bash # 在 feature-a 分支上变基 @@ -122,7 +122,7 @@ git merge feature-a ### 远程仓库 -在多人协作中,通常会有一个远程仓库,这个远程仓库是所有人共享的。这里以 Gitee 为例,GitHub 是一个提供 Git 仓库托管服务的网站。远程仓库有三种协议:HTTP、SSH 和 Git,为了方便起见,我们这里使用 SSH 协议。 +在多人协作中,通常会有一个远程仓库,这个远程仓库是所有人共享的。这里以 Gitee 为例,Gitee 是一个提供 Git 仓库托管服务的网站。远程仓库有三种协议:HTTP、SSH 和 Git,为了方便起见,我们这里使用 SSH 协议。 首先需要正确配置 SSH 密钥。可以通过 `ssh-keygen` 命令生成 SSH 密钥: From cfc774c1b3f2a33f67a7782c03309f17555dad01 Mon Sep 17 00:00:00 2001 From: SoraShu Date: Mon, 6 May 2024 10:57:35 +0800 Subject: [PATCH 8/9] update git tutorial --- docs/guide-for-beginner/git-tutorial.md | 99 +++++++++++++++++-------- 1 file changed, 70 insertions(+), 29 deletions(-) diff --git a/docs/guide-for-beginner/git-tutorial.md b/docs/guide-for-beginner/git-tutorial.md index eca728e..60a36a1 100644 --- a/docs/guide-for-beginner/git-tutorial.md +++ b/docs/guide-for-beginner/git-tutorial.md @@ -35,10 +35,10 @@ Git 的管理是基于仓库(Repository)的,仓库可以看成一个储存 一个文件在 Git 中有三种状态:已提交(committed)、已修改(modified)和已暂存(staged),这三种状态对应 Git 三个工作区域的概念: - 工作区(Working Directory):即我们的工作目录,我们对文件的修改都发生在这里。 -- 暂存区(Staging Area):即我们的缓存区,我们可以通过 `git add` 命令将工作区的文件添加到暂存区。暂存区存储了我们对文件的修改。 +- 暂存区(Staging Area):即我们的缓存区,我们可以通过 `git add` 命令将工作区的文件(或文件的变动)添加到暂存区。暂存区存储了我们对文件的修改。 - 仓库(Repository):即我们的版本库,我们可以通过 `git commit` 命令将暂存区的文件提交到仓库。 -所以我们想要修改一个文件,实际上需要经历三个步骤: +值得注意的是,由于我们对文件的编辑都发生在工作目录下,所以我们增删文件或对文件进行修改,都只会影响工作区,而不会影响暂存区和仓库。所以我们可以很容易地撤销在工作区发生的修改,这也是 Git 的优势之一。 我们真正想要在仓库中修改一个文件,实际上需要经历三个步骤: 1. 在工作目录中修改文件。 2. 使用 `git add` 将修改的文件添加到暂存区。 @@ -46,9 +46,10 @@ Git 的管理是基于仓库(Repository)的,仓库可以看成一个储存 ### Commit 与 HEAD 与 Reset -Commit 是 Git 中最小的版本单元,它包含了一个快照(snapshot)和一个指向该快照的指针。每次提交都会生成一个唯一的 SHA-1 值,这个值可以用来标识提交。 +在上一小结的内容中,我们将文件提交到仓库的操作是 `git commit`,也就是说我们对仓库的每一次变动都会产生一次 Commit。 +Commit 是 Git 中最小的版本单元,它包含了一个快照(snapshot)和一个指向该快照的指针。每次 Commit 都会生成一个唯一的 SHA-1 值,这个值可以作为这个 Commit 的标识。 -我们可以将目前的 Git 仓库想象为一个树状结构,每个 Commit 都是一个节点,每个节点都有一个指向父节点的指针。这样就形成了一个有向无环图。当前的 Commit 节点通过一个名为 `HEAD` 的指针指出。通过这样的树状结构,我们可以很方便地查看并回溯历史记录。 +我们可以将目前的 Git 仓库想象为一个链状结构,每个 Commit 都是一个节点,每个节点都有一个指向父节点的指针。这样就形成了一个有向无环图。当前的 Commit 节点通过一个名为 `HEAD` 的指针指出。通过这样的树状结构,我们可以很方便地查看并回溯历史记录。 回溯历史记录的方法为使用 `git reset` 命令,它有三种模式: @@ -56,24 +57,56 @@ Commit 是 Git 中最小的版本单元,它包含了一个快照(snapshot) - `--mixed`:将 `HEAD` 指针移动到指定的 Commit,同时重置暂存区,但不改变工作区。这是默认的模式。 - `--hard`:将 `HEAD` 指针移动到指定的 Commit,同时重置暂存区和工作区。 +实际使用方法如下所示: + +```bash +# 根据 Commit ID +git reset --mixed COMMITID +# 用当前位置进行标识 +# 如回到上上个 Commit +git reset HEAD~2 +``` + 我们可以看见,只有 `--hard` 模式会改变工作区。如果我们希望回溯历史记录时同时改变工作区,记得加上 `--hard` 选项。但这同时也会删除工作区的修改,所以当你想要回溯历史记录时,记得先将工作区的修改 `commit` 到仓库,这也是我们说的保持工作区干净的原因。 +当你想要回到原来的位置时,也很简单,例如使用分支名: + +```bash +git reset --hard master +``` + +对于分支的详细介绍将会在下一小节。 + ### 分支与切换 分支实际上与 HEAD 指针类似,它也指向一个 Commit。可以说分支的存在是为了更简单地在不同的 Commit 之间切换,在 Git 为基础的协同开发中,分支一般代表不同的开发任务与进度。例如在开发一个新功能时,我们在 `master` 分支上新建一个 `feature-a` 分支,然后在 `feature-a` 分支上进行开发,这时开发这个 `feature-a` 的人可以在不影响 `master` 分支的情况下进行开发,并且可以随时切换回 `master` 分支。 -在 Git 中,分支的切换是通过 `git checkout` 命令实现的: +下图就是一个分支的示意图,由于需要处理 issue53 所以在 master 分支上新建了一个 `iss53` 分支并且有 C3 这一个 Commit;同时,由于需要进行线上的热修复,所以在 master 分支上新建了一个 `hotfix` 分支,并且有 C5 这一个 Commit。 + +![分支示意图](https://github.com/hitszosa/wiki/assets/73573254/7f56ddea-e0d4-4ad8-a29f-383f7df5aa63) + +上述的修改可以用如下操作完成。 ```bash -# 在 master 分支上新建 feature-a 分支 -git checkout -b feature-a -# 进行开发 -some-development -# 切换回 master 分支 +# 新建 iss53 分支处理 issue53 +git checkout -b iss53 +# 进行开发并提交到暂存区 +some-development xxx +# 提交 C3 +git commit + +# 回到 master 分支 git checkout master +# 新建 hotfix 处理热修复 +git checkout -b hotfix +# 进行热修复并提交到暂存区 +some-fix +# 提交 C4 +git commit ``` -由于分支本身只是一个指针,所以也可以使用 `git checkout commit-id` 来切换到某个 Commit,这样我们就可以在不同的 Commit 之间切换。 +在 Git 中,分支的切换是通过 `git checkout` 命令实现的,由于分支本身只是一个指针,所以也可以使用 `git checkout commit-id` 来切换到某个 Commit,这样我们就可以在不同的 Commit 之间切换。 + 事实上,`git checkout` 命令还可以作用于文件,所以在新版本的 Git 中,切换分支有一个新的命令 `git switch`,它只能作用于分支。可以通过 `git switch --help` 查看相关信息,这里先按下不表。 @@ -81,42 +114,48 @@ git checkout master 这里可以算是 Git 中最复杂的部分了。许多大型项目进行一次 Rebase 可能要花费数小时,甚至数天的时间。 -延续上述场景,当 `feature-a` 开发完成后,我们需要将 `feature-a` 分支上完成的工作合并到 `master` 分支上。我们使用 `git merge` 命令来合并分支: +延续上述场景,当 `hotfix` 紧急修复完成后,我们需要将 `hotfix` 分支上完成的工作合并到 `master` 分支上。我们使用 `git merge` 命令来合并分支: ```bash # 切换到 master 分支 git checkout master -# 合并 feature-a 分支 -git merge feature-a +# 合并 hotfix 分支 +git merge hotfix ``` -这样就能将 `feature-a` 分支上的工作合并到 `master` 分支上。但这样的合并会产生一个新的 Commit,这个 Commit 会有两个父节点,一个是 `master` 分支的 Commit,一个是 `feature-a` 分支的 Commit。这样的合并方式叫做合并提交(Merge Commit)。 +这样就能将 `hotfix` 分支上的工作合并到 `master` 分支上。但这样的合并会产生一个新的 Commit,这个 Commit 会有两个父节点,一个是 `master` 分支的 Commit,一个是 `hotfix` 分支的 Commit。这样的合并方式叫做合并提交(Merge Commit)。 -> 例外:Fast-forward 合并 -> -> 当 `feature-a` 分支的 Commit 是 `master` 分支的 Commit 的直接后继时,Git 会使用 Fast-forward 合并,这样的合并不会产生新的 Commit,只是将 `master` 分支的指针直接指向 `feature-a` 分支的 Commit。 +不过我们可以发现,此次合并实际上并不需要产生新的 Commit,只需要将 `master` 的指针移动到 `hotfix` 指向的位置。这是因为 `hotfix` 分支是 `master` 分支的直接后继,Git 对这种情况会特殊处理,称为 Fast-forward 合并。合并效果如图所示: -另一种合并方式是 Rebase,Rebase 会将 `feature-a` 分支上的 Commit 逐个应用到 `master` 分支上,这样的合并方式会产生新的 Commit,但这些 Commit 不会有两个父节点,这样的合并方式叫做变基(Rebase)。 +![image](https://github.com/hitszosa/wiki/assets/73573254/d4b7e1a4-5057-4d0d-84e3-c828105c657f) + +当 `iss53` 分支进行开发,产生多次提交之后也需要合入 `master` 分支,合并效果如图: + +![image](https://github.com/hitszosa/wiki/assets/73573254/d6d2b259-a65c-48a4-9b1c-2cbb73a5dae0) + +![image](https://github.com/hitszosa/wiki/assets/73573254/e32fda27-e39d-44f1-8a4b-c52ae1411bf1) + +另一种合并方式是 Rebase,Rebase 会将 `iss53` 分支上的 Commit 逐个应用到 `master` 分支上,这样的合并方式会产生新的 Commit,但这些 Commit 不会有两个父节点,这样的合并方式叫做变基(Rebase)。 ```bash # 切换到 master 分支 git checkout master -# 变基 feature-a 分支 -git rebase feature-a +# 变基 iss53 分支 +git rebase iss53 ``` Rebase 的好处是可以保持 Commit 的线性,这样的 Commit 更容易理解,但 Rebase 也有一个缺点,那就是 Rebase 会改变 Commit 的 SHA-1 值,如上述操作可以说 Rebase 是逐个将修改应用到 master 分支上,这样会重写 master 分支的历史记录,于是当进行多人协作时,就会发现两个人的 master 分支不一致。所以在协作中多使用 Merge 合并。不过也有另一种操作,即先 Rebase 后 Merge,这样可以保持 Commit 的线性,又不会改变历史记录。 ```bash -# 在 feature-a 分支上变基 +# 在 iss53 分支上变基 git rebase master # 切换到 master 分支 git checkout master -# 合并 feature-a 分支 -git merge feature-a +# 合并 iss53 分支 +git merge iss53 ``` -由于 Rebase 后的 feature-a 是 master 的直接后继,所以这里会使用 Fast-forward 合并。 +由于 Rebase 后的 `iss53` 是 `master` 的直接后继,所以这里会使用 Fast-forward 合并。 在合并之后,若不再需要 `feature-a` 分支,可以使用 `git branch -d feature-a` 删除分支。 @@ -127,7 +166,7 @@ git merge feature-a 首先需要正确配置 SSH 密钥。可以通过 `ssh-keygen` 命令生成 SSH 密钥: ```bash -ssh-keygen -t rsa -b 4096 -C ""comment" +ssh-keygen -t rsa -b 4096 -C "comment" ``` 这里的 "comment" 是注释,用来标识这个密钥,帮助你区分不同的密钥。这次生成的密钥会保存在 `$HOME/.ssh/id_rsa` 和 `$HOME/.ssh/id_rsa.pub` 文件中(`$HOME$` 代表家目录)。`id_rsa` 是私钥,`id_rsa.pub` 是公钥。复制 `id_rsa.pub` 中的内容,然后在 Gitee 的设置中添加 SSH 密钥。为了测试是否配置成功,使用 @@ -169,6 +208,8 @@ git pull git clone git@gitee.com:userxxx/test-project.git ``` +上述操作会将仓库克隆下来,变成当前目录的一个子目录。 + ## Git 协同开发工作流 在你了解了 Git 的基本概念后,你可以开始使用 Git 进行协同开发了。在学习 Git 基础知识时,你已经了解到 Git 稍显繁杂的操作,但你真正入门 Git 协同开发只需要掌握几个基本操作。这里推荐一种简单的基于 Feature 分支的工作流。 @@ -202,9 +243,9 @@ some-development 这里列举几个不错的教程: -- [git - 简明指南 (中文翻译)](https://rogerdudler.github.io/git-guide/index.zh.html) -- [Git 的奇技淫巧 (中文翻译)](https://github.com/521xueweihan/git-tips) -- [Git - Book](https://git-scm.com/book/zh/v2) +- [git - 简明指南 (中文翻译)](https://rogerdudler.github.io/git-guide/index.zh.html):篇幅较短,适合入门 +- [Git 的奇技淫巧 (中文翻译)](https://github.com/521xueweihan/git-tips):一些 Git 的奇怪技巧,但有时候很有用 +- [Git - Book](https://git-scm.com/book/zh/v2):Git 官方的指南,很详细,推荐阅读。 同时推荐在熟悉 Git 的基本概念后使用 Git 的图形化工具,如 VsCode 的 Git 插件、JetBrains 的 Git 集成等。 From 4b4543bdd2d6082266666410154fa36203a5d124 Mon Sep 17 00:00:00 2001 From: SoraShu Date: Mon, 6 May 2024 17:57:17 +0800 Subject: [PATCH 9/9] fix typo --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fb154f9..c189040 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,5 @@ node_modules yarn.lock package.json -# pyyhon venv +# pyhon venv venv/