Featured image of post (也许是)一个 Git 教程?其三

(也许是)一个 Git 教程?其三

一起写项目吧~

最后一节,聊聊如何在 GitHub 上进行多人协作吧~

头图信息请参考第一节内容,谢谢~ 选曲依然选到了小伞的个人曲,希望你喜欢!

所以,Git 的远程到底是什么东西?

我们之前提过,Git 通过 远程 (Remote) 来实现和他人合作。我们甚至已经介绍了一些和远程进行交互的命令了。然而,Git 究竟是怎么实现这一功能的?这个功能有什么特点呢?我们和他人进行协作开发时,有什么要注意的点呢?我们一点点来介绍。我们先系统地介绍一下 远程 是什么东西吧。

远程:不过是另一台装了 Git 的机器

实际上远程并不神秘。得益于 Git 分布式的特性,每一台安装了 Git 且拥有项目源码的机器都可以说是某个远程。或者说远程是相对的:有两台机器 A 和 B,都拥有同一个项目的源码并安装了 Git,那么对于 A 来讲 B就是远程,而对 B 来讲 A 也是远程。而不同机器之间的通信则可以通过 SSH 完成,如果是比较老的项目,或者不希望通过 SSH 来连接的情况,我们甚至可以使用邮件进行通信,传递代码,就像 Linux 内核,GCC 等项目那样。总之,通过这种 每个设备都存储一份代码 的形式,Git 就实现了分布式的代码存储,每个设备既可以是正在工作的仓库,又可以是为他人提供源码的仓库。

然而,大量的实践证明,有时候有一个中心服务器真的会很省事。大家把代码的更新放在一台公开的服务器上,然后可以从这一个服务器上拉取代码,可以很好地保证开发进度以及代码的一致性。不过这样又失去了 Git 天生的分布式特性。所以,到底哪个更好呢?真分布式还是采用某个中心的代码服务器?

对比:分布式 vs 中心仓库

Git 一开始就是支持分布式存储的,这样最大的好处在于,每一个人拥有的仓库都是这个代码的一份备份。假如一个项目参与的人越多,这个项目的备份就会越多。而且每个人都是自己拥有的这份代码的主人,自己对代码拥有完全的掌控权,可以自行决定自己的代码要不要提交给别人,或者要不要接受来自他人的变更等。这种去中心化的,人人平等的思想非常符合自由开源的精神。另外这种方式不是很依赖某个中心设备,不会因为这一个设备断掉而直接完全不可用。如 Linux 内核,GCC 编译工具链等都没有一个一般意义上的中心代码服务器用来让所有合作者都往里面推送代码或者从里面拉取更新。

然而中心化的服务器自然是有它的好处的。比如说有三个人在同一个项目工作,三人没有一个中心代码仓库而是互相传递更新的代码,如果三位都对代码进行了不同的且有一定冲突的代码,那么在同步时肯定会面临很多的麻烦。而如果他们的代码存放在一个中心服务器上,那这个服务器就会忠实地记录每个人对它的修改,进而避免所有人的代码一起涌上来的尴尬,同时保持大家的进度都在同一阶段,避免每个人有自己的想法进而没法合并(即便其实可以用分支也是可以的)。另外如果在某个项目里,开发团队是有明确分工的,那么这时候应该有一个人负责对代码进行审阅修改,而此时中心服务器的优势就体现出来了,让审阅者(们)单独拥有对中心服务器代码的修改权,然后审阅者(们)就可以直接在该服务器上进行审阅合并等操作,且所有的合作者都可以直接从该位置拉取最新的代码。也许有人说,把代码直接交给审阅者不就行了,为什么非得有个中心服务器的参与?然而如果真是这样的话,审阅者他自己的电脑也在某种程度上成为了那个中心服务器了。就我个人而言,我是想不到什么普通项目有必须使用去中心化工作流程的必要的。一般来讲都还是有一个(当然也可以多个)代码托管处会好很多。

那么,谁是这个星球上最受欢迎的 中心代码仓库 呢?

代码托管平台们

GitHub: The blessed one

向您隆重介绍,这个星球最受欢迎代码托管平台,汇集无数人智慧结晶,全世界最大同性(?)交友网站(迫真,95%以上的用户都是男性),GitHub。第一期其实已经有介绍过,GitHub 和 Git 之间的关系是什么样的,以及大家可以怎么使用 GitHub。这里我们再多聊两句。

