Git 的使用

引言

不知道你有没有过这种经历:

你写好了一份代码,准备提交的时候,突然有个更好的点子,想改动一下,但是又不敢动手,怕改坏了。于是你把代码备份了一份,这才放心删改起来。

你疯狂敲键盘,点子逐渐成型,然而你这时候你的点子出现了分支:是走 A 路线,还是走 B 路线呢?你陷入了沉思,于是又把代码复制了一份...

当你完成这个项目之后,你发现你的代码被复制了几十份,放在你的硬盘里,文件名乱七八糟,甚至分不出每份代码到底是哪个阶段的,想回到某个节点的话,得还原哪份带代码。

这还只是一个人 solo 一个项目的情况。如果有十来个人一起工作,每个人都有自己的一点小想法,把代码复制一遍进行尝试,很快整个项目就变成了屎山(Pi, 2021)。

为了避免这种情况,我们强烈推荐使用 git 。这是一个非常好用的版本管理工具。

Git 概念

git 会为你保存整个文件夹历史。它会把每次改动的信息都完整地保存在一个地方,这样你就可以随时查看、还原,非常方便。

git 的工作流程是这样:
- 首先,你需要声明,要让 git追踪(track)哪些文件。当你创建新文件的时候,需要把它加入追踪的列表中。
- 然后,每次你认为你的工作进行到了一定的阶段(i.e. 需要备份一下你的代码的节点),你需要用 git提交(commit)所有被追踪(track)的文件,这样,相当与备份了一下。
- 当你有需要的时候,你可以用 git回溯(checkout)某个版本的文件。

当然不只是这些,你还可以:
- 你可以创建一个分支(branch)。你可以把代码备份(提交)到分支上。
- 你可以把一个分支``合并(merge)到另一个分支上,git 会自动分析两个分支之间的相同与不同之处,非常方便。

分支合并的功能在团队合作的时候尤其有用。通常,企业分工的时候,我们会每个人创建一个分支,在分支上开发一个具体的功能,完成后再合并回主分支。

合并的时候,会有人专门去审核代码,同意后才能合并。我们还可以撰写脚本,在试图合并的时候自动运行测试代码,测试通过后才能发出合并请求。

总之,git 为我们提供了很好的工作流程。

Git 安装

请自行搜索 git installation

Git 本地用法

我们会介绍以下几个:
- git init
- git add
- git status
- git commit
- git log
- git checkout
- git branch
- git merge

掌握它们之后,基本上就可以加入团队进行合作了。

初始化

首先,对于一个文件夹,你需要使用 git init 来初始化。它会在本地创建一个 .git 文件夹。然后,你就可以在这个文件夹里用 git 进行追溯了。

注意:请不要更改这个文件夹里的任何东西。除非你想重新初始化 git 历史。这样的话,请把整个 .git 文件夹删除,然后重新运行 git init

追踪

想让 git 追踪一个文件,你只需要输入 git add <你要追踪的文件路径>。这样,下次备份(commit)的时候,这个文件就会被放进去。

当然,这样可能会比较麻烦。你可以使用 git add -A 来追踪所有文件。

如果你不想追踪一个文件了,你可以使用 git rm --cached <你不想追踪的文件名字>

提交

提交(commit),可以理解成进行一次备份。所有被追踪的文件,都会被备份,你可以随时还原。

在提交之前,请先使用 git status 查看一下,哪些文件正在被追踪(即,这次提交会提交哪些文件),确认没有乱七八糟的东西被提交上去。

提交的时候,使用:git commit -m "<在这里留言>"。留言的话,可以说一下这次提交主要改了什么东西,最好清晰一点,让下次自己一眼能知道这是哪个版本。

团队合作的时候,留言相当重要,你要把这次提交达成的功能清晰、完整地列出来。这可能不是一句话能讲清楚的,你需要用 git commit,然后在弹出来的文档里完整地撰写提交信息(编辑的时候会用到 Vim ,建议有精力的同学学习一下)。

还原

想要还原某个版本,首先你需要用 git log 来查看所有历史的提交。这时候,你提交时候输入的留言(commit message)就很重要。

你会看到所有的 commit 后面,都有一个很长一串 0-9 数字以及 a-e 字母组成的编码。找到你想恢复的版本后,你只需要复制对应的编码,然后使用 git checkout <对应编码> 就可以回到对应的版本了。

注意,这个操作就像把你的文件夹扔到了一台时光机上,所有代码就变成那次提交时的样子了。所以,git 会强制要求你在 checkout 操作之前先进行一次 commit 操作,不然当前的进度就全都丢失了。

分支

你可以使用 git branch <新分支名> 在当前分支基础上创建一个新的分支。

你可以使用 git branch 来查看所有分支以及当前所在的分支。

你可以使用 git checkout <分支名> 来跳转到某一个分支的版本。这个操作也会把当前文件夹送上时光机(当前代码进度会丢失)

合并

当你在 main 分支,想把 dev 分支最新版本的文件合并进来,你可以使用 git merge dev

注意,有时候会提示有 conflict,你可以看它提示的 conflict 在哪个文件,打开它,按 CTRL+F 搜索 ====(一堆等号),就能看到 git 帮你把两边的代码列出来。按照自己的意思改正好之后,你可以 commit 一下,就完成了 merge 操作。

Git 远程用法

我们讲过,完整的文件夹历史会被存放在 .git 文件里。

git 的灵魂就在于,.git 文件可以放在远程服务器上,这样所有人都可以往同一个 .git 文件里提交东西,大家共享彼此的开发历史。

GitHub 就提供了这样一个平台。推荐大家注册一个 GitHub 帐号,这样不仅可以在云端保存自己的代码历史、和其它人合作,还可以展示一些自己引以为傲的项目(然后给 m5-201 的课程点一个 Star ...lol)。

你可以自己创建一个 GitHub Repository注意不要创建 README 文件),然后按照它的指引,把本地初始化好的 git 推送到自己的 GitHub Repository 上。

远程的 git 相关操作比较简单,主要是这几个: - git push 把本地的 .git 上传到远程。 - git pull 把远程的 .git 合并到本地,并 checkout 到最新的版本。如果远程的 .git 被其它人 commit 过,你需要像合并分支那样解决 conflict。 - git clone 把远程的 .git 文件下载到本地。这个命令是下载整个初始化好的文件夹,不需要进行 git init

注意