为何git搞那么复杂?
Git 本来就没想让你觉得简单。
你觉得 Git 不就是 add commit push 三连吗?那是你一直在“单机模式”下玩,最多算个局域网联机。这不叫用 Git,这叫用 Git 当百度网盘,还是个手动同步版的。
Git 的复杂性,源于它要解决的那个终极问题:一群互不信任、作息颠倒、随时可能改了代码就跑路的程序员,如何在同一个项目上干活而不会天下大乱。
你看,简单的 clone push,谁都会。但只要你开始跟团队协作,pull 一下全是冲突,屏幕上布满了 <<<<< HEAD 和 >>>>> some-random-hash,那才是噩梦的开始。
我亲身经历过,我们组一个新来的后端,能力不错,就是 Git 玩不转。有次他要合一个紧急的 hotfix,搞了半天合不进去,跑来找我。我一看他那分支图,好家伙,那叫一个盘根错节,堪比克苏鲁神话里的古神触手,分叉、合并、又分叉、又合并,中间还夹杂着几个意义不明的 merge branch ‘master’ into master。我问他干了啥,他说:“我 pull 不下来,就 fetch 了一下,然后 rebase,rebase 不行我又 merge,merge 完还是有冲突,我就 reset 了一下……”
我当场血压就上来了。他把 Git 当成了一个许愿池,哪个命令听着顺耳就敲一下,期待大力出奇迹。结果就是奇迹没发生,事故倒是差点搞出来。
这还只是冰山一角。再往上,就是操作原子历史的“禁术”了,比如 rebase -i,cherry-pick,filter-branch。这些玩意儿是干嘛的?说白了就是代码界的“时间机器”,让你回到过去修改历史。但你也知道,电影里玩时间旅行的,十个有九个都把宇宙给玩崩了。git reflog 就是你的后悔药,但很多时候你都不知道自己是啥时候“中毒”的。
Git 的设计哲学是,它不信任任何中心节点,它认为每个人的电脑都是一个完整的“平行宇宙”(repository)。你的每一次 commit 都是在这个宇宙里创造一个新的历史快照。而 branch 让你能轻易开辟出无数个“平行宇宙”。merge 和 rebase 就是在尝试合并两个不同的“时间线”,你想想这事得有多复杂?物理学家都没搞明白呢!
所以,Git 的那些命令,stage (暂存区) 是为了让你精准控制提交内容,branch 是为了隔离开发不互相干扰,merge 是为了处理协作的必然产物——分歧。这一切都是为了那个宏大的“分布式”目标服务的。它给了你无限的自由,同时也给了你把事情搞砸的无限可能。
所以问题来了,Git 这玩意儿是不是就没救了?普通人就学不会了吗?
也不是。问题不在 Git,在于我们学它的方式。市面上大部分教程,要么是字典式的命令罗列,要么是碎片化的场景讲解。官方文档像一本几千页的《新华字典》,你想查个字可以,但你指望靠字典学会写小说?网上的教程东一篇西一篇,像是捡了一堆乐高的散装零件,但没人给你图纸,告诉你怎么拼成一艘“千年隼”。
这就是为什么我非常推荐大家去看那种不追求大而全,而是聚焦于高频实战场景的教程。字节旗下团队之前出的《Git零基础实战手册》我就觉得不错。
比如它会告诉你 git pull 和 git pull –rebase 的区别和适用场景,而不是让你死记硬背。它会给你一个真实的冲突案例,手把手教你如何优雅地解决,而不是简单地删掉别人的代码。它会告诉你,当你发现一个功能分支落后主干太多时,是该用 merge 还是 rebase 来同步,以及这两种选择背后的利弊。
说到底,Git 的设计哲学是“给你无限的自由,也给你上吊的绳子”。而一本好的指导教程,就是教你如何用这根绳子去织渔网、去攀岩,而不是不小心给自己打一个死结。我们的目标不是成为一个能背下所有命令的 Git 考古学家,而是成为一个能在团队中游刃有余、不坑队友、还能在关键时刻拯救世界的 Git 工匠。