上面我们说 GitHub 是代码仓库,其实是不太严谨的,应该说它是一个代码托管平台,任何人都可以在上面创建自己的仓库,然后把代码放在上面。当然,GitHub 的功能肯定不仅限于此,它上面集成了很多很好用的功能,比如 Issues, Pull Requests, GitHub Actions 等,也提供了非常美观现代化的图形界面,能让大家直观地看到代码仓库的变更历史。它甚至提供了 GitHub Pages 来让开发者可以把静态的网页托管在上面,这让很多项目得以拥有自己的网页,或是用来做文档,或是用来宣传,功能非常多样。顺带一提,本博客就是托管在 GitHub Pages 服务上的。GitHub,伟大无需多言。

目前 GitHub 上已经有了 2亿6千万以上(268 million+)的公开仓库了,仓库来源于全世界各地,且每天都有大量的信件仓库,大量的拉取请求,以及大量的代码提交。大家在 GitHub 上的活动已经远不止简单的提交自己的代码这么简单,开发者们会在一个项目内合作开发,设定开发目标,合并他人的拉取请求,为感兴趣的项目做贡献或者提出问题,帮助他人解答问题等等。其仓库类型也是多种多样,有各种语言写成的千奇百怪的项目,也有一些很不错的资源整合项目,甚至你还会看到很多令人难绷的小作文以及互联网记忆。总之,除了托管自己的代码之外,你还可以看看别人的代码,玩玩别人的项目,和别的开发者讨论(吵架),给别的项目做贡献(改错别字)。用途多种多样,就看怎么用了。

GitHub 起源于 2007 年,至今已经 18 年历史了。18年来,GitHub 变得越来越完善,功能越来越丰富。2018 年的时候微软收购了它,在那之后就成了微软的一个子公司,而 2019 年的时候 GitHub 宣布它支持个人创建任意多个私有仓库,将 GitHub 的受欢迎程度推上了一个新台阶。而就在前不久(2025年8月11日),其 CEO 宣布卸任,GitHub 被合并在微软的 Core AI 部门。我个人认为这应该算是坏消息,毕竟 GitHub 作为全世界最大的代码托管平台,几乎已经是 开源精神 的代言人了。本来还是一个比较独立的子公司的 GitHub 现在被微软直接合并进一个部门内,怎么想都感觉其独立性要进一步下降了。是在令人感到可惜。但是就目前而言,GitHub 也依旧是同类产品中知名度最高的一个,甚至可以说是某种标准了。所以,还是先用着吧。如果 GitHub 哪一天真倒了的话,肯定还会出现新的继任者的。

GitLab: 强大的自动化以及自托管

除了 GitHub 以外,当然还有别的托管平台。其中另一个比较受欢迎的项目就是 GitLab,它除了托管到 GitLab 的服务器上以外,还支持在自己的服务器上自行搭建代码托管平台,其中也支持和 GitHub 类似的很多功能,比如查看源码,Issues, Merge Request(对应 GitHub 中的 Pull Request),CI/CD(持续集成/持续部署)等等。其中的 CI/CD 是 GitLab 最出众的特点,以速度快效率高而著称。而且由于它提供自托管(通过 GitLab Community Edition)的特性,对于那些需要较强独立性的,不希望受到 GitHub 控制的(理由嘛……我也不知道),或者就是某些公司希望保持私密性的项目,GitLab 是一个很不错的选择。有很多项目都是使用 GitLab 进行托管的,比如 KDE,Paraview 等。相较于 GitHub 而言,GitLab 的隐私性还是更强一些。然而坏消息是,GitLab 在 24 年的时候宣布不再直接为中国地区提供服务,转而由本地服务提供商 极狐 提供。我也很难讲究竟应该用哪个……

GitLab 的功能是非常全面的,如果你并不想要这么完善的功能,只是想在自己的服务器上搭一个轻量化的 Git 托管平台,你也可以选择 Gitea。它最大的特点就是轻量化了,拥有最基础的 Git 托管服务器所应该有的功能,不过随之而来的就是一些更复杂的功能可能没有,自动化相关的内容也许需要自己手动实现等等。

讲了这么多,Git 到底应该怎么实现和远程服务器的交互呢?

Git 与远程的交互方式

