本文重点说明了 Git 的工作区、暂存区、本地仓库和远程仓库,以及 Git 与 SVN 的协作模型。

1. 版本控制解决什么问题

版本控制系统(VCS)用于记录文件随时间发生的变化,使开发者能够:
  • 查看谁在什么时间修改了哪些内容;
  • 对比两个版本之间的差异;
  • 恢复到历史版本;
  • 让多人并行开发并合并修改;
  • 通过分支隔离功能开发、修复和发布工作。

2. Git 的基本模型

Git 是分布式版本控制系统。每次正常克隆都会得到项目历史和对象数据库的本地副本,因此大多数查看历史、创建分支、提交等操作可以离线完成。
Git 日常使用涉及四个位置:
  1. 工作区(Working Tree):正在编辑的实际文件。
  1. 暂存区(Index / Staging Area):下一次提交准备包含的快照。
  1. 本地仓库(Local Repository):已经创建的提交历史。
  1. 远程仓库(Remote Repository):GitHub、GitLab 或公司服务器上的共享仓库。
典型数据流:
从远程获取数据:
Git 并不要求“每次修改前必须先同步”。但团队开发时,在开始工作或推送前获取远程最新状态,可以减少冲突。

3. Git 的三种使用方式

  • 命令行 CLI:Git Bash、PowerShell、Terminal。
  • 图形界面 GUI:Fork、SourceTree、GitKraken 等。
  • IDE 集成:Visual Studio、VS Code、JetBrains Rider 等。
GUI 不是 CUI。CUI 通常指字符用户界面,GUI 指图形用户界面。

4. 常用命令分类

本章从「初始化和克隆」「查看状态和差异」和「暂存和提交」等方面说明常用命令分类。

4.1 初始化和克隆

git init 将当前目录初始化为 Git 仓库;git clone 会复制远程仓库并自动设置默认远程名 origin

4.2 查看状态和差异

  • git diff:工作区与暂存区之间的差异。
  • git diff --staged:暂存区与当前提交之间的差异。
  • git log:查看提交历史。

4.3 暂存和提交

git commit -a -m "..." 只会自动暂存已经被 Git 跟踪的文件的修改和删除,不会自动加入新建的未跟踪文件。

4.4 删除和重命名

直接在文件管理器中删除或重命名也可以,但之后仍需使用 git add -A 记录变化。

4.5 远程仓库

当前新仓库通常使用 main 作为默认分支,但实际名称应通过 git branch --show-current 确认,不能固定假设为 master

4.6 分支

git checkout 仍然可用,但现代 Git 将常见职责拆分为:
  • git switch:切换或创建分支;
  • git restore:恢复文件;
  • git checkout:兼容旧用法,也可处理更多低层场景。

4.7 标签

正确的批量推送参数是 --tags,不是 --tag

4.8 临时保存

stash 适合暂时切换任务,不应代替正常提交和分支。

5. 撤销操作:restore、reset、revert

这是 Git 最容易混淆的部分。

5.1 git restore

用于恢复工作区文件或取消暂存:
第一条会丢失未提交修改,执行前应确认。

5.2 git reset

reset 可以移动当前分支的 HEAD,并根据模式影响暂存区和工作区:
  • --soft:只移动 HEAD,保留暂存区和工作区。
  • --mixed:移动 HEAD 并重置暂存区,保留工作区;这是默认模式。
  • --hard:同时重置 HEAD、暂存区和工作区,可能永久丢失未提交修改。
git reset --hard 不应随意用于已经推送并被他人使用的共享历史。

5.3 git revert

revert 不改写已有历史,而是创建一个新的“反向提交”。对已经推送的公共分支,通常优先使用 revert

5.4 恢复误删提交

只要对象尚未被垃圾回收,reflog 经常可以找回本地误操作前的提交。

6. .gitignore

.gitignore 用来忽略不应进入仓库的文件,例如:
  • 编译输出;
  • 临时缓存;
  • IDE 本地设置;
  • 密钥和环境变量;
  • Unity 的 Library/Temp/Logs/ 等可再生成目录。
注意:
  • .gitignore 只影响尚未被跟踪的文件;
  • 已经提交过的文件不会因为后来加入忽略规则就自动停止跟踪;
  • 可使用 git check-ignore -v <文件> 排查匹配了哪条规则。

7. 冲突处理

冲突通常发生在两条开发线修改了相同文件的相同区域时。
基本流程:
常见冲突标记:
版本控制系统只能帮助标出文本冲突,业务语义是否正确仍需开发者判断。

8. SVN 的基本模型

SVN 是集中式版本控制系统。版本历史的权威副本位于中央仓库,开发者在本地使用工作副本。
常见流程:
准确理解:
  • 即使中央服务器不可用,开发者通常仍能编辑本地工作副本;
  • 但无法更新、提交或访问完整中央历史;
  • SVN 默认也支持“复制—修改—合并”模型,并不是所有文件都必须加锁;
  • 对 PSD、音频、场景二进制文件等难以合并的资源,可以使用锁机制避免多人同时修改。

9. Git 与 SVN 对比

本章从「Git」和「SVN」两方面说明 Git 与 SVN 对比。

9.1 Git

  • 分布式,本地仓库包含历史;
  • 本地提交、分支和查看历史速度快;
  • 分支成本低,适合并行功能开发;
  • 离线可完成多数操作;
  • 学习成本相对更高;
  • 大型二进制资源需要 Git LFS 等补充方案。

9.2 SVN

  • 集中式,中央仓库是权威历史;
  • 权限和目录级管理直观;
  • 工作副本操作模型较简单;
  • 对需要锁定的二进制美术资源较友好;
  • 网络或中央服务故障会阻断更新和提交;
  • 分支通常通过目录复制实现,使用习惯与 Git 不同。

10. 游戏项目中的选型建议

本章从「代码为主的小型项目」和「美术资源很多的集中式流程」两方面说明游戏项目中的选型建议。

10.1 代码为主的小型项目

优先考虑 Git:
  • 使用功能分支;
  • 代码评审通过 Pull Request;
  • 将可再生成目录加入 .gitignore
  • 大文件使用 Git LFS。

10.2 美术资源很多的集中式流程

SVN 或其他集中式资产管理工具仍可能更适合:
  • 对不可合并文件设置锁;
  • 规定场景、Prefab 和大资源的负责人;
  • 提交前先更新并解决冲突;
  • 将代码评审和资源审批流程分开。

11. 总结

Git 适合以本地提交、分支和合并为核心的分布式协作;SVN 适合强调集中权限、目录级管理和统一主线的流程。选型时应结合资产类型、团队规模、网络环境和发布方式,而不是只比较命令数量。
无论使用哪种工具,都要先确认工作区状态和变更范围,再执行提交、回退或冲突处理。

12. 官方参考