Git 解决的是「变化怎么被管理」的问题
写代码时,麻烦往往出现在第一版之后:需求会变,代码会改,团队成员还会同时推进不同任务。
今天改了一个按钮,明天修了一个 bug,后天又试了一条新方案。过几天发现新方案不行,想退回上一版;同事也在改同一批文件,大家还要把改动合到一起。只靠复制文件夹,很快就会变成一堆 final、final2、final-really。
Git 是一个版本控制系统。它的核心工作很朴素:记录项目在不同时间点的状态,知道每次是谁改了什么,允许人们比较、回退、分支开发和合并协作。
初学 Git,不必一开始就把所有命令背完。更好的顺序是理解 4 个概念:提交、三棵树、分支、远程仓库。命令只是操作这些概念的按钮。
Git 用快照记录项目历史
很多人会把 Git 想成「自动保存历史版本的工具」。这个理解没错,但还不够准确。
Git 每次提交(commit)时,会记录项目在那一刻的快照,并给这个快照一个唯一编号。这个编号通常是一串很长的哈希值,平时只看前几位就够。每个提交还会指向上一个提交,于是项目历史就连成了一条线。
flowchart LR
A["C1<br/>初始化项目"] --> B["C2<br/>新增登录页"]
B --> C["C3<br/>修复表单校验"]
C --> D["C4<br/>调整样式"]
有了这条线,Git 就能回答几类很重要的问题:现在这一版和上一版差在哪里;某个文件从什么时候变成这样;如果 C4 有问题,能不能退回 C3 的状态。
commit 比「保存一下」更正式。它是在项目历史里打一个明确的钉子:这个时间点的代码值得被记录。
工作区、暂存区、仓库分别做什么
Git 入门最容易卡住的地方,是为什么改了文件以后还要先 git add,再 git commit。理解这一步,很多命令会一下子顺起来。
本地 Git 通常可以看成三层:
- 工作区:正在编辑的文件,也就是开发者眼前看到的项目目录。
- 暂存区:准备进入下一次提交的改动清单。
- 仓库:已经被正式保存下来的提交历史。
flowchart LR
W["工作区<br/>正在改文件"] -->|git add| S["暂存区<br/>挑选要提交的改动"]
S -->|git commit| R["本地仓库<br/>保存成一次提交"]
R -->|git checkout / restore| W
暂存区的价值在于「挑选」。一个下午可能改了三件事:修 bug、调样式、顺手改文案。最好不要把它们一次性揉进同一个提交。开发者可以先把修 bug 的文件放进暂存区,提交成一条清楚记录,再处理样式和文案。
初学者最好尽早养成一个习惯:每次提交只讲一件事。提交越清楚,回看历史、排查问题、让同事 review 都越轻松。
分支让试验和协作不挤在一条路上
分支(branch)是 Git 里很关键的概念。它可以先理解成指向某个提交的指针。新建分支很轻,所以开发者可以为一个功能、一个 bug、一次实验单独开一条路。
比如 main 是稳定主线,准备上线的代码都在这里。要做登录功能时,可以开一个 feature-login 分支,在里面提交几次。等功能完成、测试通过,再把它合回 main。
gitGraph
commit id: "C1"
commit id: "C2"
branch feature-login
checkout feature-login
commit id: "L1"
commit id: "L2"
checkout main
commit id: "C3"
merge feature-login id: "M1"
分支的意义还在于给变化留出隔离空间。没确定的想法先放在分支上,稳定后再合入主线;出了问题,也能清楚知道是哪条分支带来的变化。
初学阶段不需要立刻掌握所有分支策略。先记住一个够用规则:稳定代码放在主线,新功能和修复尽量开分支,合并前先确认能跑通。
远程仓库负责把本地历史同步给团队
Git 本身是分布式版本控制系统。每个开发者电脑上的仓库,都有一份完整历史。GitHub、GitLab、Gitee 这类平台常被当作团队共同使用的远程仓库。
本地提交只存在本机。要让别人看到,需要 git push 推到远程。别人有了新提交,本地要通过 git pull 或 git fetch 拉回来。
flowchart LR
L1["开发者 A<br/>本地仓库"] -->|git push| O["远程仓库<br/>团队共享历史"]
O -->|git pull| L2["开发者 B<br/>本地仓库"]
L2 -->|git push| O
O -->|git pull| L1
这种结构有一个好处:开发者可以在本地离线提交,等网络可用或代码准备好后再同步。它也带来一个现实问题:如果两个人改了同一处代码,合并时可能出现冲突。
冲突通常不是 Git 出错,而是两边改动都成立,Git 无法替人判断哪一版才对。它会把冲突位置标出来,开发者需要打开文件,决定保留哪部分,或者把两边改动重新整理成第三种写法。
常用命令可以放回这张表里
理解概念后,再看命令就不再像背单词。大多数日常命令都能放回「看状态、选改动、保存、切分支、同步」这几类动作里。
| 任务 | 常用命令 | 作用 |
| --- | --- | --- |
| 查看当前状态 | git status | 看哪些文件被修改、暂存或未跟踪 |
| 查看差异 | git diff | 看工作区和暂存区之间的改动 |
| 暂存改动 | git add <file> | 把选中的改动放进下一次提交 |
| 创建提交 | git commit -m "message" | 把暂存区保存成本地提交 |
| 查看历史 | git log --oneline | 用简短形式查看提交记录 |
| 新建并切换分支 | git switch -c <branch> | 从当前位置开一条新分支 |
| 切换分支 | git switch <branch> | 切到已有分支继续工作 |
| 拉取远程更新 | git pull | 把远程变化同步到本地 |
| 推送本地提交 | git push | 把本地提交同步到远程 |
新手最该频繁使用的是 git status。它会告诉当前处在哪个分支、哪些文件变了、哪些改动已经暂存、下一步可以做什么。很多时候,读懂 status 的输出,比急着敲下一条命令更有用。
一次最小的 Git 工作流
日常开发里,一个很小的工作流可以这样走:
1. 从主线拉到最新:git pull。
2. 开一条新分支:git switch -c fix-login-error。
3. 修改代码或文档。
4. 查看变化:git status 和 git diff。
5. 暂存相关文件:git add <file>。
6. 创建提交:git commit -m "Fix login error message"。
7. 推到远程:git push。
8. 在代码托管平台发起合并请求。
这套流程重在节奏清楚:先同步,再隔离修改;先检查,再提交;先推送,再让别人 review。
一个团队如果能把这个节奏跑稳,Git 就会成为团队讨论变化、审查变化和恢复变化的基础设施。
新手最该避开的几个坑
第一,不要把所有改动塞进一个大提交。大提交看起来省事,后面排查问题会很痛苦。
第二,不要在没有看 git status 的情况下乱试命令。很多 Git 问题,第一步都是先确认当前状态。
第三,不要害怕分支。把不确定的工作放进分支,比直接在主线上改来改去更稳。
第四,不要把冲突当成灾难。冲突只是两边都改了同一块内容,Git 需要人来做判断。
第五,不要急着用复杂命令解决一切。rebase、reset、cherry-pick 都有用,但入门阶段先把 status、add、commit、switch、pull、push 用熟,更重要。
学 Git 的正确顺序
Git 的命令很多,但入门不需要从命令大全开始。更合适的顺序是:
- 先理解提交:一次提交就是一次值得记录的项目快照。
- 再理解三棵树:工作区负责修改,暂存区负责挑选,仓库负责保存。
- 接着理解分支:分支让不同任务在不同路线上推进。
- 最后理解远程:远程仓库让团队共享历史并完成协作。
等这些概念变得自然,再去学回退、变基、挑提交、标签和复杂冲突处理,就不会觉得 Git 是一套黑魔法。
对初学者来说,Git 最重要的能力,是在每次操作前知道自己正在移动哪一层、保存哪一次变化、同步到哪里。做到这一点,Git 就会从「让人紧张的命令行工具」变成日常开发里很可靠的一张安全网。
还没有评论,你可以写下第一条。