下面我们就来介绍一下 Git 和远程进行交互时会用到的一些命令吧。

  • git remote

    这个命令正如它的名字,是用来管理和远程相关内容的一个子命令。而且,就像 git branch 那样,如果你不带任何的参数,它会告诉你都有哪些远程是可用的。一般来讲,仓库会有一个名为 origin 的远程库,它一般就是你在 GitHub 上托管的位置了。如果你想确认远程的具体信息的话,你可以用 -v 或者 --verbose 来让 Git 把该仓库的所有远程地址都告诉你。你也可以用 show 子命令来让 Git 告诉你关于某个远程的详细信息,包括它会从哪里拉取代码,往哪里推送代码,当前分支和最新提交等等。

    而假如你的仓库还没有可用的远程,你可以使用 add 子命令来让 Git 添加一个远程仓库作为你这个仓库的远程位置。比如说你在个人 GitHub 账号下有一个空仓库,地址是 https://github.com/abc/test_repo,其中 abc 是用户名而 test_repo 则是仓库名,此时你就可以使用 git remote add origin https://github.com/abc/test_repo.git 来把这个仓库作为远程仓库添加到当前仓库名下,并给它以 origin 的名字。你当然也可以修改这个远程仓库的地址咯,使用 set-url 即可,用法和 add 差不多,只不过远程名必须是已经有了的远程名字。

    假如你感觉某个远程仓库名让你很不爽,你可以使用 rename <old-name> <new-name> 来修改它;如果这个远程已经不需要了,或者你因为什么其他的原因要删除它,也很简单,使用 remove <remote-name> 子命令就可以啦。还是比较简单易懂的。

  • git clone

    除了给现有的仓库添加远程,我们当然还可以从远程仓库复制一份到本地来呀。通过使用 git clone <repo-url> 命令就可以把一个远程仓库下载到本地。下载下来的仓库会默认放在当前文件夹下的和仓库名同名的文件夹里,且仓库名默认会是和远程仓库的名字一样的,且由于是从远程克隆下来的,它会自动设置好远程的位置(起名也是默认的 origin)。当然如果你想把该仓库下载到其他位置的话,也可以在仓库的 URL 后面添加上你要下载到的文件夹。

    一般来讲,使用这个命令就已经足够了。然而有时候,也许你会遇到仓库里使用了 Git Submodules(Git 子模块)的情况。我们这里不打算介绍 Git 子模块,然而如果你在克隆一个带有子模块的项目时没有顺带让仓库克隆其内部的子模块,后面在使用过程中又得重新搞一些有的没的。为了避免这样的麻烦,在克隆时可以直接带上 --recursive 的参数,告诉 Git“帮我把这个仓库里所有的 Git 子模块也一并下载下来”。这样就省去了后面重新配置 Git 子模块的麻烦。

    另外也许有时候你克隆一个仓库的目的并不是在仓库里做开发,而是直接使用它(像一些 ZSH 插件是托管在 GitHub 上的),此时你也许不关心它的提交历史,或者这个仓库太大了而你又不需要用上过去的所有提交历史的时候,你会希望只获取到最新的几个提交就够了。Git 非常贴心地提供了 --depth <number> 的参数,你可以指定你只想克隆到最近的多少个提交即可。这样能非常好地节约克隆的时间,对磁盘和网络都比较友好。

  • git push

    当我们本地做出一些修改,有了一些和远程不一样的提交之后,我们就可以把本地的提交推送到远程仓库了。当我们直接使用这个命令的时候,Git 会默认推送当前分支到远程仓库的对应分支上。默认的操作就是最高频的操作了,这一点很不错。而当我们需要推送到某个特定分支(比如远程分支和当前分支名称不一样的时候),我们可以先写上远程分支的名字,再写上当前分支的名字:git push <remote-branch> <local-branch>。我们也可以通过加上参数 -u 或者 --set-upstream 来修改推送的默认分支。

    也许我们的仓库拥有不止一个远程,这时候我们可能需要指定我们要推送的是哪个分支。这时候 push 的写法会有一定的变化:git push <remote-name> <local-branch>:<remote-branch>,即我们要先指定推送到哪个远程上,然后用冒号分割本地分支和远程分支。

    这个写法完全地指定了所有推送的信息,而且这个写法还有一个隐藏功能:如果我们不写本地分支,直接写 git push <remote-name> :<remote-branch>,意思就是告诉 Git“我要把空分支推送到远程覆盖那个远程分支”,结果就是让 Git 删除远程分支。当然,删除远程分支也可以使用 git push <remote-name> -d <remote-branch>(或者用 --delete)来实现,这样的语义更加明确,不过我猜也是给上面的方法一个新的包装而已。也许我们远程的分支太多了,我们不想要远程的那些没有本地对应的分支,此时我们就可以使用 git push --prune <remote-name> 来删掉(修剪)那些多出来的分支了。

    除了我们可以推送分支外,push 还兼并了推送标签(Tag)的功能。我们可以直接使用 git push --tags 来推送所有的标签,也可以 git push <remote-name> tag <tag-name> 来推送某一个标签。至于标签是什么你可以认为它是一个独立于分支树之外的持久性的快照,会保存某一时刻的信息,且不会强依附于某个分支,一般是在发行时会给某个版本打上一个标签,没错,就是那个 xx.xx.xx,一般标签都会这么打。我们这里就不过多介绍了。

    最后在这里要留一个提醒。有很多教程推荐在 push 出问题的时候使用 -f 或者 --force 参数。这个参数的功能是让 Git 不做任何的检查,用本地的状态去强行覆盖远程仓库的状态。如果你真的是在和别人一起协作的话,不要这么做。会被人移交蔡司。

  • git fetch

    这个命令是用来让我们从远程获取更新使用的。它默认会获取默认远程的所有分支的最新更新,如果我们要指定是从哪个远程获取,只需要把那个远程的名称放在后面即可。如果我们想从所有的远程都拉取更新,则可以使用 --all 来告诉 Git。类似于 git push,我们还可以在 git fetch 的后面加上 -t 或者 --tags 来让它从远程获取所有的标签信息,或者用 git fetch --prunegit fetch -p 来让 Git 删除掉本地多出来的,远程没有的分支。

    需要注意的是,Git 在设计上让 fetch 子命令不直接把远程的内容和本地进行合并。也就是说,git fetch 只会更新 本地的远程数据库,而不会把远程的数据直接放在本地的工作目录里。如果想要这么做的话,我们可以把远程的分支 通过 git merge合并 到本地上。要指定远程分支,我们需要用 <remote-name>/<remote-branch> 来告诉 Git 我们要的是在 <remote-name> 上的 <remote-branch> 分支。

    如果你感觉这实在是太麻烦了(真的很麻烦),我们可以使用下面这个融合了 fetchmerge 的命令:

  • git pull

    当我们很明确地是要把远程的变更直接应用到本地仓库时,我们可以直接 git pull 来拉取远程更新。由于它涉及“合并”的步骤,所以它的默认行为是把默认远程的变更获取到本地后把当前分支对应的远程变更应用到本分支上。也就是说,默认行为是从远程更新当前分支状态。

    自然,我们可以指定它的更新对象。我们使用 git pull <remote-name> <branch> 就可以指定要拉取的远程是哪个,并且指定要更新的分支是谁。需要注意的是,新仓库里执行 git pull 时它可能并不知道要使用什么方式把远程的变更应用到本地分支,因为除了可以使用 merge 外,还可以用变基操作 rebase 来做这件事。因此可能 Git 会询问你,是要使用哪种方法。一般我们直接用 fast-forward 就可以了,最简单方便的方式,且不会让 Git 提交历史出现一大坨自己都不认识的分支。

