[AI书房] 第14章 Git与GitHub:项目的时间旅行装置
Claude Code完全掌握
Claude Code完全掌握
第14章 Git与GitHub:项目的时间旅行装置
金京镇
Git的核心概念:仓库、提交、分支、推送、拉取、合并
凌晨两点,你正在修改网站的Hero区域,结果出了问题。本来只想改一下按钮的发光效果,整个页面布局却全崩了。你想回到三小时前的状态,可那时候的代码哪儿都找不到了。Ctrl+Z按了几十次也没用,文件已经保存过了,覆水难收。
Git就是为解决这个问题而诞生的版本控制系统(version control system)。它追踪项目中发生的所有变更,让你随时可以回到任意时间点。这跟电子游戏里的存档点差不多。每次做了有意义的修改就拍一张快照,之后随时可以倒回那个节点。
下面逐一拆解Git世界里的核心概念。
仓库(repository)是Git监控的那个文件夹。项目的全部文件,以及这些文件经历过的所有变更历史,都装在里面。可以把它比作银行账户:不只显示余额,每一笔存取记录都留着。仓库也一样,不只保存当前代码,过去的每一次变更记录都完整保留。
提交(commit)是项目在某个时间点的快照。每次提交都会记录两件事:改了什么,为什么改。这跟在Word文档里点「保存」有点像,但有一个关键区别:Word的保存会覆盖之前的状态,Git的提交则是在保留旧状态的基础上,新增一张快照。
你写下「为Hero按钮添加发光效果」这条提交信息,之后就能精准地只撤销这一次提交。
分支(branch)是项目的一个独立副本,让你在不影响主版本的情况下自由实验。默认分支通常叫main。创建一个名为「feature-login」的分支,就等于宣告:我要试验登录功能,但不碰稳定版本。
推送(push)是把本地电脑上的变更发送到远程仓库的动作。原本只存在于你电脑上的提交,上传到了云端。
拉取(pull)则相反,把远程仓库的最新变更下载到本地电脑。
合并(merge)是将两个分支的变更合为一体的操作。如果实验成功了,就把实验分支合并到main分支,让稳定版本也获得这些改动。
[图14-1] Git核心概念关系图:仓库内部的分支、提交、合并是如何相互关联的
铁轨的比喻:在保护稳定版本的同时进行实验
想象一座火车站。一列火车正沿主轨行驶。这列火车就是当前正在运营的稳定版本,也就是main分支。车上载着乘客,你不可能一边运行一边把铁轨拆了重铺。
想试验一条新线路怎么办?从主轨岔出一条试验轨道。这条试验轨道就是分支。在试验轨道上你可以随意折腾:调整铁轨角度,增设新的停靠站。主轨上的列车运行丝毫不受影响。
试验结束,结果令人满意,就把试验轨道并入主轨。这就是合并。在汇合点,两条轨道必须顺畅衔接,所以需要检查有没有冲突(conflict)。假如主轨上也修改了同一段路基,试验轨道上也修改了同一段路基,那就得由人来决定采用哪一边的改动。
[图14-2] 铁轨比喻:功能分支(试验轨道)从main分支(主轨)分岔出去,最终再汇合的示意图
来看看这个比喻在实际网站开发中是怎么用的。
假设前面章节做的那个网站已经上线,有真实用户在访问。你想把Hero区域的按钮改得更有动感。直接在main分支上改代码,修改过程中网站随时可能崩掉。换个做法:创建一个叫feature-dynamic-button的分支,在里面修改按钮代码。在本地验证通过后,再合并到main分支。
在你对Claude Code说「我对这个改动很满意,帮我推送到GitHub」之前,所有变更都只存在于你本地的分支里,线上网站完全不受影响。这就是使用分支的根本原因:在保护已有稳定版本的同时,放心尝试新东西。
工作树(worktree)把这个原理再推进了一步。通常在Git里,一个文件夹同一时间只能激活一个分支。要切换到别的分支,就得先保存或提交当前的工作。使用worktree后,同一个仓库可以在不同的文件夹里同时检出(checkout)多个分支。
Claude Code内置了worktree命令,用--worktree选项就能快速创建隔离的工作空间。
你可以同时运行多个Claude Code会话,让每个会话分别开发不同的功能。一个会话做支付页面,另一个做注册表单,还有一个改仪表盘。每个会话在独立的分支和worktree中工作,互不干扰,不用担心代码被覆盖。做完之后,把各个分支分别合并到main就行了。
[图14-3] 利用worktree实现并行开发:三个Claude Code会话分别在不同分支上同时工作的结构示意图
GitHub提供的云端备份与协作功能
Git是在本地电脑上运行的工具,变更历史存储在笔记本电脑的硬盘里。笔记本坏了,提交历史也跟着没了。一个人干活的时候,本地Git就够用了;但要跟别人一起推进项目,就需要一个能共享代码的地方。
GitHub是一个将Git仓库托管在云端的服务。如果说Git是版本管理的「工具」,GitHub就是用这个工具管理的项目存放和共享的「场所」。就像把本地电脑上的Word文档上传到Google Docs一样。
GitHub提供的核心功能如下。
云端备份:把本地仓库推送到GitHub后,代码的全部历史就在云端有了一份副本。即使笔记本坏了,也能从GitHub把整个项目重新克隆(clone)回来。
版本历史管理:在GitHub的网页界面上,可以按时间顺序查看所有提交。每次提交改了哪个文件的哪一行、谁改的、为什么改,一目了然。前面章节那条「为Hero按钮添加发光脉冲效果」的提交,在GitHub上点开就能看到具体改了哪些代码,新增的用绿色标注,删除的用红色标注。
Pull Request(拉取请求):在把分支上的改动合并到main之前,可以先请别人审查的功能。相当于一份正式提案:「这段代码合并到主分支,可以吗?」多人协作时,它充当关卡,确认各自的改动能否无冲突地合在一起。
公开与私有设置:仓库设为公开(public),任何人都能看到代码;设为私有(private),只有被邀请的人才能访问。如果网站代码里没有API密钥或密码之类的敏感信息,公开也无妨;但凡涉及哪怕一点敏感数据的项目,务必设为私有。
[图14-4] GitHub仓库页面结构:提交历史、分支列表、Pull Request标签页的位置
有一点必须注意。往GitHub推送代码时,要确保.env文件或包含API密钥的文件不会被一起上传。可以创建一个叫.gitignore的文件,在里面列出Git不应该追踪的文件清单。
对Claude Code说「帮我准备好推送到GitHub」,它通常会自动生成.gitignore文件。即便如此,推送前亲自检查一遍的习惯不能省。
基本工作流程:创建仓库→克隆→分支→提交→PR→合并
下面从头到尾走一遍使用Git和GitHub的完整流程。
第一步:在GitHub上创建仓库
登录GitHub,点击「New Repository」按钮,名字填「my-website」。描述可填可不填。选择公开或私有,然后点「Create Repository」。一个空仓库就建好了。
这件事也可以交给Claude Code。对它说「帮我创建一个叫my-website的GitHub仓库,把当前项目的代码推送上去」,它会一口气完成仓库创建、初始提交和推送。不过第一次需要通过命令行完成GitHub认证(authentication),认证一次之后就会自动保持登录状态。
第二步:克隆(clone)
如果项目已经在本地开发中,就不需要克隆。反过来,如果要在另一台电脑上继续工作,就从GitHub把仓库克隆到本地。克隆会把仓库的所有文件和完整的变更历史一次性拉下来。
第三步:创建分支并开始工作
添加新功能或修改设计时,不在main分支上直接动手,而是新建一个分支,在里面操作。Claude Code了解这个惯例,你可以用自然语言请求它帮你管理分支。
第四步:提交
每当产生有意义的变更时就提交一次。提交信息要简明扼要地写清变更目的。比起写「fix layout bug」,写「修复英雄区域卡片对齐错位问题」在日后追溯历史时更有帮助。
第5步:推送与拉取请求
将本地电脑上创建的提交推送到GitHub。在GitHub上发起拉取请求(Pull Request),提议将代码合并到主分支。即便是一个人独立开发,使用拉取请求也能多一次审查变更的机会。
第6步:合并
拉取请求通过审批后,合并到主分支。合并完成的功能分支可以删除,变更历史会保留在主分支的提交记录中。
[图 14-5] Git/GitHub基本工作流程图
使用Claude Code,这六个步骤中的大部分都可以用自然语言完成。你只需说「英雄按钮的修改我很满意,帮我推送到GitHub」,Claude Code就会暂存(staging)变更文件、撰写合适的提交信息、推送到远程仓库。但你必须理解背后的运作原理,遇到问题时才能找到原因并解决。
代码已经安全地上传到了GitHub,变更历史也记录得清清楚楚。但代码放在GitHub上,并不意味着别人就能打开浏览器访问你的网站。代码仓库和上线的网站之间,还需要再搭一座桥。
人工智能专家 金京镇 律师
AI法律政策专家 · 前国会议员 · 著有多部作品
如果这本书曾在你身边短暂停留,请支持我们,让下一个故事也能与世界见面。
(自愿赞助账户:农协 302-1096-0948-81 户名:金京镇)


