共 13 节,按顺序
- 125 分钟
初始化与你的第一次提交 (commit)
设想你在文本编辑器里写一篇文章,每改出一点像样的东西,就把全文另存一份新名字:essay-v2、essay-v3、essay-final、essay-final-actually。这么干勉强也行,直到你手里攒了三十个文件,却再也想不起你满意的那一段在哪一份里。Git...
Git initGit configWorking treeStaging areaGit addGit commit - 225 分钟
状态、差异和日志
上一课你做了一次提交,那就是恰好一个快照。真实的工作是反复修改文件,而每次提交之前,你都会想知道三件事:我改了什么,具体改的是哪几行,以及我已经保存过什么。这一课讲的就是回答这三个问题、又什么都不改动的三条命令:git status、git diff 和 git...
Git statusGit diffGit diff --stagedGit logLog formatting - 330 分钟
分支 (branch) 与合并 (merge)
到目前为止你做的每一次提交,都排在同一条叫做 main 的历史线上。真实的工作很少这么简单。你想试一个想法,又不愿意冒险动到能正常跑的版本;或者两个人要同时做不同的功能,还不能互相踩到脚。Git...
Git branchGit switchFast-forward mergeThree-way mergeMerge commit - 430 分钟
解决合并 (merge) 冲突
Git 第一次拒绝把合并做完的时候, 感觉像是哪里坏了。什么都没坏。合并冲突发生在两个分支用不同的方式改动了同一个文件的同一批行, 而 Git 确实猜不出你想留哪一版。与其说它是错误, 不如说它是 Git 直接抛给你的一个问题: "这两边不一致, 谁说了算, 还是说你想写点新的把两边揉在一起?"...
Merge conflict markersManual resolutionGit add after resolvingGit merge --abortMergetool - 530 分钟
远程仓库 (remote): push、pull、fetch
到目前为止你做的一切都只存在于自己的机器上。练手时这没问题,但真实的项目需要一份别人或者别的机器能够访问的共享副本:一台服务器上放着同一个仓库,让所有人的工作最终汇到一处。Git 把它叫做远程仓库 (remote):你这个仓库的另一份副本,通常托管在 GitHub...
Git remote addGit pushGit fetchGit pullUpstream tracking - 625 分钟
暂存 (stash) 与择优拣选 (cherry-pick)
改到一半,文件动过了,什么都没做完,这时同事发来消息:「能不能马上看一下 main 上的一个缺陷?」你没法把做了一半的活提交上去,因为一次提交应该让项目停在一个自身说得通的状态上,而现在这个状态说不通。你也没法说切分支就切分支,因为你的改动会和目标分支上已有的内容撞上,Git...
Git stashGit stash popGit stash listGit cherry-pick - 730 分钟
变基 (rebase)
周一你从 main 分出去,打算加个搜索框。现在是周四,你攒了三次提交,与此同时另外四个人已经往 main 推了东西。你的分支立足的那个项目版本,如今哪儿都找不到了。你的工作要并回 main,就得先把这两条历史线重新拧到一起,而 Git 给了你两种做法。
Git rebaseReplay on topLinear historyWhen not to rebase - 830 分钟
交互式变基 (rebase) 与提交压缩 (squash)
真实的工作不会只落成一个干净的提交。你提交一次, 五分钟后发现一个拼写错误又提交一次, 接着因为第一次提交前忘了保存某个文件, 再提交第三次。埋头干活的时候这都不算问题。等你开了一个拉取请求, 评审的人要读十一个提交才能看明白三处真正的改动, 其中两个还只是"修个拼写"和"哎呀漏了个文件",...
Git rebase -iPickSquashFixupRewordAutosquash - 920 分钟
标签 (tag) 与发布 (release)
像 main 这样的分支是一个会移动的书签。它指向最新的那个提交,而你一提交,它就往前滑,指到新的地方去。你干活的时候要的正是这个效果,但有一件事它完全做不了:永久地宣布“我们发布的 1.0.0...
Lightweight tagAnnotated tagGit tag -aGit push --tagsGitHub releases - 1020 分钟
分支 (branch) 工作流
你到目前为止学的所有东西,建分支、合并、变基、打标签,讲的都是 Git 的命令做了什么,但没有一条告诉你:什么时候该开一个分支,这个分支该留多久,谁可以直接动 main。这些事 Git 是真的不发表意见。一个团队要是完全没有约定,很快就会掉进麻烦里:分支活了好几个月,合并起来是场噩梦;main...
Trunk-based developmentGitHub FlowGit FlowShort-lived branches - 1125 分钟
恢复丢失的工作
总有那么一次,你敲下一条命令,回车,看着终端不动声色地打印出一行盖棺定论的话,然后意识到自己刚刚删掉了一整天的活。谁都干过。好消息是,而且这是整个 Git 里最让人安心的一件事:只要你提交过,它几乎肯定还在。分支不再指向某些提交时,Git...
Git reflogRecovering from reset --hardGit fsck --lost-found30-day grace period - 1225 分钟
钩子 (hook)
每个团队都有那么一条人人赞同、又人人会忘的规矩。提交前先跑一遍格式化工具。凌晨两点加的那句调试用的打印语句别提交上去。带着密码的文件别提交。这些规矩写在一个没人看的 wiki 页面上, 然后总有人违反其中一条, 代码评审就变成了一场找茬游戏, 找的还是机器一眼就能看出来的东西。
Client-side hooks.git/hooksPre-commitShell hook examplePre-commit framework - 1340 分钟
综合实战: 完整的 Pull Request 流程
到目前为止,学的都是一块一块的:这里一个提交,那里一个分支,历史需要理顺时来一次变基。在真实的工作里,这些零件是作为一整套固定流程出现的,一周要重复好几遍,而且这套流程有名字。你把项目复制一份,在一边做自己的活,请同事来看一眼,回应他们提的意见,然后才让你的工作并进共享的那一份。这个“请你看一下并合...
CloneFeature branchPushGh pr createFixup commitsAutosquash rebase+1
用你的语言学习 Git
每一节课、测验和导师回复都以你的语言显示。AI 导师会用你提问的语言来回答。
Roles that use Git
See how hiring teams interview engineers on Git, in production-like environments.
Developer Experience Engineer
Hire DX engineers in real workspaces with real CLIs, real dev loops and real onboarding friction to fix. Live or take-home.
See the interviewBackend Engineer (Go, Rust, Java)
Hire backend engineers in real services with real databases, real concurrency and real latency budgets. Live or take-home, fully recorded.
See the interviewFull Stack Developer
Hire full stack developers in real apps with real APIs, real UIs and real tests. Live or take-home, fully recorded.
See the interview