Git 的远程命令我们就介绍这么多。实际上在单人开发时,几乎不会用到这么复杂的命令。平时就是简单的 git pull 更新一下,然后做好变更之后就 git push 上去,就可以了。新仓库可能得用 remote 来添加一个远程仓库,平时都不怎么用管的。

和别人协作时要注意些什么

然而,和他人共同协作时,并不是只要知道这些命令就 OK 了,光是知道这些命令并不能帮你成为开源领域大神,不慎的操作很有可能换来别人的嘲讽……下面就简单提个几点吧~

另外,我其实也没有参与很多开源项目,如果你觉得我下面的建议不够权威,那确实是不好意思,实力不够()不过我个人认为还算实用/中肯吧。总之希望能帮到你。

阅读项目说明

参与到项目前首先应该尝试阅读这个项目的说明。如果你对某个项目感兴趣的话,相信 README 应该是已经看过了。然而如果要参与开发,光是读 README 很有可能不够。大型项目一般有所谓的 Code of Conduct,也就是所谓的行为准则。如果有这么个东西或者类似的要求的话,请阅读这些内容后再开始尝试给这个项目做贡献,不然项目的代码审核很有可能会直接拒绝你的 PR(Pull Request)。

先查查 Issues

协作开发一般是以某个 Issues 开始的,毕竟有了这样的问题,就有了针对这个问题进行开发的目标了嘛。查看 Issues 的主要目的是看看当前项目有哪些问题等待改善,另外也是看看有没有人已经尝试解决某个问题了。如果你感兴趣的问题已经有人在跟进了,这时候最好和跟进的人商量一下看看有没有什么可以帮忙的。不要稀里糊涂地直接提交一个 PR 上去。

也许你需要单开一个 Issue

有些项目会要求说,如果你想提交 PR,请给这个 PR 一个对应的 Issue,或者开启一个 Issue。这是一个不错的实践方式,让每个 PR 都有明确的目的性。之前我提交的 PR 就有被要求过开一个 Issue,并在 PR 里写明对应是要解决哪个 Issue。坏消息是我的 PR 好像没有通过自动检查……明明是一个很简单的 PR 的说……

等下,PR 到底是啥?

也许你早就想问这个问题了。我也是,经常听到别人说什么“欢迎 PR”,“提个 PR”,“合并 PR”之类的话,但是一直不清楚这到底是什么意思。我故意保留了这个风味,直到现在才解释,这样你才知道开发这块儿有多少谜语人 (bushi,补药打死窝呜呜呜)

PR 的全称是 Pull Request,也就是所谓的拉取请求。什么?拉取请求?我在请求什么东西?拉取?我一开始也想不通我要请求什么拉取,后来借助 AI 的伟力以及一些别的资料,我终于明白了:Pull Request 就是请别人审阅你提交的代码然后把它合并进项目里。所谓的“提 PR”就是发起合并请求罢了。

那么,既然 PR 是合并请求,为什么不是 Merge Request 呢?没错,GitLab 就是这么干的。GitLab 里你不提 PR 而是提 MR。两个名词指代的是同一个操作。那么 PR 的 P 究竟是为什么呢?根据一些信源的解释,PR 的 Pull 的意思是说,你想让别人把你的修改 Pull 到他们那里。就好比说,我给项目搞了个很牛的特性,但是现在只在我自己的电脑里。我希望别人也能用上我写的这个特性,所以我要写个说明文字来介绍我这个修改都干了些啥,为什么牛逼,以及为什么推荐他们都把你的这份变更 pull 到他们那里。相比起来,Merge Request 就很直白了:我做了有一份更改,现在请你把这份更改合并到你们的分支里。

从语气上来讲,PR 显然更客气一些。我在知道这个解释之后第一反应是,PR 想表达的是,如果你觉得我的变更很棒,你就可以把我的这份放到你那里。如果你觉得我的修改不好,你不 pull 就是了。而 MR 的话,相比之下就略显强硬了:你能不能把我的更改合并到你那里。也有可能是我神经过敏吧,反正在知道 PR 的词源之后,反而更喜欢这个名字了,感觉 MR 反而有点奇怪,哈哈。

不过你也应该明白了,在提交 PR 时应该给你想提交的变更做出一些说明,比如你改的东西的简要总结,为什么要改,改了之后会怎么样之类的。如果只是光秃秃地要求把代码合并进去,代码审核者估计也懒得细看你的代码究竟都干了些啥,进而选择不管你的提交。

为什么不直接把变更推送进仓库?

一般而言,仓库都是有所有权的,即便它是公开仓库,它也不是允许所有人都直接向仓库里提交代码的,一般只有直接维护者有权利变更仓库内的内容。如果一个外来者希望修改仓库内容,基本都是通过 PR 的方式来把代码变更交给审核者,让审核者决定要不要合并进仓库里。当然,如果你就是仓库拥有者或者拥有仓库的编辑权限,那你也许是被允许直接提交代码的。然而,如果你是在和好几个人一起合作的话,最好还是有个 PR 的过程,毕竟 PR 提供了一个交流讨论的地方,直接提交代码的话也很难说这个提交就一定是最合适的。

注重交流合作,语气这一块儿

可以发现,在 GitHub 上合作开发肯定是避免不了和别人交流沟通的。作为国际化的平台,一般而言还是推荐用英语交流,除非是一眼国人项目/国人特供项目/没有外国人用的项目,比如某些国内特产(科学上网),近乎是用不上英文的。如果您的英文不是很好,emmm,我想说现在的翻译软件都很好用,也不一定非得只能把英文翻译成中文,也可以把中文翻译成英文嘛。

另外就是注意礼貌这块儿()没人会喜欢和一个没素质的人合作的,一般而言。不过呢,有时候也不是说没礼貌吧,可能就是单纯的就事论事而已。记得之前看过的 黑客的自白 里说过,很多人其实单纯地就是懒得用那些套话,喜欢只针对问题做出提问,并解决问题。这一点我的建议是自行把握吧,我本人持“礼多人不怪”的态度,不过如果有人不喜欢这套,那我也无所谓,只要别骂人就行。

别在 Issue 里面灌水

很明显的一点。GitHub Issue 提供的本来是一个关于问题的讨论平台,不宜在里面灌水聊天,搞一些跑题。然而这点好像在某些仓库里没有很重要?毕竟当大家发现跑题了的时候,一般也不是刚刚才开始跑题吧。

目前就只想到这几点了。如果你有别的觉得可以补充的,欢迎告诉我。我会补在里面的!真的!

后记

说实在的,写这篇的时候有点江郎才尽了。因为我本来也是正在学习 Git 的来着,写这些东西有一部分理由是为了复习巩固/趁机学习 Git 命令的。因此,如果里面有什么内容上的纰漏,还望海涵。

也许有人会问,现在 Git 的 GUI 客户端已经这么多了,为什么还要学习 Git 的命令行操作?你说得很对:Git 现在有很多 GUI,甚至它本身已经带了一个 GUI 来着。但是,我还是觉得命令行最贴近 Git 在设计之初的使用方式。另外得益于 Git 命令行交互功能非常完善,有时候我们可以写一个简单的脚本来自动化 Git 的一些工作。而这些,GUI 是没法替我们办到的。然而不可否认的是,GUI 真的很不错。至少,Git 的分支状态在命令行下还是不够直观的,这一点必须承认。而有了 GUI 的 Git 它们的分支图一般都画的很漂亮。实不相瞒,有时候我也会直接用 VS Code 的 Git 集成来进行提交。因为很方便嘛,哈哈哈。

还有人问,现在好用的 VCS(版本控制系统)也早已经不止 Git 一个了,为什么不介绍更新的工具,而是这个老套到甚至有点老掉牙的,对用户并不是非常友好的 Git 呢?我的回答是,它第一没有那么不堪,第二实际上它也许已经成为了某种事实标准,第三它真的很好用。再加上几乎所有的 VCS 都会提供从 Git 仓库转换到其他格式的仓库的功能,这更说明了 Git 在版本控制系统这个领域的重要地位。如果您会使用 Git 的话,相信其他的 VCS 系统也不会难到您。当然,我也很愿意尝试一下别的工具,比如最近风头正盛的,使用 Rust 编写的 Jujutsu。不过这也是后话了。(Git 真的很好用了)

这篇都快写完的时候我才意识到,我还没有介绍 Git 怎么查看提交历史。感觉放在这一篇里还是有点尴尬,毕竟这一篇主要还是在讲怎么和其他人协作,而 Git 的历史查看功能放在这里就不太合适了。思来想去,我放在了上一篇里,因为它和分支还是有很大的关系的。如果你看过了上一篇,结果又没有收到上一篇的更新的话,我建议你可以回去看看()

另外,这个系列真的离不开一些工具,比如 tldr(包名是 tealdeer,不过其他版本的也很不错),以及 ChatGPT,DeepSeek 等 AI 工具的协助。当然 Git 自带的文档也很不错,在 Linux 上可以直接 man git 查看总的介绍,使用 man git-add 这样的格式来查看 Git 各个子命令(这里是 add)的使用方式。而在 Windows 上,由于没有 man,你可以使用 git help git-add 或者更简单的 git add --help 来查看在安装 Git 时就已经附赠的 Git 的文档。而且 Git 也有自己的“官方教材”: ProGit,它有多种语言的版本,作为教程而言自然是比 Git 的文档写的好懂的多。不过 Git 的文档写的也很不错就是了。

最后,非常感谢您能看到这里。如果你看完了这三篇的话,我更是感激不尽。如果这些文字能帮到你那就太好了,如果没有起太大帮助的话,希望能逗你一笑。哎呀至少笑一下吧,显得这个系列的文章也不是一无是处嘛。(之前写的那个 关于蛇引理的文章 里也说如果能博读者一笑就好了,结果发现,根本没几个人看呀可恶……更别说逗大家笑了,唉,实在是太失败了。)

那么,一如既往地,祝您身心愉快,工作顺利,少出 Bug ~!

Licensed under CC BY-NC-SA 4.0
最后更新于 6月 26, 2026 15:20 UTC